module Dahdit.Iface
  ( BinaryGetTarget (..)
  , getTarget
  , BinaryPutTarget (..)
  , putTarget
  , MutBinaryPutTarget (..)
  , mutPutTargetOffset
  , mutPutTarget
  , getEnd
  , decode
  , decodeInc
  , decodeEnd
  , decodeFile
  , decodeFileEnd
  , encode
  , encodeFile
  , mutEncode
  )
where

import Control.Monad (unless, (>=>))
import Control.Monad.Primitive (MonadPrim, PrimMonad (..), RealWorld)
import Dahdit.Binary (Binary (..))
import Dahdit.Free (Get, Put)
import Dahdit.Funs (getRemainingSize)
import Dahdit.Mem
  ( MemPtr (..)
  , MutableMem (..)
  , emptyMemPtr
  , mutViewVecMem
  , viewBSMem
  , viewSBSMem
  , viewVecMem
  , withBAMem
  , withBSMem
  , withSBSMem
  , withVecMem
  )
import Dahdit.Run
  ( GetError
  , GetIncCb
  , GetIncChunk (..)
  , newGetIncEnv
  , runCount
  , runGetIncInternal
  , runGetInternal
  , runPutInternal
  )
import Dahdit.Sizes (ByteCount (..))
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BSC
import Data.ByteString.Short (ShortByteString)
import Data.Coerce (coerce)
import Data.Primitive.ByteArray (ByteArray, MutableByteArray, emptyByteArray, sizeofByteArray)
import Data.Text (Text)
import qualified Data.Text.Encoding as TE
import Data.Vector.Storable (Vector)
import qualified Data.Vector.Storable as VS
import Data.Vector.Storable.Mutable (IOVector)
import Data.Word (Word8)

-- | Abstracts over the sources we can read from.
class (PrimMonad m) => BinaryGetTarget z m where
  -- | Get a value from the source given a starting offset, returning a result and final offset.
  -- On error, the offset will indicate where in the source the error occurred.
  getTargetOffset :: ByteCount -> Get a -> z -> m (Either GetError a, ByteCount)

  -- | Get a value incrementally from sources yielded by the given callback, returning a
  -- result, final offset in the whole stream, and final offset in the current chunk.
  -- Takes an optional maximum capacity.
  getTargetInc :: Maybe ByteCount -> Get a -> GetIncCb z m -> m (Either GetError a, ByteCount, ByteCount)

-- | Get a value from the source, returning a result and final offset.
getTarget :: (BinaryGetTarget z m) => Get a -> z -> m (Either GetError a, ByteCount)
getTarget :: forall z (m :: * -> *) a.
BinaryGetTarget z m =>
Get a -> z -> m (Either GetError a, ByteCount)
getTarget = forall z (m :: * -> *) a.
BinaryGetTarget z m =>
ByteCount -> Get a -> z -> m (Either GetError a, ByteCount)
getTargetOffset ByteCount
0

-- | Abstracts over the immutable sinks we can render to.
class (BinaryGetTarget z m) => BinaryPutTarget z m where
  -- | Put an action to the sink with the given length.
  -- Prefer 'putTarget' to safely count capacity, or use 'encode' to use byte size.
  putTargetUnsafe :: Put -> ByteCount -> m z

-- | Put an action to the sink with calculated capacity.
putTarget :: (BinaryPutTarget z m) => Put -> m z
putTarget :: forall z (m :: * -> *). BinaryPutTarget z m => Put -> m z
putTarget Put
p = forall z (m :: * -> *).
BinaryPutTarget z m =>
Put -> ByteCount -> m z
putTargetUnsafe Put
p (Put -> ByteCount
runCount Put
p)

class (BinaryGetTarget z m) => MutBinaryPutTarget z m where
  mutPutTargetOffsetUnsafe :: ByteCount -> Put -> ByteCount -> z -> m ByteCount

mutPutTargetOffset :: (MutBinaryPutTarget z m) => ByteCount -> Put -> z -> m ByteCount
mutPutTargetOffset :: forall z (m :: * -> *).
MutBinaryPutTarget z m =>
ByteCount -> Put -> z -> m ByteCount
mutPutTargetOffset ByteCount
off Put
p = forall z (m :: * -> *).
MutBinaryPutTarget z m =>
ByteCount -> Put -> ByteCount -> z -> m ByteCount
mutPutTargetOffsetUnsafe ByteCount
off Put
p (Put -> ByteCount
runCount Put
p)

mutPutTarget :: (MutBinaryPutTarget z m) => Put -> z -> m ByteCount
mutPutTarget :: forall z (m :: * -> *).
MutBinaryPutTarget z m =>
Put -> z -> m ByteCount
mutPutTarget = forall z (m :: * -> *).
MutBinaryPutTarget z m =>
ByteCount -> Put -> z -> m ByteCount
mutPutTargetOffset ByteCount
0

instance BinaryGetTarget String IO where
  getTargetOffset :: forall a.
ByteCount -> Get a -> String -> IO (Either GetError a, ByteCount)
getTargetOffset = forall a.
ByteCount -> Get a -> String -> IO (Either GetError a, ByteCount)
runGetString
  getTargetInc :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb String IO
-> IO (Either GetError a, ByteCount, ByteCount)
getTargetInc = forall a.
Maybe ByteCount
-> Get a
-> GetIncCb String IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncString

instance BinaryPutTarget String IO where
  putTargetUnsafe :: Put -> ByteCount -> IO String
putTargetUnsafe = Put -> ByteCount -> IO String
runPutString

instance BinaryGetTarget Text IO where
  getTargetOffset :: forall a.
ByteCount -> Get a -> Text -> IO (Either GetError a, ByteCount)
getTargetOffset = forall a.
ByteCount -> Get a -> Text -> IO (Either GetError a, ByteCount)
runGetText
  getTargetInc :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb Text IO
-> IO (Either GetError a, ByteCount, ByteCount)
getTargetInc = forall a.
Maybe ByteCount
-> Get a
-> GetIncCb Text IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncText

instance BinaryPutTarget Text IO where
  putTargetUnsafe :: Put -> ByteCount -> IO Text
putTargetUnsafe = Put -> ByteCount -> IO Text
runPutText

instance (PrimMonad m) => BinaryGetTarget ShortByteString m where
  getTargetOffset :: forall a.
ByteCount
-> Get a -> ShortByteString -> m (Either GetError a, ByteCount)
getTargetOffset = forall (m :: * -> *) a.
PrimMonad m =>
ByteCount
-> Get a -> ShortByteString -> m (Either GetError a, ByteCount)
runGetSBS
  getTargetInc :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb ShortByteString m
-> m (Either GetError a, ByteCount, ByteCount)
getTargetInc = forall (m :: * -> *) a.
PrimMonad m =>
Maybe ByteCount
-> Get a
-> GetIncCb ShortByteString m
-> m (Either GetError a, ByteCount, ByteCount)
runGetIncSBS

instance (PrimMonad m) => BinaryPutTarget ShortByteString m where
  putTargetUnsafe :: Put -> ByteCount -> m ShortByteString
putTargetUnsafe = forall (m :: * -> *).
PrimMonad m =>
Put -> ByteCount -> m ShortByteString
runPutSBS

instance BinaryGetTarget ByteString IO where
  getTargetOffset :: forall a.
ByteCount
-> Get a -> ByteString -> IO (Either GetError a, ByteCount)
getTargetOffset = forall a.
ByteCount
-> Get a -> ByteString -> IO (Either GetError a, ByteCount)
runGetBS
  getTargetInc :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb ByteString IO
-> IO (Either GetError a, ByteCount, ByteCount)
getTargetInc = forall a.
Maybe ByteCount
-> Get a
-> GetIncCb ByteString IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncBS

instance BinaryPutTarget ByteString IO where
  putTargetUnsafe :: Put -> ByteCount -> IO ByteString
putTargetUnsafe = Put -> ByteCount -> IO ByteString
runPutBS

instance (PrimMonad m) => BinaryGetTarget ByteArray m where
  getTargetOffset :: forall a.
ByteCount -> Get a -> ByteArray -> m (Either GetError a, ByteCount)
getTargetOffset = forall (m :: * -> *) a.
PrimMonad m =>
ByteCount -> Get a -> ByteArray -> m (Either GetError a, ByteCount)
runGetBA
  getTargetInc :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb ByteArray m
-> m (Either GetError a, ByteCount, ByteCount)
getTargetInc = forall (m :: * -> *) a.
PrimMonad m =>
Maybe ByteCount
-> Get a
-> GetIncCb ByteArray m
-> m (Either GetError a, ByteCount, ByteCount)
runGetIncBA

instance (PrimMonad m) => BinaryPutTarget ByteArray m where
  putTargetUnsafe :: Put -> ByteCount -> m ByteArray
putTargetUnsafe = forall (m :: * -> *).
PrimMonad m =>
Put -> ByteCount -> m ByteArray
runPutBA

instance BinaryGetTarget (Vector Word8) IO where
  getTargetOffset :: forall a.
ByteCount
-> Get a -> Vector Word8 -> IO (Either GetError a, ByteCount)
getTargetOffset = forall a.
ByteCount
-> Get a -> Vector Word8 -> IO (Either GetError a, ByteCount)
runGetVec
  getTargetInc :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb (Vector Word8) IO
-> IO (Either GetError a, ByteCount, ByteCount)
getTargetInc = forall a.
Maybe ByteCount
-> Get a
-> GetIncCb (Vector Word8) IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncVec

instance BinaryPutTarget (Vector Word8) IO where
  putTargetUnsafe :: Put -> ByteCount -> IO (Vector Word8)
putTargetUnsafe = Put -> ByteCount -> IO (Vector Word8)
runPutVec

instance (MonadPrim s m) => BinaryGetTarget (MutableByteArray s) m where
  getTargetOffset :: forall a.
ByteCount
-> Get a -> MutableByteArray s -> m (Either GetError a, ByteCount)
getTargetOffset ByteCount
bc Get a
g MutableByteArray s
z = forall r w (m :: * -> *) a.
MutableMem r w m =>
w -> (r -> m a) -> m a
unsafeUseFrozenMem MutableByteArray s
z (forall z (m :: * -> *) a.
BinaryGetTarget z m =>
ByteCount -> Get a -> z -> m (Either GetError a, ByteCount)
getTargetOffset ByteCount
bc Get a
g)
  getTargetInc :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb (MutableByteArray s) m
-> m (Either GetError a, ByteCount, ByteCount)
getTargetInc Maybe ByteCount
mbc Get a
g GetIncCb (MutableByteArray s) m
cb = forall z (m :: * -> *) a.
BinaryGetTarget z m =>
Maybe ByteCount
-> Get a
-> GetIncCb z m
-> m (Either GetError a, ByteCount, ByteCount)
getTargetInc Maybe ByteCount
mbc Get a
g (GetIncCb (MutableByteArray s) m
cb forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r w (m :: * -> *). MutableMem r w m => w -> m r
unsafeFreezeMem))

instance (MonadPrim s m) => MutBinaryPutTarget (MutableByteArray s) m where
  mutPutTargetOffsetUnsafe :: ByteCount -> Put -> ByteCount -> MutableByteArray s -> m ByteCount
mutPutTargetOffsetUnsafe = forall s (m :: * -> *).
MonadPrim s m =>
ByteCount -> Put -> ByteCount -> MutableByteArray s -> m ByteCount
runMutPutBA

instance BinaryGetTarget (IOVector Word8) IO where
  getTargetOffset :: forall a.
ByteCount
-> Get a -> IOVector Word8 -> IO (Either GetError a, ByteCount)
getTargetOffset ByteCount
bc Get a
g IOVector Word8
z = forall r w (m :: * -> *) a.
MutableMem r w m =>
w -> (r -> m a) -> m a
unsafeUseFrozenMem IOVector Word8
z (forall z (m :: * -> *) a.
BinaryGetTarget z m =>
ByteCount -> Get a -> z -> m (Either GetError a, ByteCount)
getTargetOffset ByteCount
bc Get a
g)
  getTargetInc :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb (IOVector Word8) IO
-> IO (Either GetError a, ByteCount, ByteCount)
getTargetInc Maybe ByteCount
mbc Get a
g GetIncCb (IOVector Word8) IO
cb = forall z (m :: * -> *) a.
BinaryGetTarget z m =>
Maybe ByteCount
-> Get a
-> GetIncCb z m
-> m (Either GetError a, ByteCount, ByteCount)
getTargetInc Maybe ByteCount
mbc Get a
g (GetIncCb (IOVector Word8) IO
cb forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r w (m :: * -> *). MutableMem r w m => w -> m r
unsafeFreezeMem))

instance MutBinaryPutTarget (IOVector Word8) IO where
  mutPutTargetOffsetUnsafe :: ByteCount -> Put -> ByteCount -> IOVector Word8 -> IO ByteCount
mutPutTargetOffsetUnsafe = ByteCount -> Put -> ByteCount -> IOVector Word8 -> IO ByteCount
runMutPutVec

-- | Wrapper that asserts a get action has consumed to the end.
getEnd :: Get a -> Get a
getEnd :: forall a. Get a -> Get a
getEnd Get a
getter = do
  a
a <- Get a
getter
  ByteCount
b <- Get ByteCount
getRemainingSize
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (ByteCount
b forall a. Eq a => a -> a -> Bool
== ByteCount
0) (forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Expected end of input but had bytes remaining: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (ByteCount -> Int
unByteCount ByteCount
b)))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a

-- | Decode a value from a source returning a result and consumed byte count.
decode :: (Binary a, BinaryGetTarget z m) => z -> m (Either GetError a, ByteCount)
decode :: forall a z (m :: * -> *).
(Binary a, BinaryGetTarget z m) =>
z -> m (Either GetError a, ByteCount)
decode = forall z (m :: * -> *) a.
BinaryGetTarget z m =>
Get a -> z -> m (Either GetError a, ByteCount)
getTarget forall a. Binary a => Get a
get

-- | Decode a value incrementally from sources yielded by a callback.
decodeInc
  :: (Binary a, BinaryGetTarget z m) => Maybe ByteCount -> GetIncCb z m -> m (Either GetError a, ByteCount, ByteCount)
decodeInc :: forall a z (m :: * -> *).
(Binary a, BinaryGetTarget z m) =>
Maybe ByteCount
-> GetIncCb z m -> m (Either GetError a, ByteCount, ByteCount)
decodeInc Maybe ByteCount
mayCap = forall z (m :: * -> *) a.
BinaryGetTarget z m =>
Maybe ByteCount
-> Get a
-> GetIncCb z m
-> m (Either GetError a, ByteCount, ByteCount)
getTargetInc Maybe ByteCount
mayCap forall a. Binary a => Get a
get

-- | 'decode' but expect the end of input.
decodeEnd :: (Binary a, BinaryGetTarget z m) => z -> m (Either GetError a, ByteCount)
decodeEnd :: forall a z (m :: * -> *).
(Binary a, BinaryGetTarget z m) =>
z -> m (Either GetError a, ByteCount)
decodeEnd = forall z (m :: * -> *) a.
BinaryGetTarget z m =>
Get a -> z -> m (Either GetError a, ByteCount)
getTarget (forall a. Get a -> Get a
getEnd forall a. Binary a => Get a
get)

-- | Decode a value from a file.
decodeFile :: (Binary a) => FilePath -> IO (Either GetError a, ByteCount)
decodeFile :: forall a. Binary a => String -> IO (Either GetError a, ByteCount)
decodeFile = forall a. Get a -> String -> IO (Either GetError a, ByteCount)
runGetFile forall a. Binary a => Get a
get

-- | 'decodeFile' but expect the end of file.
decodeFileEnd :: (Binary a) => FilePath -> IO (Either GetError a, ByteCount)
decodeFileEnd :: forall a. Binary a => String -> IO (Either GetError a, ByteCount)
decodeFileEnd = forall a. Get a -> String -> IO (Either GetError a, ByteCount)
runGetFile (forall a. Get a -> Get a
getEnd forall a. Binary a => Get a
get)

-- | Encode a value to a sink.
encode :: (Binary a, BinaryPutTarget z m) => a -> m z
encode :: forall a z (m :: * -> *).
(Binary a, BinaryPutTarget z m) =>
a -> m z
encode a
a = forall z (m :: * -> *).
BinaryPutTarget z m =>
Put -> ByteCount -> m z
putTargetUnsafe (forall a. Binary a => a -> Put
put a
a) (forall a. Binary a => a -> ByteCount
byteSize a
a)

-- | Encode a value to a file.
encodeFile :: (Binary a) => a -> FilePath -> IO ()
encodeFile :: forall a. Binary a => a -> String -> IO ()
encodeFile a
a = Put -> ByteCount -> String -> IO ()
runPutFile (forall a. Binary a => a -> Put
put a
a) (forall a. Binary a => a -> ByteCount
byteSize a
a)

-- | Encode a value to a mutable buffer, returning number of bytes filled.
mutEncode :: (Binary a, MutBinaryPutTarget z m) => a -> z -> m ByteCount
mutEncode :: forall a z (m :: * -> *).
(Binary a, MutBinaryPutTarget z m) =>
a -> z -> m ByteCount
mutEncode a
a = forall z (m :: * -> *).
MutBinaryPutTarget z m =>
ByteCount -> Put -> ByteCount -> z -> m ByteCount
mutPutTargetOffsetUnsafe ByteCount
0 (forall a. Binary a => a -> Put
put a
a) (forall a. Binary a => a -> ByteCount
byteSize a
a)

runGetString :: ByteCount -> Get a -> String -> IO (Either GetError a, ByteCount)
runGetString :: forall a.
ByteCount -> Get a -> String -> IO (Either GetError a, ByteCount)
runGetString ByteCount
off Get a
act = forall a.
ByteCount
-> Get a -> ByteString -> IO (Either GetError a, ByteCount)
runGetBS ByteCount
off Get a
act forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BSC.pack

runGetText :: ByteCount -> Get a -> Text -> IO (Either GetError a, ByteCount)
runGetText :: forall a.
ByteCount -> Get a -> Text -> IO (Either GetError a, ByteCount)
runGetText ByteCount
off Get a
act = forall a.
ByteCount
-> Get a -> ByteString -> IO (Either GetError a, ByteCount)
runGetBS ByteCount
off Get a
act forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
TE.encodeUtf8

runGetBA :: (PrimMonad m) => ByteCount -> Get a -> ByteArray -> m (Either GetError a, ByteCount)
runGetBA :: forall (m :: * -> *) a.
PrimMonad m =>
ByteCount -> Get a -> ByteArray -> m (Either GetError a, ByteCount)
runGetBA ByteCount
off Get a
act ByteArray
ba = forall r (m :: * -> *) a.
ReadMem r m =>
ByteCount
-> Get a -> ByteCount -> r -> m (Either GetError a, ByteCount)
runGetInternal ByteCount
off Get a
act (coerce :: forall a b. Coercible a b => a -> b
coerce (ByteArray -> Int
sizeofByteArray ByteArray
ba)) ByteArray
ba

runGetSBS :: (PrimMonad m) => ByteCount -> Get a -> ShortByteString -> m (Either GetError a, ByteCount)
runGetSBS :: forall (m :: * -> *) a.
PrimMonad m =>
ByteCount
-> Get a -> ShortByteString -> m (Either GetError a, ByteCount)
runGetSBS ByteCount
off Get a
act = forall (m :: * -> *) a.
PrimMonad m =>
ByteCount -> Get a -> ByteArray -> m (Either GetError a, ByteCount)
runGetBA ByteCount
off Get a
act forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> ByteArray
viewSBSMem

runGetBS :: ByteCount -> Get a -> ByteString -> IO (Either GetError a, ByteCount)
runGetBS :: forall a.
ByteCount
-> Get a -> ByteString -> IO (Either GetError a, ByteCount)
runGetBS ByteCount
off Get a
act ByteString
bs = forall r (m :: * -> *) a.
ReadMem r m =>
ByteCount
-> Get a -> ByteCount -> r -> m (Either GetError a, ByteCount)
runGetInternal ByteCount
off Get a
act (coerce :: forall a b. Coercible a b => a -> b
coerce (ByteString -> Int
BS.length ByteString
bs)) (ByteString -> MemPtr RealWorld
viewBSMem ByteString
bs)

runGetVec :: ByteCount -> Get a -> Vector Word8 -> IO (Either GetError a, ByteCount)
runGetVec :: forall a.
ByteCount
-> Get a -> Vector Word8 -> IO (Either GetError a, ByteCount)
runGetVec ByteCount
off Get a
act Vector Word8
vec = forall r (m :: * -> *) a.
ReadMem r m =>
ByteCount
-> Get a -> ByteCount -> r -> m (Either GetError a, ByteCount)
runGetInternal ByteCount
off Get a
act (coerce :: forall a b. Coercible a b => a -> b
coerce (forall a. Storable a => Vector a -> Int
VS.length Vector Word8
vec)) (Vector Word8 -> MemPtr RealWorld
viewVecMem Vector Word8
vec)

runGetFile :: Get a -> FilePath -> IO (Either GetError a, ByteCount)
runGetFile :: forall a. Get a -> String -> IO (Either GetError a, ByteCount)
runGetFile Get a
act String
fp = do
  ByteString
bs <- String -> IO ByteString
BS.readFile String
fp
  forall a.
ByteCount
-> Get a -> ByteString -> IO (Either GetError a, ByteCount)
runGetBS ByteCount
0 Get a
act ByteString
bs

runGetIncString :: Maybe ByteCount -> Get a -> GetIncCb String IO -> IO (Either GetError a, ByteCount, ByteCount)
runGetIncString :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb String IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncString Maybe ByteCount
mayCap Get a
g GetIncCb String IO
cb = forall a.
Maybe ByteCount
-> Get a
-> GetIncCb ByteString IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncBS Maybe ByteCount
mayCap Get a
g (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> ByteString
BSC.pack) forall b c a. (b -> c) -> (a -> b) -> a -> c
. GetIncCb String IO
cb)

runGetIncText :: Maybe ByteCount -> Get a -> GetIncCb Text IO -> IO (Either GetError a, ByteCount, ByteCount)
runGetIncText :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb Text IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncText Maybe ByteCount
mayCap Get a
g GetIncCb Text IO
cb = forall a.
Maybe ByteCount
-> Get a
-> GetIncCb ByteString IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncBS Maybe ByteCount
mayCap Get a
g (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> ByteString
TE.encodeUtf8) forall b c a. (b -> c) -> (a -> b) -> a -> c
. GetIncCb Text IO
cb)

runGetIncBA
  :: (PrimMonad m) => Maybe ByteCount -> Get a -> GetIncCb ByteArray m -> m (Either GetError a, ByteCount, ByteCount)
runGetIncBA :: forall (m :: * -> *) a.
PrimMonad m =>
Maybe ByteCount
-> Get a
-> GetIncCb ByteArray m
-> m (Either GetError a, ByteCount, ByteCount)
runGetIncBA Maybe ByteCount
mayCap Get a
act GetIncCb ByteArray m
cb = do
  GetIncEnv (PrimState m) ByteArray
env <- forall s (m :: * -> *) r.
MonadPrim s m =>
Maybe ByteCount -> GetIncChunk r -> m (GetIncEnv s r)
newGetIncEnv Maybe ByteCount
mayCap (forall r. ByteCount -> ByteCount -> r -> GetIncChunk r
GetIncChunk ByteCount
0 ByteCount
0 ByteArray
emptyByteArray)
  let view :: ByteArray -> GetIncChunk ByteArray
view ByteArray
s = forall r. ByteCount -> ByteCount -> r -> GetIncChunk r
GetIncChunk ByteCount
0 (coerce :: forall a b. Coercible a b => a -> b
coerce (ByteArray -> Int
sizeofByteArray ByteArray
s)) ByteArray
s
  let cb' :: GetIncRequest -> m (Maybe (GetIncChunk ByteArray))
cb' = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteArray -> GetIncChunk ByteArray
view) forall b c a. (b -> c) -> (a -> b) -> a -> c
. GetIncCb ByteArray m
cb
  forall s (m :: * -> *) r a.
(MonadPrim s m, ReadMem r m) =>
Get a
-> GetIncEnv s r
-> GetIncCbChunk r m
-> m (Either GetError a, ByteCount, ByteCount)
runGetIncInternal Get a
act GetIncEnv (PrimState m) ByteArray
env GetIncRequest -> m (Maybe (GetIncChunk ByteArray))
cb'

runGetIncSBS
  :: (PrimMonad m) => Maybe ByteCount -> Get a -> GetIncCb ShortByteString m -> m (Either GetError a, ByteCount, ByteCount)
runGetIncSBS :: forall (m :: * -> *) a.
PrimMonad m =>
Maybe ByteCount
-> Get a
-> GetIncCb ShortByteString m
-> m (Either GetError a, ByteCount, ByteCount)
runGetIncSBS Maybe ByteCount
mayCap Get a
act GetIncCb ShortByteString m
cb = forall (m :: * -> *) a.
PrimMonad m =>
Maybe ByteCount
-> Get a
-> GetIncCb ByteArray m
-> m (Either GetError a, ByteCount, ByteCount)
runGetIncBA Maybe ByteCount
mayCap Get a
act (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ShortByteString -> ByteArray
viewSBSMem) forall b c a. (b -> c) -> (a -> b) -> a -> c
. GetIncCb ShortByteString m
cb)

runGetIncMemPtr
  :: Maybe ByteCount -> Get a -> GetIncCb (MemPtr RealWorld) IO -> IO (Either GetError a, ByteCount, ByteCount)
runGetIncMemPtr :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb (MemPtr RealWorld) IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncMemPtr Maybe ByteCount
mayCap Get a
act GetIncCb (MemPtr RealWorld) IO
cb = do
  MemPtr RealWorld
mem <- IO (MemPtr RealWorld)
emptyMemPtr
  GetIncEnv RealWorld (MemPtr RealWorld)
env <- forall s (m :: * -> *) r.
MonadPrim s m =>
Maybe ByteCount -> GetIncChunk r -> m (GetIncEnv s r)
newGetIncEnv Maybe ByteCount
mayCap (forall r. ByteCount -> ByteCount -> r -> GetIncChunk r
GetIncChunk ByteCount
0 ByteCount
0 MemPtr RealWorld
mem)
  let view :: MemPtr s -> GetIncChunk (MemPtr s)
view mem' :: MemPtr s
mem'@(MemPtr ForeignPtr Word8
_ ByteCount
off ByteCount
len) = forall r. ByteCount -> ByteCount -> r -> GetIncChunk r
GetIncChunk ByteCount
0 (ByteCount
len forall a. Num a => a -> a -> a
- ByteCount
off) MemPtr s
mem'
  let cb' :: GetIncRequest -> IO (Maybe (GetIncChunk (MemPtr RealWorld)))
cb' = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {s}. MemPtr s -> GetIncChunk (MemPtr s)
view) forall b c a. (b -> c) -> (a -> b) -> a -> c
. GetIncCb (MemPtr RealWorld) IO
cb
  forall s (m :: * -> *) r a.
(MonadPrim s m, ReadMem r m) =>
Get a
-> GetIncEnv s r
-> GetIncCbChunk r m
-> m (Either GetError a, ByteCount, ByteCount)
runGetIncInternal Get a
act GetIncEnv RealWorld (MemPtr RealWorld)
env GetIncRequest -> IO (Maybe (GetIncChunk (MemPtr RealWorld)))
cb'

runGetIncBS :: Maybe ByteCount -> Get a -> GetIncCb ByteString IO -> IO (Either GetError a, ByteCount, ByteCount)
runGetIncBS :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb ByteString IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncBS Maybe ByteCount
mayCap Get a
act GetIncCb ByteString IO
cb = forall a.
Maybe ByteCount
-> Get a
-> GetIncCb (MemPtr RealWorld) IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncMemPtr Maybe ByteCount
mayCap Get a
act (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> MemPtr RealWorld
viewBSMem) forall b c a. (b -> c) -> (a -> b) -> a -> c
. GetIncCb ByteString IO
cb)

runGetIncVec :: Maybe ByteCount -> Get a -> GetIncCb (Vector Word8) IO -> IO (Either GetError a, ByteCount, ByteCount)
runGetIncVec :: forall a.
Maybe ByteCount
-> Get a
-> GetIncCb (Vector Word8) IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncVec Maybe ByteCount
mayCap Get a
act GetIncCb (Vector Word8) IO
cb = forall a.
Maybe ByteCount
-> Get a
-> GetIncCb (MemPtr RealWorld) IO
-> IO (Either GetError a, ByteCount, ByteCount)
runGetIncMemPtr Maybe ByteCount
mayCap Get a
act (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector Word8 -> MemPtr RealWorld
viewVecMem) forall b c a. (b -> c) -> (a -> b) -> a -> c
. GetIncCb (Vector Word8) IO
cb)

runPutString :: Put -> ByteCount -> IO String
runPutString :: Put -> ByteCount -> IO String
runPutString Put
act ByteCount
len = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> String
BSC.unpack (Put -> ByteCount -> IO ByteString
runPutBS Put
act ByteCount
len)

runPutText :: Put -> ByteCount -> IO Text
runPutText :: Put -> ByteCount -> IO Text
runPutText Put
act ByteCount
len = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
TE.decodeUtf8 (Put -> ByteCount -> IO ByteString
runPutBS Put
act ByteCount
len)

runPutBA :: (PrimMonad m) => Put -> ByteCount -> m ByteArray
runPutBA :: forall (m :: * -> *).
PrimMonad m =>
Put -> ByteCount -> m ByteArray
runPutBA Put
act ByteCount
len = forall s (m :: * -> *).
MonadPrim s m =>
ByteCount -> (MutableByteArray s -> m ByteCount) -> m ByteArray
withBAMem ByteCount
len (forall (q :: * -> *) (m :: * -> *).
WriteMem q m =>
ByteCount -> Put -> ByteCount -> q (PrimState m) -> m ByteCount
runPutInternal ByteCount
0 Put
act ByteCount
len)

runPutSBS :: (PrimMonad m) => Put -> ByteCount -> m ShortByteString
runPutSBS :: forall (m :: * -> *).
PrimMonad m =>
Put -> ByteCount -> m ShortByteString
runPutSBS Put
act ByteCount
len = forall s (m :: * -> *).
MonadPrim s m =>
ByteCount
-> (MutableByteArray s -> m ByteCount) -> m ShortByteString
withSBSMem ByteCount
len (forall (q :: * -> *) (m :: * -> *).
WriteMem q m =>
ByteCount -> Put -> ByteCount -> q (PrimState m) -> m ByteCount
runPutInternal ByteCount
0 Put
act ByteCount
len)

runPutBS :: Put -> ByteCount -> IO ByteString
runPutBS :: Put -> ByteCount -> IO ByteString
runPutBS Put
act ByteCount
len = ByteCount -> (MemPtr RealWorld -> IO ByteCount) -> IO ByteString
withBSMem ByteCount
len (forall (q :: * -> *) (m :: * -> *).
WriteMem q m =>
ByteCount -> Put -> ByteCount -> q (PrimState m) -> m ByteCount
runPutInternal ByteCount
0 Put
act ByteCount
len)

runPutVec :: Put -> ByteCount -> IO (Vector Word8)
runPutVec :: Put -> ByteCount -> IO (Vector Word8)
runPutVec Put
act ByteCount
len = ByteCount
-> (MemPtr RealWorld -> IO ByteCount) -> IO (Vector Word8)
withVecMem ByteCount
len (forall (q :: * -> *) (m :: * -> *).
WriteMem q m =>
ByteCount -> Put -> ByteCount -> q (PrimState m) -> m ByteCount
runPutInternal ByteCount
0 Put
act ByteCount
len)

runPutFile :: Put -> ByteCount -> FilePath -> IO ()
runPutFile :: Put -> ByteCount -> String -> IO ()
runPutFile Put
act ByteCount
cap String
fp = do
  ByteString
bs <- Put -> ByteCount -> IO ByteString
runPutBS Put
act ByteCount
cap
  String -> ByteString -> IO ()
BS.writeFile String
fp ByteString
bs

runMutPutBA :: (MonadPrim s m) => ByteCount -> Put -> ByteCount -> MutableByteArray s -> m ByteCount
runMutPutBA :: forall s (m :: * -> *).
MonadPrim s m =>
ByteCount -> Put -> ByteCount -> MutableByteArray s -> m ByteCount
runMutPutBA = forall (q :: * -> *) (m :: * -> *).
WriteMem q m =>
ByteCount -> Put -> ByteCount -> q (PrimState m) -> m ByteCount
runPutInternal

runMutPutVec :: ByteCount -> Put -> ByteCount -> IOVector Word8 -> IO ByteCount
runMutPutVec :: ByteCount -> Put -> ByteCount -> IOVector Word8 -> IO ByteCount
runMutPutVec ByteCount
off Put
act ByteCount
len IOVector Word8
mvec = forall (q :: * -> *) (m :: * -> *).
WriteMem q m =>
ByteCount -> Put -> ByteCount -> q (PrimState m) -> m ByteCount
runPutInternal ByteCount
off Put
act ByteCount
len (IOVector Word8 -> MemPtr RealWorld
mutViewVecMem IOVector Word8
mvec)