Byte-array <-> bytevector interop + charset-aware (String. bytes cs)

The host carries bytes two ways: Chez bytevectors (what String/.getBytes
produce) and jolt byte-arrays (what byte-array / the Java-array shims use). They
didn't interconvert, so code mixing the two — like clj-http-lite, which buffers
into (byte-array n) but encodes via .getBytes and decodes via (String. ^[B body
charset) — broke.

- byte-array now also accepts a bytevector or a string (UTF-8 bytes), so the two
  representations convert freely at interop seams.
- (String. bytes [charset]) decodes a bytevector OR a jolt byte-array with the
  named charset (UTF-8 default; ISO-8859-1/latin1/ascii = one byte/char). It
  previously only took a bytevector and ignored the charset.

Runtime .ss shims, no re-mint. Unit covers both directions + charset.
This commit is contained in:
Yogthos 2026-06-22 13:20:27 -04:00
parent c5e1e0544a
commit 3253df979a
3 changed files with 44 additions and 5 deletions

View file

@ -46,10 +46,20 @@
(else (make-jolt-array
(list->vector (map (lambda (c) (if (char? c) c (integer->char (exact (truncate c)))))
(seq->list (jolt-seq a)))) 'char))))
;; (byte-array n [init]) | (byte-array coll). Also coerces the host's OTHER byte
;; carrier — a Chez bytevector (what String/.getBytes produce) — and a string's
;; UTF-8 bytes, so bytevector and byte-array interconvert across interop seams.
(define (na-byte-array a . rest)
(if (number? a)
(make-jolt-array (make-vector (exact (na-idx a)) (na-byte-of (if (pair? rest) (car rest) 0))) 'byte)
(make-jolt-array (list->vector (map na-byte-of (seq->list (jolt-seq a)))) 'byte)))
(cond
((number? a) (make-jolt-array (make-vector (exact (na-idx a)) (na-byte-of (if (pair? rest) (car rest) 0))) 'byte))
((bytevector? a) (make-jolt-array (list->vector (bytevector->u8-list a)) 'byte))
((string? a) (make-jolt-array (list->vector (bytevector->u8-list (string->utf8 a))) 'byte))
(else (make-jolt-array (list->vector (map na-byte-of (seq->list (jolt-seq a)))) 'byte))))
;; jolt byte-array -> Chez bytevector (for String decode / utf8->string).
(define (na-bytearray->bv arr)
(let* ((v (jolt-array-vec arr)) (n (vector-length v)) (bv (make-bytevector n)))
(do ((i 0 (+ i 1))) ((= i n)) (bytevector-u8-set! bv i (bitwise-and (exact (vector-ref v i)) #xff)))
bv))
(define (na-make-array a . rest) ; (make-array len) | (make-array type len ...)
(make-jolt-array (make-vector (exact (na-idx (if (number? a) a (car rest)))) jolt-nil) 'object))
(define (na-into-array a . rest) (na-from-seq (if (pair? rest) (car rest) a) 'object))