(syntax-let-optionals* () type-args expr)
(syntax-let-optionals* ((param default) . rest) (arg0 . args) expr)
(syntax-let-optionals* ((param default) . rest) () expr)
(syntax-let-optionals* (param . rest) (arg0 . args) expr)
(syntax-let-optionals* (param . rest) () expr)
(syntax-let-optionals* ((param default) . rest) (arg0 . args) expr)
(syntax-let-optionals* ((param default) . rest) () expr)
(syntax-let-optionals* (param . rest) (arg0 . args) expr)
(syntax-let-optionals* (param . rest) () expr)
Defines a new record type that supports serializing to and from binary ports. The generated procedures accept keyword-style arguments:
(make: <constructor-name>)
(pred: <predicate-name>)
(read: <reader-name>)
(write: <writer-name>)
(block: <fields> ...)
The fields are also similar to define-record-type
but
with an additional type:
(field (type args ...) getter setter)
Built-in types include:
(u8)
- a single byte in [0, 255](u16/le)
- a little-endian short integer(u16/be)
- a big-endian short integer(fixed-string <length>)
- a fixed-length utf-8 string(padded-string <length> (pad <pad-char>))
- a utf-8 string padded to a given length(octal <length>)
- an integer in octal string format(decimal <length>)
- an integer in decimal string format(hexadecimal <length>)
- an integer in hexadecimal string format
In addition, the field can be a literal (char, string or bytevector), for instance as a file magic sequence or fixed separator. The fields (and any constants) are serialized in the order they appear in the block. For example, the header of a GIF file could be defined as:
(define-binary-record-type gif-header
(make: make-gif-header)
(pred: gif-header?)
(read: read-gif-header)
(write: write-gif-header)
(block:
"GIF89a"
(width (u16/le) gif-header-width)
(height (u16/le) gif-header-height)
(gct (u8) gif-header-gct)
(bgcolor (u8) gif-header-gbcolor)
(aspect-ratio (u8) gif-header-aspect-ratio)
))
ERROR on line 26 of file lib/srfi/9.scm: immutable binding: gif-header
For a more complex example see the (chibi tar)
implementation.
The binary type itself is a macro used to expand to a predicate
and reader/writer procedures, which can be defined with
define-binary-type
. For example,
(define-binary-type (u8)
(lambda (x) (and (exact-integer? x) (<= 0 x 255)))
read-u8
write-u8)
=> #<undef>