add xdecode

main
Matthew Butterick 6 years ago
parent 141589ddd3
commit 79b3cbae73

@ -28,10 +28,10 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
[else +inf.0]))
(for/list ([i (in-naturals)]
#:break (or (eof-object? (peek-byte)) (= (pos port) end-pos)))
(decode (xarray-base-type xa) #:parent new-parent))]
(xdecode (xarray-base-type xa) #:parent new-parent))]
;; we have decoded-len, which is treated as count of items
[else (for/list ([i (in-range decoded-len)])
(decode (xarray-base-type xa) #:parent new-parent))])))
(xdecode (xarray-base-type xa) #:parent new-parent))])))
(define/pre-encode (xarray-encode xa array [port-arg (current-output-port)] #:parent [parent #f])
(unless (sequence? array)
@ -77,6 +77,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
(struct xarray xarray-base (length-type) #:transparent
#:methods gen:xenomorphic
[(define decode xarray-decode)
(define xdecode xarray-decode)
(define encode xarray-encode)
(define size xarray-size)])

@ -11,7 +11,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Bitfield.coffee
(define port (->input-port port-arg))
(parameterize ([current-input-port port])
(define flag-hash (mhasheq))
(define val (decode (xbitfield-type xb)))
(define val (xdecode (xbitfield-type xb)))
(for ([(flag i) (in-indexed (xbitfield-flags xb))]
#:when flag)
(hash-set! flag-hash flag (bitwise-bit-set? val i)))
@ -32,6 +32,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Bitfield.coffee
(struct xbitfield xbase (type flags) #:transparent
#:methods gen:xenomorphic
[(define decode xbitfield-decode)
(define xdecode xbitfield-decode)
(define encode xbitfield-encode)
(define size xbitfield-size)])

@ -33,6 +33,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Buffer.coffee
(struct xbuffer xbase (len) #:transparent
#:methods gen:xenomorphic
[(define decode xbuffer-decode)
(define xdecode xbuffer-decode)
(define encode xbuffer-encode)
(define size xbuffer-size)])

@ -28,6 +28,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Enum.coffee
(struct xenum xbase (type options) #:transparent
#:methods gen:xenomorphic
[(define decode xenum-decode)
(define xdecode xenum-decode)
(define encode xenum-encode)
(define size xenum-size)])

@ -57,7 +57,8 @@
(define-generics xenomorphic
(encode xenomorphic val [port] #:parent [parent])
(decode xenomorphic [port] #:parent [parent])
(xdecode xenomorphic [port] #:parent [parent])
(decode xenomorphic [port])
(size xenomorphic [item] #:parent [parent]))
(define (finalize-size size)

@ -26,7 +26,7 @@ https://github.com/mbutterick/restructure/blob/master/src/LazyArray.coffee
(pos port (+ starting-pos (* (size type #f #:parent parent) index)))
;; use explicit `port` arg below because this evaluation is delayed
(begin0
(post-decode xla (decode type port #:parent parent))
(post-decode xla (xdecode type port #:parent parent))
(pos port orig-pos)))
(pos port (+ (pos port) (* decoded-len (size (xarray-base-type xla) #f #:parent parent))))))))
@ -40,6 +40,7 @@ https://github.com/mbutterick/restructure/blob/master/src/LazyArray.coffee
(struct xlazy-array xarray-base () #:transparent
#:methods gen:xenomorphic
[(define decode xlazy-array-decode)
(define xdecode xlazy-array-decode)
(define encode xlazy-array-encode)
(define size xlazy-array-size)])

@ -60,6 +60,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(struct xint xnumber (size signed endian) #:transparent
#:methods gen:xenomorphic
[(define decode xint-decode)
(define xdecode xint-decode)
(define encode xint-encode)
(define size (λ (i [item #f] #:parent [parent #f]) (xint-size i)))])
@ -174,6 +175,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(struct xfloat xnumber (size endian) #:transparent
#:methods gen:xenomorphic
[(define decode xfloat-decode)
(define xdecode xfloat-decode)
(define encode xfloat-encode)
(define size (λ (i [item #f] #:parent [parent #f]) (xfloat-size i)))])
@ -207,6 +209,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(struct xfixed xint (fracbits) #:transparent
#:methods gen:xenomorphic
[(define decode xfixed-decode)
(define xdecode xfixed-decode)
(define encode xfixed-encode)
(define size (λ (i [item #f] #:parent [parent #f]) (xint-size i)))])

@ -1,3 +1,4 @@
#lang debug racket/base
(require "helper.rkt")
(provide (all-defined-out))
@ -17,7 +18,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Optional.coffee
(define port (->input-port port-arg))
(parameterize ([current-input-port port])
(when (resolve-condition xo parent)
(decode (xoptional-type xo) #:parent parent))))
(xdecode (xoptional-type xo) #:parent parent))))
(define/pre-encode (xoptional-encode xo val [port-arg (current-output-port)] #:parent [parent #f])
(define port (if (output-port? port-arg) port-arg (open-output-bytes)))
@ -33,6 +34,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Optional.coffee
(struct xoptional xbase (type condition) #:transparent
#:methods gen:xenomorphic
[(define decode xoptional-decode)
(define xdecode xoptional-decode)
(define encode xoptional-encode)
(define size xoptional-size)])

@ -19,7 +19,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Pointer.coffee
(define/post-decode (xpointer-decode xp [port-arg (current-input-port)] #:parent [parent #f])
(define port (->input-port port-arg))
(parameterize ([current-input-port port])
(define offset (decode (xpointer-offset-type xp) #:parent parent))
(define offset (xdecode (xpointer-offset-type xp) #:parent parent))
(cond
[(and allow-null (= offset (null-value xp))) #f] ; handle null pointers
[else
@ -39,7 +39,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Pointer.coffee
[else
(define orig-pos (pos port))
(pos port ptr)
(set! val (decode (xpointer-type xp) #:parent parent))
(set! val (xdecode (xpointer-type xp) #:parent parent))
(pos port orig-pos)
val]))
(if (pointer-lazy? xp)
@ -93,6 +93,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Pointer.coffee
(struct xpointer xbase (offset-type type options) #:transparent
#:methods gen:xenomorphic
[(define decode xpointer-decode)
(define xdecode xpointer-decode)
(define encode xpointer-encode)
(define size xpointer-size)])

@ -25,6 +25,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Reserved.coffee
(struct xreserved xbase (type count) #:transparent
#:methods gen:xenomorphic
[(define decode xreserved-decode)
(define xdecode xreserved-decode)
(define encode xreserved-encode)
(define size xreserved-size)])

@ -83,6 +83,7 @@ https://github.com/mbutterick/restructure/blob/master/src/String.coffee
(struct xstring xbase (len encoding) #:transparent
#:methods gen:xenomorphic
[(define decode xstring-decode)
(define xdecode xstring-decode)
(define encode xstring-encode)
(define size xstring-size)])
@ -110,6 +111,7 @@ https://github.com/mbutterick/restructure/blob/master/src/String.coffee
(struct xsymbol xstring () #:transparent
#:methods gen:xenomorphic
[(define decode xsymbol-decode)
(define xdecode xsymbol-decode)
(define encode xsymbol-encode)
(define size xstring-size)])

@ -51,14 +51,14 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
([(key type) (d:in-dict fields)])
(define val (if (procedure? type)
(type sdr)
(decode type port #:parent sdr)))
(xdecode type port #:parent sdr)))
(unless (void? val)
(d:dict-set! sdr key val))
(d:dict-set! sdr '_currentOffset (- (pos port) (d:dict-ref sdr '_startOffset)))
sdr))
(define-syntax-rule (decode/hash . ARGS)
(dump (decode . ARGS)))
(dump (xdecode . ARGS)))
(define (xstruct-decode xs [port-arg (current-input-port)] #:parent [parent #f] [len 0])
(define port (->input-port port-arg))
@ -116,6 +116,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
(struct xstruct structish (fields) #:transparent #:mutable
#:methods gen:xenomorphic
[(define decode xstruct-decode)
(define xdecode xstruct-decode)
(define encode xstruct-encode)
(define size xstruct-size)])

@ -14,93 +14,94 @@ https://github.com/mbutterick/restructure/blob/master/test/Array.coffee
(test-case
"decode fixed length"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (+xarray uint8 4)) '(1 2 3 4))))
(check-equal? (decode (+xarray #:type uint8 #:length 4)) '(1 2 3 4))))
(test-case
"decode with post-decode"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(define xa (+xarray uint8 4))
(define xa (+xarray #:type uint8 #:length 4))
(set-post-decode! xa (λ (val . _) (map (λ (x) (* 2 x)) val)))
(check-equal? (decode xa) '(2 4 6 8))))
(test-case
"decode fixed number of bytes"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (+xarray uint16be 4 'bytes)) '(258 772))))
(check-equal? (decode (+xarray #:type uint16be #:length 4 #:count-bytes #t)) '(258 772))))
(test-case
"decode length from parent key"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (+xarray uint8 'len) #:parent (mhash 'len 4)) '(1 2 3 4))))
(check-equal? (xdecode (+xarray #:type uint8 #:length 'len) #:parent (mhash 'len 4)) '(1 2 3 4))))
(test-case
"decode byte count from parent key"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (+xarray uint16be 'len 'bytes) #:parent (mhash 'len 4)) '(258 772))))
(check-equal? (xdecode (+xarray #:type uint16be #:length 'len #:count-bytes #t) #:parent (mhash 'len 4)) '(258 772))))
(test-case
"decode length as number before array"
(parameterize ([current-input-port (open-input-bytes (bytes 4 1 2 3 4 5))])
(check-equal? (decode (+xarray uint8 uint8)) '(1 2 3 4))))
(check-equal? (decode (+xarray #:type uint8 #:length uint8)) '(1 2 3 4))))
(test-case
"decode byte count as number before array"
(parameterize ([current-input-port (open-input-bytes (bytes 4 1 2 3 4 5))])
(check-equal? (decode (+xarray uint16be uint8 'bytes)) '(258 772))))
(check-equal? (decode (+xarray #:type uint16be #:length uint8 #:count-bytes #t)) '(258 772))))
(test-case
"decode length from function"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (+xarray uint8 (λ _ 4))) '(1 2 3 4))))
(check-equal? (decode (+xarray #:type uint8 #:length (λ _ 4))) '(1 2 3 4))))
(test-case
"decode byte count from function"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (+xarray uint16be (λ _ 4) 'bytes)) '(258 772))))
(check-equal? (decode (+xarray #:type uint16be #:length (λ _ 4) #:count-bytes #t)) '(258 772))))
(test-case
"decode to the end of parent if no length given"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (+xarray uint8) #:parent (mhash '_length 4 '_startOffset 0)) '(1 2 3 4))))
(check-equal? (xdecode (+xarray #:type uint8) #:parent (mhash '_length 4 '_startOffset 0)) '(1 2 3 4))))
(test-case
"decode to the end of the stream if parent exists, but its length is 0"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (+xarray uint8) #:parent (mhash '_length 0 '_startOffset 0)) '(1 2 3 4 5))))
(check-equal? (xdecode (+xarray #:type uint8) #:parent (mhash '_length 0 '_startOffset 0)) '(1 2 3 4 5))))
(test-case
"decode to the end of the stream if no parent and length is given"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4))])
(check-equal? (decode (+xarray uint8)) '(1 2 3 4 ))))
(check-equal? (decode (+xarray #:type uint8)) '(1 2 3 4 ))))
(test-case
"use array length"
(check-equal? (size (+xarray uint8 10) '(1 2 3 4)) 4))
(check-equal? (size (+xarray #:type uint8 #:length 10) '(1 2 3 4)) 4))
(test-case
"add size of length field before string"
(check-equal? (size (+xarray uint8 uint8) '(1 2 3 4)) 5))
(check-equal? (size (+xarray #:type uint8 #:length uint8) '(1 2 3 4)) 5))
(test-case
"use defined length if no value given"
(check-equal? (size (+xarray uint8 10)) 10))
(check-equal? (size (+xarray #:type uint8 #:length 10)) 10))
(test-case
"encode using array length"
(check-equal? (encode (+xarray uint8 10) '(1 2 3 4) #f) (bytes 1 2 3 4)))
(check-equal? (encode (+xarray #:type uint8 #:length 10) '(1 2 3 4) #f) (bytes 1 2 3 4)))
(test-case
"encode with pre-encode"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(define xa (+xarray uint8 4))
(define xa (+xarray #:type uint8 #:length 4))
(set-pre-encode! xa (λ (val . _) (map (λ (x) (* 2 x)) val)))
(check-equal? (encode xa '(1 2 3 4) #f) (bytes 2 4 6 8))))
(test-case
"encode length as number before array"
(check-equal? (encode (+xarray uint8 uint8) '(1 2 3 4) #f) (bytes 4 1 2 3 4)))
(check-equal? (encode (+xarray #:type uint8 #:length uint8) '(1 2 3 4) #f) (bytes 4 1 2 3 4)))
(test-case
"add pointers after array if length is encoded at start"
(check-equal? (encode (+xarray (+xpointer #:offset-type uint8
#:type uint8) uint8) '(1 2 3 4) #f) (bytes 4 5 6 7 8 1 2 3 4)))
(check-equal? (encode (+xarray #:type (+xpointer #:offset-type uint8
#:type uint8)
#:length uint8) '(1 2 3 4) #f) (bytes 4 5 6 7 8 1 2 3 4)))

@ -33,8 +33,8 @@ https://github.com/mbutterick/restructure/blob/master/test/Buffer.coffee
"buffer should decode with parent key length"
(parameterize ([current-input-port (open-input-bytes (bytes #xab #xff #x1f #xb6))])
(define buf (+xbuffer #:length 'len))
(check-equal? (decode buf #:parent (hash 'len 3)) (bytes #xab #xff #x1f))
(check-equal? (decode buf #:parent (hash 'len 1)) (bytes #xb6))))
(check-equal? (xdecode buf #:parent (hash 'len 3)) (bytes #xab #xff #x1f))
(check-equal? (xdecode buf #:parent (hash 'len 1)) (bytes #xb6))))
(test-case
"size should return size"

@ -16,12 +16,12 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee
(test-case
"decode should handle null pointers"
(parameterize ([current-input-port (open-input-bytes (bytes 0))])
(check-false (decode (+xpointer) #:parent (mhash '_startOffset 50)))))
(check-false (xdecode (+xpointer) #:parent (mhash '_startOffset 50)))))
(test-case
"decode should use local offsets from start of parent by default"
(parameterize ([current-input-port (open-input-bytes (bytes 1 53))])
(check-equal? (decode (+xpointer) #:parent (mhash '_startOffset 0)) 53)))
(check-equal? (xdecode (+xpointer) #:parent (mhash '_startOffset 0)) 53)))
(test-case
"decode should support immediate offsets"
@ -32,27 +32,27 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee
"decode should support offsets relative to the parent"
(parameterize ([current-input-port (open-input-bytes (bytes 0 0 1 53))])
(pos (current-input-port) 2)
(check-equal? (decode (+xpointer #:relative-to 'parent)
(check-equal? (xdecode (+xpointer #:relative-to 'parent)
#:parent (mhash 'parent (mhash '_startOffset 2))) 53)))
(test-case
"decode should support global offsets"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 4 0 0 0 53))])
(pos (current-input-port) 2)
(check-equal? (decode (+xpointer #:relative-to 'global)
(check-equal? (xdecode (+xpointer #:relative-to 'global)
#:parent (mhash 'parent (mhash 'parent (mhash '_startOffset 2))))
53)))
(test-case
"decode should support returning pointer if there is no decode type"
(parameterize ([current-input-port (open-input-bytes (bytes 4))])
(check-equal? (decode (+xpointer uint8 'void)
(check-equal? (xdecode (+xpointer uint8 'void)
#:parent (mhash '_startOffset 0)) 4)))
(test-case
"decode should support decoding pointers lazily"
(parameterize ([current-input-port (open-input-bytes (bytes 1 53))])
(define res (decode (+xstruct (dictify 'ptr (+xpointer #:lazy #t)))))
(define res (decode (+xstruct 'ptr (+xpointer #:lazy #t))))
(check-true (promise? (dict-ref (struct-dict-res-_kv res) 'ptr)))
(check-equal? (dict-ref res 'ptr) 53)))

@ -25,12 +25,12 @@ https://github.com/mbutterick/restructure/blob/master/test/String.coffee
(test-case
"decode length from parent key"
(parameterize ([current-input-port (open-input-bytes #"testing")])
(check-equal? (decode (+xstring 'len) #:parent (mhash 'len 7)) "testing")))
(check-equal? (xdecode (+xstring 'len) #:parent (mhash 'len 7)) "testing")))
(test-case
"decode length as number before string"
(parameterize ([current-input-port (open-input-bytes #"\x07testing")])
(check-equal? (decode (+xstring uint8) #:parent (mhash 'len 7)) "testing")))
(check-equal? (xdecode (+xstring uint8) #:parent (mhash 'len 7)) "testing")))
(test-case
"decode utf8"

@ -21,7 +21,7 @@ https://github.com/mbutterick/restructure/blob/master/src/VersionedStruct.coffee
(unless parent
(raise-argument-error 'xversioned-struct-decode "valid parent" parent))
((xversioned-struct-version-getter xvs) parent)]
[else (decode (xversioned-struct-type xvs) port)]))
[else (xdecode (xversioned-struct-type xvs) port)]))
(when (dict-ref (xversioned-struct-versions xvs) 'header #f)
(_parse-fields port res (dict-ref (xversioned-struct-versions xvs) 'header)))
@ -30,7 +30,7 @@ https://github.com/mbutterick/restructure/blob/master/src/VersionedStruct.coffee
(raise-argument-error 'xversioned-struct-decode "valid version key" (cons version (xversioned-struct-versions xvs)))))
(cond
[(xversioned-struct? fields) (decode fields port #:parent parent)]
[(xversioned-struct? fields) (xdecode fields port #:parent parent)]
[else (_parse-fields port res fields)
res]))
@ -89,6 +89,7 @@ https://github.com/mbutterick/restructure/blob/master/src/VersionedStruct.coffee
(struct xversioned-struct structish (type versions version-getter version-setter) #:transparent #:mutable
#:methods gen:xenomorphic
[(define decode xversioned-struct-decode)
(define xdecode xversioned-struct-decode)
(define encode xversioned-struct-encode)
(define size xversioned-struct-size)])

Loading…
Cancel
Save