{-# language BangPatterns #-}
{-# language BinaryLiterals #-}
{-# language TypeApplications #-}
module Data.Bytes.Parser.Leb128
(
word16
, word32
, word64
, int16
, int32
, int64
) where
import Data.Bits (testBit,(.&.),unsafeShiftR,xor,complement)
import Data.Bits (unsafeShiftL,(.|.))
import Data.Bytes.Parser (Parser)
import Data.Int (Int16,Int32,Int64)
import Data.Word (Word8,Word16,Word32,Word64)
import qualified Data.Bytes.Parser as P
word16 :: e -> Parser e s Word16
word16 :: forall e s. e -> Parser e s Word16
word16 e
e = do
Word64
w <- forall e s. e -> Int -> Word64 -> Int -> Parser e s Word64
stepBoundedWord e
e Int
16 Word64
0 Int
0
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word16 Word64
w)
word32 :: e -> Parser e s Word32
word32 :: forall e s. e -> Parser e s Word32
word32 e
e = do
Word64
w <- forall e s. e -> Int -> Word64 -> Int -> Parser e s Word64
stepBoundedWord e
e Int
32 Word64
0 Int
0
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word32 Word64
w)
word64 :: e -> Parser e s Word64
word64 :: forall e s. e -> Parser e s Word64
word64 e
e = forall e s. e -> Int -> Word64 -> Int -> Parser e s Word64
stepBoundedWord e
e Int
64 Word64
0 Int
0
int16 :: e -> Parser e s Int16
int16 :: forall e s. e -> Parser e s Int16
int16 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word16 -> Int16
zigzagDecode16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e s. e -> Parser e s Word16
word16
int32 :: e -> Parser e s Int32
int32 :: forall e s. e -> Parser e s Int32
int32 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word32 -> Int32
zigzagDecode32 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e s. e -> Parser e s Word32
word32
int64 :: e -> Parser e s Int64
int64 :: forall e s. e -> Parser e s Int64
int64 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word64 -> Int64
zigzagDecode64 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e s. e -> Parser e s Word64
word64
stepBoundedWord :: e -> Int -> Word64 -> Int -> Parser e s Word64
stepBoundedWord :: forall e s. e -> Int -> Word64 -> Int -> Parser e s Word64
stepBoundedWord e
e !Int
bitLimit !Word64
acc0 !Int
accShift = do
Word8
raw <- forall e s. e -> Parser e s Word8
P.any e
e
let number :: Word8
number = Word8
raw forall a. Bits a => a -> a -> a
.&. Word8
0x7F
acc1 :: Word64
acc1 = Word64
acc0 forall a. Bits a => a -> a -> a
.|.
forall a. Bits a => a -> Int -> a
unsafeShiftL (forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 @Word64 Word8
number) Int
accShift
accShift' :: Int
accShift' = Int
accShift forall a. Num a => a -> a -> a
+ Int
7
if Int
accShift' forall a. Ord a => a -> a -> Bool
<= Int
bitLimit
then if forall a. Bits a => a -> Int -> Bool
testBit Word8
raw Int
7
then forall e s. e -> Int -> Word64 -> Int -> Parser e s Word64
stepBoundedWord e
e Int
bitLimit Word64
acc1 Int
accShift'
else forall (f :: * -> *) a. Applicative f => a -> f a
pure Word64
acc1
else if forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 @Word Word8
raw forall a. Ord a => a -> a -> Bool
< Int -> Word
twoExp (Int
bitLimit forall a. Num a => a -> a -> a
- Int
accShift)
then forall (f :: * -> *) a. Applicative f => a -> f a
pure Word64
acc1
else forall e s a. e -> Parser e s a
P.fail e
e
twoExp :: Int -> Word
twoExp :: Int -> Word
twoExp Int
x = forall a. Bits a => a -> Int -> a
unsafeShiftL Word
1 Int
x
zigzagDecode16 :: Word16 -> Int16
zigzagDecode16 :: Word16 -> Int16
zigzagDecode16 Word16
n =
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((forall a. Bits a => a -> Int -> a
unsafeShiftR Word16
n Int
1) forall a. Bits a => a -> a -> a
`xor` (forall a. Bits a => a -> a
complement (Word16
n forall a. Bits a => a -> a -> a
.&. Word16
1) forall a. Num a => a -> a -> a
+ Word16
1))
zigzagDecode32 :: Word32 -> Int32
zigzagDecode32 :: Word32 -> Int32
zigzagDecode32 Word32
n =
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((forall a. Bits a => a -> Int -> a
unsafeShiftR Word32
n Int
1) forall a. Bits a => a -> a -> a
`xor` (forall a. Bits a => a -> a
complement (Word32
n forall a. Bits a => a -> a -> a
.&. Word32
1) forall a. Num a => a -> a -> a
+ Word32
1))
zigzagDecode64 :: Word64 -> Int64
zigzagDecode64 :: Word64 -> Int64
zigzagDecode64 Word64
n =
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((forall a. Bits a => a -> Int -> a
unsafeShiftR Word64
n Int
1) forall a. Bits a => a -> a -> a
`xor` (forall a. Bits a => a -> a
complement (Word64
n forall a. Bits a => a -> a -> a
.&. Word64
1) forall a. Num a => a -> a -> a
+ Word64
1))