-- |
-- 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 = Word8 -> Parser Word8 m Word8
forall (m :: * -> *). Monad m => Word8 -> Parser Word8 m Word8
eqWord8 Word8
0 Parser Word8 m Word8 -> Parser Word8 m () -> Parser Word8 m ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> () -> Parser Word8 m ()
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 = Bool -> Either String Bool
forall a b. b -> Either a b
Right Bool
False
word8ToBool Word8
1 = Bool -> Either String Bool
forall a b. b -> Either a b
Right Bool
True
word8ToBool Word8
w = String -> Either String Bool
forall a b. a -> Either a b
Left (String
"Invalid Bool encoding " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
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 = (Word8 -> Either String Bool) -> Parser Word8 m 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 = Ordering -> Either String Ordering
forall a b. b -> Either a b
Right Ordering
LT
word8ToOrdering Word8
1 = Ordering -> Either String Ordering
forall a b. b -> Either a b
Right Ordering
EQ
word8ToOrdering Word8
2 = Ordering -> Either String Ordering
forall a b. b -> Either a b
Right Ordering
GT
word8ToOrdering Word8
w = String -> Either String Ordering
forall a b. a -> Either a b
Left (String
"Invalid Ordering encoding " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
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 = (Word8 -> Either String Ordering) -> Parser Word8 m 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 = (Word8 -> Bool) -> Parser Word8 m Word8
forall (m :: * -> *) a. Monad m => (a -> Bool) -> Parser a m a
PR.satisfy (Word8 -> Word8 -> Bool
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 = (Word8 -> Bool) -> Parser Word8 m Word8
forall (m :: * -> *) a. Monad m => (a -> Bool) -> Parser a m a
PR.satisfy (Bool -> Word8 -> Bool
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 = (Maybe' Word16 -> Word8 -> m (Step (Maybe' Word16) Word16))
-> m (Initial (Maybe' Word16) Word16)
-> (Maybe' Word16 -> m (Step (Maybe' Word16) Word16))
-> Parser Word8 m Word16
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 Maybe' Word16 -> Word8 -> m (Step (Maybe' Word16) Word16)
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 m (Initial (Maybe' Word16) Word16)
forall {a} {b}. m (Initial (Maybe' a) b)
initial Maybe' Word16 -> m (Step (Maybe' Word16) Word16)
forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

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

    extract :: p -> m (Step s b)
extract p
_ = Step s b -> m (Step s b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step s b -> m (Step s b)) -> Step s b -> m (Step s b)
forall a b. (a -> b) -> a -> b
$ String -> Step s 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 = Parser Word8 m Word16
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 = (Maybe' Word16 -> Word8 -> m (Step (Maybe' Word16) Word16))
-> m (Initial (Maybe' Word16) Word16)
-> (Maybe' Word16 -> m (Step (Maybe' Word16) Word16))
-> Parser Word8 m Word16
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 Maybe' Word16 -> Word8 -> m (Step (Maybe' Word16) Word16)
forall {m :: * -> *} {a} {b} {a}.
(Monad m, Integral a, Bits b, Num a, Num b) =>
Maybe' b -> a -> m (Step (Maybe' a) b)
step m (Initial (Maybe' Word16) Word16)
forall {a} {b}. m (Initial (Maybe' a) b)
initial Maybe' Word16 -> m (Step (Maybe' Word16) Word16)
forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

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

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

    extract :: p -> m (Step s b)
extract p
_ = Step s b -> m (Step s b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step s b -> m (Step s b)) -> Step s b -> m (Step s b)
forall a b. (a -> b) -> a -> b
$ String -> Step s 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 = Parser Word8 m Word16
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 = (Tuple' Word32 Int -> Word8 -> m (Step (Tuple' Word32 Int) Word32))
-> m (Initial (Tuple' Word32 Int) Word32)
-> (Tuple' Word32 Int -> m (Step (Tuple' Word32 Int) Word32))
-> Parser Word8 m Word32
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 Tuple' Word32 Int -> Word8 -> m (Step (Tuple' Word32 Int) Word32)
forall {m :: * -> *} {b} {a}.
(Monad m, Bits b, Integral a, Num b) =>
Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step m (Initial (Tuple' Word32 Int) Word32)
forall {b}. m (Initial (Tuple' Word32 Int) b)
initial Tuple' Word32 Int -> m (Step (Tuple' Word32 Int) Word32)
forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

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

    extract :: p -> m (Step s b)
extract p
_ = Step s b -> m (Step s b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step s b -> m (Step s b)) -> Step s b -> m (Step s b)
forall a b. (a -> b) -> a -> b
$ String -> Step s 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 = Parser Word8 m Word32
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 = (Tuple' Word32 Int -> Word8 -> m (Step (Tuple' Word32 Int) Word32))
-> m (Initial (Tuple' Word32 Int) Word32)
-> (Tuple' Word32 Int -> m (Step (Tuple' Word32 Int) Word32))
-> Parser Word8 m Word32
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 Tuple' Word32 Int -> Word8 -> m (Step (Tuple' Word32 Int) Word32)
forall {m :: * -> *} {b} {a}.
(Monad m, Bits b, Integral a, Num b) =>
Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step m (Initial (Tuple' Word32 Int) Word32)
forall {b}. m (Initial (Tuple' Word32 Int) b)
initial Tuple' Word32 Int -> m (Step (Tuple' Word32 Int) Word32)
forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

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

    extract :: p -> m (Step s b)
extract p
_ = Step s b -> m (Step s b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step s b -> m (Step s b)) -> Step s b -> m (Step s b)
forall a b. (a -> b) -> a -> b
$ String -> Step s 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 = Parser Word8 m Word32
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 = (Tuple' Word64 Int -> Word8 -> m (Step (Tuple' Word64 Int) Word64))
-> m (Initial (Tuple' Word64 Int) Word64)
-> (Tuple' Word64 Int -> m (Step (Tuple' Word64 Int) Word64))
-> Parser Word8 m Word64
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 Tuple' Word64 Int -> Word8 -> m (Step (Tuple' Word64 Int) Word64)
forall {m :: * -> *} {b} {a}.
(Monad m, Bits b, Integral a, Num b) =>
Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step m (Initial (Tuple' Word64 Int) Word64)
forall {b}. m (Initial (Tuple' Word64 Int) b)
initial Tuple' Word64 Int -> m (Step (Tuple' Word64 Int) Word64)
forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

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

    extract :: p -> m (Step s b)
extract p
_ = Step s b -> m (Step s b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step s b -> m (Step s b)) -> Step s b -> m (Step s b)
forall a b. (a -> b) -> a -> b
$ String -> Step s 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 = Parser Word8 m Word64
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 = (Tuple' Word64 Int -> Word8 -> m (Step (Tuple' Word64 Int) Word64))
-> m (Initial (Tuple' Word64 Int) Word64)
-> (Tuple' Word64 Int -> m (Step (Tuple' Word64 Int) Word64))
-> Parser Word8 m Word64
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 Tuple' Word64 Int -> Word8 -> m (Step (Tuple' Word64 Int) Word64)
forall {m :: * -> *} {b} {a}.
(Monad m, Bits b, Integral a, Num b) =>
Tuple' b Int -> a -> m (Step (Tuple' b Int) b)
step m (Initial (Tuple' Word64 Int) Word64)
forall {b}. m (Initial (Tuple' Word64 Int) b)
initial Tuple' Word64 Int -> m (Step (Tuple' Word64 Int) Word64)
forall {m :: * -> *} {p} {s} {b}. Monad m => p -> m (Step s b)
extract

    where

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

    extract :: p -> m (Step s b)
extract p
_ = Step s b -> m (Step s b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step s b -> m (Step s b)) -> Step s b -> m (Step s b)
forall a b. (a -> b) -> a -> b
$ String -> Step s 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 = Parser Word8 m Word64
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 = Word8 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int8) -> Parser Word8 m Word8 -> Parser Word8 m Int8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word8
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 = Word16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int16) -> Parser Word8 m Word16 -> Parser Word8 m Int16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word16
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 = Word16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int16) -> Parser Word8 m Word16 -> Parser Word8 m Int16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word16
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 = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int32) -> Parser Word8 m Word32 -> Parser Word8 m Int32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word32
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 = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int32) -> Parser Word8 m Word32 -> Parser Word8 m Int32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word32
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 = Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int64) -> Parser Word8 m Word64 -> Parser Word8 m Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word64
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 = Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int64) -> Parser Word8 m Word64 -> Parser Word8 m Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word64
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 (Word32 -> Float) -> Parser Word8 m Word32 -> Parser Word8 m Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word32
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 (Word32 -> Float) -> Parser Word8 m Word32 -> Parser Word8 m Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word32
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 (Word64 -> Double)
-> Parser Word8 m Word64 -> Parser Word8 m Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word64
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 (Word64 -> Double)
-> Parser Word8 m Word64 -> Parser Word8 m Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word8 m Word64
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 = (Word8 -> Char) -> Parser Word8 m Word8 -> Parser Word8 m Char
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Char
chr (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Parser Word8 m Word8
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 =
    (Array Word8 -> Word64)
-> Parser Word8 m (Array Word8) -> Parser Word8 m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Array Word64 -> Word64
forall a. Unbox a => Int -> Array a -> a
A.getIndexUnsafe Int
0 (Array Word64 -> Word64)
-> (Array Word8 -> Array Word64) -> Array Word8 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array Word8 -> Array Word64
forall a b. Array a -> Array b
A.castUnsafe) (Parser Word8 m (Array Word8) -> Parser Word8 m Word64)
-> Parser Word8 m (Array Word8) -> Parser Word8 m Word64
forall a b. (a -> b) -> a -> b
$ Int -> Fold m Word8 (Array Word8) -> Parser Word8 m (Array Word8)
forall (m :: * -> *) a b.
Monad m =>
Int -> Fold m a b -> Parser a m b
PR.takeEQ Int
8 (Int -> Fold m Word8 (Array Word8)
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