size finalizer

main
Matthew Butterick 6 years ago
parent 99cce00d36
commit 60ac5e801d

@ -62,15 +62,17 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
(define (xarray-size xa [val #f] #:parent [parent #f]) (define (xarray-size xa [val #f] #:parent [parent #f])
(when val (unless (sequence? val) (when val (unless (sequence? val)
(raise-argument-error 'xarray-size "sequence" val))) (raise-argument-error 'xarray-size "sequence" val)))
(finalize-size
(cond (cond
[val (let-values ([(parent len-size) (if (xint? (xarray-base-len xa)) [val (define-values (new-parent len-size) (if (xint? (xarray-base-len xa))
(values (mhasheq 'parent parent) (size (xarray-base-len xa))) (values (mhasheq 'parent parent) (size (xarray-base-len xa)))
(values parent 0))]) (values parent 0)))
(+ len-size (for/sum ([item val]) (define items-size (for/sum ([item val])
(size (xarray-base-type xa) item #:parent parent))))] (size (xarray-base-type xa) item #:parent new-parent)))
[else (let ([item-count (resolve-length (xarray-base-len xa) #f #:parent parent)] (+ items-size len-size)]
[item-size (size (xarray-base-type xa) #f #:parent parent)]) [else (define item-count (resolve-length (xarray-base-len xa) #f #:parent parent))
(* item-size item-count))])) (define item-size (size (xarray-base-type xa) #f #:parent parent))
(* item-size item-count)])))
(struct xarray-base (type len) #:transparent) (struct xarray-base (type len) #:transparent)
(struct xarray xarray-base (length-type) #:transparent (struct xarray xarray-base (length-type) #:transparent

@ -26,9 +26,10 @@ https://github.com/mbutterick/restructure/blob/master/src/Buffer.coffee
(define (xbuffer-size xb [val #f] #:parent [parent #f]) (define (xbuffer-size xb [val #f] #:parent [parent #f])
(when val (unless (bytes? val) (when val (unless (bytes? val)
(raise-argument-error 'xbuffer-size "bytes" val))) (raise-argument-error 'xbuffer-size "bytes" val)))
(finalize-size
(if (bytes? val) (if (bytes? val)
(bytes-length val) (bytes-length val)
(resolve-length (xbuffer-len xb) val #:parent parent))) (resolve-length (xbuffer-len xb) val #:parent parent))))
(struct xbuffer (len) #:transparent (struct xbuffer (len) #:transparent
#:methods gen:xenomorphic #:methods gen:xenomorphic

@ -13,7 +13,8 @@ https://github.com/mbutterick/restructure/blob/master/src/Enum.coffee
(define index (decode (xenum-type xe))) (define index (decode (xenum-type xe)))
(or (list-ref (xenum-options xe) index) index))) (or (list-ref (xenum-options xe) index) index)))
(define (xenum-size xe [val #f] #:parent [parent #f]) (size (xenum-type xe))) (define (xenum-size xe [val #f] #:parent [parent #f])
(size (xenum-type xe)))
(define (xenum-encode xe val [port-arg (current-output-port)] #:parent [parent #f]) (define (xenum-encode xe val [port-arg (current-output-port)] #:parent [parent #f])
(define port (if (output-port? port-arg) port-arg (open-output-bytes))) (define port (if (output-port? port-arg) port-arg (open-output-bytes)))

@ -24,9 +24,17 @@
(file-position p new-pos)) (file-position p new-pos))
(file-position p)) (file-position p))
(struct xbase (pre-encode post-decode) #:transparent #:mutable)
(define-generics xenomorphic (define-generics xenomorphic
(encode xenomorphic val [port] #:parent [parent]) (encode xenomorphic val [port] #:parent [parent])
(decode xenomorphic [port] #:parent [parent]) (decode xenomorphic [port] #:parent [parent])
(size xenomorphic [item] #:parent [parent])) (size xenomorphic [item] #:parent [parent]))
(define (finalize-size size)
(cond
[(void? size) 0]
[(and (integer? size) (not (negative? size))) size]
[else (raise-argument-error 'size "nonnegative integer" size)]))
(struct lazy-thunk (proc) #:transparent) (struct lazy-thunk (proc) #:transparent)

@ -27,9 +27,9 @@ https://github.com/mbutterick/restructure/blob/master/src/Optional.coffee
(unless port-arg (get-output-bytes port)))) (unless port-arg (get-output-bytes port))))
(define (xoptional-size xo [val #f] #:parent [parent #f]) (define (xoptional-size xo [val #f] #:parent [parent #f])
(if (resolve-condition xo parent) (finalize-size
(size (xoptional-type xo) val #:parent parent) (when (resolve-condition xo parent)
0)) (size (xoptional-type xo) val #:parent parent))))
(struct xoptional (type condition) #:transparent (struct xoptional (type condition) #:transparent
#:methods gen:xenomorphic #:methods gen:xenomorphic

@ -18,7 +18,9 @@ https://github.com/mbutterick/restructure/blob/master/src/Reserved.coffee
(unless port-arg (get-output-bytes port))) (unless port-arg (get-output-bytes port)))
(define (xreserved-size xo [val #f] #:parent [parent #f]) (define (xreserved-size xo [val #f] #:parent [parent #f])
(* (size (xreserved-type xo)) (resolve-length (xreserved-count xo) #f #:parent parent))) (define item-size (size (xreserved-type xo)))
(define count (resolve-length (xreserved-count xo) #f #:parent parent))
(finalize-size (* item-size count)))
(struct xreserved (type count) #:transparent (struct xreserved (type count) #:transparent
#:methods gen:xenomorphic #:methods gen:xenomorphic

@ -68,16 +68,18 @@ https://github.com/mbutterick/restructure/blob/master/src/String.coffee
(unless port-arg (get-output-bytes port))))) (unless port-arg (get-output-bytes port)))))
(define (xstring-size xs [val #f] #:parent [parent #f]) (define (xstring-size xs [val #f] #:parent [parent #f])
(if (not val) (finalize-size
(resolve-length (xstring-len xs) #f #:parent parent) (cond
(let* ([encoding (if (procedure? (xstring-encoding xs)) [val (define encoding (if (procedure? (xstring-encoding xs))
(or ((xstring-encoding xs) (and parent (dict-ref parent val)) 'ascii)) (or ((xstring-encoding xs) (and parent (dict-ref parent val)) 'ascii))
(xstring-encoding xs))] (xstring-encoding xs)))
[encoding (if (eq? encoding 'utf16be) 'utf16le encoding)]) (define string-size (byte-length val (if (eq? encoding 'utf16be) 'utf16le encoding)))
(+ (byte-length val encoding) (cond (define strlen-size (cond
[(not (xstring-len xs)) 1] [(not (xstring-len xs)) 1]
[(xint? (xstring-len xs)) (size (xstring-len xs))] [(xint? (xstring-len xs)) (size (xstring-len xs))]
[else 0]))))) [else 0]))
(+ string-size strlen-size)]
[else (resolve-length (xstring-len xs) #f #:parent parent)])))
(struct xstring (len encoding) #:transparent (struct xstring (len encoding) #:transparent
#:methods gen:xenomorphic #:methods gen:xenomorphic

@ -69,10 +69,11 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
(define parent (mhasheq 'parent parent-arg (define parent (mhasheq 'parent parent-arg
'val val 'val val
'pointerSize 0)) 'pointerSize 0))
(+ (for/sum ([(key type) (d:in-dict (xstruct-fields xs))] (define fields-size (for/sum ([(key type) (d:in-dict (xstruct-fields xs))]
#:when (xenomorphic? type)) #: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)))
(if include-pointers (d:dict-ref parent 'pointerSize) 0))) (define pointers-size (if include-pointers (d:dict-ref parent 'pointerSize) 0))
(finalize-size (+ fields-size pointers-size)))
(define (xstruct-encode xs val-arg [port-arg (current-output-port)] #:parent [parent-arg #f]) (define (xstruct-encode xs val-arg [port-arg (current-output-port)] #:parent [parent-arg #f])
(unless (d:dict? val-arg) (unless (d:dict? val-arg)

@ -51,7 +51,7 @@ https://github.com/mbutterick/restructure/blob/master/src/VersionedStruct.coffee
(for/sum ([(key type) (in-dict fields)]) (for/sum ([(key type) (in-dict fields)])
(size type (and val (dict-ref val key)) #:parent parent)))) (size type (and val (dict-ref val key)) #:parent parent))))
(define pointer-size (if include-pointers (dict-ref parent 'pointerSize) 0)) (define pointer-size (if include-pointers (dict-ref parent 'pointerSize) 0))
(+ version-size header-size fields-size pointer-size)) (finalize-size (+ version-size header-size fields-size pointer-size)))
(define (xversioned-struct-encode xvs val-arg [port-arg (current-output-port)] #:parent [parent-arg #f]) (define (xversioned-struct-encode xvs val-arg [port-arg (current-output-port)] #:parent [parent-arg #f])
(define port (if (output-port? port-arg) port-arg (open-output-bytes))) (define port (if (output-port? port-arg) port-arg (open-output-bytes)))

Loading…
Cancel
Save