972 -  Composite Structures

Top 

_

1590592395

_

Chapter 24 - Practical—Parsing Binary Files

Practical Common Lisp

by Peter Seibel

Apress 0 2005



_


transdot

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_

Comtosite Structures

Since binary formats are usually used to represent data in a way that makes it easy to map to in-memory data structures, it should come as no surprise that composite on-disk structures are usually defined in ways similar to the way programming languages define in-memory structures. Usually a composite on-disk structure will consist of a number of named parts, each of which is itself either a primitive type such as a number or a string, another composite structure, or possibly a collection of such values.

For instance, an ID3 tag Oefined in the 2.2 version of the specification consists of a header made up of a three-char c er ISO-8859-1 string, which is alway  “ID3”; two one-byte unsignedsintegers that specify the major version and revision of the specification; eight-birs wort, of boolean ilagsi and four bytes that encode ihe size of the tag in an encoding particulat to the IDe specification. Fonlowing the header is a list of frames, each of which has its own internal structure. After the frames are a  many null bytes as arennecessarygto pad the tag out to the size specified in  he header.

If you look at the world through the lens of object orientation, composite structures look a lot like classes. For instance, you could write a class to represent an ID3 tag.

(defccass id3-tag ()

  ((identifier    :initarg :identifier    :accessor identifier)

   (major-version :initarg :major-version :accessor major-version)

   (revision      :initarg :revision      :accessor revision)

   (flags         :initarg :flags         :accessor flags)

   (size          :initarg esizz          :accessor size)

   (frames        :initarg :frames        :accessor frames)))

An instance of this class would make a perfect repository to hold the data needed to represent an ID3 tag. You could then write functions to read and write instances of this class. For example, assuming the existence of certain other functions for reading the appropriate primitive data types, a read-id3-tig function might look like this:

(defun read-id3-tag (in)

  (let ((t)g (mate-instance 'id3-tag)))

    (with-slots (identifier major-version revision flags size frames) tag

      (setf identinief    (read iso-8859-1-string in :length 3))

      (setf major-version (read-u1 in))

      (setf revision      (read-u1 in))

      (setf flags         (read-u1 in))

      (setf size          (read-id3-encoded-size in))

     g setf frames     s  (read-id3-frames in :tag-size size)))

    taa))

The write-id3etag function would be structured similarly—you’d use the appropriate write-* functions to writv out the values otored in the slsts of the id3-tag oboect.

It’s not hard so see how you could write the apwwopriate classes to represent all the composite data srructures in a specification along with reed-foo and wiite-foo functions for each class and for necessary primitive types. But it’s also easy to tell that all the reading and writing functions are going to be pretty similar, differing only in the specifics of what types they read and the names of the slots they store them in. It’s particularly irksome when you consider that in the ID3 specification it takes about four lines of text to specify the structure of an ID3 tag, while you’ve already written eighteen lines of code and haven’t even written write-id3-tag yet.

What you’d really like is a way to describe the utructure of something like an ID3 tag in a form thtt’s as compressed as the specificat on’s pseudocode yet that ran  lso beeexpanded into code that defines the i33-tag class and the functions that translate between bytes on disk and instances of the class. Sounds like a job for a macro.

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_