From 4c50c422a114e0c94587d25c5846b71c91c0a996 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Fri, 14 Dec 2018 13:21:37 -0800 Subject: [PATCH] undump --- xenomorph/xenomorph/helper.rkt | 14 +----- xenomorph/xenomorph/struct.rkt | 44 +++++++++--------- xenomorph/xenomorph/test/enum-test.rkt | 4 +- xenomorph/xenomorph/test/number-test.rkt | 8 ++-- xenomorph/xenomorph/test/optional-test.rkt | 12 ++--- xenomorph/xenomorph/test/pointer-test.rkt | 14 +++--- xenomorph/xenomorph/test/reserved-test.rkt | 4 +- xenomorph/xenomorph/test/string-test.rkt | 14 +++--- xenomorph/xenomorph/test/struct-test.rkt | 20 ++++---- .../xenomorph/test/versioned-struct-test.rkt | 46 +++++++++---------- xenomorph/xenomorph/versioned-struct.rkt | 9 ++-- 11 files changed, 91 insertions(+), 98 deletions(-) diff --git a/xenomorph/xenomorph/helper.rkt b/xenomorph/xenomorph/helper.rkt index 92a6afc4..62ab4e3f 100644 --- a/xenomorph/xenomorph/helper.rkt +++ b/xenomorph/xenomorph/helper.rkt @@ -11,22 +11,12 @@ [else (raise-argument-error '->input-port "byte string or input port" arg)])) (define private-keys '(parent _startOffset _currentOffset _length)) -(define (dump-mutable x) +(define (dict->mutable-hash x) (define h (make-hasheq)) - (for ([(k v) (in-dict (dump x))]) + (for ([(k v) (in-dict x)]) (hash-set! h k v)) h) -(define (dump x) - (cond - [(input-port? x) (port->bytes x)] - [(output-port? x) (get-output-bytes x)] - [(dict? x) (for/hasheq ([(k v) (in-dict x)] - #:unless (memq k private-keys)) - (values k v))] - [(list? x) (map dump x)] - [else x])) - (define (pos p [new-pos #f]) (when new-pos (file-position p new-pos)) diff --git a/xenomorph/xenomorph/struct.rkt b/xenomorph/xenomorph/struct.rkt index 76fdc784..2578e906 100644 --- a/xenomorph/xenomorph/struct.rkt +++ b/xenomorph/xenomorph/struct.rkt @@ -57,10 +57,10 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee (d:dict-set! sdr '_currentOffset (- (pos port) (d:dict-ref sdr '_startOffset))) sdr)) -(define-syntax-rule (decode/hash . ARGS) - (dump (xdecode . ARGS))) +(define (xstruct-decode . args) + (dict->mutable-hash (apply xstruct-xdecode args))) -(define (xstruct-decode xs [port-arg (current-input-port)] #:parent [parent #f] [len 0]) +(define (xstruct-xdecode xs [port-arg (current-input-port)] #:parent [parent #f] [len 0]) (define port (->input-port port-arg)) (parameterize ([current-input-port port]) ;; _setup and _parse-fields are separate to cooperate with VersionedStruct @@ -79,7 +79,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee 'pointerSize 0)) (define fields-size (for/sum ([(key type) (d:in-dict (xstruct-fields xs))] #:when (xenomorphic? type)) - (size type (and val (d:dict-ref val key)) #:parent parent))) + (size type (and val (d:dict-ref val key)) #:parent parent))) (define pointers-size (if include-pointers (d:dict-ref parent 'pointerSize) 0)) (+ fields-size pointers-size)) @@ -107,16 +107,16 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee (d:dict-set! parent 'pointerOffset (+ (pos port) (xstruct-size xs val #:parent parent #f))) (for ([(key type) (d:in-dict (xstruct-fields xs))]) - (encode type (d:dict-ref val key) #:parent parent)) + (encode type (d:dict-ref val key) #:parent parent)) (for ([ptr (in-list (d:dict-ref parent 'pointers))]) - (encode (d:dict-ref ptr 'type) (d:dict-ref ptr 'val) #:parent (d:dict-ref ptr 'parent))) + (encode (d:dict-ref ptr 'type) (d:dict-ref ptr 'val) #:parent (d:dict-ref ptr 'parent))) (unless port-arg (get-output-bytes port)))) (struct structish xbase () #:transparent) (struct xstruct structish (fields) #:transparent #:mutable #:methods gen:xenomorphic [(define decode xstruct-decode) - (define xdecode xstruct-decode) + (define xdecode xstruct-xdecode) (define encode xstruct-encode) (define size xstruct-size)]) @@ -125,9 +125,9 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee (unless (even? (length args)) (raise-argument-error '+xstruct "equal keys and values" dicts)) (define fields (for/list ([kv (in-slice 2 args)]) - (unless (symbol? (car kv)) - (raise-argument-error '+xstruct "symbol" (car kv))) - (apply cons kv))) + (unless (symbol? (car kv)) + (raise-argument-error '+xstruct "symbol" (car kv))) + (apply cons kv))) (unless (d:dict? fields) (raise-argument-error '+xstruct "dict" fields)) (xstruct fields)) @@ -137,15 +137,15 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee (define (random-pick xs) (list-ref xs (random (length xs)))) (check-exn exn:fail:contract? (λ () (+xstruct 42))) (for ([i (in-range 20)]) - ;; make random structs and make sure we can round trip - (define field-types - (for/list ([i (in-range 40)]) - (random-pick (list uint8 uint16be uint16le uint32be uint32le double)))) - (define size-num-types - (for/sum ([num-type (in-list field-types)]) - (size num-type))) - (define xs (+xstruct (for/list ([num-type (in-list field-types)]) - (cons (gensym) num-type)))) - (define bs (apply bytes (for/list ([i (in-range size-num-types)]) - (random 256)))) - (check-equal? (encode xs (decode xs bs) #f) bs))) \ No newline at end of file + ;; make random structs and make sure we can round trip + (define field-types + (for/list ([i (in-range 40)]) + (random-pick (list uint8 uint16be uint16le uint32be uint32le double)))) + (define size-num-types + (for/sum ([num-type (in-list field-types)]) + (size num-type))) + (define xs (+xstruct (for/list ([num-type (in-list field-types)]) + (cons (gensym) num-type)))) + (define bs (apply bytes (for/list ([i (in-range size-num-types)]) + (random 256)))) + (check-equal? (encode xs (decode xs bs) #f) bs))) \ No newline at end of file diff --git a/xenomorph/xenomorph/test/enum-test.rkt b/xenomorph/xenomorph/test/enum-test.rkt index 7fd73d22..fe3842a8 100644 --- a/xenomorph/xenomorph/test/enum-test.rkt +++ b/xenomorph/xenomorph/test/enum-test.rkt @@ -46,7 +46,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Enum.coffee (encode e "bar") (encode e "baz") (encode e "foo") - (check-equal? (dump (current-output-port)) (bytes 1 2 0)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 1 2 0)))) (test-case "encode should encode with pre-encode" @@ -55,7 +55,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Enum.coffee (encode e "bar") (encode e "baz") (encode e "foo") - (check-equal? (dump (current-output-port)) (bytes 0 0 0)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 0 0 0)))) (test-case "should throw on unknown option" diff --git a/xenomorph/xenomorph/test/number-test.rkt b/xenomorph/xenomorph/test/number-test.rkt index a10cccfb..cb5bf398 100644 --- a/xenomorph/xenomorph/test/number-test.rkt +++ b/xenomorph/xenomorph/test/number-test.rkt @@ -15,7 +15,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee (let ([port (open-output-bytes)]) (encode uint8 #xab port) (encode uint8 #xff port) - (check-equal? (dump port) (bytes #xab #xff)))) + (check-equal? (get-output-bytes port) (bytes #xab #xff)))) (test-case "uint8: decode with post-decode, size, encode with pre-encode" @@ -29,7 +29,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee (set-pre-encode! myuint8 (λ (b) #xcc)) (encode myuint8 #xab port) (encode myuint8 #xff port) - (check-equal? (dump port) (bytes #xcc #xcc)))) + (check-equal? (get-output-bytes port) (bytes #xcc #xcc)))) (test-case "uint16 is the same endianness as the platform" @@ -89,7 +89,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee (let ([port (open-output-bytes)]) (encode int8 127 port) (encode int8 -1 port) - (check-equal? (dump port) (bytes #x7f #xff)))) + (check-equal? (get-output-bytes port) (bytes #x7f #xff)))) (test-case "int32 is the same endianness as the platform" @@ -102,7 +102,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Number.coffee (check-equal? (size int16be) 2) (let ([port (open-output-bytes)]) (encode int16be -85 port) - (check-equal? (dump port) (bytes #xff #xab)))) + (check-equal? (get-output-bytes port) (bytes #xff #xab)))) (test-case "int16le: decode, size, encode" diff --git a/xenomorph/xenomorph/test/optional-test.rkt b/xenomorph/xenomorph/test/optional-test.rkt index e3749772..8d70d07a 100644 --- a/xenomorph/xenomorph/test/optional-test.rkt +++ b/xenomorph/xenomorph/test/optional-test.rkt @@ -77,7 +77,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Optional.coffee (parameterize ([current-output-port (open-output-bytes)]) (define optional (+xoptional #:type uint8 #:condition #f)) (encode optional 128) - (check-equal? (dump (current-output-port)) (bytes)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes)))) (test-case "encode with pre-encode" @@ -85,32 +85,32 @@ https://github.com/mbutterick/restructure/blob/master/test/Optional.coffee (define optional (+xoptional #:type uint8)) (set-pre-encode! optional (λ (val) 42)) (encode optional 128) - (check-equal? (dump (current-output-port)) (bytes 42)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 42)))) (test-case "encode should not encode when condition is a function and falsy" (parameterize ([current-output-port (open-output-bytes)]) (define optional (+xoptional #:type uint8 #:condition (λ _ #f))) (encode optional 128) - (check-equal? (dump (current-output-port)) (bytes)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes)))) (test-case "encode should encode when condition is omitted" (parameterize ([current-output-port (open-output-bytes)]) (define optional (+xoptional #:type uint8)) (encode optional 128) - (check-equal? (dump (current-output-port)) (bytes 128)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 128)))) (test-case "encode should encode when condition is truthy" (parameterize ([current-output-port (open-output-bytes)]) (define optional (+xoptional #:type uint8 #:condition #t)) (encode optional 128) - (check-equal? (dump (current-output-port)) (bytes 128)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 128)))) (test-case "encode should encode when condition is a function and truthy" (parameterize ([current-output-port (open-output-bytes)]) (define optional (+xoptional #:type uint8 #:condition (λ _ #t))) (encode optional 128) - (check-equal? (dump (current-output-port)) (bytes 128)))) \ No newline at end of file + (check-equal? (get-output-bytes (current-output-port)) (bytes 128)))) \ No newline at end of file diff --git a/xenomorph/xenomorph/test/pointer-test.rkt b/xenomorph/xenomorph/test/pointer-test.rkt index ede0197c..bf8a043f 100644 --- a/xenomorph/xenomorph/test/pointer-test.rkt +++ b/xenomorph/xenomorph/test/pointer-test.rkt @@ -52,7 +52,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee (test-case "decode should support decoding pointers lazily" (parameterize ([current-input-port (open-input-bytes (bytes 1 53))]) - (define res (decode (+xstruct 'ptr (+xpointer #:lazy #t)))) + (define res (xdecode (+xstruct 'ptr (+xpointer #:lazy #t)))) (check-true (promise? (dict-ref (struct-dict-res-_kv res) 'ptr))) (check-equal? (dict-ref res 'ptr) 53))) @@ -104,7 +104,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee 'pointers null)) (encode (+xpointer) #f #:parent parent) (check-equal? (dict-ref parent 'pointerSize) 0) - (check-equal? (dump (current-output-port)) (bytes 0)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 0)))) (test-case "encode should handle local offsets" @@ -118,7 +118,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee (check-equal? (dict-ref parent 'pointers) (list (mhasheq 'type uint8 'val 10 'parent parent))) - (check-equal? (dump (current-output-port)) (bytes 1)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 1)))) (test-case "encode should handle immediate offsets" @@ -132,7 +132,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee (check-equal? (dict-ref parent 'pointers) (list (mhasheq 'type uint8 'val 10 'parent parent))) - (check-equal? (dump (current-output-port)) (bytes 0)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 0)))) (test-case "encode should handle offsets relative to parent" @@ -146,7 +146,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee (check-equal? (dict-ref (dict-ref parent 'parent) 'pointers) (list (mhasheq 'type uint8 'val 10 'parent parent))) - (check-equal? (dump (current-output-port)) (bytes 2)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 2)))) (test-case "encode should handle global offsets" @@ -163,7 +163,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee (list (mhasheq 'type uint8 'val 10 'parent parent))) - (check-equal? (dump (current-output-port)) (bytes 5)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 5)))) (test-case "encode should support void pointers" @@ -177,7 +177,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Pointer.coffee (check-equal? (dict-ref parent 'pointers) (list (mhasheq 'type uint8 'val 55 'parent parent))) - (check-equal? (dump (current-output-port)) (bytes 1)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 1)))) (test-case "encode should throw if not a void pointer instance" diff --git a/xenomorph/xenomorph/test/reserved-test.rkt b/xenomorph/xenomorph/test/reserved-test.rkt index a6f833ea..8857b812 100644 --- a/xenomorph/xenomorph/test/reserved-test.rkt +++ b/xenomorph/xenomorph/test/reserved-test.rkt @@ -37,7 +37,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Reserved.coffee (parameterize ([current-output-port (open-output-bytes)]) (define reserved (+xreserved uint16be)) (encode reserved #f) - (check-equal? (dump (current-output-port)) (bytes 0 0)))) + (check-equal? (get-output-bytes (current-output-port)) (bytes 0 0)))) (test-case "should encode with pre-encode" @@ -45,4 +45,4 @@ https://github.com/mbutterick/restructure/blob/master/test/Reserved.coffee (define reserved (+xreserved uint32be)) (set-pre-encode! reserved (λ (val) 42)) (encode reserved #f) - (check-equal? (dump (current-output-port)) (bytes 0 0 0 0)))) \ No newline at end of file + (check-equal? (get-output-bytes (current-output-port)) (bytes 0 0 0 0)))) \ No newline at end of file diff --git a/xenomorph/xenomorph/test/string-test.rkt b/xenomorph/xenomorph/test/string-test.rkt index 52ca3c3f..e600441b 100644 --- a/xenomorph/xenomorph/test/string-test.rkt +++ b/xenomorph/xenomorph/test/string-test.rkt @@ -83,7 +83,7 @@ https://github.com/mbutterick/restructure/blob/master/test/String.coffee "encode using string length" (parameterize ([current-output-port (open-output-bytes)]) (encode (+xstring 7) "testing") - (check-equal? (dump (current-output-port)) #"testing"))) + (check-equal? (get-output-bytes (current-output-port)) #"testing"))) (test-case "encode using string length and pre-encode" @@ -91,34 +91,34 @@ https://github.com/mbutterick/restructure/blob/master/test/String.coffee (define xs (+xstring 7)) (set-pre-encode! xs (compose1 list->string reverse string->list)) (encode xs "testing") - (check-equal? (dump (current-output-port)) #"gnitset"))) + (check-equal? (get-output-bytes (current-output-port)) #"gnitset"))) (test-case "encode length as number before string" (parameterize ([current-output-port (open-output-bytes)]) (encode (+xstring uint8) "testing") - (check-equal? (dump (current-output-port)) #"\x07testing"))) + (check-equal? (get-output-bytes (current-output-port)) #"\x07testing"))) (test-case "encode length as number before string utf8" (parameterize ([current-output-port (open-output-bytes)]) (encode (+xstring uint8 'utf8) "testing 😜") - (check-equal? (dump (current-output-port)) (string->bytes/utf-8 "\x0ctesting 😜")))) + (check-equal? (get-output-bytes (current-output-port)) (string->bytes/utf-8 "\x0ctesting 😜")))) (test-case "encode utf8" (parameterize ([current-output-port (open-output-bytes)]) (encode (+xstring 4 'utf8) "🍻" ) - (check-equal? (dump (current-output-port)) (string->bytes/utf-8 "🍻")))) + (check-equal? (get-output-bytes (current-output-port)) (string->bytes/utf-8 "🍻")))) (test-case "encode encoding computed from function" (parameterize ([current-output-port (open-output-bytes)]) (encode (+xstring 4 (λ _ 'utf8)) "🍻") - (check-equal? (dump (current-output-port)) (string->bytes/utf-8 "🍻")))) + (check-equal? (get-output-bytes (current-output-port)) (string->bytes/utf-8 "🍻")))) (test-case "encode null-terminated string" (parameterize ([current-output-port (open-output-bytes)]) (encode (+xstring #f 'utf8) "🍻" ) - (check-equal? (dump (current-output-port)) (string->bytes/utf-8 "🍻\x00")))) \ No newline at end of file + (check-equal? (get-output-bytes (current-output-port)) (string->bytes/utf-8 "🍻\x00")))) \ No newline at end of file diff --git a/xenomorph/xenomorph/test/struct-test.rkt b/xenomorph/xenomorph/test/struct-test.rkt index 22d6c2e8..c8354102 100644 --- a/xenomorph/xenomorph/test/struct-test.rkt +++ b/xenomorph/xenomorph/test/struct-test.rkt @@ -16,23 +16,23 @@ https://github.com/mbutterick/restructure/blob/master/test/Struct.coffee "decode into an object" (parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x15")]) (check-equal? - (decode/hash (+xstruct 'name (+xstring #:length uint8) 'age uint8)) - (hasheq 'name "roxyb" 'age 21)))) + (decode (+xstruct 'name (+xstring #:length uint8) 'age uint8)) + (mhasheq 'name "roxyb" 'age 21)))) (test-case "decode with process hook" (parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x20")]) (define struct (+xstruct 'name (+xstring #:length uint8) 'age uint8)) (set-post-decode! struct (λ (o . _) (dict-set! o 'canDrink (>= (dict-ref o 'age) 21)) o)) - (check-equal? (decode/hash struct) - (hasheq 'name "roxyb" 'age 32 'canDrink #t)))) + (check-equal? (decode struct) + (mhasheq 'name "roxyb" 'age 32 'canDrink #t)))) (test-case "decode supports function keys" (parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x20")]) (define struct (+xstruct 'name (+xstring #:length uint8) 'age uint8 'canDrink (λ (o) (>= (dict-ref o 'age) 21)))) - (check-equal? (decode/hash struct) - (hasheq 'name "roxyb" 'age 32 'canDrink #t)))) + (check-equal? (decode struct) + (mhasheq 'name "roxyb" 'age 32 'canDrink #t)))) (test-case "compute the correct size" @@ -57,8 +57,8 @@ https://github.com/mbutterick/restructure/blob/master/test/Struct.coffee (test-case "encode objects to buffers" (parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x15")]) - (check-equal? (decode/hash (+xstruct 'name (+xstring #:length uint8) 'age uint8)) - (hasheq 'name "roxyb" 'age 21)))) + (check-equal? (decode (+xstruct 'name (+xstring #:length uint8) 'age uint8)) + (mhasheq 'name "roxyb" 'age 21)))) (test-case "support pre-encode hook" @@ -68,7 +68,7 @@ https://github.com/mbutterick/restructure/blob/master/test/Struct.coffee 'age uint8)) (set-pre-encode! struct (λ (val) (dict-set! val 'nameLength (string-length (dict-ref val 'name))) val)) (encode struct (mhasheq 'name "roxyb" 'age 21)) - (check-equal? (dump (current-output-port)) #"\x05roxyb\x15"))) + (check-equal? (get-output-bytes (current-output-port)) #"\x05roxyb\x15"))) (test-case "encode pointer data after structure" @@ -77,4 +77,4 @@ https://github.com/mbutterick/restructure/blob/master/test/Struct.coffee 'age uint8 'ptr (+xpointer #:type (+xstring #:length uint8)))) (encode struct (hasheq 'name "roxyb" 'age 21 'ptr "hello")) - (check-equal? (dump (current-output-port)) #"\x05roxyb\x15\x08\x05hello"))) \ No newline at end of file + (check-equal? (get-output-bytes (current-output-port)) #"\x05roxyb\x15\x08\x05hello"))) \ No newline at end of file diff --git a/xenomorph/xenomorph/test/versioned-struct-test.rkt b/xenomorph/xenomorph/test/versioned-struct-test.rkt index 61de216b..a73787a0 100644 --- a/xenomorph/xenomorph/test/versioned-struct-test.rkt +++ b/xenomorph/xenomorph/test/versioned-struct-test.rkt @@ -23,9 +23,9 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe 'age uint8 'gender uint8)))]) (parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")]) - (check-equal? (decode/hash vstruct) (hasheq 'name "roxyb" 'age 21 'version 0))) + (check-equal? (decode vstruct) (mhasheq 'name "roxyb" 'age 21 'version 0))) (parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x0aroxyb 🤘\x15\x00"))]) - (check-equal? (decode/hash vstruct) (hasheq 'name "roxyb 🤘" 'age 21 'version 1 'gender 0))))) + (check-equal? (decode vstruct) (mhasheq 'name "roxyb 🤘" 'age 21 'version 1 'gender 0))))) (test-case "decode should throw for unknown version" @@ -49,12 +49,12 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe 1 (dictify 'name (+xstring #:length uint8 #:encoding 'utf8) 'gender uint8)))]) (parameterize ([current-input-port (open-input-bytes #"\x00\x15\x01\x05roxyb")]) - (check-equal? (decode/hash vstruct) (hasheq 'name "roxyb" + (check-equal? (decode vstruct) (mhasheq 'name "roxyb" 'age 21 'alive 1 'version 0))) (parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x15\x01\x0aroxyb 🤘\x00"))]) - (check-equal? (decode/hash vstruct) (hasheq 'name "roxyb 🤘" + (check-equal? (decode vstruct) (mhasheq 'name "roxyb 🤘" 'age 21 'version 1 'alive 1 @@ -70,11 +70,11 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe 'age uint8 'gender uint8)))]) (parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x15")]) - (check-equal? (decode/hash vstruct #:parent (mhash 'version 0)) - (hasheq 'name "roxyb" 'age 21 'version 0))) + (check-equal? (dict->mutable-hash (xdecode vstruct #:parent (mhash 'version 0))) + (mhasheq 'name "roxyb" 'age 21 'version 0))) (parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x0aroxyb 🤘\x15\x00"))]) - (check-equal? (decode/hash vstruct #:parent (mhash 'version 1)) - (hasheq 'name "roxyb 🤘" 'age 21 'version 1 'gender 0))))) + (check-equal? (dict->mutable-hash (xdecode vstruct #:parent (mhash 'version 1))) + (mhasheq 'name "roxyb 🤘" 'age 21 'version 1 'gender 0))))) (test-case "decode should support sub versioned structs" @@ -88,14 +88,14 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe 1 (dictify 'name (+xstring uint8) 'isDessert uint8)))))]) (parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")]) - (check-equal? (decode/hash vstruct #:parent (mhash 'version 0)) - (hasheq 'name "roxyb" 'age 21 'version 0))) + (check-equal? (dict->mutable-hash (xdecode vstruct #:parent (mhash 'version 0))) + (mhasheq 'name "roxyb" 'age 21 'version 0))) (parameterize ([current-input-port (open-input-bytes #"\x01\x00\x05pasta")]) - (check-equal? (decode/hash vstruct #:parent (mhash 'version 0)) - (hasheq 'name "pasta" 'version 0))) + (check-equal? (dict->mutable-hash (xdecode vstruct #:parent (mhash 'version 0))) + (mhasheq 'name "pasta" 'version 0))) (parameterize ([current-input-port (open-input-bytes #"\x01\x01\x09ice cream\x01")]) - (check-equal? (decode/hash vstruct #:parent (mhash 'version 0)) - (hasheq 'name "ice cream" 'isDessert 1 'version 1))))) + (check-equal? (dict->mutable-hash (xdecode vstruct #:parent (mhash 'version 0))) + (mhasheq 'name "ice cream" 'isDessert 1 'version 1))))) (test-case "decode should support process hook" @@ -108,8 +108,8 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe 'gender uint8)))]) (set-post-decode! vstruct (λ (val) (dict-set! val 'processed "true") val)) (parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")]) - (check-equal? (decode/hash vstruct) - (hasheq 'name "roxyb" 'processed "true" 'age 21 'version 0))))) + (check-equal? (decode vstruct) + (mhasheq 'name "roxyb" 'processed "true" 'age 21 'version 0))))) (test-case "size should compute the correct size" @@ -189,7 +189,7 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe [op (open-output-bytes)]) (encode vstruct (mhasheq 'name "roxyb" 'age 21 'version 0) op) (encode vstruct (mhasheq 'name "roxyb 🤘" 'age 21 'gender 0 'version 1) op) - (check-equal? (dump op) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00")))) + (check-equal? (get-output-bytes op) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00")))) (test-case "encode should throw for unknown version" @@ -215,7 +215,7 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe [op (open-output-bytes)]) (encode vstruct (mhasheq 'name "roxyb" 'age 21 'alive 1 'version 0) op) (encode vstruct (mhasheq 'name "roxyb 🤘" 'gender 0 'age 21 'alive 1 'version 1) op) - (check-equal? (dump op) (string->bytes/utf-8 "\x00\x15\x01\x05roxyb\x01\x15\x01\x0aroxyb 🤘\x00")))) + (check-equal? (get-output-bytes op) (string->bytes/utf-8 "\x00\x15\x01\x05roxyb\x01\x15\x01\x0aroxyb 🤘\x00")))) (test-case "encode should encode pointer data after structure" @@ -230,7 +230,7 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe [op (open-output-bytes)]) (encode vstruct (mhasheq 'version 1 'name "roxyb" 'age 21 'ptr "hello") op) - (check-equal? (dump op) (string->bytes/utf-8 "\x01\x05roxyb\x15\x09\x05hello")))) + (check-equal? (get-output-bytes op) (string->bytes/utf-8 "\x01\x05roxyb\x15\x09\x05hello")))) (test-case "encode should support preEncode hook" @@ -241,8 +241,8 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe 1 (dictify 'name (+xstring #:length uint8 #:encoding 'utf8) 'age uint8 'gender uint8)))] - [stream (open-output-bytes)]) + [op (open-output-bytes)]) (set-pre-encode! vstruct (λ (val) (dict-set! val 'version (if (dict-ref val 'gender #f) 1 0)) val)) - (encode vstruct (mhasheq 'name "roxyb" 'age 21 'version 0) stream) - (encode vstruct (mhasheq 'name "roxyb 🤘" 'age 21 'gender 0) stream) - (check-equal? (dump stream) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00")))) \ No newline at end of file + (encode vstruct (mhasheq 'name "roxyb" 'age 21 'version 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")))) \ No newline at end of file diff --git a/xenomorph/xenomorph/versioned-struct.rkt b/xenomorph/xenomorph/versioned-struct.rkt index 861c399b..bedcae69 100644 --- a/xenomorph/xenomorph/versioned-struct.rkt +++ b/xenomorph/xenomorph/versioned-struct.rkt @@ -2,14 +2,17 @@ (require "helper.rkt" "struct.rkt" racket/dict sugar/unstable/dict) -(provide (all-defined-out) decode/hash) +(provide (all-defined-out)) #| approximates https://github.com/mbutterick/restructure/blob/master/src/VersionedStruct.coffee |# -(define/post-decode (xversioned-struct-decode xvs [port-arg (current-input-port)] #:parent [parent #f] [length 0]) +(define (xversioned-struct-decode . args) + (dict->mutable-hash (apply xversioned-struct-xdecode args))) + +(define/post-decode (xversioned-struct-xdecode xvs [port-arg (current-input-port)] #:parent [parent #f] [length 0]) (define port (->input-port port-arg)) (define res (_setup port parent length)) @@ -89,7 +92,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 xdecode xversioned-struct-xdecode) (define encode xversioned-struct-encode) (define size xversioned-struct-size)])