Git Product home page Git Product logo

lisp-binary's Introduction

lisp-binary

A library to easily read and write complex binary formats.

(Jump to Documentation)

LISP-BINARY provides the DEFBINARY macro, with which you can declare the structure of some piece of binary data, whether it's a file format, a network protocol, or what have you.

It is similar in spirit to Binary-Types and Kaitai Struct, but more powerful.

Quick demo:

(defpackage :instant-compressor
  (:use :common-lisp :lisp-binary)
  (:documentation "A file compressor written in 20 minutes. 7-bit ASCII only."))

(defbinary compressed-text ()
  (magic "IZ" :type (magic :actual-type (terminated-string 1)
                            :value "IZ"))
  (n-chars 0 :type (unsigned-byte 32))
  (buffer 0 :type (simple-array (unsigned-byte 7) (n-chars))))


(defun compress-file (in-filename out-filename)
  (with-open-binary-file (in in-filename
                             :direction :input)
    (let* ((file-size (file-length in))
           (buffer (read-bytes file-size in)))
      (with-open-binary-file (out-raw out-filename
                                      :direction :output
                                      :if-exists :supersede)
        (with-wrapped-in-bit-stream (out out-raw :byte-order :big-endian)
          ;; Notice the lack of a compression algorithm. The compression is done
          ;; entirely by the bit stream and the buffer's 7-bit element-type.
          (write-binary (make-compressed-text :n-chars file-size
                                              :buffer (make-array file-size
                                                                  :element-type '(unsigned-byte 7)
                                                                  :initial-contents (coerce buffer 'list)))
                        out))))))
    
(defun decompress-file (in-filename out-filename)
  (with-open-binary-file (in-raw in-filename
                             :direction :input)
    (with-wrapped-in-bit-stream (in in-raw :byte-order :big-endian)
      (with-open-binary-file (out out-filename
                                  :direction :output
                                  :if-exists :supersede)
        (write-bytes (slot-value (read-binary 'compressed-text in) 'buffer) out)))))

The DEFBINARY macro generates a DEFSTRUCT form to contain the data, and instances of the methods READ-BINARY and WRITE-BINARY, which read the data from a stream.

The DEFBINARY macro can generate code to automatically read and write the following types of data:

  • Signed (one's complement or two's complement) and unsigned integers of all sizes, including non-byte-aligned sizes.
  • Checked magic numbers
  • Bit fields
  • Floating point values in IEEE half, single, double, quadruple, and octuple precision formats.
  • Enumerated types (an integer goes in the file, but all you see is a symbol)
  • Strings: NUL-terminated (or an alternative terminator if you need it), Pascal-style counted strings (preceded by an integer giving the length), and fixed-length strings. Any encoding supported by FLEXI-STREAMS is supported.
  • Arrays: Fixed-length and Pascal-style counted arrays are directly supported. The element-type can be anything you could use elsewhere in the DEFBINARY form (for example, you could have an array of NUL-terminated strings). The length of the "fixed-length" type of array is evaluated at runtime, and can incorporate the values of other fields.
  • Raw byte buffers. They read as 8-bit integers instead of characters, and aren't subject to a character-encoding.
  • Offsets to data found later in the file (you see the data pointed to, not the offset).
  • Other structs declared with DEFBINARY.

It is also possible to declare fields whose type isn't chosen until runtime, and fields that have custom reader and writer functions. With these features, this library can be used to both read and write nearly any binary format.

Both byte orders are supported for all data types, and the byte order can be declared either statically or dynamically (so that it changes as the file is read-- required by a number of formats, including TIFF).

LISP-BINARY also provides:

  • Primitives for reading integers, floats, and strings.
  • A bit-stream library which can be used to read one bit at a time.

lisp-binary's People

Contributors

heegaiximephoomeeghahyaiseekh avatar j3pic avatar phoe avatar ralt avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.