{-# OPTIONS_HADDOCK prune #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
module Lightning.Protocol.BOLT1.Prim (
ChainHash
, chainHash
, unChainHash
, encodeU16
, encodeU32
, encodeU64
, encodeS8
, encodeS16
, encodeS32
, encodeS64
, encodeTu16
, encodeTu32
, encodeTu64
, encodeMinSigned
, encodeBigSize
, decodeU16
, decodeU32
, decodeU64
, decodeS8
, decodeS16
, decodeS32
, decodeS64
, decodeTu16
, decodeTu32
, decodeTu64
, decodeMinSigned
, decodeBigSize
, encodeLength
) where
import Control.DeepSeq (NFData)
import Data.Bits (unsafeShiftL, unsafeShiftR, (.|.))
import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy as BSL
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Word (Word16, Word32, Word64)
import GHC.Generics (Generic)
newtype ChainHash = ChainHash BS.ByteString
deriving stock (ChainHash -> ChainHash -> Bool
(ChainHash -> ChainHash -> Bool)
-> (ChainHash -> ChainHash -> Bool) -> Eq ChainHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChainHash -> ChainHash -> Bool
== :: ChainHash -> ChainHash -> Bool
$c/= :: ChainHash -> ChainHash -> Bool
/= :: ChainHash -> ChainHash -> Bool
Eq, Int -> ChainHash -> ShowS
[ChainHash] -> ShowS
ChainHash -> String
(Int -> ChainHash -> ShowS)
-> (ChainHash -> String)
-> ([ChainHash] -> ShowS)
-> Show ChainHash
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChainHash -> ShowS
showsPrec :: Int -> ChainHash -> ShowS
$cshow :: ChainHash -> String
show :: ChainHash -> String
$cshowList :: [ChainHash] -> ShowS
showList :: [ChainHash] -> ShowS
Show, (forall x. ChainHash -> Rep ChainHash x)
-> (forall x. Rep ChainHash x -> ChainHash) -> Generic ChainHash
forall x. Rep ChainHash x -> ChainHash
forall x. ChainHash -> Rep ChainHash x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ChainHash -> Rep ChainHash x
from :: forall x. ChainHash -> Rep ChainHash x
$cto :: forall x. Rep ChainHash x -> ChainHash
to :: forall x. Rep ChainHash x -> ChainHash
Generic)
instance NFData ChainHash
chainHash :: BS.ByteString -> Maybe ChainHash
chainHash :: ByteString -> Maybe ChainHash
chainHash ByteString
bs
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
32 = ChainHash -> Maybe ChainHash
forall a. a -> Maybe a
Just (ByteString -> ChainHash
ChainHash ByteString
bs)
| Bool
otherwise = Maybe ChainHash
forall a. Maybe a
Nothing
{-# INLINE chainHash #-}
unChainHash :: ChainHash -> BS.ByteString
unChainHash :: ChainHash -> ByteString
unChainHash (ChainHash ByteString
bs) = ByteString
bs
{-# INLINE unChainHash #-}
encodeU16 :: Word16 -> BS.ByteString
encodeU16 :: Word16 -> ByteString
encodeU16 = LazyByteString -> ByteString
BSL.toStrict (LazyByteString -> ByteString)
-> (Word16 -> LazyByteString) -> Word16 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
BSB.toLazyByteString (Builder -> LazyByteString)
-> (Word16 -> Builder) -> Word16 -> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Builder
BSB.word16BE
{-# INLINE encodeU16 #-}
encodeU32 :: Word32 -> BS.ByteString
encodeU32 :: Word32 -> ByteString
encodeU32 = LazyByteString -> ByteString
BSL.toStrict (LazyByteString -> ByteString)
-> (Word32 -> LazyByteString) -> Word32 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
BSB.toLazyByteString (Builder -> LazyByteString)
-> (Word32 -> Builder) -> Word32 -> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Builder
BSB.word32BE
{-# INLINE encodeU32 #-}
encodeU64 :: Word64 -> BS.ByteString
encodeU64 :: Word64 -> ByteString
encodeU64 = LazyByteString -> ByteString
BSL.toStrict (LazyByteString -> ByteString)
-> (Word64 -> LazyByteString) -> Word64 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
BSB.toLazyByteString (Builder -> LazyByteString)
-> (Word64 -> Builder) -> Word64 -> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Builder
BSB.word64BE
{-# INLINE encodeU64 #-}
encodeS8 :: Int8 -> BS.ByteString
encodeS8 :: Int8 -> ByteString
encodeS8 = Word8 -> ByteString
BS.singleton (Word8 -> ByteString) -> (Int8 -> Word8) -> Int8 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int8 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE encodeS8 #-}
encodeS16 :: Int16 -> BS.ByteString
encodeS16 :: Int16 -> ByteString
encodeS16 = LazyByteString -> ByteString
BSL.toStrict (LazyByteString -> ByteString)
-> (Int16 -> LazyByteString) -> Int16 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
BSB.toLazyByteString (Builder -> LazyByteString)
-> (Int16 -> Builder) -> Int16 -> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> Builder
BSB.int16BE
{-# INLINE encodeS16 #-}
encodeS32 :: Int32 -> BS.ByteString
encodeS32 :: Int32 -> ByteString
encodeS32 = LazyByteString -> ByteString
BSL.toStrict (LazyByteString -> ByteString)
-> (Int32 -> LazyByteString) -> Int32 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
BSB.toLazyByteString (Builder -> LazyByteString)
-> (Int32 -> Builder) -> Int32 -> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Builder
BSB.int32BE
{-# INLINE encodeS32 #-}
encodeS64 :: Int64 -> BS.ByteString
encodeS64 :: Int64 -> ByteString
encodeS64 = LazyByteString -> ByteString
BSL.toStrict (LazyByteString -> ByteString)
-> (Int64 -> LazyByteString) -> Int64 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
BSB.toLazyByteString (Builder -> LazyByteString)
-> (Int64 -> Builder) -> Int64 -> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Builder
BSB.int64BE
{-# INLINE encodeS64 #-}
encodeTu16 :: Word16 -> BS.ByteString
encodeTu16 :: Word16 -> ByteString
encodeTu16 Word16
0 = ByteString
BS.empty
encodeTu16 !Word16
x
| Word16
x Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
< Word16
0x100 = Word8 -> ByteString
BS.singleton (Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
x)
| Bool
otherwise = Word16 -> ByteString
encodeU16 Word16
x
{-# INLINE encodeTu16 #-}
encodeTu32 :: Word32 -> BS.ByteString
encodeTu32 :: Word32 -> ByteString
encodeTu32 Word32
0 = ByteString
BS.empty
encodeTu32 !Word32
x
| Word32
x Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
< Word32
0x100 = Word8 -> ByteString
BS.singleton (Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x)
| Word32
x Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
< Word32
0x10000 = Word16 -> ByteString
encodeU16 (Word32 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x)
| Word32
x Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
< Word32
0x1000000 = [Word8] -> ByteString
BS.pack [ Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
x Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
16)
, Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
x Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
8)
, Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x
]
| Bool
otherwise = Word32 -> ByteString
encodeU32 Word32
x
{-# INLINE encodeTu32 #-}
encodeTu64 :: Word64 -> BS.ByteString
encodeTu64 :: Word64 -> ByteString
encodeTu64 Word64
0 = ByteString
BS.empty
encodeTu64 !Word64
x
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x100 = Word8 -> ByteString
BS.singleton (Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x)
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x10000 = Word16 -> ByteString
encodeU16 (Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x)
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x1000000 = [Word8] -> ByteString
BS.pack [ Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
16)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
8)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x
]
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x100000000 = Word32 -> ByteString
encodeU32 (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x)
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x10000000000 = [Word8] -> ByteString
BS.pack [ Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
32)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
24)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
16)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
8)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x
]
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x1000000000000 = [Word8] -> ByteString
BS.pack [ Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
40)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
32)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
24)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
16)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
8)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x
]
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x100000000000000 = [Word8] -> ByteString
BS.pack [ Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
48)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
40)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
32)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
24)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
16)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
8)
, Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x
]
| Bool
otherwise = Word64 -> ByteString
encodeU64 Word64
x
{-# INLINE encodeTu64 #-}
encodeMinSigned :: Int64 -> BS.ByteString
encodeMinSigned :: Int64 -> ByteString
encodeMinSigned !Int64
x
| Int64
x Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
>= -Int64
128 Bool -> Bool -> Bool
&& Int64
x Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
127 =
Word8 -> ByteString
BS.singleton (Int64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
x)
| Int64
x Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
>= -Int64
32768 Bool -> Bool -> Bool
&& Int64
x Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
32767 =
Int16 -> ByteString
encodeS16 (Int64 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
x)
| Int64
x Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
>= -Int64
2147483648 Bool -> Bool -> Bool
&& Int64
x Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
2147483647 =
Int32 -> ByteString
encodeS32 (Int64 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
x)
| Bool
otherwise =
Int64 -> ByteString
encodeS64 Int64
x
{-# INLINE encodeMinSigned #-}
encodeBigSize :: Word64 -> BS.ByteString
encodeBigSize :: Word64 -> ByteString
encodeBigSize !Word64
x
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0xfd = Word8 -> ByteString
BS.singleton (Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x)
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x10000 = Word8 -> ByteString -> ByteString
BS.cons Word8
0xfd (Word16 -> ByteString
encodeU16 (Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x))
| Word64
x Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
0x100000000 = Word8 -> ByteString -> ByteString
BS.cons Word8
0xfe (Word32 -> ByteString
encodeU32 (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x))
| Bool
otherwise = Word8 -> ByteString -> ByteString
BS.cons Word8
0xff (Word64 -> ByteString
encodeU64 Word64
x)
{-# INLINE encodeBigSize #-}
encodeLength :: BS.ByteString -> Maybe BS.ByteString
encodeLength :: ByteString -> Maybe ByteString
encodeLength !ByteString
bs
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
65535 = Maybe ByteString
forall a. Maybe a
Nothing
| Bool
otherwise = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Word16 -> ByteString
encodeU16 (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
BS.length ByteString
bs)))
{-# INLINE encodeLength #-}
decodeU16 :: BS.ByteString -> Maybe (Word16, BS.ByteString)
decodeU16 :: ByteString -> Maybe (Word16, ByteString)
decodeU16 !ByteString
bs
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2 = Maybe (Word16, ByteString)
forall a. Maybe a
Nothing
| Bool
otherwise =
let !b0 :: Word16
b0 = Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
0)
!b1 :: Word16
b1 = Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
1)
!val :: Word16
val = (Word16
b0 Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
8) Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16
b1
in (Word16, ByteString) -> Maybe (Word16, ByteString)
forall a. a -> Maybe a
Just (Word16
val, Int -> ByteString -> ByteString
BS.drop Int
2 ByteString
bs)
{-# INLINE decodeU16 #-}
decodeU32 :: BS.ByteString -> Maybe (Word32, BS.ByteString)
decodeU32 :: ByteString -> Maybe (Word32, ByteString)
decodeU32 !ByteString
bs
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
4 = Maybe (Word32, ByteString)
forall a. Maybe a
Nothing
| Bool
otherwise =
let !b0 :: Word32
b0 = Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
0)
!b1 :: Word32
b1 = Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
1)
!b2 :: Word32
b2 = Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
2)
!b3 :: Word32
b3 = Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
3)
!val :: Word32
val = (Word32
b0 Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
24) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. (Word32
b1 Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
16)
Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. (Word32
b2 Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32
b3
in (Word32, ByteString) -> Maybe (Word32, ByteString)
forall a. a -> Maybe a
Just (Word32
val, Int -> ByteString -> ByteString
BS.drop Int
4 ByteString
bs)
{-# INLINE decodeU32 #-}
decodeU64 :: BS.ByteString -> Maybe (Word64, BS.ByteString)
decodeU64 :: ByteString -> Maybe (Word64, ByteString)
decodeU64 !ByteString
bs
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
8 = Maybe (Word64, ByteString)
forall a. Maybe a
Nothing
| Bool
otherwise =
let !b0 :: Word64
b0 = Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
0)
!b1 :: Word64
b1 = Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
1)
!b2 :: Word64
b2 = Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
2)
!b3 :: Word64
b3 = Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
3)
!b4 :: Word64
b4 = Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
4)
!b5 :: Word64
b5 = Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
5)
!b6 :: Word64
b6 = Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
6)
!b7 :: Word64
b7 = Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
7)
!val :: Word64
val = (Word64
b0 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
56) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64
b1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
48)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64
b2 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
40) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64
b3 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
32)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64
b4 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
24) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64
b5 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
16)
Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64
b6 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
8) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
b7
in (Word64, ByteString) -> Maybe (Word64, ByteString)
forall a. a -> Maybe a
Just (Word64
val, Int -> ByteString -> ByteString
BS.drop Int
8 ByteString
bs)
{-# INLINE decodeU64 #-}
decodeS8 :: BS.ByteString -> Maybe (Int8, BS.ByteString)
decodeS8 :: ByteString -> Maybe (Int8, ByteString)
decodeS8 !ByteString
bs
| ByteString -> Bool
BS.null ByteString
bs = Maybe (Int8, ByteString)
forall a. Maybe a
Nothing
| Bool
otherwise = (Int8, ByteString) -> Maybe (Int8, ByteString)
forall a. a -> Maybe a
Just (Word8 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
0), Int -> ByteString -> ByteString
BS.drop Int
1 ByteString
bs)
{-# INLINE decodeS8 #-}
decodeS16 :: BS.ByteString -> Maybe (Int16, BS.ByteString)
decodeS16 :: ByteString -> Maybe (Int16, ByteString)
decodeS16 !ByteString
bs = do
(w, rest) <- ByteString -> Maybe (Word16, ByteString)
decodeU16 ByteString
bs
Just (fromIntegral w, rest)
{-# INLINE decodeS16 #-}
decodeS32 :: BS.ByteString -> Maybe (Int32, BS.ByteString)
decodeS32 :: ByteString -> Maybe (Int32, ByteString)
decodeS32 !ByteString
bs = do
(w, rest) <- ByteString -> Maybe (Word32, ByteString)
decodeU32 ByteString
bs
Just (fromIntegral w, rest)
{-# INLINE decodeS32 #-}
decodeS64 :: BS.ByteString -> Maybe (Int64, BS.ByteString)
decodeS64 :: ByteString -> Maybe (Int64, ByteString)
decodeS64 !ByteString
bs = do
(w, rest) <- ByteString -> Maybe (Word64, ByteString)
decodeU64 ByteString
bs
Just (fromIntegral w, rest)
{-# INLINE decodeS64 #-}
decodeTu16 :: Int -> BS.ByteString -> Maybe (Word16, BS.ByteString)
decodeTu16 :: Int -> ByteString -> Maybe (Word16, ByteString)
decodeTu16 !Int
len !ByteString
bs
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
2 = Maybe (Word16, ByteString)
forall a. Maybe a
Nothing
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = Maybe (Word16, ByteString)
forall a. Maybe a
Nothing
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = (Word16, ByteString) -> Maybe (Word16, ByteString)
forall a. a -> Maybe a
Just (Word16
0, ByteString
bs)
| Bool
otherwise =
let !bytes :: ByteString
bytes = Int -> ByteString -> ByteString
BS.take Int
len ByteString
bs
!rest :: ByteString
rest = Int -> ByteString -> ByteString
BS.drop Int
len ByteString
bs
in if HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bytes Int
0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0
then Maybe (Word16, ByteString)
forall a. Maybe a
Nothing
else (Word16, ByteString) -> Maybe (Word16, ByteString)
forall a. a -> Maybe a
Just (ByteString -> Word16
decodeBeWord16 ByteString
bytes, ByteString
rest)
where
decodeBeWord16 :: BS.ByteString -> Word16
decodeBeWord16 :: ByteString -> Word16
decodeBeWord16 ByteString
b = case ByteString -> Int
BS.length ByteString
b of
Int
1 -> Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
b Int
0)
Int
2 -> (Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
b Int
0) Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
8)
Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
b Int
1)
Int
_ -> Word16
0
{-# INLINE decodeTu16 #-}
decodeTu32 :: Int -> BS.ByteString -> Maybe (Word32, BS.ByteString)
decodeTu32 :: Int -> ByteString -> Maybe (Word32, ByteString)
decodeTu32 !Int
len !ByteString
bs
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
4 = Maybe (Word32, ByteString)
forall a. Maybe a
Nothing
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = Maybe (Word32, ByteString)
forall a. Maybe a
Nothing
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = (Word32, ByteString) -> Maybe (Word32, ByteString)
forall a. a -> Maybe a
Just (Word32
0, ByteString
bs)
| Bool
otherwise =
let !bytes :: ByteString
bytes = Int -> ByteString -> ByteString
BS.take Int
len ByteString
bs
!rest :: ByteString
rest = Int -> ByteString -> ByteString
BS.drop Int
len ByteString
bs
in if HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bytes Int
0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0
then Maybe (Word32, ByteString)
forall a. Maybe a
Nothing
else (Word32, ByteString) -> Maybe (Word32, ByteString)
forall a. a -> Maybe a
Just (Int -> ByteString -> Word32
decodeBeWord32 Int
len ByteString
bytes, ByteString
rest)
where
decodeBeWord32 :: Int -> BS.ByteString -> Word32
decodeBeWord32 :: Int -> ByteString -> Word32
decodeBeWord32 Int
n ByteString
b = Word32 -> Int -> Word32
forall {t}. (Bits t, Num t) => t -> Int -> t
go Word32
0 Int
0
where
go :: t -> Int -> t
go !t
acc !Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n = t
acc
| Bool
otherwise = t -> Int -> t
go ((t
acc t -> Int -> t
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
8)
t -> t -> t
forall a. Bits a => a -> a -> a
.|. Word8 -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
b Int
i)) (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE decodeTu32 #-}
decodeTu64 :: Int -> BS.ByteString -> Maybe (Word64, BS.ByteString)
decodeTu64 :: Int -> ByteString -> Maybe (Word64, ByteString)
decodeTu64 !Int
len !ByteString
bs
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
8 = Maybe (Word64, ByteString)
forall a. Maybe a
Nothing
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = Maybe (Word64, ByteString)
forall a. Maybe a
Nothing
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = (Word64, ByteString) -> Maybe (Word64, ByteString)
forall a. a -> Maybe a
Just (Word64
0, ByteString
bs)
| Bool
otherwise =
let !bytes :: ByteString
bytes = Int -> ByteString -> ByteString
BS.take Int
len ByteString
bs
!rest :: ByteString
rest = Int -> ByteString -> ByteString
BS.drop Int
len ByteString
bs
in if HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bytes Int
0 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0
then Maybe (Word64, ByteString)
forall a. Maybe a
Nothing
else (Word64, ByteString) -> Maybe (Word64, ByteString)
forall a. a -> Maybe a
Just (Int -> ByteString -> Word64
decodeBeWord64 Int
len ByteString
bytes, ByteString
rest)
where
decodeBeWord64 :: Int -> BS.ByteString -> Word64
decodeBeWord64 :: Int -> ByteString -> Word64
decodeBeWord64 Int
n ByteString
b = Word64 -> Int -> Word64
forall {t}. (Bits t, Num t) => t -> Int -> t
go Word64
0 Int
0
where
go :: t -> Int -> t
go !t
acc !Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n = t
acc
| Bool
otherwise = t -> Int -> t
go ((t
acc t -> Int -> t
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
8)
t -> t -> t
forall a. Bits a => a -> a -> a
.|. Word8 -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
b Int
i)) (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE decodeTu64 #-}
decodeMinSigned :: Int -> BS.ByteString -> Maybe (Int64, BS.ByteString)
decodeMinSigned :: Int -> ByteString -> Maybe (Int64, ByteString)
decodeMinSigned !Int
len !ByteString
bs
| ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = Maybe (Int64, ByteString)
forall a. Maybe a
Nothing
| Bool
otherwise = case Int
len of
Int
1 -> do
(v, rest) <- ByteString -> Maybe (Int8, ByteString)
decodeS8 ByteString
bs
Just (fromIntegral v, rest)
Int
2 -> do
(v, rest) <- ByteString -> Maybe (Int16, ByteString)
decodeS16 ByteString
bs
if v >= -128 && v <= 127
then Nothing
else Just (fromIntegral v, rest)
Int
4 -> do
(v, rest) <- ByteString -> Maybe (Int32, ByteString)
decodeS32 ByteString
bs
if v >= -32768 && v <= 32767
then Nothing
else Just (fromIntegral v, rest)
Int
8 -> do
(v, rest) <- ByteString -> Maybe (Int64, ByteString)
decodeS64 ByteString
bs
if v >= -2147483648 && v <= 2147483647
then Nothing
else Just (v, rest)
Int
_ -> Maybe (Int64, ByteString)
forall a. Maybe a
Nothing
{-# INLINE decodeMinSigned #-}
decodeBigSize :: BS.ByteString -> Maybe (Word64, BS.ByteString)
decodeBigSize :: ByteString -> Maybe (Word64, ByteString)
decodeBigSize !ByteString
bs
| ByteString -> Bool
BS.null ByteString
bs = Maybe (Word64, ByteString)
forall a. Maybe a
Nothing
| Bool
otherwise = case HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
BS.index ByteString
bs Int
0 of
Word8
0xff -> do
(val, rest) <- ByteString -> Maybe (Word64, ByteString)
decodeU64 (Int -> ByteString -> ByteString
BS.drop Int
1 ByteString
bs)
if val >= 0x100000000
then Just (val, rest)
else Nothing
Word8
0xfe -> do
(val, rest) <- ByteString -> Maybe (Word32, ByteString)
decodeU32 (Int -> ByteString -> ByteString
BS.drop Int
1 ByteString
bs)
if val >= 0x10000
then Just (fromIntegral val, rest)
else Nothing
Word8
0xfd -> do
(val, rest) <- ByteString -> Maybe (Word16, ByteString)
decodeU16 (Int -> ByteString -> ByteString
BS.drop Int
1 ByteString
bs)
if val >= 0xfd
then Just (fromIntegral val, rest)
else Nothing
Word8
b -> (Word64, ByteString) -> Maybe (Word64, ByteString)
forall a. a -> Maybe a
Just (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b, Int -> ByteString -> ByteString
BS.drop Int
1 ByteString
bs)