Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Variable-length integers (varints), a method to store arbitrarily large integers in a space efficient manner.
Note that varints aren't particularly efficient due to their decoding being slow. They are most interesting when you wish to provide support for large integers, but know that many (most?) inputs will be small, and want to be space efficient for them. Protocol Buffers uses them extensively, while Cap'n Proto swears them off.
TODO
- https://en.wikipedia.org/wiki/Variable-length_quantity
- I've defined basic unsigned varints. Signed varints have lots of options. You can use twos comp, zigzag, a sign bit, whatever.
Synopsis
- newtype Varnat (enc :: Encoding) (cont :: ContinuationBitBehaviour) (e :: Endianness) i = Varnat {
- getVarnat :: i
- data ContinuationBitBehaviour
- data Encoding
- class VarintContinuation (cont :: ContinuationBitBehaviour) where
- testVarintCont :: forall cont a. VarintContinuation cont => Bits a => a -> Int -> Bool
- setVarintCont :: forall cont a. VarintContinuation cont => Bits a => a -> Int -> a
Documentation
newtype Varnat (enc :: Encoding) (cont :: ContinuationBitBehaviour) (e :: Endianness) i Source #
A variable-length unsigned integer (natural).
The base algorithm is to split the natural into groups of 7 bits, and use the MSB to indicate whether another octet follows. You must specify a handful of type variables, which select precise varint behaviour beyond this. See their documentation for details.
You may select the type to use varnats at, but error handling isn't provided:
negatives won't work correctly, and overflow cannot be detected. So most of
the time, you probably want Natural
and Integer
.
Some examples:
- @
Varnat
'Redundant
'OnContinues
'BE
matches VLQ. - @
Varnat
'Redundant
'OnContinues
'LE
matches LEB128, protobuf. - @
Varnat
'Bijective
'OnContinues
'LE
matches Git's varints. - @
Varnat
'Bijective
'OffContinues
'LE
matches BPS's varints.
Instances
Enum i => Enum (Varnat enc cont e i) Source # | |
Defined in Binrep.Type.Varint succ :: Varnat enc cont e i -> Varnat enc cont e i # pred :: Varnat enc cont e i -> Varnat enc cont e i # toEnum :: Int -> Varnat enc cont e i # fromEnum :: Varnat enc cont e i -> Int # enumFrom :: Varnat enc cont e i -> [Varnat enc cont e i] # enumFromThen :: Varnat enc cont e i -> Varnat enc cont e i -> [Varnat enc cont e i] # enumFromTo :: Varnat enc cont e i -> Varnat enc cont e i -> [Varnat enc cont e i] # enumFromThenTo :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i -> [Varnat enc cont e i] # | |
Num i => Num (Varnat enc cont e i) Source # | |
Defined in Binrep.Type.Varint (+) :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i # (-) :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i # (*) :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i # negate :: Varnat enc cont e i -> Varnat enc cont e i # abs :: Varnat enc cont e i -> Varnat enc cont e i # signum :: Varnat enc cont e i -> Varnat enc cont e i # fromInteger :: Integer -> Varnat enc cont e i # | |
Integral i => Integral (Varnat enc cont e i) Source # | |
Defined in Binrep.Type.Varint quot :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i # rem :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i # div :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i # mod :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i # quotRem :: Varnat enc cont e i -> Varnat enc cont e i -> (Varnat enc cont e i, Varnat enc cont e i) # divMod :: Varnat enc cont e i -> Varnat enc cont e i -> (Varnat enc cont e i, Varnat enc cont e i) # | |
Real i => Real (Varnat enc cont e i) Source # | |
Defined in Binrep.Type.Varint toRational :: Varnat enc cont e i -> Rational # | |
Show i => Show (Varnat enc cont e i) Source # | |
(VarintContinuation cont, Integral i, Bits i) => Get (Varnat 'Bijective cont 'BE i) Source # | TODO nothing to test against - unsure if correct |
(VarintContinuation cont, Integral i, Bits i) => Get (Varnat 'Bijective cont 'LE i) Source # | Git varint (cont=on), BPS (beat patches) (cont=off) |
(VarintContinuation cont, Integral i, Bits i) => Get (Varnat 'Redundant cont 'BE i) Source # | VLQ (cont=on) |
(VarintContinuation cont, Integral i, Bits i) => Get (Varnat 'Redundant cont 'LE i) Source # | protobuf (cont=on), LEB128 (cont=on) not truly infinite length since shifters take |
(VarintContinuation cont, Integral i, Bits i) => Put (Varnat 'Redundant cont 'BE i) Source # | |
(VarintContinuation cont, Integral i, Bits i) => Put (Varnat 'Redundant cont 'LE i) Source # | |
Eq i => Eq (Varnat enc cont e i) Source # | |
Ord i => Ord (Varnat enc cont e i) Source # | |
Defined in Binrep.Type.Varint compare :: Varnat enc cont e i -> Varnat enc cont e i -> Ordering # (<) :: Varnat enc cont e i -> Varnat enc cont e i -> Bool # (<=) :: Varnat enc cont e i -> Varnat enc cont e i -> Bool # (>) :: Varnat enc cont e i -> Varnat enc cont e i -> Bool # (>=) :: Varnat enc cont e i -> Varnat enc cont e i -> Bool # max :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i # min :: Varnat enc cont e i -> Varnat enc cont e i -> Varnat enc cont e i # |
data ContinuationBitBehaviour Source #
OnContinues | on=continue, off=end |
OffContinues | on=end, off=continue |
class VarintContinuation (cont :: ContinuationBitBehaviour) where Source #
Instances
VarintContinuation 'OffContinues Source # | |
Defined in Binrep.Type.Varint | |
VarintContinuation 'OnContinues Source # | |
Defined in Binrep.Type.Varint |
testVarintCont :: forall cont a. VarintContinuation cont => Bits a => a -> Int -> Bool Source #
setVarintCont :: forall cont a. VarintContinuation cont => Bits a => a -> Int -> a Source #