@@ -1,6 +1,7 @@
11module BitsPut
22 ( BitPut
33 , runBitPut
4+ , joinPut
45
56 , putBool
67 , putWord8
@@ -12,6 +13,8 @@ module BitsPut
1213import qualified Data.Binary.Builder as B
1314import Data.Binary.Builder ( Builder )
1415import qualified Data.Binary.Put as Put
16+import Data.Binary.Put ( Put )
17+
1518import Data.ByteString
1619
1720import Data.Bits
@@ -74,18 +77,28 @@ putWord64be :: Int -> Word64 -> BitPut ()
7477putWord64be n w
7578 | n <= 16 = putWord16be n (fromIntegral w)
7679
80+joinPut :: Put -> BitPut ()
81+joinPut m = BitPut $ \s0 -> PairS () $
82+ let (S b0 _ _) = flushIncomplete s0
83+ b = Put.execPut m
84+ in (S (b0`mappend`b) 0 0)
85+
7786flush :: S -> S
7887flush s@(S b w o)
7988 | o > 8 = error "flush: offset > 8"
8089 | o == 8 = S (b `mappend` B.singleton w) 0 0
8190 | otherwise = s
8291
92+flushIncomplete :: S -> S
93+flushIncomplete s@(S b w o)
94+ | o == 0 = s
95+ | otherwise = (S (b `mappend` B.singleton w) 0 0)
96+
8397runBitPut :: BitPut () -> Put.Put
8498runBitPut m = Put.putBuilder b'
8599 where
86− PairS _ (S b t o) = run m (S mempty 0 0)
87− b' | o == 0 = b
88− | otherwise = b `mappend` B.singleton t
100+ PairS _ s@(S b t o) = run m (S mempty 0 0)
101+ (S b' _ _) = flushIncomplete s
89102
90103instance Monad BitPut where
91104 m >>= k = BitPut $ \s ->