@@ -43,8 +43,8 @@ import GHC.Word
4343import GHC.Int
4444#endif
4545
46−data S = S !ByteString -- ^ Input
47− !Int -- ^ Bit offset (0-7)
46+data S = S !ByteString -- Input
47+ !Int -- Bit offset (0-7)
4848 deriving (Show)
4949
5050-- | A block that will be read with only one boundry check. Needs to know the
@@ -60,6 +60,31 @@ instance Applicative Block where
6060 (Block i _) *> (Block j q) = Block (i+j) (q . incS i)
6161 (Block i p) <* (Block j _) = Block (i+j) p
6262
63+-- | Get a block. Guaranteed to be done with one single boundry check, and must
64+-- therefore require a statically known number of bits.
65+-- Build blocks using 'bool', 'word8', 'word16be', 'word32be', 'word64be' and 'Applicative'.
66+--
67+-- @
68+-- data IPV6Header = IPV6Header {
69+-- ipv6Version :: 'Word8'
70+-- , ipv6TrafficClass :: 'Word8'
71+-- , ipv6FlowLabel :: 'Word32
72+-- , ipv6PayloadLength :: 'Word16'
73+-- , ipv6NextHeader :: 'Word8'
74+-- , ipv6HopLimit :: 'Word8'
75+-- , ipv6SourceAddress :: 'ByteString'
76+-- , ipv6DestinationAddress :: 'ByteString'
77+-- }
78+--
79+-- parse = IPV6Header '<$>' 'word8' 4
80+-- '<*>' 'word8' 8
81+-- '<*>' 'word32be' 24
82+-- '<*>' 'word16be' 16
83+-- '<*>' 'word8' 8
84+-- '<*>' 'word8' 8
85+-- '<*>' 'byteString' 16
86+-- '<*>' 'byteString' 16
87+-- @
6388block :: Block a -> BitGet a
6489block (Block i p) = do
6590 ensureBits i
@@ -221,7 +246,7 @@ readWord64be n s@(S bs o)
221246 | otherwise = error "readWord64be: tried to read more than 64 bits"
222247
223248------------------------------------------------------------------------
224−-- unrolled codensity/state monad
249+
225250newtype BitGet a = B { runState :: S -> Get (S,a) }
226251
227252instance Monad BitGet where