binary-bits-0.5: Bit parsing/writing on top of binary.

Copyright(c) Lennart Kolmodin 2010-2011
LicenseBSD3-style (see LICENSE)
Portabilityportable (should run where the package binary runs)
Safe HaskellNone




Parse bits easily. Parsing can be done either in a monadic style, or more efficiently, using the Applicative style.

For the monadic style, write your parser as a BitGet monad using the

functions and run it with runBitGet.

For the applicative style, compose the fuctions

to make a Block. Use block to turn it into the BitGet monad to be able to run it with runBitGet.


BitGet monad

Parse bits using a monad.

myBitParser :: Get (Word8, Word8)
myBitParser = runGetBit parse4by4

parse4by4 :: BitGet (Word8, Word8)
parse4by4 = do
   bits <- getWord8 4
   more <- getWord8 4
   return (bits,more)

data BitGet a Source

BitGet is a monad, applicative and a functor. See runBitGet for how to run it.

runBitGet :: BitGet a -> Get a Source

Run a BitGet within the Binary packages Get monad. If a byte has been partially consumed it will be discarded once runBitGet is finished.

Get bytes

getBool :: BitGet Bool Source

Get 1 bit as a Bool.

getWord8 :: Int -> BitGet Word8 Source

Get n bits as a Word8. n must be within [0..8].

getWord16be :: Int -> BitGet Word16 Source

Get n bits as a Word16. n must be within [0..16].

getWord32be :: Int -> BitGet Word32 Source

Get n bits as a Word32. n must be within [0..32].

getWord64be :: Int -> BitGet Word64 Source

Get n bits as a Word64. n must be within [0..64].


Parse more efficiently in blocks. Each block is read with only one boundry check (checking that there is enough input) as the size of the block can be calculated statically. This is somewhat limiting as you cannot make the parsing depend on the input being parsed.

data IPV6Header = IPV6Header {
     ipv6Version :: Word8
   , ipv6TrafficClass :: Word8
   , ipv6FlowLabel :: 'Word32
   , ipv6PayloadLength :: Word16
   , ipv6NextHeader :: Word8
   , ipv6HopLimit :: Word8
   , ipv6SourceAddress :: ByteString
   , ipv6DestinationAddress :: ByteString

 ipv6headerblock =
         IPV6Header <$> word8 4
                    <*> word8 8
                    <*> word32be 24
                    <*> word16be 16
                    <*> word8 8
                    <*> word8 8
                    <*> byteString 16
                    <*> byteString 16

ipv6Header :: Get IPV6Header
ipv6Header = runBitGet (block ipv6headerblock)

data Block a Source

A block that will be read with only one boundry check. Needs to know the number of bits in advance.

block :: Block a -> BitGet a Source

Get a block. Will be read with one single boundry check, and therefore requires a statically known number of bits. Build blocks using bool, word8, word16be, word32be, word64be, byteString and Applicative.

Read in Blocks

bool :: Block Bool Source

Read a 1 bit Bool.

word8 :: Int -> Block Word8 Source

Read n bits as a Word8. n must be within [0..8].

word16be :: Int -> Block Word16 Source

Read n bits as a Word16. n must be within [0..16].

word32be :: Int -> Block Word32 Source

Read n bits as a Word32. n must be within [0..32].

word64be :: Int -> Block Word64 Source

Read n bits as a Word64. n must be within [0..64].

getLazyByteString :: Int -> BitGet ByteString Source

Get n bytes as a lazy ByteString.

isEmpty :: BitGet Bool Source

Test whether all input has been consumed, i.e. there are no remaining undecoded bytes.