packages feed

rattletrap-14.1.4: src/lib/Rattletrap/BitBuilder.hs

{- hlint ignore "Avoid restricted extensions" -}
{-# LANGUAGE BangPatterns #-}

module Rattletrap.BitBuilder where

import qualified Data.Bits as Bits
import qualified Data.ByteString.Builder as Builder
import qualified Data.Word as Word

data BitBuilder = BitBuilder
  { buffer :: Word.Word8,
    builder :: Builder.Builder,
    offset :: Int
  }

empty :: BitBuilder
empty = BitBuilder {buffer = 0x00, builder = mempty, offset = 0}

push :: Bool -> BitBuilder -> BitBuilder
push b x =
  let !newBuffer = if b then Bits.setBit (buffer x) (offset x) else buffer x
   in if offset x == 7
        then
          BitBuilder
            { buffer = 0x00,
              builder = builder x <> Builder.word8 newBuffer,
              offset = 0
            }
        else x {buffer = newBuffer, offset = offset x + 1}

toBuilder :: BitBuilder -> Builder.Builder
toBuilder x =
  if offset x == 0 then builder x else builder x <> Builder.word8 (buffer x)