-- |
-- Module      : Streamly.Internal.Data.Binary.Stream
-- Copyright   : (c) 2022 Composewell Technologies
-- License     : BSD-3-Clause
-- Maintainer  : streamly@composewell.com
-- Portability : GHC
--
-- Encode Haskell data types to byte streams.
--
-- The primary purpose of this module is to serialize primitive Haskell types
-- to streams for convenient byte by byte processing when such a need arises.
--
-- It would be inefficient to use this to build byte streams from algebraic
-- data types. For general serialization of ADTs please use the Serialize type
-- class instances. The fastest way to convert general Haskell types to byte
-- streams is to serialize them to an array and then stream the array.

-- XXX remove unit, bool, ordering, and the type class as well

module Streamly.Internal.Data.Binary.Stream
    (
    -- * Type class
      ToBytes (..)

    -- * Encoders
    , unit
    , bool
    , ordering
    , word8
    , word16be
    , word16le
    , word32be
    , word32le
    , word64be
    , word64le
    , word64host
    , int8
    , int16be
    , int16le
    , int32be
    , int32le
    , int64be
    , int64le
    , float32be
    , float32le
    , double64be
    , double64le
    , charLatin1
    , charUtf8
    )
where

#include "MachDeps.h"

import Data.Bits (shiftR)
import Data.Char (ord)
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Word (Word8, Word16, Word32, Word64)
import GHC.Float (castDoubleToWord64, castFloatToWord32)
import Streamly.Internal.Data.Stream (Stream)
import Streamly.Internal.Data.Stream (Step(..))
import Streamly.Internal.Unicode.Stream (readCharUtf8)

import qualified Streamly.Internal.Data.Stream as Stream
import qualified Streamly.Internal.Data.Stream as D

-- XXX Use StreamD directly?

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

{-# INLINE boolToWord8 #-}
boolToWord8 :: Bool -> Word8
boolToWord8 :: Bool -> Word8
boolToWord8 Bool
False = Word8
0
boolToWord8 Bool
True = Word8
1

-- | A value of type 'Bool' is encoded as follows in binary encoding.
--
-- @
-- 0 ==> False
-- 1 ==> True
-- @
--
-- /Pre-release/
--
{-# INLINE bool #-}
bool :: Applicative m => Bool -> Stream m Word8
bool :: forall (m :: * -> *). Applicative m => Bool -> Stream m Word8
bool = Word8 -> Stream m Word8
forall (m :: * -> *) a. Applicative m => a -> Stream m a
Stream.fromPure (Word8 -> Stream m Word8)
-> (Bool -> Word8) -> Bool -> Stream m Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Word8
boolToWord8

{-# INLINE orderingToWord8 #-}
orderingToWord8 :: Ordering -> Word8
orderingToWord8 :: Ordering -> Word8
orderingToWord8 Ordering
LT = Word8
0
orderingToWord8 Ordering
EQ = Word8
1
orderingToWord8 Ordering
GT = Word8
2

-- | A value of type 'Ordering' is encoded as follows in binary encoding.
--
-- @
-- 0 ==> LT
-- 1 ==> EQ
-- 2 ==> GT
-- @
--
-- /Pre-release/
--
{-# INLINE ordering #-}
ordering :: Applicative m => Ordering -> Stream m Word8
ordering :: forall (m :: * -> *). Applicative m => Ordering -> Stream m Word8
ordering = Word8 -> Stream m Word8
forall (m :: * -> *) a. Applicative m => a -> Stream m a
Stream.fromPure (Word8 -> Stream m Word8)
-> (Ordering -> Word8) -> Ordering -> Stream m Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ordering -> Word8
orderingToWord8

-- | Stream a 'Word8'.
--
-- /Pre-release/
--
{-# INLINE word8 #-}
word8 :: Applicative m => Word8 -> Stream m Word8
word8 :: forall (m :: * -> *). Applicative m => Word8 -> Stream m Word8
word8 = Word8 -> Stream m Word8
forall (m :: * -> *) a. Applicative m => a -> Stream m a
Stream.fromPure

data W16State = W16B1 | W16B2 | W16Done

{-# INLINE word16beD #-}
word16beD :: Applicative m => Word16 -> D.Stream m Word8
word16beD :: forall (m :: * -> *). Applicative m => Word16 -> Stream m Word8
word16beD Word16
w = (State StreamK m Word8 -> W16State -> m (Step W16State Word8))
-> W16State -> Stream m Word8
forall (m :: * -> *) a s.
(State StreamK m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State StreamK m Word8 -> W16State -> m (Step W16State Word8)
forall {f :: * -> *} {p}.
Applicative f =>
p -> W16State -> f (Step W16State Word8)
step W16State
W16B1

    where

    step :: p -> W16State -> f (Step W16State Word8)
step p
_ W16State
W16B1 = Step W16State Word8 -> f (Step W16State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step W16State Word8 -> f (Step W16State Word8))
-> Step W16State Word8 -> f (Step W16State Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> W16State -> Step W16State Word8
forall s a. a -> s -> Step s a
Yield (Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftR Word16
w Int
8) :: Word8) W16State
W16B2
    step p
_ W16State
W16B2 = Step W16State Word8 -> f (Step W16State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step W16State Word8 -> f (Step W16State Word8))
-> Step W16State Word8 -> f (Step W16State Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> W16State -> Step W16State Word8
forall s a. a -> s -> Step s a
Yield (Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
w :: Word8) W16State
W16Done
    step p
_ W16State
W16Done = Step W16State Word8 -> f (Step W16State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Step W16State Word8
forall s a. Step s a
Stop

-- | Stream a 'Word16' as two bytes, 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 => Word16 -> Stream m Word8
word16be :: forall (m :: * -> *). Monad m => Word16 -> Stream m Word8
word16be = Word16 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word16 -> Stream m Word8
word16beD

-- | Little endian (LSB first) Word16
{-# INLINE word16leD #-}
word16leD :: Applicative m => Word16 -> D.Stream m Word8
word16leD :: forall (m :: * -> *). Applicative m => Word16 -> Stream m Word8
word16leD Word16
w = (State StreamK m Word8 -> W16State -> m (Step W16State Word8))
-> W16State -> Stream m Word8
forall (m :: * -> *) a s.
(State StreamK m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State StreamK m Word8 -> W16State -> m (Step W16State Word8)
forall {f :: * -> *} {p}.
Applicative f =>
p -> W16State -> f (Step W16State Word8)
step W16State
W16B1

    where

    step :: p -> W16State -> f (Step W16State Word8)
step p
_ W16State
W16B1 = Step W16State Word8 -> f (Step W16State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step W16State Word8 -> f (Step W16State Word8))
-> Step W16State Word8 -> f (Step W16State Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> W16State -> Step W16State Word8
forall s a. a -> s -> Step s a
Yield (Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
w :: Word8) W16State
W16B2
    step p
_ W16State
W16B2 = Step W16State Word8 -> f (Step W16State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step W16State Word8 -> f (Step W16State Word8))
-> Step W16State Word8 -> f (Step W16State Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> W16State -> Step W16State Word8
forall s a. a -> s -> Step s a
Yield (Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftR Word16
w Int
8) :: Word8) W16State
W16Done
    step p
_ W16State
W16Done = Step W16State Word8 -> f (Step W16State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Step W16State Word8
forall s a. Step s a
Stop

-- | Stream a 'Word16' as two bytes, 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 => Word16 -> Stream m Word8
word16le :: forall (m :: * -> *). Monad m => Word16 -> Stream m Word8
word16le = Word16 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word16 -> Stream m Word8
word16leD

data W32State = W32B1 | W32B2 | W32B3 | W32B4 | W32Done

-- | Big endian (MSB first) Word32
{-# INLINE word32beD #-}
word32beD :: Applicative m => Word32 -> D.Stream m Word8
word32beD :: forall (m :: * -> *). Applicative m => Word32 -> Stream m Word8
word32beD Word32
w = (State StreamK m Word8 -> W32State -> m (Step W32State Word8))
-> W32State -> Stream m Word8
forall (m :: * -> *) a s.
(State StreamK m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State StreamK m Word8 -> W32State -> m (Step W32State Word8)
forall {f :: * -> *} {p}.
Applicative f =>
p -> W32State -> f (Step W32State Word8)
step W32State
W32B1

    where

    yield :: Int -> s -> f (Step s Word8)
yield Int
n s
s = Step s Word8 -> f (Step s Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step s Word8 -> f (Step s Word8))
-> Step s Word8 -> f (Step s Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> s -> Step s Word8
forall s a. a -> s -> Step s a
Yield (Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
w Int
n) :: Word8) s
s

    step :: p -> W32State -> f (Step W32State Word8)
step p
_ W32State
W32B1 = Int -> W32State -> f (Step W32State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
24 W32State
W32B2
    step p
_ W32State
W32B2 = Int -> W32State -> f (Step W32State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
16 W32State
W32B3
    step p
_ W32State
W32B3 = Int -> W32State -> f (Step W32State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
8 W32State
W32B4
    step p
_ W32State
W32B4 = Step W32State Word8 -> f (Step W32State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step W32State Word8 -> f (Step W32State Word8))
-> Step W32State Word8 -> f (Step W32State Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> W32State -> Step W32State Word8
forall s a. a -> s -> Step s a
Yield (Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
w :: Word8) W32State
W32Done
    step p
_ W32State
W32Done = Step W32State Word8 -> f (Step W32State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Step W32State Word8
forall s a. Step s a
Stop

-- | Stream a 'Word32' as four bytes, 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 => Word32 -> Stream m Word8
word32be :: forall (m :: * -> *). Monad m => Word32 -> Stream m Word8
word32be = Word32 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word32 -> Stream m Word8
word32beD

-- | Little endian (LSB first) Word32
{-# INLINE word32leD #-}
word32leD :: Applicative m => Word32 -> D.Stream m Word8
word32leD :: forall (m :: * -> *). Applicative m => Word32 -> Stream m Word8
word32leD Word32
w = (State StreamK m Word8 -> W32State -> m (Step W32State Word8))
-> W32State -> Stream m Word8
forall (m :: * -> *) a s.
(State StreamK m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State StreamK m Word8 -> W32State -> m (Step W32State Word8)
forall {f :: * -> *} {p}.
Applicative f =>
p -> W32State -> f (Step W32State Word8)
step W32State
W32B1

    where

    yield :: Int -> s -> f (Step s Word8)
yield Int
n s
s = Step s Word8 -> f (Step s Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step s Word8 -> f (Step s Word8))
-> Step s Word8 -> f (Step s Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> s -> Step s Word8
forall s a. a -> s -> Step s a
Yield (Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
w Int
n) :: Word8) s
s

    step :: p -> W32State -> f (Step W32State Word8)
step p
_ W32State
W32B1 = Step W32State Word8 -> f (Step W32State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step W32State Word8 -> f (Step W32State Word8))
-> Step W32State Word8 -> f (Step W32State Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> W32State -> Step W32State Word8
forall s a. a -> s -> Step s a
Yield (Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
w :: Word8) W32State
W32B2
    step p
_ W32State
W32B2 = Int -> W32State -> f (Step W32State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
8 W32State
W32B3
    step p
_ W32State
W32B3 = Int -> W32State -> f (Step W32State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
16 W32State
W32B4
    step p
_ W32State
W32B4 = Int -> W32State -> f (Step W32State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
24 W32State
W32Done
    step p
_ W32State
W32Done = Step W32State Word8 -> f (Step W32State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Step W32State Word8
forall s a. Step s a
Stop

-- | Stream a 'Word32' as four bytes, 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 => Word32 -> Stream m Word8
word32le :: forall (m :: * -> *). Monad m => Word32 -> Stream m Word8
word32le = Word32 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word32 -> Stream m Word8
word32leD

data W64State =
    W64B1 | W64B2 | W64B3 | W64B4 | W64B5 | W64B6 | W64B7 | W64B8 | W64Done

-- | Big endian (MSB first) Word64
{-# INLINE word64beD #-}
word64beD :: Applicative m => Word64 -> D.Stream m Word8
word64beD :: forall (m :: * -> *). Applicative m => Word64 -> Stream m Word8
word64beD Word64
w = (State StreamK m Word8 -> W64State -> m (Step W64State Word8))
-> W64State -> Stream m Word8
forall (m :: * -> *) a s.
(State StreamK m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State StreamK m Word8 -> W64State -> m (Step W64State Word8)
forall {f :: * -> *} {p}.
Applicative f =>
p -> W64State -> f (Step W64State Word8)
step W64State
W64B1

    where

    yield :: Int -> s -> f (Step s Word8)
yield Int
n s
s = Step s Word8 -> f (Step s Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step s Word8 -> f (Step s Word8))
-> Step s Word8 -> f (Step s Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> s -> Step s Word8
forall s a. a -> s -> Step s a
Yield (Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
shiftR Word64
w Int
n) :: Word8) s
s

    step :: p -> W64State -> f (Step W64State Word8)
step p
_ W64State
W64B1 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
56 W64State
W64B2
    step p
_ W64State
W64B2 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
48 W64State
W64B3
    step p
_ W64State
W64B3 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
40 W64State
W64B4
    step p
_ W64State
W64B4 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
32 W64State
W64B5
    step p
_ W64State
W64B5 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
24 W64State
W64B6
    step p
_ W64State
W64B6 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
16 W64State
W64B7
    step p
_ W64State
W64B7 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield  Int
8 W64State
W64B8
    step p
_ W64State
W64B8 = Step W64State Word8 -> f (Step W64State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step W64State Word8 -> f (Step W64State Word8))
-> Step W64State Word8 -> f (Step W64State Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> W64State -> Step W64State Word8
forall s a. a -> s -> Step s a
Yield (Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w :: Word8) W64State
W64Done
    step p
_ W64State
W64Done = Step W64State Word8 -> f (Step W64State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Step W64State Word8
forall s a. Step s a
Stop

-- | Stream a 'Word64' as eight bytes, 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 => Word64 -> Stream m Word8
word64be :: forall (m :: * -> *). Monad m => Word64 -> Stream m Word8
word64be = Word64 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word64 -> Stream m Word8
word64beD

-- | Little endian (LSB first) Word64
{-# INLINE word64leD #-}
word64leD :: Applicative m => Word64 -> D.Stream m Word8
word64leD :: forall (m :: * -> *). Applicative m => Word64 -> Stream m Word8
word64leD Word64
w = (State StreamK m Word8 -> W64State -> m (Step W64State Word8))
-> W64State -> Stream m Word8
forall (m :: * -> *) a s.
(State StreamK m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State StreamK m Word8 -> W64State -> m (Step W64State Word8)
forall {f :: * -> *} {p}.
Applicative f =>
p -> W64State -> f (Step W64State Word8)
step W64State
W64B1

    where

    yield :: Int -> s -> f (Step s Word8)
yield Int
n s
s = Step s Word8 -> f (Step s Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step s Word8 -> f (Step s Word8))
-> Step s Word8 -> f (Step s Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> s -> Step s Word8
forall s a. a -> s -> Step s a
Yield (Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
shiftR Word64
w Int
n) :: Word8) s
s

    step :: p -> W64State -> f (Step W64State Word8)
step p
_ W64State
W64B1 = Step W64State Word8 -> f (Step W64State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Step W64State Word8 -> f (Step W64State Word8))
-> Step W64State Word8 -> f (Step W64State Word8)
forall a b. (a -> b) -> a -> b
$ Word8 -> W64State -> Step W64State Word8
forall s a. a -> s -> Step s a
Yield (Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w :: Word8) W64State
W64B2
    step p
_ W64State
W64B2 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield  Int
8 W64State
W64B3
    step p
_ W64State
W64B3 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
16 W64State
W64B4
    step p
_ W64State
W64B4 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
24 W64State
W64B5
    step p
_ W64State
W64B5 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
32 W64State
W64B6
    step p
_ W64State
W64B6 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
40 W64State
W64B7
    step p
_ W64State
W64B7 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
48 W64State
W64B8
    step p
_ W64State
W64B8 = Int -> W64State -> f (Step W64State Word8)
forall {f :: * -> *} {s}.
Applicative f =>
Int -> s -> f (Step s Word8)
yield Int
56 W64State
W64Done
    step p
_ W64State
W64Done = Step W64State Word8 -> f (Step W64State Word8)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Step W64State Word8
forall s a. Step s a
Stop

-- | Stream a 'Word64' as eight bytes, 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 => Word64 -> Stream m Word8
word64le :: forall (m :: * -> *). Monad m => Word64 -> Stream m Word8
word64le = Word64 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word64 -> Stream m Word8
word64leD

{-# INLINE int8 #-}
int8 :: Applicative m => Int8 -> Stream m Word8
int8 :: forall (m :: * -> *). Applicative m => Int8 -> Stream m Word8
int8 Int8
i = Word8 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word8 -> Stream m Word8
word8 (Int8 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int8
i :: Word8)

-- | Stream a 'Int16' as two bytes, 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 => Int16 -> Stream m Word8
int16be :: forall (m :: * -> *). Monad m => Int16 -> Stream m Word8
int16be Int16
i = Word16 -> Stream m Word8
forall (m :: * -> *). Monad m => Word16 -> Stream m Word8
word16be (Int16 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
i :: Word16)

-- | Stream a 'Int16' as two bytes, 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 => Int16 -> Stream m Word8
int16le :: forall (m :: * -> *). Monad m => Int16 -> Stream m Word8
int16le Int16
i = Word16 -> Stream m Word8
forall (m :: * -> *). Monad m => Word16 -> Stream m Word8
word16le (Int16 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
i :: Word16)

-- | Stream a 'Int32' as four bytes, 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 => Int32 -> Stream m Word8
int32be :: forall (m :: * -> *). Monad m => Int32 -> Stream m Word8
int32be Int32
i = Word32 -> Stream m Word8
forall (m :: * -> *). Monad m => Word32 -> Stream m Word8
word32be (Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
i :: Word32)

{-# INLINE int32le #-}
int32le :: Monad m => Int32 -> Stream m Word8
int32le :: forall (m :: * -> *). Monad m => Int32 -> Stream m Word8
int32le Int32
i = Word32 -> Stream m Word8
forall (m :: * -> *). Monad m => Word32 -> Stream m Word8
word32le (Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
i :: Word32)

-- | Stream a 'Int64' as eight bytes, 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 => Int64 -> Stream m Word8
int64be :: forall (m :: * -> *). Monad m => Int64 -> Stream m Word8
int64be Int64
i = Word64 -> Stream m Word8
forall (m :: * -> *). Monad m => Word64 -> Stream m Word8
word64be (Int64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i :: Word64)

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

-- | Big endian (MSB first) Float
{-# INLINE float32be #-}
float32be :: Monad m => Float -> Stream m Word8
float32be :: forall (m :: * -> *). Monad m => Float -> Stream m Word8
float32be = Word32 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word32 -> Stream m Word8
word32beD (Word32 -> Stream m Word8)
-> (Float -> Word32) -> Float -> Stream m Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Word32
castFloatToWord32

-- | Little endian (LSB first) Float
{-# INLINE float32le #-}
float32le :: Monad m => Float -> Stream m Word8
float32le :: forall (m :: * -> *). Monad m => Float -> Stream m Word8
float32le = Word32 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word32 -> Stream m Word8
word32leD (Word32 -> Stream m Word8)
-> (Float -> Word32) -> Float -> Stream m Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Word32
castFloatToWord32

-- | Big endian (MSB first) Double
{-# INLINE double64be #-}
double64be :: Monad m => Double -> Stream m Word8
double64be :: forall (m :: * -> *). Monad m => Double -> Stream m Word8
double64be = Word64 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word64 -> Stream m Word8
word64beD (Word64 -> Stream m Word8)
-> (Double -> Word64) -> Double -> Stream m Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Word64
castDoubleToWord64

-- | Little endian (LSB first) Double
{-# INLINE double64le #-}
double64le :: Monad m => Double -> Stream m Word8
double64le :: forall (m :: * -> *). Monad m => Double -> Stream m Word8
double64le = Word64 -> Stream m Word8
forall (m :: * -> *). Applicative m => Word64 -> Stream m Word8
word64leD (Word64 -> Stream m Word8)
-> (Double -> Word64) -> Double -> Stream m Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Word64
castDoubleToWord64

-- | Encode a Unicode character to stream of bytes in 0-255 range.
--
{-# INLINE charLatin1 #-}
charLatin1 :: Applicative m => Char -> Stream m Word8
charLatin1 :: forall (m :: * -> *). Applicative m => Char -> Stream m Word8
charLatin1 = Word8 -> Stream m Word8
forall (m :: * -> *) a. Applicative m => a -> Stream m a
Stream.fromPure (Word8 -> Stream m Word8)
-> (Char -> Word8) -> Char -> Stream m Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> (Char -> Int) -> Char -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord

{-# INLINE charUtf8 #-}
charUtf8 :: Monad m => Char -> Stream m Word8
charUtf8 :: forall (m :: * -> *). Monad m => Char -> Stream m Word8
charUtf8 = Unfold m Char Word8 -> Char -> Stream m Word8
forall (m :: * -> *) a b.
Applicative m =>
Unfold m a b -> a -> Stream m b
Stream.unfold Unfold m Char Word8
forall (m :: * -> *). Monad m => Unfold m Char Word8
readCharUtf8

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

-- | Stream a 'Word64' as eight bytes in the host byte order.
--
-- /Pre-release/
--
{-# INLINE word64host #-}
word64host :: Monad m => Word64 -> Stream m Word8
word64host :: forall (m :: * -> *). Monad m => Word64 -> Stream m Word8
word64host =
#ifdef WORDS_BIGENDIAN
    word64be
#else
    Word64 -> Stream m Word8
forall (m :: * -> *). Monad m => Word64 -> Stream m Word8
word64le
#endif

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

class ToBytes a where
    -- | Convert a Haskell type to a byte stream.
    toBytes :: a -> Stream m Word8