Documentation

Commentary

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".

Requires

Dependencies