-- |
-- Module      : Streamly.Internal.Data.Binary.Parser
-- Copyright   : (c) 2020 Composewell Technologies
-- License     : BSD-3-Clause
-- Maintainer  : streamly@composewell.com
-- Portability : GHC
--
-- Decode Haskell data types from byte streams.
--
-- It would be inefficient to use this to compose parsers for general algebraic
-- data types. For general deserialization of ADTs please use the Serialize
-- type class instances. The fastest way to deserialize byte streams
-- representing Haskell data types is to write them to arrays and deserialize
-- the array using the Serialize type class.

module Streamly.Internal.Data.Binary.Parser
    (
    -- * Type class
      FromBytes (..)

    -- * Decoders
    , unit
    , bool
    , ordering
    , eqWord8 -- XXX rename to word8Eq
    , word8
    , word16be
    , word16le
    , word32be
    , word32le
    , word64be
    , word64le
    , word64host
    , int8
    , int16be
    , int16le
    , int32be
    , int32le
    , int64be
    , int64le
    , float32be
    , float32le
    , double64be
    , double64le
    , charLatin1
    )
where

import Control.Monad.IO.Class (MonadIO)
import Data.Bits ((.|.), unsafeShiftL)
import Data.Char (chr)
import Data.Int (Int8, Int16, Int32, Int64)
import GHC.Float (castWord32ToFloat, castWord64ToDouble)
import Data.Word (Word8, Word16, Word32, Word64)
import Streamly.Internal.Data.Parser (Parser)
import Streamly.Internal.Data.Maybe.Strict (Maybe'(..))
import Streamly.Internal.Data.Tuple.Strict (Tuple' (..))
import qualified Streamly.Data.Array as A
import qualified Streamly.Internal.Data.Array as A
    (getIndexUnsafe, castUnsafe)
import qualified Streamly.Internal.Data.Parser as PR
    (fromPure, either, satisfy, takeEQ)
import qualified Streamly.Internal.Data.Parser as PRD
    (Parser(..), Initial(..), Step(..))

-- Note: The () type does not need to have an on-disk representation in theory.
-- But we use a concrete representation for it so that we count how many ()
-- types we have. Or when we have an array of units the array a concrete
-- length.

-- | A value of type '()' is encoded as @0@ in binary encoding.
--
-- @
-- 0 ==> ()
-- @
--
-- /Pre-release/
--
{-# INLINE unit #-}
unit :: Monad m => Parser Word8 m ()
unit :: forall (m :: * -> *). Monad m => Parser Word8 m ()
unit = forall (m :: * -> *). Monad m => Word8 -> Parser Word8 m Word8
eqWord8 Word8
0 forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *) b a. Monad m => b -> Parser a m b
PR.fromPure ()

{-# INLINE word8ToBool #-}
word8ToBool :: Word8 -> Either String Bool
word8ToBool :: Word8 -> Either String Bool
word8ToBool Word8
0 = forall a b. b -> Either a b
Right Bool
False
word8ToBool Word8
1 = forall a b. b -> Either a b
Right Bool
True
word8ToBool Word8
w = forall a b. a -> Either a b
Left (String
"Invalid Bool encoding " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
Prelude.show Word8
w)

-- | A value of type 'Bool' is encoded as follows in binary encoding.
--
-- @
-- 0 ==> False
-- 1 ==> True
-- @
--
-- /Pre-release/
--
{-# INLINE bool #-}
bool :: Monad m => Parser Word8 m Bool
bool :: forall (m :: * -> *). Monad m => Parser Word8 m Bool
bool = forall (m :: * -> *) a b.
Monad m =>
(a -> Either String b) -> Parser a m b
PR.either Word8 -> Either String Bool
word8ToBool

{-# INLINE word8ToOrdering #-}
word8ToOrdering :: Word8 -> Either String Ordering
word8ToOrdering :: Word8 -> Either String Ordering
word8ToOrdering Word8
0 = forall a b. b -> Either a b
Right Ordering
LT
word8ToOrdering Word8
1 = forall a b. b -> Either a b
Right Ordering
EQ
word8ToOrdering Word8
2 = forall a b. b -> Either a b
Right Ordering
GT
word8ToOrdering Word8
w = forall a b. a -> Either a b
Left (String
"Invalid Ordering encoding " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
Prelude.show Word8
w)

-- | A value of type 'Ordering' is encoded as follows in binary encoding.
--
-- @
-- 0 ==> LT
-- 1 ==> EQ
-- 2 ==> GT
-- @
--
-- /Pre-release/
--
{-# INLINE ordering #-}
ordering :: Monad m => Parser Word8 m Ordering
ordering :: forall (m :: * -> *). Monad m => Parser Word8 m Ordering
ordering = forall (m :: * -> *) a b.
Monad m =>
(a -> Either String b) -> Parser a m b
PR.either Word8 -> Either String Ordering
word8ToOrdering

-- XXX should go in a Word8 parser module?
-- | Accept the input byte only if it is equal to the specified value.
--
-- /Pre-release/
--
{-# INLINE eqWord8 #-}
eqWord8 :: Monad m => Word8 -> Parser Word8 m Word8
eqWord8 :: forall (m :: * -> *). Monad m => Word8 -> Parser Word8 m Word8
eqWord8 Word8
b = forall (m :: * -> *) a. Monad m => (a -> Bool) -> Parser a m a
PR.satisfy (forall a. Eq a => a -> a -> Bool
== Word8
b)

-- | Accept any byte.
--
-- /Pre-release/
--
{-# INLINE word8 #-}
word8 :: Monad m => Parser Word8 m Word8
word8 :: forall (m :: * -> *). Monad m => Parser Word8 m Word8
word8 = forall (m :: * -> *) a. Monad m => (a -> Bool) -> Parser a m a
PR.satisfy (forall a b. a -> b -> a
const Bool
True)

-- | Big endian (MSB first) Word16
{-# INLINE word16beD #-}
word16beD :: Monad m => PRD.Parser Word8 m Word16
word16beD :: forall (m :: * -> *). Monad m => Parser Word8 m Word16
word16beD = forall a (m :: * -> *) b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m (Step s b)) -> Parser a m b
PRD.Parser forall {m :: * -> *} {a} {a} {b}.
(Monad m, Integral a, Bits a, Bits b, Num a, Num b) =>
Maybe' b -> a -> m (Step (Maybe' a) b)
step forall {a} {b}. m (Initial (Maybe' a) b)
initial forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

    initial :: m (Initial (Maybe' a) b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
PRD.IPartial forall a. Maybe' a
Nothing'

    step :: Maybe' b -> a -> m (Step (Maybe' a) b)
step Maybe' b
Nothing' a
a =
        -- XXX We can use a non-failing parser or a fold so that we do not
        -- have to buffer for backtracking which is inefficient.
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
PRD.Continue Int
0 (forall a. a -> Maybe' a
Just' (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
8))
    step (Just' b
w) a
a =
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
PRD.Done Int
0 (b
w forall a. Bits a => a -> a -> a
.|. forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a)

    extract :: p -> m (Step s b)
extract p
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
PRD.Error String
"word16be: end of input"

-- | Parse two bytes as a 'Word16', the first byte is the MSB of the Word16 and
-- second byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE word16be #-}
word16be :: Monad m => Parser Word8 m Word16
word16be :: forall (m :: * -> *). Monad m => Parser Word8 m Word16
word16be = forall (m :: * -> *). Monad m => Parser Word8 m Word16
word16beD

-- | Little endian (LSB first) Word16
{-# INLINE word16leD #-}
word16leD :: Monad m => PRD.Parser Word8 m Word16
word16leD :: forall (m :: * -> *). Monad m => Parser Word8 m Word16
word16leD = forall a (m :: * -> *) b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m (Step s b)) -> Parser a m b
PRD.Parser forall {m :: * -> *} {a} {b} {a}.
(Monad m, Integral a, Bits b, Num a, Num b) =>
Maybe' b -> a -> m (Step (Maybe' a) b)
step forall {a} {b}. m (Initial (Maybe' a) b)
initial forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

    initial :: m (Initial (Maybe' a) b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
PRD.IPartial forall a. Maybe' a
Nothing'

    step :: Maybe' b -> a -> m (Step (Maybe' a) b)
step Maybe' b
Nothing' a
a =
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
PRD.Continue Int
0 (forall a. a -> Maybe' a
Just' (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a))
    step (Just' b
w) a
a =
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
PRD.Done Int
0 (b
w forall a. Bits a => a -> a -> a
.|. forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
8)

    extract :: p -> m (Step s b)
extract p
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
PRD.Error String
"word16le: end of input"

-- | Parse two bytes as a 'Word16', the first byte is the LSB of the Word16 and
-- second byte is the MSB (little endian representation).
--
-- /Pre-release/
--
{-# INLINE word16le #-}
word16le :: Monad m => Parser Word8 m Word16
word16le :: forall (m :: * -> *). Monad m => Parser Word8 m Word16
word16le = forall (m :: * -> *). Monad m => Parser Word8 m Word16
word16leD

-- | Big endian (MSB first) Word32
{-# INLINE word32beD #-}
word32beD :: Monad m => PRD.Parser Word8 m Word32
word32beD :: forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32beD = forall a (m :: * -> *) b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m (Step s b)) -> Parser a m b
PRD.Parser forall {m :: * -> *} {b} {a}.
(Monad m, Bits b, Integral a, Num b) =>
Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step forall {b}. m (Initial (Tuple' Word32 Int) b)
initial forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

    initial :: m (Initial (Tuple' Word32 Int) b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
PRD.IPartial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Word32
0 Int
24

    step :: Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step (Tuple' b
w Int
sh) a
a = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        if Int
sh forall a. Eq a => a -> a -> Bool
/= Int
0
        then
            let w1 :: b
w1 = b
w forall a. Bits a => a -> a -> a
.|. (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
sh)
             in forall s b. Int -> s -> Step s b
PRD.Continue Int
0 (forall a b. a -> b -> Tuple' a b
Tuple' b
w1 (Int
sh forall a. Num a => a -> a -> a
- Int
8))
        else forall s b. Int -> b -> Step s b
PRD.Done Int
0 (b
w forall a. Bits a => a -> a -> a
.|. forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a)

    extract :: p -> m (Step s b)
extract p
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
PRD.Error String
"word32beD: end of input"

-- | Parse four bytes as a 'Word32', the first byte is the MSB of the Word32
-- and last byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE word32be #-}
word32be :: Monad m => Parser Word8 m Word32
word32be :: forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32be = forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32beD

-- | Little endian (LSB first) Word32
{-# INLINE word32leD #-}
word32leD :: Monad m => PRD.Parser Word8 m Word32
word32leD :: forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32leD = forall a (m :: * -> *) b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m (Step s b)) -> Parser a m b
PRD.Parser forall {m :: * -> *} {b} {a}.
(Monad m, Bits b, Integral a, Num b) =>
Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step forall {b}. m (Initial (Tuple' Word32 Int) b)
initial forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

    initial :: m (Initial (Tuple' Word32 Int) b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
PRD.IPartial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Word32
0 Int
0

    step :: Tuple' b Int -> p -> m (Step (Tuple' b Int) b)
step (Tuple' b
w Int
sh) p
a = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        let w1 :: b
w1 = b
w forall a. Bits a => a -> a -> a
.|. (forall a b. (Integral a, Num b) => a -> b
fromIntegral p
a forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
sh)
         in if Int
sh forall a. Eq a => a -> a -> Bool
/= Int
24
            then forall s b. Int -> s -> Step s b
PRD.Continue Int
0 (forall a b. a -> b -> Tuple' a b
Tuple' b
w1 (Int
sh forall a. Num a => a -> a -> a
+ Int
8))
            else forall s b. Int -> b -> Step s b
PRD.Done Int
0 b
w1

    extract :: p -> m (Step s b)
extract p
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
PRD.Error String
"word32leD: end of input"

-- | Parse four bytes as a 'Word32', the first byte is the MSB of the Word32
-- and last byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE word32le #-}
word32le :: Monad m => Parser Word8 m Word32
word32le :: forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32le = forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32leD

-- | Big endian (MSB first) Word64
{-# INLINE word64beD #-}
word64beD :: Monad m => PRD.Parser Word8 m Word64
word64beD :: forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64beD = forall a (m :: * -> *) b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m (Step s b)) -> Parser a m b
PRD.Parser forall {m :: * -> *} {b} {a}.
(Monad m, Bits b, Integral a, Num b) =>
Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step forall {b}. m (Initial (Tuple' Word64 Int) b)
initial forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

    initial :: m (Initial (Tuple' Word64 Int) b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
PRD.IPartial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Word64
0 Int
56

    step :: Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step (Tuple' b
w Int
sh) a
a = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        if Int
sh forall a. Eq a => a -> a -> Bool
/= Int
0
        then
            let w1 :: b
w1 = b
w forall a. Bits a => a -> a -> a
.|. (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
sh)
             in forall s b. Int -> s -> Step s b
PRD.Continue Int
0 (forall a b. a -> b -> Tuple' a b
Tuple' b
w1 (Int
sh forall a. Num a => a -> a -> a
- Int
8))
        else forall s b. Int -> b -> Step s b
PRD.Done Int
0 (b
w forall a. Bits a => a -> a -> a
.|. forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a)

    extract :: p -> m (Step s b)
extract p
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
PRD.Error String
"word64beD: end of input"

-- | Parse eight bytes as a 'Word64', the first byte is the MSB of the Word64
-- and last byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE word64be #-}
word64be :: Monad m => Parser Word8 m Word64
word64be :: forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64be = forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64beD

-- | Little endian (LSB first) Word64
{-# INLINE word64leD #-}
word64leD :: Monad m => PRD.Parser Word8 m Word64
word64leD :: forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64leD = forall a (m :: * -> *) b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m (Step s b)) -> Parser a m b
PRD.Parser forall {m :: * -> *} {b} {a}.
(Monad m, Bits b, Integral a, Num b) =>
Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step forall {b}. m (Initial (Tuple' Word64 Int) b)
initial forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

    initial :: m (Initial (Tuple' Word64 Int) b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
PRD.IPartial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Word64
0 Int
0

    step :: Tuple' b Int -> p -> m (Step (Tuple' b Int) b)
step (Tuple' b
w Int
sh) p
a = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        let w1 :: b
w1 = b
w forall a. Bits a => a -> a -> a
.|. (forall a b. (Integral a, Num b) => a -> b
fromIntegral p
a forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
sh)
         in if Int
sh forall a. Eq a => a -> a -> Bool
/= Int
56
            then forall s b. Int -> s -> Step s b
PRD.Continue Int
0 (forall a b. a -> b -> Tuple' a b
Tuple' b
w1 (Int
sh forall a. Num a => a -> a -> a
+ Int
8))
            else forall s b. Int -> b -> Step s b
PRD.Done Int
0 b
w1

    extract :: p -> m (Step s b)
extract p
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
PRD.Error String
"word64leD: end of input"

-- | Parse eight bytes as a 'Word64', the first byte is the MSB of the Word64
-- and last byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE word64le #-}
word64le :: Monad m => Parser Word8 m Word64
word64le :: forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64le = forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64leD

{-# INLINE int8 #-}
int8 :: Monad m => Parser Word8 m Int8
int8 :: forall (m :: * -> *). Monad m => Parser Word8 m Int8
int8 = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word8
word8

-- | Parse two bytes as a 'Int16', the first byte is the MSB of the Int16 and
-- second byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE int16be #-}
int16be :: Monad m => Parser Word8 m Int16
int16be :: forall (m :: * -> *). Monad m => Parser Word8 m Int16
int16be = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word16
word16be

-- | Parse two bytes as a 'Int16', the first byte is the LSB of the Int16 and
-- second byte is the MSB (little endian representation).
--
-- /Pre-release/
--
{-# INLINE int16le #-}
int16le :: Monad m => Parser Word8 m Int16
int16le :: forall (m :: * -> *). Monad m => Parser Word8 m Int16
int16le = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word16
word16le

-- | Parse four bytes as a 'Int32', the first byte is the MSB of the Int32
-- and last byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE int32be #-}
int32be :: Monad m => Parser Word8 m Int32
int32be :: forall (m :: * -> *). Monad m => Parser Word8 m Int32
int32be = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32be

-- | Parse four bytes as a 'Int32', the first byte is the MSB of the Int32
-- and last byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE int32le #-}
int32le :: Monad m => Parser Word8 m Int32
int32le :: forall (m :: * -> *). Monad m => Parser Word8 m Int32
int32le = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32le

-- | Parse eight bytes as a 'Int64', the first byte is the MSB of the Int64
-- and last byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE int64be #-}
int64be :: Monad m => Parser Word8 m Int64
int64be :: forall (m :: * -> *). Monad m => Parser Word8 m Int64
int64be = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64be

-- | Parse eight bytes as a 'Int64', the first byte is the MSB of the Int64
-- and last byte is the LSB (big endian representation).
--
-- /Pre-release/
--
{-# INLINE int64le #-}
int64le :: Monad m => Parser Word8 m Int64
int64le :: forall (m :: * -> *). Monad m => Parser Word8 m Int64
int64le = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64le

{-# INLINE float32be #-}
float32be :: MonadIO m => Parser Word8 m Float
float32be :: forall (m :: * -> *). MonadIO m => Parser Word8 m Float
float32be = Word32 -> Float
castWord32ToFloat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32be

{-# INLINE float32le #-}
float32le :: MonadIO m => Parser Word8 m Float
float32le :: forall (m :: * -> *). MonadIO m => Parser Word8 m Float
float32le = Word32 -> Float
castWord32ToFloat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word32
word32le

{-# INLINE double64be #-}
double64be :: MonadIO m => Parser Word8 m Double
double64be :: forall (m :: * -> *). MonadIO m => Parser Word8 m Double
double64be =  Word64 -> Double
castWord64ToDouble forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64be

{-# INLINE double64le #-}
double64le :: MonadIO m => Parser Word8 m Double
double64le :: forall (m :: * -> *). MonadIO m => Parser Word8 m Double
double64le = Word64 -> Double
castWord64ToDouble forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). Monad m => Parser Word8 m Word64
word64le

-- | Accept any byte.
--
-- /Pre-release/
--
{-# INLINE charLatin1 #-}
charLatin1 :: Monad m => Parser Word8 m Char
charLatin1 :: forall (m :: * -> *). Monad m => Parser Word8 m Char
charLatin1 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Char
chr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) forall (m :: * -> *). Monad m => Parser Word8 m Word8
word8

-------------------------------------------------------------------------------
-- Host byte order
-------------------------------------------------------------------------------

-- | Parse eight bytes as a 'Word64' in the host byte order.
--
-- /Pre-release/
--
{-# INLINE word64host #-}
word64host :: MonadIO m => Parser Word8 m Word64
word64host :: forall (m :: * -> *). MonadIO m => Parser Word8 m Word64
word64host =
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Unbox a => Int -> Array a -> a
A.getIndexUnsafe Int
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Array a -> Array b
A.castUnsafe) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b.
Monad m =>
Int -> Fold m a b -> Parser a m b
PR.takeEQ Int
8 (forall (m :: * -> *) a.
(MonadIO m, Unbox a) =>
Int -> Fold m a (Array a)
A.writeN Int
8)

-------------------------------------------------------------------------------
-- Type class
-------------------------------------------------------------------------------

class FromBytes a where
    -- | Decode a byte stream to a Haskell type.
    fromBytes :: Parser Word8 m a