http2-0.0.0: Network/HPACK/Huffman/Bit.hs
{-# LANGUAGE BangPatterns #-}
module Network.HPACK.Huffman.Bit (
B(..)
, Bits
, fromBits
, toBits
) where
import Data.List (foldl')
import Data.Word (Word8)
-- | Data type for Bit.
data B = F -- ^ Zero
| T -- ^ One
deriving (Eq,Ord,Show)
fromBit :: B -> Word8
fromBit F = 0
fromBit T = 1
toBit :: Word8 -> B
toBit 0 = F
toBit 1 = T
toBit _ = error "toBit"
-- | Bit sequence.
type Bits = [B]
-- | From 'Bits' of length 8 to 'Word8'.
--
-- >>> fromBits [T,F,T,F,T,F,T,F]
-- 170
-- >>> fromBits [F,T,F,T,F,T,F,T]
-- 85
fromBits :: Bits -> Word8
fromBits = foldl' (\x y -> x * 2 + y) 0 . map fromBit
-- | From 'Word8' to 'Bits' of length 8.
--
-- >>> toBits 170
-- [T,F,T,F,T,F,T,F]
-- >>> toBits 85
-- [F,T,F,T,F,T,F,T]
toBits :: Word8 -> Bits
toBits = toBits' [] 0
toBits' :: Bits -> Int -> Word8 -> Bits
toBits' bs !cnt 0
| cnt == 8 = bs
| otherwise = replicate (8 - cnt) F ++ bs -- filling missing bits from MSB
toBits' bs !cnt x = toBits' (b:bs) (cnt + 1) q
where
q = x `div` 2
r = x `mod` 2
b = toBit r