Next: Bindat Functions, Up: Byte Packing
To control unpacking and packing, you write a data layout specification, a special nested list describing named and typed fields. This specification controls the length of each field to be processed, and how to pack or unpack it. We normally keep bindat specs in variables whose names end in ‘-bindat-spec’; that kind of name is automatically recognized as risky.
A field's type describes the size (in bytes) of the object
that the field represents and, in the case of multibyte fields, how
the bytes are ordered within the field. The two possible orderings
are big endian (also known as “network byte ordering”) and
little endian. For instance, the number #x23cd
(decimal
9165) in big endian would be the two bytes #x23
#xcd
;
and in little endian, #xcd
#x23
. Here are the possible
type values:
u8
byte
u16
word
short
u24
u32
dword
long
u16r
u24r
u32r
str
lenstrz
lenvec
len [
type]
(vec
len [
type])
.
ip
[127 0 0 1]
for localhost.
bits
len8 *
len − 1
and ending with zero. For example: bits
2
unpacks #x28
#x1c
to (2 3 4 11 13)
and
#x1c
#x28
to (3 5 10 11 12)
.
(eval
form)
For a fixed-size field, the length len is given as an integer specifying the number of bytes in the field.
When the length of a field is not fixed, it typically depends on the
value of a preceding field. In this case, the length len can be
given either as a list (
name ...)
identifying a
field name in the format specified for bindat-get-field
below, or by an expression (eval
form)
where form
should evaluate to an integer, specifying the field length.
A field specification generally has the form ([
name]
handler)
, where name is optional. Don't use names that
are symbols meaningful as type specifications (above) or handler
specifications (below), since that would be ambiguous. name can
be a symbol or an expression (eval
form)
, in which case
form should evaluate to a symbol.
handler describes how to unpack or pack the field and can be one of the following:
eval
formfill
lenalign
lenstruct
spec-nameunion
form (
tag spec)...
(eval
expr)
, evaluate
expr with the variable tag
dynamically bound to the value
of form. A non-nil
result indicates a match.
equal
to the value of form.
t
.
repeat
count field-specs...
eval
form is used, it is evaluated just once.
For correct operation, each specification in field-specs must
include a name.
For the (eval
form)
forms used in a bindat specification,
the form can access and update these dynamically bound variables
during evaluation:
last
bindat-raw
bindat-idx
bindat-raw
) for unpacking or packing.
struct
bindat-get-field
to access specific fields of this structure.
count
index
repeat
block, these contain the maximum number of
repetitions (as specified by the count parameter), and the
current repetition number (counting from 0). Setting count
to
zero will terminate the inner-most repeat block after the current
repetition has completed.