diff --git a/xenomorph/xenomorph/enum.rkt b/xenomorph/xenomorph/enum.rkt index 6c574dbf..7359fc2e 100644 --- a/xenomorph/xenomorph/enum.rkt +++ b/xenomorph/xenomorph/enum.rkt @@ -41,8 +41,8 @@ https://github.com/mbutterick/restructure/blob/master/src/Enum.coffee (define/contract (x:enum [type-arg #f] [values-arg #f] - #:type [type-kwarg #f] - #:values [values-kwarg #f] + #:type [type-kwarg uint8] + #:values [values-kwarg null] #:pre-encode [pre-proc #f] #:post-decode [post-proc #f] #:base-class [base-class x:enum%]) diff --git a/xenomorph/xenomorph/optional.rkt b/xenomorph/xenomorph/optional.rkt index 657fe61a..0e83859c 100644 --- a/xenomorph/xenomorph/optional.rkt +++ b/xenomorph/xenomorph/optional.rkt @@ -15,8 +15,8 @@ https://github.com/mbutterick/restructure/blob/master/src/Optional.coffee (super-new) (init-field [(@type type)] [(@condition condition)]) - (unless (xenomorphic-type? @type) - (raise-argument-error 'x:optional"xenomorphic type" @type)) + (unless (xenomorphic? @type) + (raise-argument-error 'x:optional "xenomorphic type" @type)) (define (resolve-condition parent) (match @condition diff --git a/xenomorph/xenomorph/reserved.rkt b/xenomorph/xenomorph/reserved.rkt index 0f617272..6991d434 100644 --- a/xenomorph/xenomorph/reserved.rkt +++ b/xenomorph/xenomorph/reserved.rkt @@ -1,5 +1,8 @@ #lang racket/base -(require racket/class "base.rkt" "util.rkt") +(require racket/class + racket/contract + "base.rkt" + "util.rkt") (provide (all-defined-out)) #| @@ -25,12 +28,29 @@ https://github.com/mbutterick/restructure/blob/master/src/Reserved.coffee (define/augment (x:size [val #f] [parent #f]) (* (send @type x:size) (resolve-length @count #f parent))))) -(define (x:reserved [type-arg #f] [count-arg #f] - #:type [type-kwarg #f] - #:count [count-kwarg #f] - #:pre-encode [pre-proc #f] - #:post-decode [post-proc #f] - #:base-class [base-class x:reserved%]) +(define (x:reserved? x) (is-a? x x:reserved%)) + +(define/contract (x:reserved [type-arg #f] + [count-arg #f] + #:type [type-kwarg #f] + #:count [count-kwarg 1] + #:pre-encode [pre-proc #f] + #:post-decode [post-proc #f] + #:base-class [base-class x:reserved%]) + (() + ((or/c xenomorphic? #false) + (or/c exact-positive-integer? #false) + #:type (or/c xenomorphic? #false) + #:count exact-positive-integer? + #:pre-encode (or/c (any/c . -> . any/c) #false) + #:post-decode (or/c (any/c . -> . any/c) #false) + #:base-class (λ (c) (subclass? c x:reserved%))) + . ->* . + x:reserved?) (define type (or type-arg type-kwarg)) - (define count (or count-arg count-kwarg 1)) - (new (generate-subclass base-class pre-proc post-proc) [type type] [count count])) \ No newline at end of file + (unless (xenomorphic? type) + (raise-argument-error 'x:reserved "xenomorphic type" type)) + (define count (or count-arg count-kwarg)) + (new (generate-subclass base-class pre-proc post-proc) + [type type] + [count count])) \ No newline at end of file diff --git a/xenomorph/xenomorph/scribblings/xenomorph.scrbl b/xenomorph/xenomorph/scribblings/xenomorph.scrbl index ef29f723..1701b2c4 100644 --- a/xenomorph/xenomorph/scribblings/xenomorph.scrbl +++ b/xenomorph/xenomorph/scribblings/xenomorph.scrbl @@ -1292,6 +1292,68 @@ Generate an instance of @racket[x:optional%] (or a subclass of @racket[x:optiona @defmodule[xenomorph/reserved] +The reserved object simply skips data. The advantage of using a reserved object rather than the type itself is a) it clearly signals that the data is being ignored, and b) it prevents writing to that part of the data structure. + +@defclass[x:reserved% x:base% ()]{ +Base class for reserved formats. Use @racket[x:reserved] to conveniently instantiate new reserved formats. + + +@defconstructor[ +([type xenomorphic?] +[count exact-positive-integer?])]{ +Create class instance that represents an reserved format. See @racket[x:reserved] for a description of the fields. + +} + +@defmethod[ +#:mode extend +(x:decode +[input-port input-port?] +[parent (or/c xenomorphic? #false)]) +void?]{ +Returns @racket[(void)]. +} + +@defmethod[ +#:mode extend +(x:encode +[val any/c] +[input-port input-port?] +[parent (or/c xenomorphic? #false)]) +bytes?]{ +Encodes zeroes as a @tech{byte string} that is the length of @racket[_type]. +} + +} + +@defproc[ +(x:reserved? +[x any/c]) +boolean?]{ +Whether @racket[x] is an object of type @racket[x:reserved%]. +} + +@defproc[ +(x:reserved +[type-arg (or/c xenomorphic? #false) #false] +[count-arg (or/c exact-positive-integer? #false)] +[#:type type-kw (or/c xenomorphic? #false)] +[#:count count-kw exact-positive-integer? 1] +[#:pre-encode pre-encode-proc (or/c (any/c . -> . any/c) #false) #false] +[#:post-decode post-decode-proc (or/c (any/c . -> . any/c) #false) #false] +[#:base-class base-class (λ (c) (subclass? c x:reserved%)) x:reserved%] +) +x:reserved?]{ +Generate an instance of @racket[x:reserved%] (or a subclass of @racket[x:reserved%]) with certain optional attributes. + +@racket[type-arg] or @racket[type-kw] (whichever is provided, though @racket[type-arg] takes precedence) controls the type wrapped by the reserved object, which must be @racket[xenomorphic?]. + +@racket[count-arg] or @racket[count-kw] (whichever is provided, though @racket[count-arg] takes precedence) is the number of items of @racket[_type] that should be skipped. + +@racket[pre-encode-proc] and @racket[post-decode-proc] control the pre-encoding and post-decoding procedures, respectively. Each takes as input the value to be processed and returns a new value. + +@racket[base-class] controls the class used for instantiation of the new object. +} @subsection{Utilities}