file-systems: Fix UTF-16 handling in initrd.

Follow-up to f73f4b3a2d.

* gnu/build/file-systems.scm (bytevector->u16-list): New procedure.
(utf16->string): New procedure.
This commit is contained in:
Danny Milosavljevic 2020-05-03 21:40:04 +02:00
parent 96e399ee30
commit bb357c509e
No known key found for this signature in database
GPG key ID: E71A35542C30BAA5

View file

@ -110,6 +110,31 @@ (define (bytevector-utf16-length bv)
(loop (+ index 2)))
length))))
(define* (bytevector->u16-list bv endianness #:optional (index 0))
(if (< index (bytevector-length bv))
(cons (bytevector-u16-ref bv index endianness)
(bytevector->u16-list bv endianness (+ index 2)))
'()))
;; The initrd doesn't have iconv data, so do the conversion ourselves.
(define (utf16->string bv endianness)
(list->string
(map integer->char
(reverse
(let loop ((remainder (bytevector->u16-list bv endianness))
(result '()))
(match remainder
(() result)
((a) (cons a result))
((a b x ...)
(if (and (>= a #xD800) (< a #xDC00) ; high surrogate
(>= b #xDC00) (< b #xE000)) ; low surrogate
(loop x (cons (+ #x10000
(* #x400 (- a #xD800))
(- b #xDC00))
result))
(loop (cons b x) (cons a result))))))))))
(define (null-terminated-utf16->string bv endianness)
(utf16->string (sub-bytevector bv 0 (bytevector-utf16-length bv))
endianness))