You are looking at historical revision 28806 of this page. It may differ significantly from its current revision.
bitstring
Description
Easy binary data manipulation. Support binary encoding-decoding with matching and condition guards. Implements the subset of Erlang bit syntax.
Authors
rivo
Requirements
No requiremtents.
API
Basic syntax description
(bitmatch binary-data ((pattern ...) expression) ... (else expression)) (bitconstruct (pattern ...) ... (else expression))
Patterns description
- (NAME)
- Read byte from stream and bind to varaible NAME or compare with immediate value if name not a symbol name. Supported immediate values types: integer char string
- (NAME BITS)
- (NAME BITS big)
- Read n-BITS big endian integer, bind-or-compare to NAME.
- (NAME BITS little)
- Read n-BITS little endian integer, bind-or-compare to NAME.
- (NAME 16 float)
- Read ieee-754 floating point half-precision, bind-or-compare to NAME.
- (NAME 32 float)
- Read ieee-754 floating point single precision, bind-or-compare to NAME.
- (NAME BITS bitstring)
- Read raw BITS from stream, bind-or-compare to NAME.
- (NAME bitstring)
- Greedy read, consume all available bits.
- ()
- Empty bitstring
- (PACKET-NAME bitpacket)
- Read a packet defined by the (bitpacket PACKET-NAME ...) declaration. Bind each packet field to current lexical scope. !!! bitpacket is an experimental feature !!!
- (check EXPRESSION)
- user guard EXPRESSION. Matching will continue only when this evaluates to a true value.
- Match binary data against patterns.
- If nothing matches and else guard didn't specified 'bitstring-match-failure exception rise.
- Else guard is optional.
- Construct bitstring based on patterns-list.
- The else-guard clause is optional.
- If nothing matches and else guard was not specified, an exception of type bitstring-match-failure is raised.
- Supports special pattern for concatenating bitstrings.
- ((EXPRESSION ...) bitstring)
- EXPRESSION should evaluate to bitstring during constructing.
Define well-known set of fields. Fields syntax the same as bitmatch pattern syntax.
[procedure] (bitstring-compare bitstring1 bitstring2)Compare bitstrings.
[procedure] (bitstring->list bitstring)Convert bitstring to list.
[procedure] (bitstring? bitstring)Test variable type.
[procedure] (bitstring-length bitstring)Return length in bits.
Examples
; Example 1. Tagged data structure. ; ; struct Tagged { ; enum { IntegerType = 1, FloatType = 2 }; ; unsigned char Tag; // integer type = 1, float type = 2 ; union { ; unsigned int IValue; ; float FValue; ; }; ; }; ; (use bitstring) ; The following will print "integer:3721182122", ; which is the decimal value of #xDDCCBBAA (bitmatch "\x01\xAA\xBB\xCC\xDD" (((#x01) (IValue 32 little)) (print "integer:" IValue)) (((#x02) (FValue 32 float)) (print "float:" FValue))) ; Example 2. Fixed length string. ; ; struct FixedString { ; short Length; // length of StringData array ; char StringData[0]; ; }; ; (use bitstring) ; This will print "StringData:(65 66 67 68 69)" ; First it reads the length byte of 5, bind it to Length and ; then it will read a bit string with a length of that many octets. (bitmatch "\x05\x00ABCDE" (((Length 16 little) (StringData (* 8 Length) bitstring)) (print "StringData:" (bitstring->list StringData))) (else (print "invalid string"))) ; Example 3. IP packet parsing. ; (use bitstring srfi-4) (define IPRaw `#u8( #x45 #x00 #x00 #x6c #x92 #xcc #x00 #x00 #x38 #x06 #x00 #x00 #x92 #x95 #xba #x14 #xa9 #x7c #x15 #x95 )) (bitmatch IPRaw (((Version 4) (IHL 4) (TOS 8) (TL 16) (Identification 16) (Reserved 1) (DF 1) (MF 1) (FramgentOffset 13) (TTL 8) (Protocol 8) (check (or (= Protocol 1) (= Protocol 2) (= Protocol 6) (= Protocol 17))) (CheckSum 16) (SourceAddr 32 bitstring) (DestinationAddr 32 bitstring) (Optional bitstring)) ; print packet filds (print "\n Version: " Version "\n IHL: " IHL "\n TOS: " TOS "\n TL: " TL "\n Identification: " Identification "\n DF: " DF "\n MF: " MF "\n FramgentOffset: " FramgentOffset "\n Protocol: " Protocol "\n CheckSum: " CheckSum "\n SourceAddr: " (bitmatch SourceAddr (((A)(B)(C)(D)) (list A B C D))) "\n DestinationAddr: " (bitmatch DestinationAddr (((A)(B)(C)(D)) (list A B C D))))) (else (print "bad datagram"))) ; Example 3.1 Using bitconstruct. (define (construct-fixed-string str) (bitconstruct (( (string-length str) 16) (str bitstring) ))) ; The following will print "#t" (bitmatch (construct-fixed-string "qwerty.") (((7 16) ("qwerty.")) (print #t)) (else (print #f))) ; Example 3.2 Concatenating bitstrings. (define (construct-complex-object) (bitconstruct ( ((construct-fixed-string "A") bitstring) (#xAABB 16) ((construct-fixed-string "RRR") bitstring)) (#\X))) (print (construct-complex-object)) ; Basic TGA image parser. ; Support True-Image type format and Run-Length-Encoding compression. ; SPEC: http://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf ; Full Source: https://bitbucket.org/rivo/bitstring/src/tip/tests?at=default ; ; WARNING!!! bitpacket feature is experimental !!! (use bitstring posix srfi-4) (bitpacket TGA-Header (ID-length 8) (ColorMapType 8) (ImageType 8) (TGA-ColorMapSpec bitpacket) (TGA-ImageSpec bitpacket)) (bitpacket TGA-ColorMapSpec (FirstEntryIndex 16 little) (ColorMapLength 16 little) (ColorMapEntrySize 8)) (bitpacket TGA-ImageSpec (X-Origin 16 little) (Y-Origin 16 little) (ImageWidth 16 little) (ImageHeight 16 little) (PixelDepth 8) (ImageTransferOrder 2) (#x00 2) ; reserved (AttributesBitsPerPixel 4)) (define (bitstring->blob bs) (u8vector->blob (list->u8vector (bitstring->list bs)))) (define (parse-tga file file-out) (let* ((fi (file-open file (+ open/rdonly open/binary))) (fo (file-open file-out (+ open/write open/creat open/trunc open/binary))) (size (file-size fi)) (res (file-read fi size)) (data (car res))) (bitmatch data ; True-Color uncompressed (((TGA-Header bitpacket) (check (and (= 0 ColorMapType) (= 2 ImageType))) (ID-data ID-length bitstring) (Image-data (* ImageWidth ImageHeight PixelDepth) bitstring) (Rest-data bitstring)) (begin (print "True-Color uncompressed") (print ImageWidth "x" ImageHeight "x" PixelDepth) (parse-image-uncompressed (lambda (color) (file-write fo (bitstring->blob color))) PixelDepth Image-data))) ; True-Color compressed (((TGA-Header bitpacket) (check (and (= 0 ColorMapType) (= 10 ImageType))) (ID-data ID-length bitstring) (Image-data bitstring)) (begin (print "True-Color compressed") (print ImageWidth "x" ImageHeight "x" PixelDepth) (parse-image-compressed (lambda (color) (file-write fo (bitstring->blob color))) PixelDepth Image-data)))))) (define (parse-image-uncompressed func depth image) (bitmatch image ((()) 'ok) (((Color depth bitstring) (Rest bitstring)) (begin (func Color) (parse-image-uncompressed func depth Rest))))) (define (parse-image-compressed func depth image) (bitmatch image ((()) 'ok) (((1 1) (Count 7) (Color depth bitstring) (Rest bitstring)) (let loop ((i 0)) (func Color) (if (< i Count) (loop (+ i 1)) (parse-image-compressed func depth Rest)))) (((0 1) (Count 7) (RAW-data (* depth (+ Count 1)) bitstring) (Rest bitstring)) (begin (parse-image-uncompressed func depth RAW-data) (parse-image-compressed func depth Rest))))) ; Convert images to raw pixels ;(parse-tga "tests/24compressed.tga" "tests/24c.raw") ;(parse-tga "tests/24uncompressed.tga" "tests/24u.raw")
License
BSD
Repository
Bitstring is maintained in a hg bitbucket repository.
Version History
0.2 introduce bitconstruct
0.1 first public release