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

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 aSource

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 BoolSource

Get 1 bit as a Bool.

getWord8 :: Int -> BitGet Word8Source

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

getWord16be :: Int -> BitGet Word16Source

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

getWord32be :: Int -> BitGet Word32Source

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

getWord64be :: Int -> BitGet Word64Source

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 aSource

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 BoolSource

Read a 1 bit Bool.

word8 :: Int -> Block Word8Source

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

word16be :: Int -> Block Word16Source

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

word32be :: Int -> Block Word32Source

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

word64be :: Int -> Block Word64Source

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