main
Matthew Butterick 7 years ago
parent ac7b8bc69b
commit 8a75e8dd09

@ -6,8 +6,8 @@
(pos posable [new-pos]) (pos posable [new-pos])
#:defaults #:defaults
([port? (define (pos p [new-pos #f]) (when new-pos ([port? (define (pos p [new-pos #f]) (when new-pos
(file-position p new-pos)) (file-position p new-pos))
(file-position p))])) (file-position p))]))
(define posable<%> (define posable<%>
(interface* () (interface* ()
@ -24,8 +24,12 @@
(interface* () (interface* ()
([(generic-property gen:codable) ([(generic-property gen:codable)
(generic-method-table gen:codable (generic-method-table gen:codable
(define (decode o [stream (current-input-port)] #:parent [parent #f]) (send o decode stream parent)) (define (decode o [port (current-input-port)] #:parent [parent #f])
(define (encode o [val #f] [stream (current-output-port)] #:parent [parent #f]) (send o encode stream val parent)))]))) (send o decode port parent))
(define (encode o [val #f] [port (current-output-port)] #:parent [parent #f])
(when (port? val)
(raise-argument-error 'encode "encodable value" val))
(send o encode port val parent)))])))
(define-generics sizable (define-generics sizable

@ -45,7 +45,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
(define-subclass xenomorph-base% (Struct [fields (dictify)]) (define-subclass xenomorph-base% (Struct [fields (dictify)])
(field [[_process process] (λ (res port ctx) res)] (field [[_process process] (λ (val port ctx) val)]
[[_pre-encode pre-encode] (λ (val port) val)]) ; store as field so it can be mutated from outside [[_pre-encode pre-encode] (λ (val port) val)]) ; store as field so it can be mutated from outside
(define/overment (post-decode res stream [ctx #f]) (define/overment (post-decode res stream [ctx #f])

@ -10,7 +10,7 @@ https://github.com/mbuttrackerick/restructure/blob/master/src/VersionedStruct.co
(define-subclass Struct (VersionedStruct type [versions (dictify)]) (define-subclass Struct (VersionedStruct type [versions (dictify)])
(unless ((disjoin integer? procedure? RestructureBase? symbol?) type) (unless ((disjoin integer? procedure? xenomorph-base%? symbol?) type)
(raise-argument-error 'VersionedStruct "integer, function, symbol, or Restructure object" type)) (raise-argument-error 'VersionedStruct "integer, function, symbol, or Restructure object" type))
(unless (and (dict? versions) (andmap (λ (val) (or (dict? val) (Struct? val))) (map cdr versions))) (unless (and (dict? versions) (andmap (λ (val) (or (dict? val) (Struct? val))) (map cdr versions)))
(raise-argument-error 'VersionedStruct "dict of dicts or Structs" versions)) (raise-argument-error 'VersionedStruct "dict of dicts or Structs" versions))
@ -58,17 +58,15 @@ https://github.com/mbuttrackerick/restructure/blob/master/src/VersionedStruct.co
(define/override (encode stream val [parent #f]) (define/override (encode stream val [parent #f])
(unless (hash? val) (unless (hash? val)
(raise-argument-error 'Struct:encode "hash" val)) (raise-argument-error 'VersionedStruct:encode "hash" val))
(send this preEncode val stream) ; preEncode goes first, because it might bring input hash into compliance
(define ctx (mhash 'pointers empty (define ctx (mhash 'pointers empty
'startOffset (· stream pos) 'startOffset (pos stream)
'parent parent 'parent parent
'val val 'val val
'pointerSize 0)) 'pointerSize 0))
(ref-set! ctx 'pointerOffset (+ (· stream pos) (size val ctx #f))) (ref-set! ctx 'pointerOffset (+ (pos stream) (size val ctx #f)))
(when (not (or (key? type) (procedure? type))) (when (not (or (key? type) (procedure? type)))
(send type encode stream (or forced-version (· val version)))) (send type encode stream (or forced-version (· val version))))

@ -9,126 +9,70 @@ https://github.com/mbutterick/restructure/blob/master/test/Struct.coffee
;describe 'Struct', -> ;describe 'Struct', ->
; describe 'decode', -> ; describe 'decode', ->
; it 'should decode into an object', -> ; it 'should decode into an object', ->
; stream = new DecodeStream new Buffer '\x05devon\x15'
; struct = new Struct
; name: new StringT uint8
; age: uint8
;
; struct.decode(stream).should.deep.equal
; name: 'devon'
; age: 21
(let ([stream (+DecodeStream (+Buffer "\x05devon\x15"))] (parameterize ([current-input-port (open-input-bytes #"\x05devon\x15")])
[struct (+Struct (dictify 'name (+StringT uint8) (check-equal?
'age uint8))]) (dump (decode (+Struct (dictify 'name (+StringT uint8)
(check-equal? (dump (decode struct stream)) 'age uint8))))
(mhasheq 'name "devon" 'age 21))) (mhasheq 'name "devon" 'age 21)))
;
; it 'should support process hook', -> ; it 'should support process hook', ->
; stream = new DecodeStream new Buffer '\x05devon\x20'
; struct = new Struct (parameterize ([current-input-port (open-input-bytes #"\x05devon\x20")])
; name: new StringT uint8 (define struct (+Struct (dictify 'name (+StringT uint8)
; age: uint8 'age uint8)))
; (set-field! process struct (λ (o . _) (ref-set! o 'canDrink (>= (· o age) 21)) o))
; struct.process = -> (check-equal? (dump (decode struct))
; @canDrink = @age >= 21
;
; struct.decode(stream).should.deep.equal
; name: 'devon'
; age: 32
; canDrink: true
(let ([stream (+DecodeStream (+Buffer "\x05devon\x20"))]
[struct (+Struct (dictify 'name (+StringT uint8)
'age uint8))])
(set-field! process struct (λ (o stream _) (ref-set! o 'canDrink (>= (· o age) 21)) o))
(check-equal? (dump (decode struct stream))
(mhasheq 'name "devon" 'age 32 'canDrink #t))) (mhasheq 'name "devon" 'age 32 'canDrink #t)))
;
; it 'should support function keys', -> ; it 'should support function keys', ->
; stream = new DecodeStream new Buffer '\x05devon\x20'
; struct = new Struct (parameterize ([current-input-port (open-input-bytes #"\x05devon\x20")])
; name: new StringT uint8 (define struct (+Struct (dictify 'name (+StringT uint8)
; age: uint8 'age uint8
; canDrink: -> @age >= 21 'canDrink (λ (o) (>= (ref o 'age) 21)))))
; (check-equal? (dump (decode struct))
; struct.decode(stream).should.deep.equal
; name: 'devon'
; age: 32
; canDrink: true
(let ([stream (+DecodeStream (+Buffer "\x05devon\x20"))]
[struct (+Struct (dictify 'name (+StringT uint8)
'age uint8
'canDrink (λ (o) (>= (ref o 'age) 21))))])
(check-equal? (dump (decode struct stream))
(mhasheq 'name "devon" 'age 32 'canDrink #t))) (mhasheq 'name "devon" 'age 32 'canDrink #t)))
; ;
; describe 'size', -> ; describe 'size', ->
; it 'should compute the correct size', -> ; it 'should compute the correct size', ->
; struct = new Struct
; name: new StringT uint8
; age: uint8
;
; struct.size(name: 'devon', age: 21).should.equal 7
(let ([struct (+Struct (dictify 'name (+StringT uint8) (check-equal? (size (+Struct (dictify
'age uint8))]) 'name (+StringT uint8)
(check-equal? (size struct (hasheq 'name "devon" 'age 32)) 7)) 'age uint8))
(hasheq 'name "devon" 'age 32)) 7)
; it 'should compute the correct size with pointers', -> ; it 'should compute the correct size with pointers', ->
; struct = new Struct
; name: new StringT uint8
; age: uint8
; ptr: new Pointer uint8, new StringT uint8
;
; size = struct.size
; name: 'devon'
; age: 21
; ptr: 'hello'
;
; size.should.equal 14
(let ([struct (+Struct (dictify 'name (+StringT uint8) (check-equal? (size (+Struct (dictify
'age uint8 'name (+StringT uint8)
'ptr (+Pointer uint8 (+StringT uint8))))]) 'age uint8
(check-equal? (size struct (mhash 'name "devon" 'age 21 'ptr "hello")) 14)) 'ptr (+Pointer uint8 (+StringT uint8))))
(mhash 'name "devon" 'age 21 'ptr "hello")) 14)
;
; it 'should get the correct size when no value is given', -> ; it 'should get the correct size when no value is given', ->
; struct = new Struct
; name: new StringT 4
; age: uint8
;
; struct.size().should.equal 5
(let ([struct (+Struct (dictify 'name (+StringT 4) (check-equal? (size (+Struct (dictify
'age uint8))]) 'name (+StringT 4)
(check-equal? (size struct) 5)) 'age uint8))) 5)
; it 'should throw when getting non-fixed length size and no value is given', ->
(check-exn exn:fail:contract? (λ () (size (+Struct (dictify 'name (+StringT uint8)
'age uint8)))))
;
; it 'should throw when getting non-fixed length size and no value is given', ->
; struct = new Struct
; name: new StringT uint8
; age: uint8
;
; should.throw ->
; struct.size()
; , /not a fixed size/i
(let ([struct (+Struct (dictify 'name (+StringT uint8)
'age uint8))])
(check-exn exn:fail:contract? (λ () (size struct))))
; ;
; describe 'encode', -> ; describe 'encode', ->
@ -148,66 +92,29 @@ https://github.com/mbutterick/restructure/blob/master/test/Struct.coffee
; ;
; stream.end() ; stream.end()
(let ([stream (+DecodeStream (+Buffer "\x05devon\x15"))] (parameterize ([current-input-port (open-input-bytes #"\x05devon\x15")])
[struct (+Struct (dictify 'name (+StringT uint8) (check-equal? (dump (decode (+Struct (dictify 'name (+StringT uint8)
'age uint8))]) 'age uint8))))
(check-equal? (dump (decode struct stream))
(mhasheq 'name "devon" 'age 21))) (mhasheq 'name "devon" 'age 21)))
;
; it 'should support preEncode hook', (done) ->
; stream = new EncodeStream
; stream.pipe concat (buf) ->
; buf.should.deep.equal new Buffer '\x05devon\x15'
; done()
;
; struct = new Struct
; nameLength: uint8
; name: new StringT 'nameLength'
; age: uint8
;
; struct.preEncode = ->
; @nameLength = @name.length
;
; struct.encode stream,
; name: 'devon'
; age: 21
;
; stream.end()
(let ([stream (+EncodeStream)] ; it 'should support preEncode hook', (done) ->
[struct (+Struct (dictify 'nameLength uint8
'name (+StringT 'nameLength)
'age uint8))])
(set-field! preEncode struct (λ (val stream) (ref-set! val 'nameLength (length (ref val 'name)))))
(encode struct stream (mhasheq 'name "devon" 'age 21))
(check-equal? (dump stream)
(+Buffer "\x05devon\x15")))
(parameterize ([current-output-port (open-output-bytes)])
(define struct (+Struct (dictify 'nameLength uint8
'name (+StringT 'nameLength)
'age uint8)))
(set-field! pre-encode struct (λ (val port) (ref-set! val 'nameLength (length (ref val 'name))) val))
(encode struct (mhasheq 'name "devon" 'age 21))
(check-equal? (dump (current-output-port)) #"\x05devon\x15"))
; it 'should encode pointer data after structure', (done) -> ; it 'should encode pointer data after structure', (done) ->
; stream = new EncodeStream
; stream.pipe concat (buf) ->
; buf.should.deep.equal new Buffer '\x05devon\x15\x08\x05hello'
; done()
;
; struct = new Struct
; name: new StringT uint8
; age: uint8
; ptr: new Pointer uint8, new StringT uint8
;
; struct.encode stream,
; name: 'devon'
; age: 21
; ptr: 'hello'
;
; stream.end()
(parameterize ([current-output-port (open-output-bytes)])
(define struct (+Struct (dictify 'name (+StringT uint8)
'age uint8
'ptr (+Pointer uint8 (+StringT uint8)))))
(encode struct (mhasheq 'name "devon" 'age 21 'ptr "hello"))
(check-equal? (dump (current-output-port)) #"\x05devon\x15\x08\x05hello"))
(let ([stream (+EncodeStream)]
[struct (+Struct (dictify 'name (+StringT uint8)
'age uint8
'ptr (+Pointer uint8 (+StringT uint8))))])
(encode struct stream (mhasheq 'name "devon" 'age 21 'ptr "hello"))
(check-equal? (dump stream) (+Buffer "\x05devon\x15\x08\x05hello")))

@ -8,27 +8,6 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
;describe 'VersionedStruct', -> ;describe 'VersionedStruct', ->
; describe 'decode', -> ; describe 'decode', ->
; it 'should get version from number type', -> ; it 'should get version from number type', ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; gender: uint8
;
; stream = new DecodeStream new Buffer '\x00\x05devon\x15'
; struct.decode(stream).should.deep.equal
; version: 0
; name: 'devon'
; age: 21
;
; stream = new DecodeStream new Buffer '\x01\x0adevon 👍\x15\x00', 'utf8'
; struct.decode(stream).should.deep.equal
; version: 1
; name: 'devon 👍'
; age: 21
; gender: 0
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -38,34 +17,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'age uint8 'age uint8
'gender uint8)))]) 'gender uint8)))])
(let ([stream (+DecodeStream (+Buffer "\x00\x05devon\x15"))]) (parameterize ([current-input-port (open-input-bytes #"\x00\x05devon\x15")])
(check-equal? (dump (decode struct stream)) (mhasheq 'name "devon" (check-equal? (dump (decode struct)) (mhasheq 'name "devon"
'age 21 'age 21
'version 0))) 'version 0)))
(let ([stream (+DecodeStream (+Buffer "\x01\x0adevon 👍\x15\x00"))])
(check-equal? (dump (decode struct stream)) (mhasheq 'name "devon 👍"
'age 21
'version 1
'gender 0))))
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x0adevon 👍\x15\x00"))])
(check-equal? (dump (decode struct)) (mhasheq 'name "devon 👍"
'age 21
'version 1
'gender 0))))
;
; it 'should throw for unknown version', -> ; it 'should throw for unknown version', ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; gender: uint8
;
; stream = new DecodeStream new Buffer '\x05\x05devon\x15'
; should.throw ->
; struct.decode(stream)
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -75,36 +39,12 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'age uint8 'age uint8
'gender uint8)))]) 'gender uint8)))])
(let ([stream (+DecodeStream (+Buffer "\x05\x05devon\x15"))]) (parameterize ([current-input-port (open-input-bytes #"\x05\x05devon\x15")])
(check-exn exn:fail:contract? (λ () (decode struct stream))))) (check-exn exn:fail:contract? (λ () (decode struct)))))
; ;
; it 'should support common header block', -> ; it 'should support common header block', ->
; struct = new VersionedStruct uint8,
; header:
; age: uint8
; alive: uint8
; 0:
; name: new StringT uint8, 'ascii'
; 1:
; name: new StringT uint8, 'utf8'
; gender: uint8
;
; stream = new DecodeStream new Buffer '\x00\x15\x01\x05devon'
; struct.decode(stream).should.deep.equal
; version: 0
; age: 21
; alive: 1
; name: 'devon'
;
; stream = new DecodeStream new Buffer '\x01\x15\x01\x0adevon 👍\x00', 'utf8'
; struct.decode(stream).should.deep.equal
; version: 1
; age: 21
; alive: 1
; name: 'devon 👍'
; gender: 0
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -114,42 +54,21 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8 'utf8) 1 (dictify 'name (+StringT uint8 'utf8)
'gender uint8)))]) 'gender uint8)))])
(let ([stream (+DecodeStream (+Buffer "\x00\x15\x01\x05devon"))]) (parameterize ([current-input-port (open-input-bytes #"\x00\x15\x01\x05devon")])
(check-equal? (dump (decode struct stream)) (mhasheq 'name "devon" (check-equal? (dump (decode struct)) (mhasheq 'name "devon"
'age 21 'age 21
'alive 1 'alive 1
'version 0))) 'version 0)))
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x15\x01\x0adevon 👍\x00"))])
(check-equal? (dump (decode struct)) (mhasheq 'name "devon 👍"
'age 21
'version 1
'alive 1
'gender 0))))
(let ([stream (+DecodeStream (+Buffer "\x01\x15\x01\x0adevon 👍\x00"))])
(check-equal? (dump (decode struct stream)) (mhasheq 'name "devon 👍"
'age 21
'version 1
'alive 1
'gender 0))))
;
; it 'should support parent version key', -> ; it 'should support parent version key', ->
; struct = new VersionedStruct 'version',
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; gender: uint8
;
; stream = new DecodeStream new Buffer '\x05devon\x15'
; struct.decode(stream, version: 0).should.deep.equal
; version: 0
; name: 'devon'
; age: 21
;
; stream = new DecodeStream new Buffer '\x0adevon 👍\x15\x00', 'utf8'
; struct.decode(stream, version: 1).should.deep.equal
; version: 1
; name: 'devon 👍'
; age: 21
; gender: 0
(let ([struct (+VersionedStruct 'version (let ([struct (+VersionedStruct 'version
(dictify (dictify
@ -159,47 +78,21 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'age uint8 'age uint8
'gender uint8)))]) 'gender uint8)))])
(let ([stream (+DecodeStream (+Buffer "\x05devon\x15"))]) (parameterize ([current-input-port (open-input-bytes #"\x05devon\x15")])
(check-equal? (dump (decode struct stream (mhash 'version 0))) (mhasheq 'name "devon" (check-equal? (dump (decode struct #:parent (mhash 'version 0))) (mhasheq 'name "devon"
'age 21 'age 21
'version 0))) 'version 0)))
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x0adevon 👍\x15\x00"))])
(check-equal? (dump (decode struct #:parent (mhash 'version 1))) (mhasheq 'name "devon 👍"
'age 21
'version 1
'gender 0))))
(let ([stream (+DecodeStream (+Buffer "\x0adevon 👍\x15\x00" 'utf8))])
(check-equal? (dump (decode struct stream (mhash 'version 1))) (mhasheq 'name "devon 👍"
'age 21
'version 1
'gender 0))))
; ;
; it 'should support sub versioned structs', -> ; it 'should support sub versioned structs', ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1: new VersionedStruct uint8,
; 0:
; name: new StringT uint8
; 1:
; name: new StringT uint8
; isDesert: uint8
;
; stream = new DecodeStream new Buffer '\x00\x05devon\x15'
; struct.decode(stream, version: 0).should.deep.equal
; version: 0
; name: 'devon'
; age: 21
;
; stream = new DecodeStream new Buffer '\x01\x00\x05pasta'
; struct.decode(stream, version: 0).should.deep.equal
; version: 0
; name: 'pasta'
;
; stream = new DecodeStream new Buffer '\x01\x01\x09ice cream\x01'
; struct.decode(stream, version: 0).should.deep.equal
; version: 1
; name: 'ice cream'
; isDesert: 1
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -211,42 +104,23 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8) 1 (dictify 'name (+StringT uint8)
'isDessert uint8)))))]) 'isDessert uint8)))))])
(let ([stream (+DecodeStream (+Buffer "\x00\x05devon\x15"))]) (parameterize ([current-input-port (open-input-bytes #"\x00\x05devon\x15")])
(check-equal? (dump (decode struct stream (mhash 'version 0))) (mhasheq 'name "devon" (check-equal? (dump (decode struct #:parent (mhash 'version 0))) (mhasheq 'name "devon"
'age 21 'age 21
'version 0))) 'version 0)))
(let ([stream (+DecodeStream (+Buffer "\x01\x00\x05pasta"))]) (parameterize ([current-input-port (open-input-bytes #"\x01\x00\x05pasta")])
(check-equal? (dump (decode struct stream (mhash 'version 0))) (mhasheq 'name "pasta" (check-equal? (dump (decode struct #:parent (mhash 'version 0))) (mhasheq 'name "pasta"
'version 0))) 'version 0)))
(let ([stream (+DecodeStream (+Buffer "\x01\x01\x09ice cream\x01"))]) (parameterize ([current-input-port (open-input-bytes #"\x01\x01\x09ice cream\x01")])
(check-equal? (dump (decode struct stream (mhash 'version 0))) (mhasheq 'name "ice cream" (check-equal? (dump (decode struct #:parent (mhash 'version 0))) (mhasheq 'name "ice cream"
'isDessert 1 'isDessert 1
'version 1)))) 'version 1))))
; ;
; it 'should support process hook', -> ; it 'should support process hook', ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; gender: uint8
;
; struct.process = ->
; @processed = true
;
; stream = new DecodeStream new Buffer '\x00\x05devon\x15'
; struct.decode(stream).should.deep.equal
; version: 0
; name: 'devon'
; age: 21
; processed: true
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -256,38 +130,16 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'age uint8 'age uint8
'gender uint8)))]) 'gender uint8)))])
(set-field! process struct (λ (o stream ctx) (ref-set! o 'processed "true") o)) (set-field! process struct (λ (o stream ctx) (ref-set! o 'processed "true") o))
(let ([stream (+DecodeStream (+Buffer "\x00\x05devon\x15"))]) (parameterize ([current-input-port (open-input-bytes #"\x00\x05devon\x15")])
(check-equal? (dump (decode struct stream)) (mhasheq 'name "devon" (check-equal? (dump (decode struct)) (mhasheq 'name "devon"
'processed "true" 'processed "true"
'age 21 'age 21
'version 0)))) 'version 0))))
; ;
; describe 'size', -> ; describe 'size', ->
; it 'should compute the correct size', -> ; it 'should compute the correct size', ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; gender: uint8
;
; size = struct.size
; version: 0
; name: 'devon'
; age: 21
;
; size.should.equal 8
;
; size = struct.size
; version: 1
; name: 'devon 👍'
; age: 21
; gender: 0
;
; size.should.equal 14
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -298,31 +150,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'gender uint8)))]) 'gender uint8)))])
(check-equal? (size struct (mhasheq 'name "devon" (check-equal? (size struct (mhasheq 'name "devon"
'age 21 'age 21
'version 0)) 8) 'version 0)) 8)
(check-equal? (size struct (mhasheq 'name "devon 👍" (check-equal? (size struct (mhasheq 'name "devon 👍"
'gender 0 'gender 0
'age 21 'age 21
'version 1)) 14)) 'version 1)) 14))
; ;
; it 'should throw for unknown version', -> ; it 'should throw for unknown version', ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; gender: uint8
;
; should.throw ->
; struct.size
; version: 5
; name: 'devon'
; age: 21
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -333,38 +173,12 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'gender uint8)))]) 'gender uint8)))])
(check-exn exn:fail:contract? (λ () (size struct (mhasheq 'name "devon" (check-exn exn:fail:contract? (λ () (size struct (mhasheq 'name "devon"
'age 21 'age 21
'version 5))))) 'version 5)))))
; ;
; it 'should support common header block', -> ; it 'should support common header block', ->
; struct = new VersionedStruct uint8,
; header:
; age: uint8
; alive: uint8
; 0:
; name: new StringT uint8, 'ascii'
; 1:
; name: new StringT uint8, 'utf8'
; gender: uint8
;
; size = struct.size
; version: 0
; age: 21
; alive: 1
; name: 'devon'
;
; size.should.equal 9
;
; size = struct.size
; version: 1
; age: 21
; alive: 1
; name: 'devon 👍'
; gender: 0
;
; size.should.equal 15
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -375,35 +189,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'gender uint8)))]) 'gender uint8)))])
(check-equal? (size struct (mhasheq 'name "devon" (check-equal? (size struct (mhasheq 'name "devon"
'age 21 'age 21
'alive 1 'alive 1
'version 0)) 9) 'version 0)) 9)
(check-equal? (size struct (mhasheq 'name "devon 👍" (check-equal? (size struct (mhasheq 'name "devon 👍"
'gender 0 'gender 0
'age 21 'age 21
'alive 1 'alive 1
'version 1)) 15)) 'version 1)) 15))
; it 'should compute the correct size with pointers', ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; ptr: new Pointer uint8, new StringT uint8
;
; size = struct.size
; version: 1
; name: 'devon'
; age: 21
; ptr: 'hello'
;
; size.should.equal 15
; it 'should compute the correct size with pointers', ->
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
@ -415,25 +213,14 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'ptr (+Pointer uint8 (+StringT uint8)))))]) 'ptr (+Pointer uint8 (+StringT uint8)))))])
(check-equal? (size struct (mhasheq 'name "devon" (check-equal? (size struct (mhasheq 'name "devon"
'age 21 'age 21
'version 1 'version 1
'ptr "hello")) 15)) 'ptr "hello")) 15))
; ;
; it 'should throw if no value is given', -> ; it 'should throw if no value is given', ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT 4, 'ascii'
; age: uint8
; 1:
; name: new StringT 4, 'utf8'
; age: uint8
; gender: uint8
;
; should.throw ->
; struct.size()
; , /not a fixed size/i
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
@ -446,35 +233,10 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(check-exn exn:fail:contract? (λ () (size struct)))) (check-exn exn:fail:contract? (λ () (size struct))))
;
; describe 'encode', -> ; describe 'encode', ->
; it 'should encode objects to buffers', (done) -> ; it 'should encode objects to buffers', (done) ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; gender: uint8
;
; stream = new EncodeStream
; stream.pipe concat (buf) ->
; buf.should.deep.equal new Buffer '\x00\x05devon\x15\x01\x0adevon 👍\x15\x00', 'utf8'
; done()
;
; struct.encode stream,
; version: 0
; name: 'devon'
; age: 21
;
; struct.encode stream,
; version: 1
; name: 'devon 👍'
; age: 21
; gender: 0
;
; stream.end()
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -483,34 +245,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8 'utf8) 1 (dictify 'name (+StringT uint8 'utf8)
'age uint8 'age uint8
'gender uint8)))] 'gender uint8)))]
[stream (+EncodeStream)]) [port (open-output-bytes)])
(encode struct stream (mhasheq 'name "devon" (encode struct (mhasheq 'name "devon"
'age 21 'age 21
'version 0)) 'version 0) port)
(encode struct stream (mhasheq 'name "devon 👍" (encode struct (mhasheq 'name "devon 👍"
'age 21 'age 21
'gender 0 'gender 0
'version 1)) 'version 1) port)
(check-equal? (dump stream) (+Buffer "\x00\x05devon\x15\x01\x0adevon 👍\x15\x00" 'utf8))) (check-equal? (dump port) (+Buffer "\x00\x05devon\x15\x01\x0adevon 👍\x15\x00" 'utf8)))
; ;
; it 'should throw for unknown version', -> ; it 'should throw for unknown version', ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; gender: uint8
;
; stream = new EncodeStream
; should.throw ->
; struct.encode stream,
; version: 5
; name: 'devon'
; age: 21
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -519,43 +266,14 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8 'utf8) 1 (dictify 'name (+StringT uint8 'utf8)
'age uint8 'age uint8
'gender uint8)))] 'gender uint8)))]
[stream (+EncodeStream)]) [port (open-output-bytes)])
(check-exn exn:fail:contract? (λ () (encode struct stream (mhasheq 'name "devon" (check-exn exn:fail:contract? (λ () (encode struct port (mhasheq 'name "devon"
'age 21 'age 21
'version 5))))) 'version 5)))))
;
; it 'should support common header block', (done) ->
; struct = new VersionedStruct uint8,
; header:
; age: uint8
; alive: uint8
; 0:
; name: new StringT uint8, 'ascii'
; 1:
; name: new StringT uint8, 'utf8'
; gender: uint8
;
; stream = new EncodeStream
; stream.pipe concat (buf) ->
; buf.should.deep.equal new Buffer '\x00\x15\x01\x05devon\x01\x15\x01\x0adevon 👍\x00', 'utf8'
; done()
;
; struct.encode stream,
; version: 0
; age: 21
; alive: 1
; name: 'devon'
;
; struct.encode stream,
; version: 1
; age: 21
; alive: 1
; name: 'devon 👍'
; gender: 0
;
; stream.end()
; it 'should support common header block', (done) ->
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -564,46 +282,24 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
0 (dictify 'name (+StringT uint8 'ascii)) 0 (dictify 'name (+StringT uint8 'ascii))
1 (dictify 'name (+StringT uint8 'utf8) 1 (dictify 'name (+StringT uint8 'utf8)
'gender uint8)))] 'gender uint8)))]
[stream (+EncodeStream)]) [stream (open-output-bytes)])
(encode struct stream (mhasheq 'name "devon" (encode struct (mhasheq 'name "devon"
'age 21 'age 21
'alive 1 'alive 1
'version 0)) 'version 0) stream)
(encode struct stream (mhasheq 'name "devon 👍" (encode struct (mhasheq 'name "devon 👍"
'gender 0 'gender 0
'age 21 'age 21
'alive 1 'alive 1
'version 1)) 'version 1) stream)
(check-equal? (dump stream) (+Buffer "\x00\x15\x01\x05devon\x01\x15\x01\x0adevon 👍\x00" 'utf8))) (check-equal? (dump stream) (string->bytes/utf-8 "\x00\x15\x01\x05devon\x01\x15\x01\x0adevon 👍\x00")))
; it 'should encode pointer data after structure', (done) -> ; it 'should encode pointer data after structure', (done) ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; ptr: new Pointer uint8, new StringT uint8
;
; stream = new EncodeStream
; stream.pipe concat (buf) ->
; buf.should.deep.equal new Buffer '\x01\x05devon\x15\x09\x05hello', 'utf8'
; done()
;
; struct.encode stream,
; version: 1
; name: 'devon'
; age: 21
; ptr: 'hello'
;
; stream.end()
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
@ -612,46 +308,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8 'utf8) 1 (dictify 'name (+StringT uint8 'utf8)
'age uint8 'age uint8
'ptr (+Pointer uint8 (+StringT uint8)))))] 'ptr (+Pointer uint8 (+StringT uint8)))))]
[stream (+EncodeStream)]) [stream (open-output-bytes)])
(encode struct stream (mhasheq 'version 1 (encode struct (mhasheq 'version 1
'name "devon" 'name "devon"
'age 21 'age 21
'ptr "hello")) 'ptr "hello") stream)
(check-equal? (dump stream) (+Buffer "\x01\x05devon\x15\x09\x05hello" 'utf8))) (check-equal? (dump stream) (string->bytes/utf-8 "\x01\x05devon\x15\x09\x05hello")))
;
; it 'should support preEncode hook', (done) ->
; struct = new VersionedStruct uint8,
; 0:
; name: new StringT uint8, 'ascii'
; age: uint8
; 1:
; name: new StringT uint8, 'utf8'
; age: uint8
; gender: uint8
;
; struct.preEncode = ->
; @version = if @gender? then 1 else 0
;
; stream = new EncodeStream
; stream.pipe concat (buf) ->
; buf.should.deep.equal new Buffer '\x00\x05devon\x15\x01\x0adevon 👍\x15\x00', 'utf8'
; done()
;
; struct.encode stream,
; name: 'devon'
; age: 21
;
; struct.encode stream,
; name: 'devon 👍'
; age: 21
; gender: 0
;
; stream.end()
; it 'should support preEncode hook', (done) ->
(let ([struct (+VersionedStruct uint8 (let ([struct (+VersionedStruct uint8
(dictify (dictify
0 (dictify 'name (+StringT uint8 'ascii) 0 (dictify 'name (+StringT uint8 'ascii)
@ -659,12 +328,12 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8 'utf8) 1 (dictify 'name (+StringT uint8 'utf8)
'age uint8 'age uint8
'gender uint8)))] 'gender uint8)))]
[stream (+EncodeStream)]) [stream (open-output-bytes)])
(set-field! preEncode struct (λ (val stream) (ref-set! val 'version (if (ref val 'gender) 1 0)))) (set-field! pre-encode struct (λ (val port) (ref-set! val 'version (if (ref val 'gender) 1 0)) val))
(encode struct stream (mhasheq 'name "devon" (encode struct (mhasheq 'name "devon"
'age 21 'age 21
'version 0)) 'version 0) stream)
(encode struct stream (mhasheq 'name "devon 👍" (encode struct (mhasheq 'name "devon 👍"
'age 21 'age 21
'gender 0)) 'gender 0) stream)
(check-equal? (dump stream) (+Buffer "\x00\x05devon\x15\x01\x0adevon 👍\x15\x00" 'utf8))) (check-equal? (dump stream) (string->bytes/utf-8 "\x00\x05devon\x15\x01\x0adevon 👍\x15\x00")))

Loading…
Cancel
Save