on master help sign in
Keep the current chunk within the BitGet monad.
0e5029eLennart Kolmodin
Data/Binary/Bits/Get.hs+19−3
@@ -82,6 +82,7 @@ module Data.Binary.Bits.Get
82 ) where
82 ) where
83
83
84import Data.Binary.Get as B ( runGet, Get, getByteString )
84import Data.Binary.Get as B ( runGet, Get, getByteString )
85+import Data.Binary.Get.Internal as B ( get, put, ensureN )
85
86
86import Data.ByteString as B
87import Data.ByteString as B
87import Data.ByteString.Unsafe
88import Data.ByteString.Unsafe
@@ -335,7 +336,7 @@ newtype BitGet a = B { runState :: S -> Get (S,a) }
335
336
336instance Monad BitGet where
337instance Monad BitGet where
337 return x = B $ \s -> return (s,x)
338 return x = B $ \s -> return (s,x)
338− fail str = B $ \_s -> fail str
339+ fail str = B $ \(S inp n) -> putBackState inp n >> fail str
339 (B f) >>= g = B $ \s -> do (s',a) <- f s
340 (B f) >>= g = B $ \s -> do (s',a) <- f s
340 runState (g a) s'
341 runState (g a) s'
341
342
@@ -350,9 +351,22 @@ instance Applicative BitGet where
350-- been partially consumed it will be discarded once 'runBitGet' is finished.
351-- been partially consumed it will be discarded once 'runBitGet' is finished.
351runBitGet :: BitGet a -> Get a
352runBitGet :: BitGet a -> Get a
352runBitGet bg = do
353runBitGet bg = do
354+ s <- mkInitState
353− (_,a) <- runState bg (S B.empty 0)
355+ ((S str' n),a) <- runState bg s
356+ putBackState str' n
354 return a
357 return a
355
358
359+mkInitState :: Get S
360+mkInitState = do
361+ str <- get
362+ put B.empty
363+ return (S str 0)
364+
365+putBackState :: B.ByteString -> Int -> Get ()
366+putBackState bs n = do
367+ remaining <- get
368+ put (B.drop (if n==0 then 0 else 1) bs `B.append` remaining)
369+
356getState :: BitGet S
370getState :: BitGet S
357getState = B $ \s -> return (s,s)
371getState = B $ \s -> return (s,s)
358
372
@@ -370,7 +384,9 @@ ensureBits n = do
370 then return ()
384 then return ()
371 else do let currentBits = B.length bs * 8 - o
385 else do let currentBits = B.length bs * 8 - o
372 let byteCount = (n - currentBits + 7) `div` 8
386 let byteCount = (n - currentBits + 7) `div` 8
373− B $ \_ -> do bs' <- B.getByteString byteCount
387+ B $ \_ -> do B.ensureN byteCount
388+ bs' <- B.get
389+ put B.empty
374 return (S (bs`append`bs') o, ())
390 return (S (bs`append`bs') o, ())
375
391
376-- | Get 1 bit as a 'Bool'.
392-- | Get 1 bit as a 'Bool'.
binary-bits.cabal+2−2
@@ -18,7 +18,7 @@ source-repository head
18 location: git://github.com/kolmodin/binary-bits.git
18 location: git://github.com/kolmodin/binary-bits.git
19
19
20library
20library
21− build-depends: base==4.*, binary, bytestring
21+ build-depends: base==4.*, binary >= 0.6.0.0, bytestring
22
22
23 other-extensions: RankNTypes, MagicHash, BangPatterns, CPP
23 other-extensions: RankNTypes, MagicHash, BangPatterns, CPP
24
24
@@ -35,7 +35,7 @@ test-suite qc
35 main-is: BitsQC.hs
35 main-is: BitsQC.hs
36 default-language: Haskell98
36 default-language: Haskell98
37
37
38− build-depends: base==4.*, binary, bytestring,
38+ build-depends: base==4.*, binary >= 0.6.0.0, bytestring,
39 QuickCheck>=2, random,
39 QuickCheck>=2, random,
40 test-framework,
40 test-framework,
41 test-framework-quickcheck2
41 test-framework-quickcheck2