remove `size` from generic interface

main
Matthew Butterick 5 years ago
parent 1cbbd7aa56
commit 5fc17d8b8f

@ -56,9 +56,6 @@ We don't make port-arg the last arg (similar to other Racket port funcs) because
(define port (if (output-port? port-arg) port-arg (open-output-bytes)))
(send xo x:encode val port parent . args)
(unless port-arg (get-output-bytes port)))
(define (size xo [val #f] #:parent [parent #f] . args)
(send xo x:size val parent . args))
(define (xenomorphic-type? x) (is-a? x x:base%))
(define xenomorphic? xenomorphic-type?)

@ -23,8 +23,8 @@ https://github.com/mbutterick/restructure/blob/master/src/Bitfield.coffee
(unless (= (length named-flags) (length (remove-duplicates named-flags)))
(raise-argument-error 'x:bitfield% "no duplicates among flag names" named-flags)))
(when (> (length @flags) (* 8 (size @type)))
(raise-argument-error 'x:bitfield% (format "~a flags or fewer (~a-byte bitfield)" (* 8 (size @type)) (size @type)) (length @flags)))
(when (> (length @flags) (* 8 (send @type x:size)))
(raise-argument-error 'x:bitfield% (format "~a flags or fewer (~a-byte bitfield)" (* 8 (send @type x:size)) (send @type x:size)) (length @flags)))
(define/augment (x:decode port parent)
(define val (send @type x:decode port))

@ -115,7 +115,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
(random-pick (list uint8 uint16be uint16le uint32be uint32le double))))
(define size-num-types
(for/sum ([num-type (in-list field-types)])
(size num-type)))
(send num-type x:size)))
(define xs (x:dict (for/list ([num-type (in-list field-types)])
(cons (gensym) num-type))))
(define bs (apply bytes (for/list ([i (in-range size-num-types)])

@ -168,10 +168,10 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(encode i 772 op)
(check-equal? (get-output-bytes op) (bytes 1 2 3 4)))
(check-equal? (size (x:int 1)) 1)
(check-equal? (size (x:int)) 2)
(check-equal? (size (x:int 4)) 4)
(check-equal? (size (x:int 8)) 8)
(check-equal? (send (x:int 1) x:size) 1)
(check-equal? (send (x:int) x:size) 2)
(check-equal? (send (x:int 4) x:size) 4)
(check-equal? (send (x:int 8) x:size) 8)
(check-equal? (decode int8 (bytes 127)) 127)
(check-equal? (decode int8 (bytes 255)) -1)

@ -134,4 +134,4 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
(require rackunit "base.rkt")
(check-equal? (decode (x:list uint16be 3) #"ABCDEF") '(16706 17220 17734))
(check-equal? (encode (x:list uint16be 3) '(16706 17220 17734) #f) #"ABCDEF")
(check-equal? (size (x:list uint16be) '(1 2 3)) 6))
(check-equal? (send (x:list uint16be) x:size '(1 2 3)) 6))

@ -56,7 +56,7 @@
(define S (x:string uint8 'utf8))
(check-equal? (decode S #"\2BCDEF") "BC")
(check-equal? (encode S "Mike" #f) #"\4Mike")
(check-equal? (size (x:string) "foobar") 7) ; null terminated when no len
(check-equal? (send (x:string) x:size "foobar") 7) ; null terminated when no len
(check-equal? (decode (x:symbol 4) #"Mike") 'Mike)
(check-equal? (encode (x:symbol 4) 'Mike #f) #"Mike")
(check-equal? (encode (x:symbol 4) "Mike" #f) #"Mike")

@ -19,7 +19,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Bitfield.coffee
(test-case
"bitfield: should have the right size"
(check-equal? (size bitfield) 1))
(check-equal? (send bitfield x:size) 1))
(test-case
"bitfield: should reject too many flags"

@ -37,11 +37,11 @@ https://github.com/mbutterick/restructure/blob/master/test/Buffer.coffee
(test-case
"bytes: hould return size"
(check-equal? (size (x:bytes #:length 2) (bytes #xab #xff)) 2))
(check-equal? (send (x:bytes #:length 2) x:size (bytes #xab #xff)) 2))
(test-case
"bytes: hould use defined length if no value given"
(check-equal? (size (x:bytes #:length 10)) 10))
(check-equal? (send (x:bytes #:length 10) x:size) 10))
(test-case
"bytes: should encode"

@ -46,23 +46,24 @@ https://github.com/mbutterick/restructure/blob/master/test/Struct.coffee
(test-case
"dict: compute the correct size"
(check-equal? (size (x:dict 'name (x:string #:length uint8) 'age uint8)
(hasheq 'name "roxyb" 'age 32)) 7))
(check-equal? (send (x:dict 'name (x:string #:length uint8) 'age uint8)
x:size (hasheq 'name "roxyb" 'age 32)) 7))
(test-case
"dict: compute the correct size with pointers"
(check-equal? (size (x:dict 'name (x:string #:length uint8)
(check-equal? (send (x:dict 'name (x:string #:length uint8)
'age uint8
'ptr (x:pointer #:type uint8 #:dest-type (x:string #:length uint8)))
x:size
(mhash 'name "roxyb" 'age 21 'ptr "hello")) 14))
(test-case
"dict: get the correct size when no value is given"
(check-equal? (size (x:dict 'name (x:string 4) 'age uint8)) 5))
(check-equal? (send (x:dict 'name (x:string 4) 'age uint8) x:size) 5))
(test-case
"dict: throw when getting non-fixed length size and no value is given"
(check-exn exn:fail:contract? (λ () (size (x:dict 'name (x:string #:length uint8) 'age uint8)))))
(check-exn exn:fail:contract? (λ () (send (x:dict 'name (x:string #:length uint8) 'age uint8) x:size))))
(test-case
"dict: encode objects to buffers"

@ -23,7 +23,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Enum.coffee
(test-case
"enum: should have the right size"
(check-equal? (size e) 1))
(check-equal? (send e x:size) 1))
(test-case
"enum: decode should decode"

@ -85,15 +85,15 @@ https://github.com/mbutterick/restructure/blob/master/test/Array.coffee
(test-case
"list: use array length"
(check-equal? (size (x:list #:type uint8 #:length 10) '(1 2 3 4)) 4))
(check-equal? (send (x:list #:type uint8 #:length 10) x:size '(1 2 3 4)) 4))
(test-case
"list: add size of length field before string"
(check-equal? (size (x:list #:type uint8 #:length uint8) '(1 2 3 4)) 5))
(check-equal? (send (x:list #:type uint8 #:length uint8) x:size '(1 2 3 4)) 5))
(test-case
"list: use defined length if no value given"
(check-equal? (size (x:list #:type uint8 #:length 10)) 10))
(check-equal? (send (x:list #:type uint8 #:length 10) x:size) 10))
(test-case
"list: encode using array length"

@ -14,7 +14,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(parameterize ([current-input-port (open-input-bytes (bytes #xab #xff))])
(check-equal? (decode uint8) #xab)
(check-equal? (decode uint8) #xff))
(check-equal? (size uint8) 1)
(check-equal? (send uint8 x:size) 1)
(let ([port (open-output-bytes)])
(encode uint8 #xab port)
(encode uint8 #xff port)
@ -28,7 +28,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(parameterize ([current-input-port (open-input-bytes (bytes #xab #xff))])
(check-equal? (decode myuint8) #xdeadbeef)
(check-equal? (decode myuint8) #xdeadbeef))
(check-equal? (size myuint8) 1)
(check-equal? (send myuint8 x:size) 1)
(let ([port (open-output-bytes)])
(encode myuint8 #xab port)
(encode myuint8 #xff port)
@ -42,13 +42,13 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: uint16be: decode, size, encode"
(check-equal? (decode uint16be (open-input-bytes (bytes #xab #xff))) #xabff)
(check-equal? (size uint16be) 2)
(check-equal? (send uint16be x:size) 2)
(check-equal? (encode uint16be #xabff #f) (bytes #xab #xff)))
(test-case
"number: uint16le: decode, size, encode"
(check-equal? (decode uint16le (open-input-bytes (bytes #xff #xab))) #xabff)
(check-equal? (size uint16le) 2)
(check-equal? (send uint16le x:size) 2)
(check-equal? (encode uint16le #xabff #f) (bytes #xff #xab)))
(test-case
@ -58,13 +58,13 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: uint24be: decode, size, encode"
(check-equal? (decode uint24be (open-input-bytes (bytes #xff #xab #x24))) #xffab24)
(check-equal? (size uint24be) 3)
(check-equal? (send uint24be x:size) 3)
(check-equal? (encode uint24be #xffab24 #f) (bytes #xff #xab #x24)))
(test-case
"number: uint24le: decode, size, encode"
(check-equal? (decode uint24le (open-input-bytes (bytes #x24 #xab #xff))) #xffab24)
(check-equal? (size uint24le) 3)
(check-equal? (send uint24le x:size) 3)
(check-equal? (encode uint24le #xffab24 #f) (bytes #x24 #xab #xff)))
(test-case
@ -74,13 +74,13 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: uint32be: decode, size, encode"
(check-equal? (decode uint32be (open-input-bytes (bytes #xff #xab #x24 #xbf))) #xffab24bf)
(check-equal? (size uint32be) 4)
(check-equal? (send uint32be x:size) 4)
(check-equal? (encode uint32be #xffab24bf #f) (bytes #xff #xab #x24 #xbf)))
(test-case
"number: uint32le: decode, size, encode"
(check-equal? (decode uint32le (open-input-bytes (bytes #xbf #x24 #xab #xff))) #xffab24bf)
(check-equal? (size uint32le) 4)
(check-equal? (send uint32le x:size) 4)
(check-equal? (encode uint32le #xffab24bf #f) (bytes #xbf #x24 #xab #xff)))
(test-case
@ -88,7 +88,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(let ([port (open-input-bytes (bytes #x7f #xff))])
(check-equal? (decode int8 port) 127)
(check-equal? (decode int8 port) -1))
(check-equal? (size int8) 1)
(check-equal? (send int8 x:size) 1)
(let ([port (open-output-bytes)])
(encode int8 127 port)
(encode int8 -1 port)
@ -102,7 +102,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
"number: int16be: decode, size, encode"
(let ([port (open-input-bytes (bytes #xff #xab))])
(check-equal? (decode int16be port) -85))
(check-equal? (size int16be) 2)
(check-equal? (send int16be x:size) 2)
(let ([port (open-output-bytes)])
(encode int16be -85 port)
(check-equal? (get-output-bytes port) (bytes #xff #xab))))
@ -110,7 +110,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: int16le: decode, size, encode"
(check-equal? (decode int16le (open-input-bytes (bytes #xab #xff))) -85)
(check-equal? (size int16le) 2)
(check-equal? (send int16le x:size) 2)
(check-equal? (encode int16le -85 #f) (bytes #xab #xff)))
(test-case
@ -120,13 +120,13 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: int24be: decode, size, encode"
(check-equal? (decode int24be (open-input-bytes (bytes #xff #xab #x24))) -21724)
(check-equal? (size int24be) 3)
(check-equal? (send int24be x:size) 3)
(check-equal? (encode int24be -21724 #f) (bytes #xff #xab #x24)))
(test-case
"number: int24le: decode, size, encode"
(check-equal? (decode int24le (open-input-bytes (bytes #x24 #xab #xff))) -21724)
(check-equal? (size int24le) 3)
(check-equal? (send int24le x:size) 3)
(check-equal? (encode int24le -21724 #f) (bytes #x24 #xab #xff)))
(test-case
"number: int32 is the same endianness as the platform"
@ -136,13 +136,13 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: int32be: decode, size, encode"
(check-equal? (decode int32be (open-input-bytes (bytes #xff #xab #x24 #xbf))) -5561153)
(check-equal? (size int32be) 4)
(check-equal? (send int32be x:size) 4)
(check-equal? (encode int32be -5561153 #f) (bytes #xff #xab #x24 #xbf)))
(test-case
"number: int32le: decode, size, encode"
(check-equal? (decode int32le (open-input-bytes (bytes #xbf #x24 #xab #xff))) -5561153)
(check-equal? (size int32le) 4)
(check-equal? (send int32le x:size) 4)
(check-equal? (encode int32le -5561153 #f) (bytes #xbf #x24 #xab #xff)))
(test-case
@ -152,13 +152,13 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: floatbe: decode, size, encode"
(check-= (decode floatbe (open-input-bytes (bytes #x43 #x7a #x8c #xcd))) 250.55 0.01)
(check-equal? (size floatbe) 4)
(check-equal? (send floatbe x:size) 4)
(check-equal? (encode floatbe 250.55 #f) (bytes #x43 #x7a #x8c #xcd)))
(test-case
"number: floatle: decode, size, encode"
(check-= (decode floatle (open-input-bytes (bytes #xcd #x8c #x7a #x43))) 250.55 0.01)
(check-equal? (size floatle) 4)
(check-equal? (send floatle x:size) 4)
(check-equal? (encode floatle 250.55 #f) (bytes #xcd #x8c #x7a #x43)))
(test-case
@ -168,13 +168,13 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: doublebe: decode, size, encode"
(check-equal? (decode doublebe (open-input-bytes (bytes #x40 #x93 #x4a #x3d #x70 #xa3 #xd7 #x0a))) 1234.56)
(check-equal? (size doublebe) 8)
(check-equal? (send doublebe x:size) 8)
(check-equal? (encode doublebe 1234.56 #f) (bytes #x40 #x93 #x4a #x3d #x70 #xa3 #xd7 #x0a)))
(test-case
"number: doublele: decode, size, encode"
(check-equal? (decode doublele (open-input-bytes (bytes #x0a #xd7 #xa3 #x70 #x3d #x4a #x93 #x40))) 1234.56)
(check-equal? (size doublele) 8)
(check-equal? (send doublele x:size) 8)
(check-equal? (encode doublele 1234.56 #f) (bytes #x0a #xd7 #xa3 #x70 #x3d #x4a #x93 #x40)))
(test-case
@ -185,13 +185,13 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: fixed16be: decode, size, encode"
(check-= (decode fixed16be (open-input-bytes (bytes #x19 #x57))) 25.34 0.01)
(check-equal? (size fixed16be) 2)
(check-equal? (send fixed16be x:size) 2)
(check-equal? (encode fixed16be 25.34 #f) (bytes #x19 #x57)))
(test-case
"number: fixed16le: decode, size, encode"
(check-= (decode fixed16le (open-input-bytes (bytes #x57 #x19))) 25.34 0.01)
(check-equal? (size fixed16le) 2)
(check-equal? (send fixed16le x:size) 2)
(check-equal? (encode fixed16le 25.34 #f) (bytes #x57 #x19)))
(test-case
@ -202,11 +202,11 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee
(test-case
"number: fixed32be: decode, size, encode"
(check-= (decode fixed32be (open-input-bytes (bytes #x00 #xfa #x8c #xcc))) 250.55 0.01)
(check-equal? (size fixed32be) 4)
(check-equal? (send fixed32be x:size) 4)
(check-equal? (encode fixed32be 250.55 #f) (bytes #x00 #xfa #x8c #xcc)))
(test-case
"number: fixed32le: decode, size, encode"
(check-= (decode fixed32le (open-input-bytes (bytes #xcc #x8c #xfa #x00))) 250.55 0.01)
(check-equal? (size fixed32le) 4)
(check-equal? (send fixed32le x:size) 4)
(check-equal? (encode fixed32le 250.55 #f) (bytes #xcc #x8c #xfa #x00)))

@ -55,23 +55,23 @@ https://github.com/mbutterick/restructure/blob/master/test/Optional.coffee
(test-case
"optional: size"
(check-equal? (size (x:optional uint8 #:condition #f)) 0))
(check-equal? (send (x:optional uint8 #:condition #f) x:size) 0))
(test-case
"optional: size should return 0 when condition is a function and falsy"
(check-equal? (size (x:optional uint8 #:condition (λ _ #f))) 0))
(check-equal? (send (x:optional uint8 #:condition (λ _ #f)) x:size) 0))
(test-case
"optional: size should return given type size when condition is omitted"
(check-equal? (size (x:optional uint8)) 1))
(check-equal? (send (x:optional uint8) x:size) 1))
(test-case
"optional: size should return given type size when condition is truthy"
(check-equal? (size (x:optional uint8 #:condition #t)) 1))
(check-equal? (send (x:optional uint8 #:condition #t) x:size) 1))
(test-case
"optional: size should return given type size when condition is a function and truthy"
(check-equal? (size (x:optional uint8 #:condition (λ _ #t))) 1))
(check-equal? (send (x:optional uint8 #:condition (λ _ #t)) x:size) 1))
(test-case
"optional: encode should not encode when condition is falsy"

@ -61,41 +61,41 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee
(test-case
"pointer: size"
(let ([parent (mhash x:pointer-size-key 0)])
(check-equal? (size (x:pointer uint8) 10 #:parent parent) 1)
(check-equal? (send (x:pointer uint8) x:size 10 parent) 1)
(check-equal? (hash-ref parent x:pointer-size-key) 1)))
(test-case
"pointer: size should add to immediate pointerSize"
(let ([parent (mhash x:pointer-size-key 0)])
(check-equal? (size (x:pointer uint8 #:relative-to 'immediate) 10 #:parent parent) 1)
(check-equal? (send (x:pointer uint8 #:relative-to 'immediate) x:size 10 parent) 1)
(check-equal? (hash-ref parent x:pointer-size-key) 1)))
(test-case
"pointer: size should add to parent pointerSize"
(let ([parent (mhash x:parent-key (mhash x:pointer-size-key 0))])
(check-equal? (size (x:pointer uint8 #:relative-to 'parent) 10 #:parent parent) 1)
(check-equal? (send (x:pointer uint8 #:relative-to 'parent) x:size 10 parent) 1)
(check-equal? (hash-ref* parent x:parent-key x:pointer-size-key) 1)))
(test-case
"pointer: size should add to global pointerSize"
(let ([parent (mhash x:parent-key (mhash x:parent-key (mhash x:parent-key (mhash x:pointer-size-key 0))))])
(check-equal? (size (x:pointer uint8 #:relative-to 'global) 10 #:parent parent) 1)
(check-equal? (send (x:pointer uint8 #:relative-to 'global) x:size 10 parent) 1)
(check-equal? (hash-ref* parent x:parent-key x:parent-key x:parent-key x:pointer-size-key) 1)))
(test-case
"pointer: size should handle void pointers"
(let ([parent (mhash x:pointer-size-key 0)])
(check-equal? (size (x:pointer uint8 'void) (x:void-pointer uint8 50) #:parent parent) 1)
(check-equal? (send (x:pointer uint8 'void) x:size (x:void-pointer uint8 50) parent) 1)
(check-equal? (hash-ref parent x:pointer-size-key) 1)))
(test-case
"pointer: size should throw if no type and not a void pointer"
(let ([parent (mhash x:pointer-size-key 0)])
(check-exn exn:fail:contract? (λ () (size (x:pointer uint8 'void) 30 #:parent parent)))))
(check-exn exn:fail:contract? (λ () (send (x:pointer uint8 'void) x:size 30 parent)))))
(test-case
"pointer: size should return a fixed size without a value"
(check-equal? (size (x:pointer uint8)) 1))
(check-equal? (send (x:pointer uint8) x:size) 1))
(test-case
"pointer: encode should handle null pointers"

@ -13,11 +13,11 @@ https://github.com/mbutterick/restructure/blob/master/test/Reserved.coffee
(test-case
"reserved: size should have a default count of 1"
(check-equal? (size (x:reserved uint8)) 1))
(check-equal? (send (x:reserved uint8) x:size) 1))
(test-case
"reserved: size should allow custom counts and types"
(check-equal? (size (x:reserved uint16be 10)) 20))
(check-equal? (send (x:reserved uint16be 10) x:size) 20))
(test-case
"reserved: should decode"

@ -57,7 +57,7 @@ https://github.com/mbutterick/restructure/blob/master/test/LazyArray.coffee
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(define xla (x:stream uint8 4))
(define arr (decode xla))
(check-equal? (size xla arr) 4)))
(check-equal? (send xla x:size arr) 4)))
(test-case
"lazy-array: encode should work with xlazy-arrays"

@ -56,29 +56,29 @@ https://github.com/mbutterick/restructure/blob/master/test/String.coffee
(test-case
"string: size should use string length"
(check-equal? (size (x:string 7) "testing") 7))
(check-equal? (send (x:string 7) x:size "testing") 7))
(test-case
"string: size should use correct encoding"
(check-equal? (size (x:string 10 'utf8) "🍻") 4))
(check-equal? (send (x:string 10 'utf8) x:size "🍻") 4))
(test-case
"string: size should use encoding from function"
(check-equal? (size (x:string 10 (λ _ 'utf8)) "🍻") 4))
(check-equal? (send (x:string 10 (λ _ 'utf8)) x:size "🍻") 4))
(test-case
"string: should add size of length field before string"
(check-equal? (size (x:string uint8 'utf8) "🍻") 5))
(check-equal? (send (x:string uint8 'utf8) x:size "🍻") 5))
; todo: it "should work with utf16be encoding"
(test-case
"string: size should take null-byte into account"
(check-equal? (size (x:string #f 'utf8) "🍻") 5))
(check-equal? (send (x:string #f 'utf8) x:size "🍻") 5))
(test-case
"string: size should use defined length if no value given"
(check-equal? (size (x:string 10)) 10))
(check-equal? (send (x:string 10) x:size) 10))
(test-case
"string: encode using string length"

@ -52,29 +52,29 @@
(test-case
"symbol: size should use symbol length"
(check-equal? (size (x:symbol 7) 'testing) 7))
(check-equal? (send (x:symbol 7) x:size 'testing) 7))
(test-case
"symbol: size should use correct encoding"
(check-equal? (size (x:symbol 10 'utf8) '🍻) 4))
(check-equal? (send (x:symbol 10 'utf8) x:size '🍻) 4))
(test-case
"symbol: size should use encoding from function"
(check-equal? (size (x:symbol 10 (λ _ 'utf8)) '🍻) 4))
(check-equal? (send (x:symbol 10 (λ _ 'utf8)) x:size '🍻) 4))
(test-case
"symbol: should add size of length field before symbol"
(check-equal? (size (x:symbol uint8 'utf8) '🍻) 5))
(check-equal? (send (x:symbol uint8 'utf8) x:size '🍻) 5))
; todo: it "should work with utf16be encoding"
(test-case
"symbol: size should take null-byte into account"
(check-equal? (size (x:symbol #f 'utf8) '🍻) 5))
(check-equal? (send (x:symbol #f 'utf8) x:size '🍻) 5))
(test-case
"symbol: size should use defined length if no value given"
(check-equal? (size (x:symbol 10)) 10))
(check-equal? (send (x:symbol 10) x:size) 10))
(test-case
"symbol: encode using symbol length"

@ -86,15 +86,15 @@ https://github.com/mbutterick/restructure/blob/master/test/Array.coffee
(test-case
"vector: use array length"
(check-equal? (size (x:vector #:type uint8 #:length 10) '#(1 2 3 4)) 4))
(check-equal? (send (x:vector #:type uint8 #:length 10) x:size '#(1 2 3 4)) 4))
(test-case
"vector: add size of length field before string"
(check-equal? (size (x:vector #:type uint8 #:length uint8) '#(1 2 3 4)) 5))
(check-equal? (send (x:vector #:type uint8 #:length uint8) x:size '#(1 2 3 4)) 5))
(test-case
"vector: use defined length if no value given"
(check-equal? (size (x:vector #:type uint8 #:length 10)) 10))
(check-equal? (send (x:vector #:type uint8 #:length 10) x:size) 10))
(test-case
"vector: encode using array length"

@ -1,6 +1,7 @@
#lang racket/base
(require rackunit
racket/dict
racket/class
sugar/unstable/dict
"../base.rkt"
"../number.rkt"
@ -18,12 +19,12 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(test-case
"versioned dict: decode should get version from number type"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
(check-equal? (decode vstruct) (mhasheq 'name "roxyb" 'age 21 x:version-key 0)))
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x0aroxyb 🤘\x15\x00"))])
@ -32,14 +33,14 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(test-case
"versioned dict: decode should get version from number type, nested"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8
'nested (x:dict 'foo uint8))
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8
'nested (x:dict 'foo uint8))))])
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8
'nested (x:dict 'foo uint8))
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8
'nested (x:dict 'foo uint8))))])
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15\x2a")])
(check-equal? (decode vstruct) (mhasheq 'name "roxyb" 'age 21 'nested (mhasheq 'foo 42) x:version-key 0)))
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x0aroxyb 🤘\x15\x00\x2a"))])
@ -48,45 +49,45 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(test-case
"versioned dict: decode should throw for unknown version"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(parameterize ([current-input-port (open-input-bytes #"\x05\x05roxyb\x15")])
(check-exn exn:fail:contract? (λ () (decode vstruct))))))
(test-case
"versioned dict: decode should support common header block"
(let ([vstruct (x:versioned-dict uint8
(dictify
'header (dictify 'age uint8
'alive uint8)
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii))
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'gender uint8)))])
(dictify
'header (dictify 'age uint8
'alive uint8)
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii))
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'gender uint8)))])
(parameterize ([current-input-port (open-input-bytes #"\x00\x15\x01\x05roxyb")])
(check-equal? (decode vstruct) (mhasheq 'name "roxyb"
'age 21
'alive 1
x:version-key 0)))
'age 21
'alive 1
x:version-key 0)))
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x15\x01\x0aroxyb 🤘\x00"))])
(check-equal? (decode vstruct) (mhasheq 'name "roxyb 🤘"
'age 21
x:version-key 1
'alive 1
'gender 0)))))
'age 21
x:version-key 1
'alive 1
'gender 0)))))
(test-case
"versioned dict: decode should support parent version key"
(let ([vstruct (x:versioned-dict x:version-key
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x15")])
(check-equal? (decode vstruct #:parent (mhash x:version-key 0))
(mhasheq 'name "roxyb" 'age 21 x:version-key 0)))
@ -97,14 +98,14 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(test-case
"versioned dict: decode should support sub versioned dicts"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string uint8))
1 (dictify 'name (x:string uint8)
'isDessert uint8)))))])
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string uint8))
1 (dictify 'name (x:string uint8)
'isDessert uint8)))))])
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
(check-equal? (decode vstruct #:parent (mhash x:version-key 0))
(mhasheq 'name "roxyb" 'age 21 x:version-key 0)))
@ -118,13 +119,13 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(test-case
"versioned dict: decode should support process hook"
(let ([vstruct (x:versioned-dict #:post-decode (λ (val) (hash-set! val 'processed "true") val)
uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
(check-equal? (decode vstruct)
(mhasheq 'name "roxyb" 'processed "true" 'age 21 x:version-key 0)))))
@ -132,77 +133,77 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(test-case
"versioned dict: size should compute the correct size"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(check-equal? (size vstruct (mhasheq 'name "roxyb"
'age 21
x:version-key 0)) 8)
(check-equal? (size vstruct (mhasheq 'name "roxyb 🤘"
'gender 0
'age 21
x:version-key 1)) 14)))
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(check-equal? (send vstruct x:size (mhasheq 'name "roxyb"
'age 21
x:version-key 0)) 8)
(check-equal? (send vstruct x:size (mhasheq 'name "roxyb 🤘"
'gender 0
'age 21
x:version-key 1)) 14)))
(test-case
"versioned dict: size should throw for unknown version"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(check-exn exn:fail:contract? (λ () (size vstruct (mhasheq 'name "roxyb" 'age 21 x:version-key 5))))))
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(check-exn exn:fail:contract? (λ () (send vstruct x:size (mhasheq 'name "roxyb" 'age 21 x:version-key 5))))))
(test-case
"versioned dict: size should support common header block"
(let ([struct (x:versioned-dict uint8
(dictify
'header (dictify 'age uint8
'alive uint8)
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii))
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'gender uint8)))])
(check-equal? (size struct (mhasheq 'name "roxyb" 'age 21 'alive 1 x:version-key 0)) 9)
(check-equal? (size struct (mhasheq 'name "roxyb 🤘" 'gender 0 'age 21 'alive 1 x:version-key 1)) 15)))
(dictify
'header (dictify 'age uint8
'alive uint8)
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii))
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'gender uint8)))])
(check-equal? (send struct x:size (mhasheq 'name "roxyb" 'age 21 'alive 1 x:version-key 0)) 9)
(check-equal? (send struct x:size (mhasheq 'name "roxyb 🤘" 'gender 0 'age 21 'alive 1 x:version-key 1)) 15)))
(test-case
"versioned dict: size should compute the correct size with pointers"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'ptr (x:pointer uint8 #:dest-type (x:string uint8)))))])
(check-equal? (size vstruct (mhasheq 'name "roxyb"
'age 21
x:version-key 1
'ptr "hello")) 15)))
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'ptr (x:pointer uint8 #:dest-type (x:string uint8)))))])
(check-equal? (send vstruct x:size (mhasheq 'name "roxyb"
'age 21
x:version-key 1
'ptr "hello")) 15)))
(test-case
"versioned dict: size should throw if no value is given"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(check-exn exn:fail:contract? (λ () (size vstruct)))))
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))])
(check-exn exn:fail:contract? (λ () (send vstruct x:size)))))
(test-case
"versioned dict: encode should encode objects to buffers"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))]
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))]
[op (open-output-bytes)])
(encode vstruct (mhasheq 'name "roxyb" 'age 21 x:version-key 0) op)
(encode vstruct (mhasheq 'name "roxyb 🤘" 'age 21 'gender 0 x:version-key 1) op)
@ -211,24 +212,24 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(test-case
"versioned dict: encode should throw for unknown version"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))]
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))]
[op (open-output-bytes)])
(check-exn exn:fail:contract? (λ () (encode vstruct op (mhasheq 'name "roxyb" 'age 21 x:version-key 5))))))
(test-case
"versioned dict: encode should support common header block"
(let ([vstruct (x:versioned-dict uint8
(dictify
'header (dictify 'age uint8
'alive uint8)
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii))
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'gender uint8)))]
(dictify
'header (dictify 'age uint8
'alive uint8)
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii))
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'gender uint8)))]
[op (open-output-bytes)])
(encode vstruct (mhasheq 'name "roxyb" 'age 21 'alive 1 x:version-key 0) op)
(encode vstruct (mhasheq 'name "roxyb 🤘" 'gender 0 'age 21 'alive 1 x:version-key 1) op)
@ -237,28 +238,28 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(test-case
"versioned dict: encode should encode pointer data after structure"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'ptr (x:pointer uint8 #:dest-type (x:string uint8)))))]
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'ptr (x:pointer uint8 #:dest-type (x:string uint8)))))]
[op (open-output-bytes)])
(encode vstruct (mhasheq x:version-key 1 'name "roxyb" 'age 21 'ptr "hello") op)
(check-equal? (get-output-bytes op) (string->bytes/utf-8 "\x01\x05roxyb\x15\x09\x05hello"))))
#;(test-case
"versioned dict: encode should support preEncode hook"
(let ([vstruct (x:versioned-dict uint8
"versioned dict: encode should support preEncode hook"
(let ([vstruct (x:versioned-dict uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8)
1 (x:dict 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8)))]
[op (open-output-bytes)])
(set-pre-encode! vstruct (λ (val) (hash-set! val x:version-key (if (hash-ref val 'gender #f) 1 0)) val))
(encode vstruct (mhasheq 'name "roxyb" 'age 21 x:version-key 0) op)
(encode vstruct (mhasheq 'name "roxyb 🤘" 'age 21 'gender 0) op)
(check-equal? (get-output-bytes op) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00"))))
'age uint8
'gender uint8)))]
[op (open-output-bytes)])
(set-pre-encode! vstruct (λ (val) (hash-set! val x:version-key (if (hash-ref val 'gender #f) 1 0)) val))
(encode vstruct (mhasheq 'name "roxyb" 'age 21 x:version-key 0) op)
(encode vstruct (mhasheq 'name "roxyb 🤘" 'age 21 'gender 0) op)
(check-equal? (get-output-bytes op) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00"))))

@ -59,5 +59,5 @@
(check-equal? (decode (x:vector uint16be 3) #"ABCDEF") '#(16706 17220 17734))
(check-equal? (encode (x:vector uint16be 3) '(16706 17220 17734) #f) #"ABCDEF")
(check-equal? (encode (x:vector uint16be 3) '#(16706 17220 17734) #f) #"ABCDEF")
(check-equal? (size (x:vector uint16be) '#(1 2 3)) 6)
(check-equal? (size (x:vector doublebe) '#(1 2 3 4 5)) 40))
(check-equal? (send (x:vector uint16be) x:size '#(1 2 3)) 6)
(check-equal? (send (x:vector doublebe) x:size '#(1 2 3 4 5)) 40))
Loading…
Cancel
Save