Skip to content

DEFBINARY structs

j3pic edited this page Feb 17, 2022 · 1 revision

Lambda-list:

(NAME (&REST DEFSTRUCT-OPTIONS &KEY
        (BYTE-ORDER LITTLE-ENDIAN) (PRESERVE-*BYTE-ORDER* T)
        ALIGN EXPORT (BYTE-COUNT-NAME (GENSYM))
        &ALLOW-OTHER-KEYS)
  &REST FIELD-DESCRIPTIONS)

Documentation

Defines a struct that represents binary data, and also generates readers and writers.

The syntax is analogous to Common Lisp's DEFSTRUCT form, with a list of slots that have default values and types. Unlike DEFSTRUCT, all slots must be given types. The types are what the library uses to generate code to read the structure.

Example:

   (defbinary simple-binary (:export t
                             :byte-order :little-endian)
       (magic 38284 :type (magic :actual-type (unsigned-byte 16)
                                 :value 38284))
       (size 0 :type (unsigned-byte 32))
       (oddball-value 0 :type (unsigned-byte 32)
                        :byte-order :big-endian)
       ((b g r) 0 :type (bit-field :raw-type (unsigned-byte 8)
                                   :member-types
                                        ((unsigned-byte 2)
                                         (unsigned-byte 3)
                                         (unsigned-byte 3))))
       (name "" :type (counted-string 1 :external-format :utf8))
       (alias #() :type (counted-buffer 4)
                  :byte-order :big-endian)
       (floating-point 0.0d0 :type double-float)
       (big-float 0 :type octuple-float)
       (odd-float 0 :type (double-float :byte-order :big-endian))
       (c-string "" :type (terminated-buffer 1 :terminator 0))
       (nothing nil :type null) ;; Reads and writes nothing.
       (other-struct nil :type other-binary 
                     :reader #'read-other-binary
                     :writer #'write-other-binary)
       (struct-array #() :type (counted-array 1 simple-binary))
       (blah-type 0 :type (unsigned-byte 32))
       (blah nil :type (eval (case oddball-value
                           ((1) '(unsigned-byte 32))
                           ((2) '(counted-string 2)))))
       (an-array #() :type (simple-array (unsigned-byte 32) ((length c-string))))
       (body #() :type (simple-array (unsigned-byte 8) (size))))

The above generates a DEFSTRUCT definition for SIMPLE-BINARY, along with a definition for a READ-BINARY method and a WRITE-BINARY method.

The READ-BINARY method is EQL-specialized, and will construct the needed object for you. It can be invoked like this:

    (read-binary 'simple-binary stream)

The WRITE-BINARY method is called like this:

    (write-binary object stream)

Options

:BYTE-ORDER is either :little-endian or :big-endian to control the byte order that will be used when reading, writing, or sending over a network. It is defined on a struct-wide basis, and can be overridden on a per-slot basis.

:EXPORT determines whether the struct name, slot names, and generators will be exported from the current package.