|
|
|
#lang restructure/racket
|
|
|
|
(provide (all-defined-out))
|
|
|
|
|
|
|
|
#| approximates
|
|
|
|
https://github.com/mbutterick/restructure/blob/master/src/DecodeStream.coffee
|
|
|
|
|#
|
|
|
|
|
|
|
|
(define (read-bytes-exact count p)
|
|
|
|
(define bs (read-bytes count p))
|
|
|
|
(unless (and (bytes? bs) (= (bytes-length bs) count))
|
|
|
|
(raise-argument-error 'read-bytes-exact (format "byte string length ~a" count) bs))
|
|
|
|
bs)
|
|
|
|
|
|
|
|
(provide (rename-out [type-sizes TYPES]))
|
|
|
|
|
|
|
|
(define type-sizes (let-values ([(intkeys intvalues)
|
|
|
|
(for*/lists (intkeys intvalues)
|
|
|
|
([signed (in-list '(U ""))]
|
|
|
|
[size (in-list '(8 16 24 32))])
|
|
|
|
(values
|
|
|
|
(format "~aInt~a" signed size)
|
|
|
|
(/ size 8)))])
|
|
|
|
(for/hash ([key (in-list (append '(Float Double) intkeys))]
|
|
|
|
[value (in-list (append '(4 8) intvalues))]
|
|
|
|
#:when key
|
|
|
|
[endian '("" BE LE)])
|
|
|
|
(values (string->symbol (format "~a~a" key endian)) value))))
|
|
|
|
|
|
|
|
;; basically just a wrapper for a Racket port
|
|
|
|
(define-subclass object% (RDecodeStream [buffer-in #f])
|
|
|
|
(field [_port (cond
|
|
|
|
[(not buffer-in) (open-input-bytes (bytes))]
|
|
|
|
[(bytes? buffer-in) (open-input-bytes buffer-in)]
|
|
|
|
[(input-port? buffer-in) buffer-in]
|
|
|
|
[else (raise-argument-error 'RDecodeStream "bytes or input port" buffer-in)])])
|
|
|
|
(getter-field [pos (port-position _port)])
|
|
|
|
(getter-field [length (and (bytes? buffer-in) (bytes-length buffer-in))])
|
|
|
|
|
|
|
|
(define/public (read count)
|
|
|
|
(read-bytes-exact count _port)))
|