{-# language BangPatterns #-}
{-# language BinaryLiterals #-}
{-# language DataKinds #-}
{-# language DeriveFunctor #-}
{-# language DerivingStrategies #-}
{-# language GADTSyntax #-}
{-# language KindSignatures #-}
{-# language LambdaCase #-}
{-# language MagicHash #-}
{-# language MultiWayIf #-}
{-# language PolyKinds #-}
{-# language RankNTypes #-}
{-# language ScopedTypeVariables #-}
{-# language StandaloneDeriving #-}
{-# language TypeApplications #-}
{-# language UnboxedSums #-}
{-# language UnboxedTuples #-}
module Data.Bytes.Parser.LittleEndian
(
word8
, word16
, word32
, word64
, word128
, word256
, int8
, int16
, int32
, int64
, word16Array
, word32Array
, word64Array
, word128Array
, word256Array
, int64Array
) where
import Prelude hiding (length,any,fail,takeWhile)
import Control.Applicative (liftA2)
import Data.Bits ((.|.),unsafeShiftL)
import Data.Primitive (ByteArray(..),PrimArray(..))
import Data.Bytes.Types (Bytes(..))
import Data.Bytes.Parser.Internal (Parser,uneffectful)
import Data.Bytes.Parser.Internal (Result(..))
import Data.Bytes.Parser.Internal (swapArray16,swapArray32)
import Data.Bytes.Parser.Internal (swapArray64,swapArray128,swapArray256)
import Data.Word (Word8,Word16,Word32,Word64)
import Data.Int (Int8,Int16,Int32,Int64)
import Data.WideWord (Word128(Word128),Word256(Word256))
import GHC.ByteOrder (ByteOrder(LittleEndian,BigEndian),targetByteOrder)
import qualified Data.Bytes as Bytes
import qualified Data.Bytes.Parser as P
import qualified Data.Primitive as PM
word8 :: e -> Parser e s Word8
word8 :: forall e s. e -> Parser e s Word8
word8 = forall e s. e -> Parser e s Word8
P.any
word16Array ::
e
-> Int
-> Parser e s (PrimArray Word16)
word16Array :: forall e s. e -> Int -> Parser e s (PrimArray Word16)
word16Array e
e !Int
n = case ByteOrder
targetByteOrder of
ByteOrder
LittleEndian -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteArray -> PrimArray Word16
asWord16s forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteArray
Bytes.toByteArrayClone) (forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
2))
ByteOrder
BigEndian -> do
Bytes
bs <- forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
2)
let r :: ByteArray
r = Bytes -> ByteArray
swapArray16 Bytes
bs
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteArray -> PrimArray Word16
asWord16s ByteArray
r)
word32Array ::
e
-> Int
-> Parser e s (PrimArray Word32)
word32Array :: forall e s. e -> Int -> Parser e s (PrimArray Word32)
word32Array e
e !Int
n = case ByteOrder
targetByteOrder of
ByteOrder
LittleEndian -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteArray -> PrimArray Word32
asWord32s forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteArray
Bytes.toByteArrayClone) (forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
4))
ByteOrder
BigEndian -> do
Bytes
bs <- forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
4)
let r :: ByteArray
r = Bytes -> ByteArray
swapArray32 Bytes
bs
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteArray -> PrimArray Word32
asWord32s ByteArray
r)
word64Array ::
e
-> Int
-> Parser e s (PrimArray Word64)
word64Array :: forall e s. e -> Int -> Parser e s (PrimArray Word64)
word64Array e
e !Int
n = case ByteOrder
targetByteOrder of
ByteOrder
LittleEndian -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteArray -> PrimArray Word64
asWord64s forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteArray
Bytes.toByteArrayClone) (forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
8))
ByteOrder
BigEndian -> do
Bytes
bs <- forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
8)
let r :: ByteArray
r = Bytes -> ByteArray
swapArray64 Bytes
bs
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteArray -> PrimArray Word64
asWord64s ByteArray
r)
word128Array ::
e
-> Int
-> Parser e s (PrimArray Word128)
word128Array :: forall e s. e -> Int -> Parser e s (PrimArray Word128)
word128Array e
e !Int
n = case ByteOrder
targetByteOrder of
ByteOrder
LittleEndian -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteArray -> PrimArray Word128
asWord128s forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteArray
Bytes.toByteArrayClone) (forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
16))
ByteOrder
BigEndian -> do
Bytes
bs <- forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
16)
let r :: ByteArray
r = Bytes -> ByteArray
swapArray128 Bytes
bs
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteArray -> PrimArray Word128
asWord128s ByteArray
r)
word256Array ::
e
-> Int
-> Parser e s (PrimArray Word256)
word256Array :: forall e s. e -> Int -> Parser e s (PrimArray Word256)
word256Array e
e !Int
n = case ByteOrder
targetByteOrder of
ByteOrder
LittleEndian -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteArray -> PrimArray Word256
asWord256s forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> ByteArray
Bytes.toByteArrayClone) (forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
32))
ByteOrder
BigEndian -> do
Bytes
bs <- forall e s. e -> Int -> Parser e s Bytes
P.take e
e (Int
n forall a. Num a => a -> a -> a
* Int
32)
let r :: ByteArray
r = Bytes -> ByteArray
swapArray256 Bytes
bs
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteArray -> PrimArray Word256
asWord256s ByteArray
r)
int64Array ::
e
-> Int
-> Parser e s (PrimArray Int64)
int64Array :: forall e s. e -> Int -> Parser e s (PrimArray Int64)
int64Array e
e !Int
n = do
PrimArray ByteArray#
x <- forall e s. e -> Int -> Parser e s (PrimArray Word64)
word64Array e
e Int
n
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
x)
asWord16s :: ByteArray -> PrimArray Word16
asWord16s :: ByteArray -> PrimArray Word16
asWord16s (ByteArray ByteArray#
x) = forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
x
asWord32s :: ByteArray -> PrimArray Word32
asWord32s :: ByteArray -> PrimArray Word32
asWord32s (ByteArray ByteArray#
x) = forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
x
asWord64s :: ByteArray -> PrimArray Word64
asWord64s :: ByteArray -> PrimArray Word64
asWord64s (ByteArray ByteArray#
x) = forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
x
asWord128s :: ByteArray -> PrimArray Word128
asWord128s :: ByteArray -> PrimArray Word128
asWord128s (ByteArray ByteArray#
x) = forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
x
asWord256s :: ByteArray -> PrimArray Word256
asWord256s :: ByteArray -> PrimArray Word256
asWord256s (ByteArray ByteArray#
x) = forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
x
word16 :: e -> Parser e s Word16
word16 :: forall e s. e -> Parser e s Word16
word16 e
e = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> if Bytes -> Int
length Bytes
chunk forall a. Ord a => a -> a -> Bool
>= Int
2
then
let wa :: Word8
wa = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk) :: Word8
wb :: Word8
wb = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
1) :: Word8
in forall e a. a -> Int -> Int -> Result e a
Success
(forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word @Word16 (forall a. Bits a => a -> Int -> a
unsafeShiftL (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
wb) Int
8 forall a. Bits a => a -> a -> a
.|. forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
wa))
(Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
2) (Bytes -> Int
length Bytes
chunk forall a. Num a => a -> a -> a
- Int
2)
else forall e a. e -> Result e a
Failure e
e
word32 :: e -> Parser e s Word32
word32 :: forall e s. e -> Parser e s Word32
word32 e
e = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> if Bytes -> Int
length Bytes
chunk forall a. Ord a => a -> a -> Bool
>= Int
4
then
let wa :: Word8
wa = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk) :: Word8
wb :: Word8
wb = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
1) :: Word8
wc :: Word8
wc = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
2) :: Word8
wd :: Word8
wd = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
3) :: Word8
in forall e a. a -> Int -> Int -> Result e a
Success
(forall a b. (Integral a, Num b) => a -> b
fromIntegral @Word @Word32
( forall a. Bits a => a -> Int -> a
unsafeShiftL (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
wd) Int
24 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
wc) Int
16 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
wb) Int
8 forall a. Bits a => a -> a -> a
.|.
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
wa
)
)
(Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
4) (Bytes -> Int
length Bytes
chunk forall a. Num a => a -> a -> a
- Int
4)
else forall e a. e -> Result e a
Failure e
e
word64 :: e -> Parser e s Word64
word64 :: forall e s. e -> Parser e s Word64
word64 e
e = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> if Bytes -> Int
length Bytes
chunk forall a. Ord a => a -> a -> Bool
>= Int
8
then
let wa :: Word8
wa = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk) :: Word8
wb :: Word8
wb = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
1) :: Word8
wc :: Word8
wc = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
2) :: Word8
wd :: Word8
wd = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
3) :: Word8
we :: Word8
we = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
4) :: Word8
wf :: Word8
wf = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
5) :: Word8
wg :: Word8
wg = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
6) :: Word8
wh :: Word8
wh = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
7) :: Word8
in forall e a. a -> Int -> Int -> Result e a
Success
( forall a. Bits a => a -> Int -> a
unsafeShiftL (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
wh) Int
56 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
wg) Int
48 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
wf) Int
40 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
we) Int
32 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
wd) Int
24 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
wc) Int
16 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
wb) Int
8 forall a. Bits a => a -> a -> a
.|.
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
wa
)
(Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
8) (Bytes -> Int
length Bytes
chunk forall a. Num a => a -> a -> a
- Int
8)
else forall e a. e -> Result e a
Failure e
e
word256 :: e -> Parser e s Word256
word256 :: forall e s. e -> Parser e s Word256
word256 e
e = (\Word64
d Word64
c Word64
b Word64
a -> Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a Word64
b Word64
c Word64
d) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e s. e -> Parser e s Word64
word64 e
e forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall e s. e -> Parser e s Word64
word64 e
e forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall e s. e -> Parser e s Word64
word64 e
e forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall e s. e -> Parser e s Word64
word64 e
e
word128 :: e -> Parser e s Word128
word128 :: forall e s. e -> Parser e s Word128
word128 e
e = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (forall a b c. (a -> b -> c) -> b -> a -> c
flip Word64 -> Word64 -> Word128
Word128) (forall e s. e -> Parser e s Word64
word64 e
e) (forall e s. e -> Parser e s Word64
word64 e
e)
int8 :: e -> Parser e s Int8
int8 :: forall e s. e -> Parser e s Int8
int8 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e s. e -> Parser e s Word8
word8
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 forall a b. (Integral a, Num b) => a -> b
fromIntegral 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 forall a b. (Integral a, Num b) => a -> b
fromIntegral 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 forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e s. e -> Parser e s Word64
word64