{-# language BangPatterns #-}
{-# language TypeApplications #-}
module Data.Bytes.Parser.Base128
(
word16
, word32
, word64
) where
import Control.Monad (when)
import Data.Bits (testBit,unsafeShiftL,(.|.),bit,clearBit)
import Data.Bytes.Parser (Parser)
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 = forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word16 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e s. e -> Int -> Word64 -> Parser e s Word64
stepBoundedWord e
e Int
16 Word64
0
word32 :: e -> Parser e s Word32
word32 :: forall e s. e -> Parser e s Word32
word32 e
e = forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word32 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e s. e -> Int -> Word64 -> Parser e s Word64
stepBoundedWord e
e Int
32 Word64
0
word64 :: e -> Parser e s Word64
word64 :: forall e s. e -> Parser e s Word64
word64 e
e = forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word64 @Word64 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e s. e -> Int -> Word64 -> Parser e s Word64
stepBoundedWord e
e Int
64 Word64
0
stepBoundedWord :: e -> Int -> Word64 -> Parser e s Word64
stepBoundedWord :: forall e s. e -> Int -> Word64 -> Parser e s Word64
stepBoundedWord e
e !Int
bitLimit !Word64
acc = do
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word64
acc forall a. Ord a => a -> a -> Bool
>= forall a. Bits a => Int -> a
bit (Int
bitLimit forall a. Num a => a -> a -> a
- Int
7)) forall a b. (a -> b) -> a -> b
$ forall e s a. e -> Parser e s a
P.fail e
e
Word8
raw <- forall e s. e -> Parser e s Word8
P.any e
e
let content :: Word8
content = forall a. Bits a => a -> Int -> a
clearBit Word8
raw Int
7
acc' :: Word64
acc' = forall a. Bits a => a -> Int -> a
unsafeShiftL Word64
acc Int
7 forall a. Bits a => a -> a -> a
.|. forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word8 @Word64 Word8
content
if forall a. Bits a => a -> Int -> Bool
testBit Word8
raw Int
7
then forall e s. e -> Int -> Word64 -> Parser e s Word64
stepBoundedWord e
e Int
bitLimit Word64
acc'
else forall (f :: * -> *) a. Applicative f => a -> f a
pure Word64
acc'