diff --git a/host/chez/io.ss b/host/chez/io.ss index 20c081c..766bb28 100644 --- a/host/chez/io.ss +++ b/host/chez/io.ss @@ -284,4 +284,11 @@ ((file-exists? (string-append (car roots) "/" nm)) (make-jfile (string-append (car roots) "/" nm))) (else (loop (cdr roots))))))) (def-var! "clojure.java.io" "resource" jolt-io-resource) -(def-var! "clojure.java.io" "as-url" (lambda (x) (if (and (jhost? x) (string=? (jhost-tag x) "url")) x (make-url (jolt-str-render-one x))))) +;; as-url honors a library-registered URL class (e.g. jolt-lang/http-client's full +;; java.net.URL shim) so io/as-url and (URL. spec) agree; else the file-only jhost. +(def-var! "clojure.java.io" "as-url" + (lambda (x) + (cond ((and (jhost? x) (string=? (jhost-tag x) "url")) x) + ((htable? x) x) + (else (let ((ctor (lookup-class class-ctors-tbl "URL"))) + (if ctor (ctor (jolt-str-render-one x)) (make-url (jolt-str-render-one x)))))))) diff --git a/host/chez/natives-array.ss b/host/chez/natives-array.ss index 895fd85..ba7f6ac 100644 --- a/host/chez/natives-array.ss +++ b/host/chez/natives-array.ss @@ -205,3 +205,29 @@ (cons "chunk" na-chunk) (cons "chunk-cons" na-chunk-cons) (cons "chunk-first" na-chunk-first) (cons "chunk-rest" na-chunk-rest) (cons "chunk-next" na-chunk-next) (cons "chunked-seq?" na-chunked-seq?))) + +;; --- clojure.java.io/copy --------------------------------------------------- +;; Copy src -> dst, JVM-style. Raw bytes (byte-array / bytevector / string) and a +;; jhost reader write in one shot; any other source (a stream shim with a .read +;; method, e.g. jolt-lang/http-client's ByteArrayInputStream) drains via .read +;; into a byte-array buffer and .write to dst — both reached through method +;; dispatch, so a library's tagged-table streams work without the host knowing +;; their layout. Lives here (not io.ss) because io.ss loads before byte-array. +(define (jolt-io-copy src dst . _opts) + (define (write-all! bytes) + (record-method-dispatch dst "write" (list->cseq (list bytes 0 (vector-length (jolt-array-vec bytes)))))) + (cond + ((or (bytevector? src) (string? src) + (and (jolt-array? src) (eq? (jolt-array-kind src) 'byte))) + (write-all! (na-byte-array src))) + ((and (jhost? src) (member (jhost-tag src) '("string-reader" "pushback-reader"))) + (write-all! (na-byte-array (drain-reader src)))) + (else + (let ((buf (na-byte-array 8192))) + (let loop () + (let ((n (record-method-dispatch src "read" (list->cseq (list buf 0 8192))))) + (when (and (number? n) (> (jnum->exact n) 0)) + (record-method-dispatch dst "write" (list->cseq (list buf 0 n))) + (loop))))))) + jolt-nil) +(def-var! "clojure.java.io" "copy" jolt-io-copy)