@@ -60,6 +60,7 @@ module Data.Binary.Bits.Get
61 -- ** Get bytes
61 -- ** Get bytes
63 , getWord8
64 , getWord8
64 , getWord16
65 , getWord16
65 , getWord32
66 , getWord32
@@ -114,6 +115,8 @@ import Control.Applicative
114import Control.Monad (when,foldM_)
115import Control.Monad (when,foldM_)
116import Prelude as P
117import Prelude as P
119+import GHC.Base (uncheckedShiftLWord8#, wordToWord8#, Int (..), andWord8#, Word8#, (-#), Int#, xorI#, eqWord8#, TYPE)
118-- $bitget
121-- $bitget
119-- Parse bits using a monad.
122-- Parse bits using a monad.
@@ -182,6 +185,18 @@ readBool (S bs o bo) = case bo of
182 LL -> testBit (unsafeHead bs) o
185 LL -> testBit (unsafeHead bs) o
183 LB -> testBit (unsafeHead bs) o
186 LB -> testBit (unsafeHead bs) o
188+-- | Read a single bit
189+readBool# :: S -> Int
190+readBool# (S bs (I# o) bo) = case bo of
191+ BB -> testBit# (7# -# o)
192+ BL -> testBit# (7# -# o)
196+ !(W8# w) = unsafeHead bs
197+ testBit# n = I# (((w `andWord8#` (wordToWord8# 1## `uncheckedShiftLWord8#` n)) `eqWord8#` wordToWord8# 0##) `xorI#` 1#)
185-- | Extract a range of bits from (ws :: ByteString)
200-- | Extract a range of bits from (ws :: ByteString)
187-- Constraint: 8 * (length ws -1 ) < o+n <= 8 * length ws
202-- Constraint: 8 * (length ws -1 ) < o+n <= 8 * length ws
@@ -363,6 +378,10 @@ isEmpty = B $ \ (S bs o bo) -> if B.null bs
363getBool :: BitGet Bool
378getBool :: BitGet Bool
364getBool = block bool
379getBool = block bool
381+-- | Get 1 bit as a 'Bool'.
382+getBool# :: BitGet Int
383+getBool# = block bool#
366-- | Get @n@ bits as a 'Word8'. @n@ must be within @[0..8]@.
385-- | Get @n@ bits as a 'Word8'. @n@ must be within @[0..8]@.
367getWord8 :: Int -> BitGet Word8
386getWord8 :: Int -> BitGet Word8
368getWord8 n = block (word8 n)
387getWord8 n = block (word8 n)
@@ -438,6 +457,10 @@ block (Block i p) = do
438bool :: Block Bool
457bool :: Block Bool
439bool = Block 1 readBool
458bool = Block 1 readBool
460+-- | Read a 1 bit 'Bool'.
462+bool# = Block 1 readBool#
441-- | Read @n@ bits as a 'Word8'. @n@ must be within @[0..8]@.
464-- | Read @n@ bits as a 'Word8'. @n@ must be within @[0..8]@.
442word8 :: Int -> Block Word8
465word8 :: Int -> Block Word8
443word8 n = Block n (readWordChecked 8 n)
466word8 n = Block n (readWordChecked 8 n)