6 -- | Lazy bitstrings based on 'L.ByteString' which treats a byte
7 -- stream as a bit sequence in the same way as WavPack's manner.
8 module Codec.Audio.WavPack.BitString
9 ( -- * The BitString Type
25 -- * Conversion from/to 'L.ByteString'
35 import qualified Data.ByteString.Lazy as L
38 import qualified Data.Strict as S
40 import Prelude hiding (drop, head, length, null, splitAt, tail, take)
41 import Prelude.Unicode
43 -- | The BitString Type.
47 , leftBytes ∷ !L.ByteString
49 , rightBytes ∷ !L.ByteString
56 -- | bit length from 0 to 8
58 -- | current byte @(0 <= remByte <= (1 `'shiftL'` 'remLen') - 1)@
64 remEmpty = Remnant 0 0
66 remNull ∷ Remnant → Bool
67 remNull = (0 ≡) ∘ remLen
69 remSingleton ∷ Bool -> Remnant
70 remSingleton b = Remnant {
72 , remByte = if b then 1 else 0
75 byteToRem ∷ Word8 → Remnant
76 byteToRem w = Remnant {
81 remToStr ∷ Remnant → L.ByteString
84 | otherwise = L.singleton $ remByte r
86 consRem ∷ Bool → Remnant → (# Remnant, S.Maybe Word8 #)
88 | remLen r ≡ 8 = (# remSingleton b, S.Just $ remByte r #)
89 | remLen r ≡ 7 = (# remEmpty, S.Just w' #)
90 | otherwise = let !r' = r {
97 w' = (remByte r `shiftR` 1)
101 snocRem ∷ Remnant → Bool → (# S.Maybe Word8, Remnant #)
103 | remLen r ≡ 8 = (# S.Just $ remByte r, remSingleton b #)
104 | remLen r ≡ 7 = (# S.Just w', remEmpty #)
105 | otherwise = let !r' = r {
106 remLen = remLen r + 1
112 w' | b = bit (remLen r) .|. remByte r
113 | otherwise = remByte r
115 unconsRem ∷ Remnant → (# S.Maybe Bool, Remnant #)
117 | remNull r = (# S.Nothing, remEmpty #)
118 | otherwise = let !b = remByte r `testBit` 1
120 remLen = remLen r - 1
121 , remByte = remByte r `shiftR` 1
126 unconsBytes ∷ L.ByteString → (# S.Maybe Remnant, L.ByteString #)
128 = case L.uncons bs of
130 → (# S.Just (byteToRem w), bs' #)
132 → (# S.Nothing, L.empty #)
134 appendRem ∷ Remnant → Remnant → Remnant
135 appendRem a b = Remnant {
136 remLen = remLen a + remLen b
137 , remByte = (remByte a `shiftL` remLen b) .|. remByte b
140 splitRemAt ∷ Integral n ⇒ n → Remnant → (# S.Maybe Remnant, Remnant #)
142 | remLen r ≥ fromIntegral n
144 remLen = fromIntegral n
145 , remByte = remByte r .&. ((1 `shiftL` fromIntegral n) - 1)
148 remLen = remLen r - fromIntegral n
149 , remByte = remByte r `shiftR` fromIntegral n
154 = (# S.Nothing, remEmpty #)
156 -- | /O(1)/ The empty 'BitString'.
160 , leftBytes = L.empty
161 , rightBytes = L.empty
162 , rightRem = remEmpty
165 -- | /O(1)/ Convert a 'Bool' into a 'BitString'.
166 singleton ∷ Bool → BitString
167 singleton b = BitString {
168 leftRem = remSingleton b
169 , leftBytes = L.empty
170 , rightBytes = L.empty
171 , rightRem = remEmpty
174 -- | /O(1)/ Prepend a bit to the beginning of a 'BitString'.
175 cons ∷ Bool → BitString → BitString
177 = case consRem b $ leftRem bs of
181 , leftBytes = L.cons' w $ leftBytes bs
185 → bs { leftRem = lr' }
187 -- | /O(1)/ Append a bit to the end of a 'BitString'.
188 snoc ∷ BitString → Bool → BitString
190 = case snocRem (rightRem bs) b of
193 rightBytes = L.cons' w $ rightBytes bs
198 → bs { rightRem = rr' }
200 -- | /amortized O(1)/ Extract the first bit of a 'BitString', which
201 -- must be non-empty.
202 head ∷ BitString → Bool
203 head bs = case uncons bs of
207 → error "head: empty BitString"
209 -- | /amortized O(1)/ Extract the bits after the head of a
210 -- 'BitString', which must be non-empty.
211 tail ∷ BitString → BitString
212 tail bs = case uncons bs of
216 → error "tail: empty BitString"
218 -- | /amortized O(1)/ Extract the the head and tail of a 'BitString',
219 -- returning 'Nothing' if it's empty.
220 uncons ∷ BitString → Maybe (Bool, BitString)
222 = case unconsRem $ leftRem bs of
224 → Just (b, bs { leftRem = lr' })
227 → case unconsBytes $ leftBytes bs of
229 → let !bs' = bs { leftRem = lr
236 → if L.null $ rightBytes bs then
237 case unconsRem $ rightRem bs of
239 → Just (b, bs { rightRem = rr' })
244 let !bs' = bs { leftBytes = L.reverse
250 -- | /O(1)/ Test whether a 'BitString' is empty.
251 null ∷ BitString → Bool
253 = remLen (leftRem bs) ≡ 0
255 L.null (leftBytes bs)
257 L.null (rightBytes bs)
259 remLen (rightRem bs) ≡ 0
261 -- | /O(n)/ Return the number of bits in a 'BitString'.
262 length ∷ Integral n ⇒ BitString → n
264 = fromIntegral $ ( fromIntegral (remLen $ leftRem bs)
266 L.length (leftBytes bs) ⋅ 8
268 L.length (rightBytes bs) ⋅ 8
270 fromIntegral (remLen $ rightRem bs)
272 {-# SPECIALISE length ∷ BitString → Int64 #-}
274 -- | /O(1)/ Convert a 'L.ByteString' into a 'BitString'.
275 fromByteString ∷ L.ByteString → BitString
276 fromByteString bs = BitString {
279 , rightBytes = L.empty
280 , rightRem = remEmpty
283 -- | /O(n)/ Convert a 'BitString' into 'L.ByteString', padding
284 -- incomplete bytes to single bytes with necessary 0's at their
285 -- MSB. Thus the following equation does not hold when the length of
286 -- 'BitString' isn't multiple of 8.
288 -- > fromByteString . toByteString = id
290 -- But the following always holds true.
292 -- > toByteString . fromByteString = id
293 toByteString ∷ BitString → L.ByteString
295 = L.concat [ remToStr $ leftRem bs
297 , L.reverse $ rightBytes bs
298 , remToStr $ rightRem bs
301 -- | /O(n)/ @'take' n bs@ returns the prefix of @bs@ of length
302 -- @n@. @bs@ must have at least @n@ bits.
303 take ∷ Integral n ⇒ n → BitString → BitString
304 take n xs = case splitAt n xs of
307 -- | /O(n)/ @'drop' n bs@ returns the suffix of @bs@ after the first
308 -- @n@ bits. @bs@ must have at least @n@ bits.
309 drop ∷ Integral n ⇒ n → BitString → BitString
310 drop n xs = case splitAt n xs of
311 (_, dropped) → dropped
313 -- | /O(n)/ @'splitAt' n bs@ is equivalent to @('take' n bs, 'drop' n
315 splitAt ∷ Integral n ⇒ n → BitString → (BitString, BitString)
317 = case splitRemAt n $ leftRem bs of
319 -- The leftRem has enough bits.
320 → let !h' = BitString {
322 , leftBytes = L.empty
323 , rightBytes = L.empty
324 , rightRem = remEmpty
327 (h', bs { leftRem = lr' })
330 → let !bytesToTake = (n - fromIntegral (remLen $ leftRem bs)) `div` 8
331 !amortised = leftBytes bs `L.append` (L.reverse $ rightBytes bs)
332 -- 0 ≤ bitsToTake < 8 - remLen (leftRem bs)
333 -- ∴ remLen (leftRem bs) + bitsToTake < 8
334 !bitsToTake = n - bytesToTake ⋅ 8 - fromIntegral (remLen $ leftRem bs)
336 case (# bytesToTake, L.uncons amortised #) of
337 (#_, Just (!w, amor') #)
338 -- There is at least one byte in the byte pool
340 → let !h1 = leftRem bs
342 = case splitRemAt bitsToTake $ byteToRem w of
343 (# S.Just h2', lr'' #) → (# h2', lr'' #)
344 (# S.Nothing , _ #) → error "internal error"
345 !h = h1 `appendRem` h2
347 = L.splitAt (fromIntegral bytesToTake) amor'
349 if L.length bytes ≡ fromIntegral bytesToTake then
350 -- The byte pool actuall has at least
351 -- bytesToTake bytes.
352 let !h' = BitString {
355 , rightBytes = L.empty
356 , rightRem = remEmpty
361 , rightBytes = L.empty
362 , rightRem = rightRem bs
367 error "splitAt: not enough bits"
370 -- No bytes are in the byte pool but the
371 -- rightRem may have enough bits.
372 → case splitRemAt bitsToTake $ rightRem bs of
374 → let !h' = BitString {
376 , leftBytes = L.empty
377 , rightBytes = L.empty
382 , leftBytes = L.empty
383 , rightBytes = L.empty
390 → error "splitAt: not enough bits"
393 -- No bytes are in the byte pool but more than 8
394 -- bits are requested. The rightRem can't have
396 → error "splitAt: not enough bits"