Next: , Up: Byte Packing


37.18.1 Describing Data Layout

To control unpacking and packing, you write a data layout specification, a special nested list describing named and typed fields. This specification controls 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
Unsigned byte, with length 1.
u16
word
short
Unsigned integer in network byte order, with length 2.
u24
Unsigned integer in network byte order, with length 3.
u32
dword
long
Unsigned integer in network byte order, with length 4. Note: These values may be limited by Emacs' integer implementation limits.
u16r
u24r
u32r
Unsigned integer in little endian order, with length 2, 3 and 4, respectively.
str len
String of length len.
strz len
Zero-terminated string of length len.
vec len
Vector of len bytes.
ip
Four-byte vector representing an Internet address. For example: [127 0 0 1] for localhost.
bits len
List of set bits in len bytes. The bytes are taken in big endian order and the bits are numbered starting with 8 * 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)
form is a Lisp expression evaluated at the moment the field is unpacked or packed. The result of the evaluation should be one of the above-listed type specifications.

A field specification generally has the form ([name] handler). The square braces indicate that 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 the 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:

type
Unpack/pack this field according to the type specification type.
eval form
Evaluate form, a Lisp expression, for side-effect only. If the field name is specified, the value is bound to that field name. form can access and update these dynamically bound variables:
bindat-raw
The data as a byte array.
bindat-idx
Current index into bindat-raw of the unpacking or packing operation.
struct
Alist.
last
Value of the last field processed.

fill len
Skip len bytes. In packing, this leaves them unchanged, which normally means they remain zero. In unpacking, this means they are ignored.
align len
Skip to the next multiple of len bytes.
struct spec-name
Process spec-name as a sub-specification. This describes a structure nested within another structure.
union form (tag spec)...
Evaluate form, a Lisp expression, find the first tag that matches it, and process its associated data layout specification spec. Matching can occur in one of three ways:
repeat count field-specs...
Process the field-specs recursively, in order, then repeat starting from the first one, processing all the specs count times overall. count may be an integer, or a list of one element that names a previous field. For correct operation, each spec in field-specs must include a name.

Xah Signet