File: bindat.el.html
Packing and unpacking of (binary) data structures.
The data formats used in binary files and network protocols are
often structured data which can be described by a C-style structure
such as the one shown below. Using the bindat package, decoding
and encoding binary data formats like these is made simple using a
structure specification which closely resembles the C style
structure declarations.
Encoded (binary) data is stored in a unibyte string or vector,
while the decoded data is stored in an alist with (FIELD . VALUE)
pairs.
Example:
Consider the following C structures:
struct header {
uint32_t dest_ip;
uint32_t src_ip;
uint16_t dest_port;
uint16_t src_port;
};
struct data {
uint8_t type;
uint8_t opcode;
uint32_t length; /* In little endian order */
unsigned char id[8]; /* nul-terminated string */
unsigned char data[/* (length + 3) & ~3 */];
};
struct packet {
struct header header;
uint8_t items;
unsigned char filler[3];
struct data item[/* items */];
};
The corresponding Lisp bindat specification could look like this:
(bindat-defmacro ip () '(vec 4 byte))
(setq header-bindat-spec
(bindat-type
(dest-ip ip)
(src-ip ip)
(dest-port uint 16)
(src-port uint 16)))
(setq data-bindat-spec
(bindat-type
(type u8)
(opcode u8)
(length uint 32 t) ;; little endian order
(id strz 8)
(data vec length)
(_ align 4)))
(setq packet-bindat-spec
(bindat-type
(header type header-bindat-spec)
(nitems u8)
(_ fill 3)
(items repeat nitems type data-bindat-spec)))
A binary data representation may look like
[ 192 168 1 100 192 168 1 101 01 28 21 32 2 0 0 0
2 3 5 0 ?A ?B ?C ?D ?E ?F 0 0 1 2 3 4 5 0 0 0
1 4 7 0 ?B ?C ?D ?E ?F ?G 0 0 6 7 8 9 10 11 12 0 ]
The corresponding decoded structure returned by bindat-unpack (or taken
by bindat-pack) looks like:
((header
(dest-ip . [192 168 1 100])
(src-ip . [192 168 1 101])
(dest-port . 284)
(src-port . 5408))
(items . 2)
(item ((data . [1 2 3 4 5])
(id . "ABCDEF")
(length . 5)
(opcode . 3)
(type . 2))
((data . [6 7 8 9 10 11 12])
(id . "BCDEFG")
(length . 7)
(opcode . 4)
(type . 1))))
To access a specific value in this structure, use the function
bindat-get-field with the structure as first arg followed by a list
of field names and array indexes, e.g. using the data above,
(bindat-get-field decoded-structure 'item 1 'id)
returns "BCDEFG".
Defined variables (1)
bindat--op | The operation we’re currently building. |