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:
parent
96e399ee30
commit
bb357c509e
|
@ -110,6 +110,31 @@ (define (bytevector-utf16-length bv)
|
||||||
(loop (+ index 2)))
|
(loop (+ index 2)))
|
||||||
length))))
|
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)
|
(define (null-terminated-utf16->string bv endianness)
|
||||||
(utf16->string (sub-bytevector bv 0 (bytevector-utf16-length bv))
|
(utf16->string (sub-bytevector bv 0 (bytevector-utf16-length bv))
|
||||||
endianness))
|
endianness))
|
||||||
|
|
Loading…
Reference in a new issue