rename fields

main
Matthew Butterick 6 years ago
parent 38c13f17b6
commit 4242d6150a

@ -16,28 +16,28 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
(define xarray%
(class xenobase%
(super-new)
(init-field type len length-type)
(init-field [(@type type)] [(@len len)] [(@length-type length-type)])
(unless (xenomorphic-type? type)
(raise-argument-error '+xarray "xenomorphic type" type))
(unless (length-resolvable? len)
(raise-argument-error '+xarray "length-resolvable?" len))
(unless (memq length-type '(bytes count))
(raise-argument-error '+xarray "'bytes or 'count" length-type))
(unless (xenomorphic-type? @type)
(raise-argument-error '+xarray "xenomorphic type" @type))
(unless (length-resolvable? @len)
(raise-argument-error '+xarray "length-resolvable?" @len))
(unless (memq @length-type '(bytes count))
(raise-argument-error '+xarray "'bytes or 'count" @length-type))
(define/augride (xxdecode port parent)
(define new-parent (if (xint? len)
(define new-parent (if (xint? @len)
(mhasheq 'parent parent
'_startOffset (pos port)
'_currentOffset 0
'_length len)
'_length @len)
parent))
(define resolved-len (resolve-length len #:parent parent))
(define len (resolve-length @len #:parent parent))
(cond
[(or (not resolved-len) (eq? length-type 'bytes))
[(or (not len) (eq? @length-type 'bytes))
(define end-pos (cond
;; resolved-len is byte length
[resolved-len (+ (pos port) resolved-len)]
[len (+ (pos port) len)]
;; no resolved-len, but parent has length
[(and parent (not (zero? (dict-ref parent '_length))))
(+ (dict-ref parent '_startOffset) (dict-ref parent '_length))]
@ -45,10 +45,10 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
[else +inf.0]))
(for/list ([i (in-naturals)]
#:break (or (eof-object? (peek-byte)) (= (pos port) end-pos)))
(send type xxdecode port new-parent))]
(send @type xxdecode port new-parent))]
;; we have resolved-len, which is treated as count of items
[else (for/list ([i (in-range resolved-len)])
(send type xxdecode port new-parent))]))
[else (for/list ([i (in-range len)])
(send @type xxdecode port new-parent))]))
(define/augride (xxencode array port [parent #f])
(unless (sequence? array)
@ -60,17 +60,17 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
#;[item-count (length items)]
#;[max-items (if (number? (xarray-len xa)) (xarray-len xa) item-count)])
(for ([item array])
(send type xxencode item port parent))))
(send @type xxencode item port parent))))
(cond
[(xint? len)
(let ([parent (mhash 'pointers null
'startOffset (pos port)
'parent parent)])
(dict-set! parent 'pointerOffset (+ (pos port) (xxsize array parent)))
(send len xxencode (length array) port) ; encode length at front
(encode-items parent)
(for ([ptr (in-list (dict-ref parent 'pointers))]) ; encode pointer data at end
(send (dict-ref ptr 'type) xxencode (dict-ref ptr 'val) port)))]
[(xint? @len)
(define new-parent (mhash 'pointers null
'startOffset (pos port)
'parent parent))
(dict-set! new-parent 'pointerOffset (+ (pos port) (xxsize array new-parent)))
(send @len xxencode (length array) port) ; encode length at front
(encode-items new-parent)
(for ([ptr (in-list (dict-ref new-parent 'pointers))]) ; encode pointer data at end
(send (dict-ref ptr 'type) xxencode (dict-ref ptr 'val) port))]
[else (encode-items parent)]))
(define/augride (xxsize [val #f] [parent #f])
@ -78,15 +78,15 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
(raise-argument-error 'xarray-size "sequence" val)))
(cond
[val (define-values (new-parent len-size)
(if (xint? len)
(values (mhasheq 'parent parent) (send len xxsize))
(if (xint? @len)
(values (mhasheq 'parent parent) (send @len xxsize))
(values parent 0)))
(define items-size (for/sum ([item val])
(send type xxsize item new-parent)))
(send @type xxsize item new-parent)))
(+ items-size len-size)]
[else (define item-count (resolve-length len #f #:parent parent))
(define item-size (send type xxsize #f parent))
(* item-size item-count)]))))
[else (define count (resolve-length @len #f #:parent parent))
(define size (send @type xxsize #f parent))
(* size count)]))))
(define (+xarray [type-arg #f] [len-arg #f] [length-type-arg 'count]
#:type [type-kwarg #f]

@ -10,24 +10,26 @@ https://github.com/mbutterick/restructure/blob/master/src/Bitfield.coffee
(define xbitfield%
(class xenobase%
(super-new)
(init-field type flags)
(init-field [(@type type)][(@flags flags)])
(unless (andmap (λ (f) (or (symbol? f) (not f))) @flags)
(raise-argument-error '+xbitfield "list of symbols" @flags))
(define/augment (xxdecode port parent)
(define val (send @type xxdecode port))
(define flag-hash (mhasheq))
(define val (send type xxdecode port))
(for ([(flag idx) (in-indexed flags)]
(for ([(flag idx) (in-indexed @flags)]
#:when flag)
(hash-set! flag-hash flag (bitwise-bit-set? val idx)))
flag-hash)
(define/augment (xxencode flag-hash port [parent #f])
(define bit-int (for/sum ([(flag idx) (in-indexed flags)]
(define bit-int (for/sum ([(flag idx) (in-indexed @flags)]
#:when (and flag (dict-ref flag-hash flag #f)))
(arithmetic-shift 1 idx)))
(send type xxencode bit-int port))
(send @type xxencode bit-int port))
(define/augment (xxsize [val #f] [parent #f])
(send type xxsize))))
(send @type xxsize))))
(define (+xbitfield [type-arg #f] [flag-arg #f]
#:type [type-kwarg #f]
@ -35,8 +37,6 @@ https://github.com/mbutterick/restructure/blob/master/src/Bitfield.coffee
#:subclass [class xbitfield%])
(define type (or type-arg type-kwarg))
(define flags (or flag-arg flag-kwarg null))
(unless (andmap (λ (f) (or (symbol? f) (not f))) flags)
(raise-argument-error '+xbitfield "list of symbols" flags))
(new class [type type] [flags flags]))
(module+ test

@ -10,17 +10,19 @@ https://github.com/mbutterick/restructure/blob/master/src/Buffer.coffee
(define xbuffer%
(class xenobase%
(super-new)
(init-field len)
(init-field [(@len len)])
(unless (length-resolvable? @len)
(raise-argument-error '+xbuffer "resolvable length" @len))
(define/augment (xxdecode port parent)
(define decoded-len (resolve-length len #:parent parent))
(read-bytes decoded-len))
(define len (resolve-length @len #:parent parent))
(read-bytes len))
(define/augment (xxencode buf port [parent #f])
(unless (bytes? buf)
(raise-argument-error 'xbuffer-encode "bytes" buf))
(when (xint? len)
(send len xxencode (bytes-length buf) port))
(when (xint? @len)
(send @len xxencode (bytes-length buf) port))
(write-bytes buf port))
(define/augment (xxsize [val #f] [parent #f])
@ -28,12 +30,10 @@ https://github.com/mbutterick/restructure/blob/master/src/Buffer.coffee
(raise-argument-error 'xbuffer-size "bytes" val)))
(if (bytes? val)
(bytes-length val)
(resolve-length len val #:parent parent)))))
(resolve-length @len val #:parent parent)))))
(define (+xbuffer [len-arg #f]
#:length [len-kwarg #f]
#:subclass [class xbuffer%])
(define len (or len-arg len-kwarg #xffff))
(unless (length-resolvable? len)
(raise-argument-error '+xbuffer "resolvable length" len))
(new class [len len]))

@ -10,29 +10,30 @@ https://github.com/mbutterick/restructure/blob/master/src/Enum.coffee
(define xenum%
(class xenobase%
(super-new)
(init-field type values)
(init-field [(@type type)] [(@values values)])
(unless (xenomorphic-type? @type)
(raise-argument-error '+xenum "xenomorphic type" @type))
(unless (list? @values)
(raise-argument-error '+xenum "list of values" @values))
(define/augment (xxdecode port parent)
(define index (send type xxdecode port parent))
(or (list-ref values index) index))
(define index (send @type xxdecode port parent))
(or (list-ref @values index) index))
(define/augment (xxencode val port [parent #f])
(define index (index-of values val))
(define index (index-of @values val))
(unless index
(raise-argument-error 'xenum-encode "valid option" val))
(send type xxencode index port parent))
(send @type xxencode index port parent))
(define/augment (xxsize [val #f] [parent #f])
(send type xxsize val parent))))
(send @type xxsize val parent))))
(define (+xenum [type-arg #f] [values-arg #f]
#:type [type-kwarg #f]
#:values [values-kwarg #f]
#:subclass [class xenum%])
(define type (or type-arg type-kwarg))
(unless (xenomorphic-type? type)
(raise-argument-error '+xenum "xenomorphic type" type))
(define values (or values-arg values-kwarg))
(unless (list? values)
(raise-argument-error '+xenum "list of values" values))
(new class [type type] [values values]))

@ -11,26 +11,26 @@ https://github.com/mbutterick/restructure/blob/master/src/LazyArray.coffee
(define xlazy-array%
(class xarray%
(super-new)
(inherit-field type len)
(inherit-field [@type type] [@len len])
(define/override (xxdecode port parent)
(define starting-pos (pos port)) ; ! placement matters. `resolve-length` will change `pos`
(define decoded-len (resolve-length len #:parent parent))
(let ([parent (if (xint? len)
(mhasheq 'parent parent
'_startOffset starting-pos
'_currentOffset 0
'_length len)
parent)])
(define starting-pos (pos port))
(begin0
(for/stream ([index (in-range decoded-len)])
(define orig-pos (pos port))
(pos port (+ starting-pos (* (send type xxsize #f parent) index)))
(begin0
(send type xxdecode port parent)
(pos port orig-pos)))
(pos port (+ (pos port) (* decoded-len (send type xxsize #f parent)))))))
(define len (resolve-length @len #:parent parent))
(define new-parent (if (xint? @len)
(mhasheq 'parent parent
'_startOffset starting-pos
'_currentOffset 0
'_length @len)
parent))
(define stream-starting-pos (pos port))
(begin0
(for/stream ([index (in-range len)])
(define orig-pos (pos port))
(pos port (+ stream-starting-pos (* (send @type xxsize #f new-parent) index)))
(begin0
(send @type xxdecode port new-parent)
(pos port orig-pos)))
(pos port (+ (pos port) (* len (send @type xxsize #f new-parent))))))
(define/override (xxencode val port [parent #f])
(super xxencode (if (stream? val) (stream->list val) val) port parent))

@ -26,13 +26,16 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(define xnumber%
(class xenobase%
(super-new)
(init-field size endian)
(unless (exact-positive-integer? size)
(raise-argument-error 'xenomorph "exact positive integer" size))
(unless (memq endian '(le be))
(raise-argument-error 'xenomorph "'le or 'be" endian))
(field [bits (* size 8)])
(define/augment (xxsize . _) size)))
(init-field [(@size size)] [(@endian endian)])
(unless (exact-positive-integer? @size)
(raise-argument-error 'xenomorph "exact positive integer" @size))
(unless (memq @endian '(le be))
(raise-argument-error 'xenomorph "'le or 'be" @endian))
(field [@bits (* @size 8)])
(define/augment (xxsize . _) @size)))
(define (xint? x) (is-a? x xint%))
@ -40,31 +43,31 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(class xnumber%
(super-new)
(init-field signed)
(inherit-field endian size bits)
(inherit-field (@endian endian) (@size size) @bits)
;; if a signed integer has n bits, it can contain a number
;; between - (expt 2 (sub1 n)) and (sub1 (expt 2 (sub1 n)).
(define signed-max (sub1 (arithmetic-shift 1 (sub1 bits))))
(define signed-max (sub1 (arithmetic-shift 1 (sub1 @bits))))
(define signed-min (sub1 (- signed-max)))
(define delta (if signed 0 signed-min))
(field [bound-min (- signed-min delta)]
[bound-max (- signed-max delta)])
(define/augment (xxdecode port . _)
(define bs ((if (eq? endian system-endian) values reverse-bytes) (read-bytes size port)))
(define bs ((if (eq? @endian system-endian) values reverse-bytes) (read-bytes @size port)))
(define uint (for/sum ([b (in-bytes bs)]
[i (in-naturals)])
(arithmetic-shift b (* 8 i))))
(if signed (unsigned->signed uint bits) uint))
(if signed (unsigned->signed uint @bits) uint))
(define/augment (xxencode val . _)
(unless (<= bound-min val bound-max)
(raise-argument-error 'encode
(format "value that fits within ~a ~a-byte int (~a to ~a)" (if signed "signed" "unsigned") size bound-min bound-max) val))
(format "value that fits within ~a ~a-byte int (~a to ~a)" (if signed "signed" "unsigned") @size bound-min bound-max) val))
(for/fold ([bs null]
[val (exact-if-possible val)]
#:result (apply bytes ((if (eq? endian 'be) values reverse) bs)))
([i (in-range size)])
#:result (apply bytes ((if (eq? @endian 'be) values reverse) bs)))
([i (in-range @size)])
(values (cons (bitwise-and val #xff) bs) (arithmetic-shift val -8))))))
(define (+xint [size 2]
@ -144,13 +147,13 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(define xfloat%
(class xnumber%
(super-new)
(inherit-field size endian)
(inherit-field (@size size) (@endian endian))
(define/augment (xxdecode port . _)
(floating-point-bytes->real (read-bytes size port) (eq? endian 'be)))
(floating-point-bytes->real (read-bytes @size port) (eq? @endian 'be)))
(define/augment (xxencode val . _)
(real->floating-point-bytes val size (eq? endian 'be)))))
(real->floating-point-bytes val @size (eq? @endian 'be)))))
(define (+xfloat [size 4] #:endian [endian system-endian])
(new xfloat% [size size] [endian endian]))
@ -166,11 +169,11 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(define xfixed%
(class xint%
(super-new)
(init-field fracbits)
(unless (exact-positive-integer? fracbits)
(raise-argument-error '+xfixed "exact positive integer for fracbits" fracbits))
(init-field [(@fracbits fracbits)])
(unless (exact-positive-integer? @fracbits)
(raise-argument-error '+xfixed "exact positive integer for fracbits" @fracbits))
(define fixed-shift (arithmetic-shift 1 fracbits))
(define fixed-shift (arithmetic-shift 1 @fracbits))
(define/override (post-decode int)
(exact-if-possible (/ int fixed-shift 1.0)))

@ -10,29 +10,25 @@ https://github.com/mbutterick/restructure/blob/master/src/Optional.coffee
(define xoptional%
(class xenobase%
(super-new)
(init-field type condition)
(init-field [(@type type)] [(@condition condition)])
(unless (xenomorphic-type? type)
(raise-argument-error '+xoptional"xenomorphic type" type))
(unless (xenomorphic-type? @type)
(raise-argument-error '+xoptional"xenomorphic type" @type))
(define (resolve-condition parent)
(define maybe-proc condition)
(if (procedure? maybe-proc)
(maybe-proc parent)
maybe-proc))
(define maybe-proc @condition)
(if (procedure? maybe-proc) (maybe-proc parent) maybe-proc))
(define/augment (xxdecode port parent)
(when (resolve-condition parent)
(send type xxdecode port parent)))
(send @type xxdecode port parent)))
(define/augment (xxencode val port [parent #f])
(when (resolve-condition parent)
(send type xxencode val port parent)))
(send @type xxencode val port parent)))
(define/augment (xxsize [val #f] [parent #f])
(if (resolve-condition parent)
(send type xxsize val parent)
0))))
(if (resolve-condition parent) (send @type xxsize val parent) 0))))
(define no-val (gensym))

@ -17,7 +17,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Pointer.coffee
[(dict-ref parent 'parent #f) => find-top-parent]
[else parent]))
(define (resolve-void-pointer type val)
(define (resolve-pointer type val)
(cond
[type (values type val)]
[(xvoid-pointer? val) (values (xvoid-pointer-type val) (xvoid-pointer-value val))]
@ -26,69 +26,69 @@ https://github.com/mbutterick/restructure/blob/master/src/Pointer.coffee
(define xpointer%
(class xenobase%
(super-new)
(init-field offset-type type options)
(init-field [(@offset-type offset-type)][(@type type)] [(@options options)])
(define pointer-relative-to (dict-ref options 'relative-to))
(define allow-null (dict-ref options 'allowNull))
(define null-value (dict-ref options 'nullValue))
(define pointer-lazy? (dict-ref options 'lazy))
(define pointer-relative-to (dict-ref @options 'relative-to))
(define allow-null (dict-ref @options 'allowNull))
(define null-value (dict-ref @options 'nullValue))
(define pointer-lazy? (dict-ref @options 'lazy))
(define/augment (xxdecode port parent)
(define offset (send offset-type xxdecode port parent))
(define offset (send @offset-type xxdecode port parent))
(cond
[(and allow-null (= offset null-value)) #f] ; handle null pointers
[else
(define relative (+ (case pointer-relative-to
[(local) (dict-ref parent '_startOffset)]
[(immediate) (- (pos port) (send offset-type xxsize))]
[(immediate) (- (pos port) (send @offset-type xxsize))]
[(parent) (dict-ref (dict-ref parent 'parent) '_startOffset)]
[(global) (or (dict-ref (find-top-parent parent) '_startOffset) 0)]
[else (error 'unknown-pointer-style)])))
(define ptr (+ offset relative))
(cond
[type (define (decode-value)
(define orig-pos (pos port))
(pos port ptr)
(begin0
(send type xxdecode port parent)
(pos port orig-pos)))
(if pointer-lazy? (delay (decode-value)) (decode-value))]
[@type (define (decode-value)
(define orig-pos (pos port))
(pos port ptr)
(begin0
(send @type xxdecode port parent)
(pos port orig-pos)))
(if pointer-lazy? (delay (decode-value)) (decode-value))]
[else ptr])]))
(define/augment (xxencode val port [parent #f])
(define/augment (xxencode val-in port [parent #f])
(unless parent ; todo: furnish default pointer context? adapt from Struct?
(raise-argument-error 'xpointer-encode "valid pointer context" parent))
(if (not val)
(send offset-type xxencode null-value port)
(let* ([new-parent (case pointer-relative-to
[(local immediate) parent]
[(parent) (dict-ref parent 'parent)]
[(global) (find-top-parent parent)]
[else (error 'unknown-pointer-style)])]
[relative (+ (case pointer-relative-to
[(local parent) (dict-ref new-parent 'startOffset)]
[(immediate) (+ (pos port) (send offset-type xxsize val parent))]
[(global) 0]))])
(send offset-type xxencode (- (dict-ref new-parent 'pointerOffset) relative) port)
(let-values ([(type val) (resolve-void-pointer type val)])
(dict-set! new-parent 'pointers (append (dict-ref new-parent 'pointers)
(list (mhasheq 'type type
'val val
'parent parent))))
(dict-set! new-parent 'pointerOffset
(+ (dict-ref new-parent 'pointerOffset) (send type xxsize val parent)))))))
(cond
[val-in
(define new-parent (case pointer-relative-to
[(local immediate) parent]
[(parent) (dict-ref parent 'parent)]
[(global) (find-top-parent parent)]
[else (error 'unknown-pointer-style)]))
(define relative (+ (case pointer-relative-to
[(local parent) (dict-ref new-parent 'startOffset)]
[(immediate) (+ (pos port) (send @offset-type xxsize val-in parent))]
[(global) 0])))
(send @offset-type xxencode (- (dict-ref new-parent 'pointerOffset) relative) port)
(define-values (type val) (resolve-pointer @type val-in))
(dict-update! new-parent 'pointers
(λ (ptrs) (append ptrs (list (mhasheq 'type type 'val val 'parent parent)))))
(dict-set! new-parent 'pointerOffset
(+ (dict-ref new-parent 'pointerOffset) (send type xxsize val parent)))]
[else (send @offset-type xxencode null-value port)]))
(define/augment (xxsize [val #f] [parent #f])
(let*-values ([(parent) (case pointer-relative-to
[(local immediate) parent]
[(parent) (dict-ref parent 'parent)]
[(global) (find-top-parent parent)]
[else (error 'unknown-pointer-style)])]
[(type val) (resolve-void-pointer type val)])
(when (and val parent)
(dict-set! parent 'pointerSize (and (dict-ref parent 'pointerSize #f)
(+ (dict-ref parent 'pointerSize) (send type xxsize val parent)))))
(send offset-type xxsize)))))
(define/augment (xxsize [val-in #f] [parent #f])
(define new-parent (case pointer-relative-to
[(local immediate) parent]
[(parent) (dict-ref parent 'parent)]
[(global) (find-top-parent parent)]
[else (error 'unknown-pointer-style)]))
(define-values (type val) (resolve-pointer @type val-in))
(when (and val new-parent)
(dict-set! new-parent 'pointerSize
(and (dict-ref new-parent 'pointerSize #f)
(+ (dict-ref new-parent 'pointerSize) (send type xxsize val new-parent)))))
(send @offset-type xxsize))))
(define (+xpointer [offset-arg #f] [type-arg #f]
#:offset-type [offset-kwarg #f]

@ -10,10 +10,10 @@ https://github.com/mbutterick/restructure/blob/master/src/Reserved.coffee
(define xreserved%
(class xenobase%
(super-new)
(init-field type count)
(init-field [(@type type)] [(@count count)])
(unless (xenomorphic-type? type)
(raise-argument-error '+xoptional"xenomorphic type" type))
(unless (xenomorphic-type? @type)
(raise-argument-error '+xoptional"xenomorphic type" @type))
(define/augment (xxdecode port parent)
(pos port (+ (pos port) (xxsize #f parent)))
@ -23,7 +23,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Reserved.coffee
(make-bytes (xxsize val parent) 0))
(define/augment (xxsize [val #f] [parent #f])
(* (send type xxsize) (resolve-length count #f #:parent parent)))))
(* (send @type xxsize) (resolve-length @count #f #:parent parent)))))
(define (+xreserved [type-arg #f] [count-arg #f]
#:type [type-kwarg #f]

Loading…
Cancel
Save