{- | 'Builder's for several variable-length integer encoding schemes.
-}
module Data.ByteString.Builder.VarWord
( varWordBe, denseVarWordBe
, varWordLe
) where
import Data.ByteString.Builder (Builder)
import Data.ByteString.Builder.Prim (primBounded)
import Data.Bits (Bits)
import Foreign.Storable (Storable)
import qualified Data.ByteString.Builder.Prim.VarWord as Prim
-- | Produce a 'Builder' to encode an integer with a variable-length (chunked)
-- encoding. 7-bit chunks are produced in big-endian (most significant chunk
-- first) order, and each is prefixed with a continuation bit.
--
-- > 18464 == 1 0010000 0100000 ==
-- > (A) (B) (C)
-- >
-- > +-- Keep reading
-- > | +-- Keep reading
-- > | | +-- Stop
-- > v v v
-- > 10000001 10010000 00100000
-- > |<--->| |<--->| |<--->|
-- > (A) (B) (C)
--
-- >>> Builder.toLazyByteString $ varWordBe (18464 :: Word32)
-- "\129\144\32"
varWordBe :: (Bits a, Integral a, Storable a) => a -> Builder
varWordBe = primBounded Prim.varWordBe
-- | Produce a 'Builder' to encode an integer with a variable-length (chunked)
-- encoding. 7-bit chunks are produced in big-endian (most significant chunk
-- first) order, each is prefixed with a continuation bit, and the
-- continuation bit carries a further bit of information to reduce the size of
-- the resulting encoding.
--
-- > 34976 == 10 0010001 0100000 == 34976
-- > (A) (B) (C)
-- >
-- > +-- Keep reading
-- > | +-- Keep reading
-- > | | +-- Stop
-- > v v v
-- > 10000001 10010000 00100000
-- > |<--->| |<--->| |<--->|
-- > (A-1) (B-1) (C)
--
-- >>> Builder.toLazyByteString $ denseVarWordBe (34976 :: Word32)
-- "\129\144\32"
denseVarWordBe :: (Bits a, Integral a, Storable a) => a -> Builder
denseVarWordBe = primBounded Prim.denseVarWordBe
-- | Produce a 'Builder' to encode an integer with a varible-length (chunked)
-- encoding. 7-bit chunks are produced in little-endian (least significant
-- chunk first) order, and each is prefixed with a continuation bit.
--
-- > 526337 == 100000 0010000 0000001 ==
-- > (A) (B) (C)
-- >
-- > +-- Keep reading
-- > | +-- Keep reading
-- > | | +-- Stop
-- > v v v
-- > 10000001 10010000 00100000
-- > |<--->| |<--->| |<--->|
-- > (C) (B) (A)
--
-- >>> Builder.toLazyByteString $ varWordLe (526337 :: Word32)
-- "\129\144\32"
varWordLe :: (Bits a, Integral a, Storable a) => a -> Builder
varWordLe = primBounded Prim.varWordLe