main
Matthew Butterick 7 years ago
parent ac7b8bc69b
commit 8a75e8dd09

@ -6,8 +6,8 @@
(pos posable [new-pos])
#:defaults
([port? (define (pos p [new-pos #f]) (when new-pos
(file-position p new-pos))
(file-position p))]))
(file-position p new-pos))
(file-position p))]))
(define posable<%>
(interface* ()
@ -24,8 +24,12 @@
(interface* ()
([(generic-property gen:codable)
(generic-method-table gen:codable
(define (decode o [stream (current-input-port)] #:parent [parent #f]) (send o decode stream parent))
(define (encode o [val #f] [stream (current-output-port)] #:parent [parent #f]) (send o encode stream val parent)))])))
(define (decode o [port (current-input-port)] #:parent [parent #f])
(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

@ -45,7 +45,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
(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
(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)])
(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))
(unless (and (dict? versions) (andmap (λ (val) (or (dict? val) (Struct? val))) (map cdr 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])
(unless (hash? val)
(raise-argument-error 'Struct:encode "hash" val))
(send this preEncode val stream) ; preEncode goes first, because it might bring input hash into compliance
(raise-argument-error 'VersionedStruct:encode "hash" val))
(define ctx (mhash 'pointers empty
'startOffset (· stream pos)
'startOffset (pos stream)
'parent parent
'val val
'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)))
(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 'decode', ->
; 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"))]
[struct (+Struct (dictify 'name (+StringT uint8)
'age uint8))])
(check-equal? (dump (decode struct stream))
(mhasheq 'name "devon" 'age 21)))
(parameterize ([current-input-port (open-input-bytes #"\x05devon\x15")])
(check-equal?
(dump (decode (+Struct (dictify 'name (+StringT uint8)
'age uint8))))
(mhasheq 'name "devon" 'age 21)))
;
; it 'should support process hook', ->
; stream = new DecodeStream new Buffer '\x05devon\x20'
; struct = new Struct
; name: new StringT uint8
; age: uint8
;
; struct.process = ->
; @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))
(parameterize ([current-input-port (open-input-bytes #"\x05devon\x20")])
(define struct (+Struct (dictify 'name (+StringT uint8)
'age uint8)))
(set-field! process struct (λ (o . _) (ref-set! o 'canDrink (>= (· o age) 21)) o))
(check-equal? (dump (decode struct))
(mhasheq 'name "devon" 'age 32 'canDrink #t)))
;
; it 'should support function keys', ->
; stream = new DecodeStream new Buffer '\x05devon\x20'
; struct = new Struct
; name: new StringT uint8
; age: uint8
; 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
'canDrink (λ (o) (>= (ref o 'age) 21))))])
(check-equal? (dump (decode struct stream))
(parameterize ([current-input-port (open-input-bytes #"\x05devon\x20")])
(define struct (+Struct (dictify 'name (+StringT uint8)
'age uint8
'canDrink (λ (o) (>= (ref o 'age) 21)))))
(check-equal? (dump (decode struct))
(mhasheq 'name "devon" 'age 32 'canDrink #t)))
;
; describe '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)
'age uint8))])
(check-equal? (size struct (hasheq 'name "devon" 'age 32)) 7))
(check-equal? (size (+Struct (dictify
'name (+StringT uint8)
'age uint8))
(hasheq 'name "devon" 'age 32)) 7)
; 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)
'age uint8
'ptr (+Pointer uint8 (+StringT uint8))))])
(check-equal? (size struct (mhash 'name "devon" 'age 21 'ptr "hello")) 14))
(check-equal? (size (+Struct (dictify
'name (+StringT uint8)
'age uint8
'ptr (+Pointer uint8 (+StringT uint8))))
(mhash 'name "devon" 'age 21 'ptr "hello")) 14)
;
; 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)
'age uint8))])
(check-equal? (size struct) 5))
(check-equal? (size (+Struct (dictify
'name (+StringT 4)
'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', ->
@ -148,66 +92,29 @@ https://github.com/mbutterick/restructure/blob/master/test/Struct.coffee
;
; stream.end()
(let ([stream (+DecodeStream (+Buffer "\x05devon\x15"))]
[struct (+Struct (dictify 'name (+StringT uint8)
'age uint8))])
(check-equal? (dump (decode struct stream))
(parameterize ([current-input-port (open-input-bytes #"\x05devon\x15")])
(check-equal? (dump (decode (+Struct (dictify 'name (+StringT uint8)
'age uint8))))
(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)]
[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")))
; it 'should support preEncode hook', (done) ->
(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) ->
; 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 'decode', ->
; 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
(dictify
@ -38,34 +17,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'age uint8
'gender uint8)))])
(let ([stream (+DecodeStream (+Buffer "\x00\x05devon\x15"))])
(check-equal? (dump (decode struct stream)) (mhasheq 'name "devon"
'age 21
'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 #"\x00\x05devon\x15")])
(check-equal? (dump (decode struct)) (mhasheq 'name "devon"
'age 21
'version 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', ->
; 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
(dictify
@ -75,36 +39,12 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'age uint8
'gender uint8)))])
(let ([stream (+DecodeStream (+Buffer "\x05\x05devon\x15"))])
(check-exn exn:fail:contract? (λ () (decode struct stream)))))
(parameterize ([current-input-port (open-input-bytes #"\x05\x05devon\x15")])
(check-exn exn:fail:contract? (λ () (decode struct)))))
;
; 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
(dictify
@ -114,42 +54,21 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8 'utf8)
'gender uint8)))])
(let ([stream (+DecodeStream (+Buffer "\x00\x15\x01\x05devon"))])
(check-equal? (dump (decode struct stream)) (mhasheq 'name "devon"
'age 21
'alive 1
'version 0)))
(parameterize ([current-input-port (open-input-bytes #"\x00\x15\x01\x05devon")])
(check-equal? (dump (decode struct)) (mhasheq 'name "devon"
'age 21
'alive 1
'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', ->
; 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
(dictify
@ -159,47 +78,21 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'age uint8
'gender uint8)))])
(let ([stream (+DecodeStream (+Buffer "\x05devon\x15"))])
(check-equal? (dump (decode struct stream (mhash 'version 0))) (mhasheq 'name "devon"
'age 21
'version 0)))
(parameterize ([current-input-port (open-input-bytes #"\x05devon\x15")])
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (mhasheq 'name "devon"
'age 21
'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', ->
; 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
(dictify
@ -211,42 +104,23 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8)
'isDessert uint8)))))])
(let ([stream (+DecodeStream (+Buffer "\x00\x05devon\x15"))])
(check-equal? (dump (decode struct stream (mhash 'version 0))) (mhasheq 'name "devon"
'age 21
'version 0)))
(parameterize ([current-input-port (open-input-bytes #"\x00\x05devon\x15")])
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (mhasheq 'name "devon"
'age 21
'version 0)))
(let ([stream (+DecodeStream (+Buffer "\x01\x00\x05pasta"))])
(check-equal? (dump (decode struct stream (mhash 'version 0))) (mhasheq 'name "pasta"
'version 0)))
(parameterize ([current-input-port (open-input-bytes #"\x01\x00\x05pasta")])
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (mhasheq 'name "pasta"
'version 0)))
(let ([stream (+DecodeStream (+Buffer "\x01\x01\x09ice cream\x01"))])
(check-equal? (dump (decode struct stream (mhash 'version 0))) (mhasheq 'name "ice cream"
'isDessert 1
'version 1))))
(parameterize ([current-input-port (open-input-bytes #"\x01\x01\x09ice cream\x01")])
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (mhasheq 'name "ice cream"
'isDessert 1
'version 1))))
;
; 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
(dictify
@ -256,38 +130,16 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'age uint8
'gender uint8)))])
(set-field! process struct (λ (o stream ctx) (ref-set! o 'processed "true") o))
(let ([stream (+DecodeStream (+Buffer "\x00\x05devon\x15"))])
(check-equal? (dump (decode struct stream)) (mhasheq 'name "devon"
'processed "true"
'age 21
'version 0))))
(parameterize ([current-input-port (open-input-bytes #"\x00\x05devon\x15")])
(check-equal? (dump (decode struct)) (mhasheq 'name "devon"
'processed "true"
'age 21
'version 0))))
;
; describe '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
(dictify
@ -298,31 +150,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'gender uint8)))])
(check-equal? (size struct (mhasheq 'name "devon"
'age 21
'version 0)) 8)
'age 21
'version 0)) 8)
(check-equal? (size struct (mhasheq 'name "devon 👍"
'gender 0
'age 21
'version 1)) 14))
'gender 0
'age 21
'version 1)) 14))
;
; 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
(dictify
@ -333,38 +173,12 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'gender uint8)))])
(check-exn exn:fail:contract? (λ () (size struct (mhasheq 'name "devon"
'age 21
'version 5)))))
'age 21
'version 5)))))
;
; 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
(dictify
@ -375,35 +189,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'gender uint8)))])
(check-equal? (size struct (mhasheq 'name "devon"
'age 21
'alive 1
'version 0)) 9)
'age 21
'alive 1
'version 0)) 9)
(check-equal? (size struct (mhasheq 'name "devon 👍"
'gender 0
'age 21
'alive 1
'version 1)) 15))
'gender 0
'age 21
'alive 1
'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
@ -415,25 +213,14 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
'ptr (+Pointer uint8 (+StringT uint8)))))])
(check-equal? (size struct (mhasheq 'name "devon"
'age 21
'version 1
'ptr "hello")) 15))
'age 21
'version 1
'ptr "hello")) 15))
;
; 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
@ -446,35 +233,10 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(check-exn exn:fail:contract? (λ () (size struct))))
;
; describe 'encode', ->
; 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
(dictify
@ -483,34 +245,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8 'utf8)
'age uint8
'gender uint8)))]
[stream (+EncodeStream)])
(encode struct stream (mhasheq 'name "devon"
'age 21
'version 0))
(encode struct stream (mhasheq 'name "devon 👍"
'age 21
'gender 0
'version 1))
(check-equal? (dump stream) (+Buffer "\x00\x05devon\x15\x01\x0adevon 👍\x15\x00" 'utf8)))
[port (open-output-bytes)])
(encode struct (mhasheq 'name "devon"
'age 21
'version 0) port)
(encode struct (mhasheq 'name "devon 👍"
'age 21
'gender 0
'version 1) port)
(check-equal? (dump port) (+Buffer "\x00\x05devon\x15\x01\x0adevon 👍\x15\x00" 'utf8)))
;
; 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
(dictify
@ -519,43 +266,14 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8 'utf8)
'age uint8
'gender uint8)))]
[stream (+EncodeStream)])
(check-exn exn:fail:contract? (λ () (encode struct stream (mhasheq 'name "devon"
'age 21
'version 5)))))
[port (open-output-bytes)])
(check-exn exn:fail:contract? (λ () (encode struct port (mhasheq 'name "devon"
'age 21
'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
(dictify
@ -564,46 +282,24 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
0 (dictify 'name (+StringT uint8 'ascii))
1 (dictify 'name (+StringT uint8 'utf8)
'gender uint8)))]
[stream (+EncodeStream)])
[stream (open-output-bytes)])
(encode struct stream (mhasheq 'name "devon"
'age 21
'alive 1
'version 0))
(encode struct (mhasheq 'name "devon"
'age 21
'alive 1
'version 0) stream)
(encode struct stream (mhasheq 'name "devon 👍"
'gender 0
'age 21
'alive 1
'version 1))
(encode struct (mhasheq 'name "devon 👍"
'gender 0
'age 21
'alive 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) ->
; 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
(dictify
@ -612,46 +308,19 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
1 (dictify 'name (+StringT uint8 'utf8)
'age uint8
'ptr (+Pointer uint8 (+StringT uint8)))))]
[stream (+EncodeStream)])
(encode struct stream (mhasheq 'version 1
'name "devon"
'age 21
'ptr "hello"))
[stream (open-output-bytes)])
(encode struct (mhasheq 'version 1
'name "devon"
'age 21
'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
(dictify
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)
'age uint8
'gender uint8)))]
[stream (+EncodeStream)])
(set-field! preEncode struct (λ (val stream) (ref-set! val 'version (if (ref val 'gender) 1 0))))
(encode struct stream (mhasheq 'name "devon"
[stream (open-output-bytes)])
(set-field! pre-encode struct (λ (val port) (ref-set! val 'version (if (ref val 'gender) 1 0)) val))
(encode struct (mhasheq 'name "devon"
'age 21
'version 0))
(encode struct stream (mhasheq 'name "devon 👍"
'version 0) stream)
(encode struct (mhasheq 'name "devon 👍"
'age 21
'gender 0))
(check-equal? (dump stream) (+Buffer "\x00\x05devon\x15\x01\x0adevon 👍\x15\x00" 'utf8)))
'gender 0) stream)
(check-equal? (dump stream) (string->bytes/utf-8 "\x00\x05devon\x15\x01\x0adevon 👍\x15\x00")))

Loading…
Cancel
Save