You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
typesetting/pitfall/restructure/string.rkt

61 lines
2.3 KiB
Racket

8 years ago
#lang restructure/racket
8 years ago
(require "number.rkt" "utils.rkt" "stream.rkt")
8 years ago
(provide (all-defined-out))
8 years ago
#|
approximates
https://github.com/mbutterick/restructure/blob/master/src/String.coffee
|#
8 years ago
(define (byte-length val encoding)
8 years ago
(define encoder
(caseq encoding
8 years ago
[(ascii utf8) string->bytes/utf-8]))
(bytes-length (encoder (format "~a" val))))
8 years ago
8 years ago
(define-subclass Streamcoder (StringT [len #f] [encoding 'ascii])
8 years ago
(define/augment (decode stream [parent #f])
8 years ago
(let ([len (or (resolve-length len stream parent) (send stream count-nonzero-chars))]
[encoding (if (procedure? encoding)
(or (encoding parent) 'ascii)
encoding)]
[adjustment (if (and (not len) (< (· stream pos) (· stream length))) 1 0)])
(define string (send stream readString len encoding))
(send stream pos (+ (· stream pos) adjustment))
string))
8 years ago
8 years ago
(define/augment (encode stream val [parent #f])
(let* ([val (format "~a" val)]
[encoding (if (procedure? encoding)
(or (encoding (and parent (· parent val)) 'ascii))
encoding)])
(when (NumberT? len)
(send len encode stream (byte-length val encoding)))
(send stream writeString val encoding)
(when (not len) (send stream writeUInt8 #x00)))) ; null terminated when no len
8 years ago
(define/override (size [val #f] [parent #f])
8 years ago
(if (not val)
(resolve-length len #f parent)
(let* ([encoding (if (procedure? encoding)
(or (encoding (and parent (· parent val)) 'ascii))
encoding)]
[encoding (if (eq? encoding 'utf16be) 'utf16le encoding)])
(+ (byte-length val encoding) (cond
[(not len) 1]
[(NumberT? len) (send len size)]
[else 0]))))))
8 years ago
(define-values (String? +String) (values StringT? +StringT))
8 years ago
(test-module
8 years ago
(require "stream.rkt")
(define stream (+DecodeStream #"\2BCDEF"))
(define S (+String uint8 'utf8))
(check-equal? (send S decode stream) "BC")
8 years ago
(check-equal? (send S encode #f "Mike") #"\4Mike")
(check-equal? (send (+String) size "foobar") 7)) ; null terminated when no len