{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE UnboxedSums #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE ViewPatterns #-}
module Hmssql.Tds.Parser
(
Parser, parse, runParser, runParserAt, parseChunks, runFrom
, Got (..), At (..), Await (..), Feed (..), feedBytes, Runner (..), feedRunner
, effect, consume, consumeWhole, dynamic, oneShotRecipe
, failValue, recover, attempt
, Recipe, ask, withEnv, liftParser
, peekToken, peekWord8
, word8, word16le, word32le, word64le, word32be
, bytes, ownedBytes, boundedBytes, ownedBoundedBytes
, chunk, chunkOrDiscard, skip, count
, bVarChar, usVarChar, isolate, limited
, ValueBytes (..), valueBytes, keepBytes, bytesValue, convertBytes, prefixedValue, prefixedRowValue
, Accumulator, accumulator, append, finish
, ReadFailure (..), DecodeError (..), ProtocolError (..), ResultAbandoned (..)
) where
import Control.Exception (Exception, throwIO, mask_, finally)
import Control.Monad (unless)
import Data.IORef
import qualified Streaming as S
import qualified Streaming.Prelude as S
import Streaming (Of (..))
import qualified Data.ByteString as B
import qualified Data.ByteString.Internal as BI
import qualified Data.ByteString.Unsafe as BU
import Data.Bits (shiftL, testBit, (.|.))
import Data.Text (Text)
import Hmssql.Internal.Derived
import qualified Hmssql.Tds.Utf16 as Utf16
import Data.Word (Word8, Word16, Word32, Word64)
import Foreign.ForeignPtr (ForeignPtr)
import Foreign.Marshal.Utils (copyBytes)
import Foreign.Ptr (plusPtr)
import Data.Primitive.SmallArray (SmallArray (..), smallArrayFromListN)
import GHC.Exts (Int (..), Int#, indexSmallArray#, int2Word#, isTrue#, ltWord#, oneShot, (+#), (>=#), (==#))
import Streaming (Stream, inspect)
import Streaming.Internal (Stream (..))
import qualified Hmssql.Tds.Bytes as Read
newtype Runner = Runner
{ Runner -> forall a. IORef (Stream Await IO (Got a)) -> IO (Got a)
runAwait :: forall a. IORef (Stream Await IO (Got a)) -> IO (Got a) }
data Feed
= More !B.ByteString
| Discard !B.ByteString
| EndOfMessage
feedBytes :: Feed -> Maybe B.ByteString
feedBytes :: Feed -> Maybe ByteString
feedBytes (More ByteString
bytes) = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
bytes
feedBytes (Discard ByteString
bytes) = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
bytes
feedBytes Feed
EndOfMessage = Maybe ByteString
forall a. Maybe a
Nothing
data Got a = Got !a {-# UNPACK #-} !B.ByteString
data At a = At !a {-# UNPACK #-} !Int | FailedAt !ReadFailure {-# UNPACK #-} !Int
data Await next
= NeedMore (Feed -> next)
| forall x. RunConsumer !Bool (Runner -> IO x) (Maybe x -> next)
instance Functor Await where
fmap :: forall a b. (a -> b) -> Await a -> Await b
fmap a -> b
f (NeedMore Feed -> a
k) = (Feed -> b) -> Await b
forall next. (Feed -> next) -> Await next
NeedMore (a -> b
f (a -> b) -> (Feed -> a) -> Feed -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Feed -> a
k)
fmap a -> b
f (RunConsumer Bool
live Runner -> IO x
io Maybe x -> a
k) = Bool -> (Runner -> IO x) -> (Maybe x -> b) -> Await b
forall next x.
Bool -> (Runner -> IO x) -> (Maybe x -> next) -> Await next
RunConsumer Bool
live Runner -> IO x
io (a -> b
f (a -> b) -> (Maybe x -> a) -> Maybe x -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe x -> a
k)
type Result a = (# (# a, Int# #) | Stream Await IO (Outcome a) | (# ReadFailure, Int# #) #)
pattern Parsed :: a -> Int -> Result a
pattern $bParsed :: forall a. a -> Int -> Result a
$mParsed :: forall {r} {a}. Result a -> (a -> Int -> r) -> ((# #) -> r) -> r
Parsed a pos <- (# (# a, (I# -> pos) #) | | #)
where Parsed !a
a (I# Int#
pos) = (# (# a
a, Int#
pos #) | | #)
pattern Suspended :: Stream Await IO (Outcome a) -> Result a
pattern $bSuspended :: forall a. Stream Await IO (Outcome a) -> Result a
$mSuspended :: forall {r} {a}.
Result a -> (Stream Await IO (Outcome a) -> r) -> ((# #) -> r) -> r
Suspended suspended = (# | suspended | #)
pattern Failed :: ReadFailure -> Int -> Result a
pattern $bFailed :: forall a. ReadFailure -> Int -> Result a
$mFailed :: forall {r} {a}.
Result a -> (ReadFailure -> Int -> r) -> ((# #) -> r) -> r
Failed failure pos <- (# | | (# failure, (I# -> pos) #) #)
where Failed !ReadFailure
failure (I# Int#
pos) = (# | | (# ReadFailure
failure, Int#
pos #) #)
{-# COMPLETE Parsed, Suspended, Failed #-}
unread :: B.ByteString -> Int -> B.ByteString
unread :: ByteString -> Int -> ByteString
unread ByteString
bs Int
pos = Int -> ByteString -> ByteString
BU.unsafeDrop Int
pos ByteString
bs
{-# INLINE unread #-}
slice :: B.ByteString -> Int -> Int -> B.ByteString
slice :: ByteString -> Int -> Int -> ByteString
slice ByteString
bs Int
pos Int
n = Int -> ByteString -> ByteString
BU.unsafeTake Int
n (Int -> ByteString -> ByteString
BU.unsafeDrop Int
pos ByteString
bs)
{-# INLINE slice #-}
remaining :: B.ByteString -> Int -> Int
remaining :: ByteString -> Int -> Int
remaining ByteString
bs Int
pos = ByteString -> Int
B.length ByteString
bs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
pos
{-# INLINE remaining #-}
data Outcome a = Done !a {-# UNPACK #-} !B.ByteString | Stopped !ReadFailure {-# UNPACK #-} !B.ByteString
newtype Recipe env a = Recipe { forall env a. Recipe env a -> env -> ByteString -> Int -> Result a
runRecipe :: env -> B.ByteString -> Int -> Result a }
type Parser = Recipe ()
run :: Parser a -> B.ByteString -> Int -> Result a
run :: forall a. Parser a -> ByteString -> Int -> Result a
run Parser a
p = Parser a -> () -> ByteString -> Int -> Result a
forall env a. Recipe env a -> env -> ByteString -> Int -> Result a
runRecipe Parser a
p ()
{-# INLINE run #-}
parser :: (B.ByteString -> Int -> Result a) -> Parser a
parser :: forall a. (ByteString -> Int -> Result a) -> Parser a
parser ByteString -> Int -> Result a
p = (() -> ByteString -> Int -> Result a) -> Recipe () a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe (\() -> ByteString -> Int -> Result a
p)
{-# INLINE parser #-}
ask :: Recipe env env
ask :: forall env. Recipe env env
ask = (env -> ByteString -> Int -> Result env) -> Recipe env env
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result env) -> Recipe env env)
-> (env -> ByteString -> Int -> Result env) -> Recipe env env
forall a b. (a -> b) -> a -> b
$ \env
env ByteString
_ Int
pos -> env -> Int -> Result env
forall a. a -> Int -> Result a
Parsed env
env Int
pos
{-# INLINE ask #-}
liftParser :: Parser a -> Recipe env a
liftParser :: forall a env. Parser a -> Recipe env a
liftParser Parser a
p = (env -> ByteString -> Int -> Result a) -> Recipe env a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result a) -> Recipe env a)
-> (env -> ByteString -> Int -> Result a) -> Recipe env a
forall a b. (a -> b) -> a -> b
$ \env
_ -> Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run Parser a
p
{-# INLINE liftParser #-}
withEnv :: env -> Recipe env a -> Parser a
withEnv :: forall env a. env -> Recipe env a -> Parser a
withEnv env
env Recipe env a
p = (ByteString -> Int -> Result a) -> Parser a
forall a. (ByteString -> Int -> Result a) -> Parser a
parser (Recipe env a -> env -> ByteString -> Int -> Result a
forall env a. Recipe env a -> env -> ByteString -> Int -> Result a
runRecipe Recipe env a
p env
env)
{-# INLINE withEnv #-}
dynamic :: Recipe env a -> Recipe env a
dynamic :: forall env a. Recipe env a -> Recipe env a
dynamic (Recipe env -> ByteString -> Int -> Result a
p) = (env -> ByteString -> Int -> Result a) -> Recipe env a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result a) -> Recipe env a)
-> (env -> ByteString -> Int -> Result a) -> Recipe env a
forall a b. (a -> b) -> a -> b
$ \env
env ByteString
bs (I# Int#
pos) -> let !box :: Int
box = Int# -> Int
boxPosition Int#
pos in env -> ByteString -> Int -> Result a
p env
env ByteString
bs Int
box
{-# INLINE dynamic #-}
oneShotRecipe :: Recipe env a -> Recipe env a
oneShotRecipe :: forall env a. Recipe env a -> Recipe env a
oneShotRecipe (Recipe env -> ByteString -> Int -> Result a
p) = (env -> ByteString -> Int -> Result a) -> Recipe env a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result a)
-> env -> ByteString -> Int -> Result a
forall a b. (a -> b) -> a -> b
oneShot (\env
env -> (ByteString -> Int -> Result a) -> ByteString -> Int -> Result a
forall a b. (a -> b) -> a -> b
oneShot (\ByteString
bs -> (Int -> Result a) -> Int -> Result a
forall a b. (a -> b) -> a -> b
oneShot (\Int
pos -> env -> ByteString -> Int -> Result a
p env
env ByteString
bs Int
pos))))
{-# INLINE oneShotRecipe #-}
boxPosition :: Int# -> Int
boxPosition :: Int# -> Int
boxPosition Int#
pos
| Int# -> Bool
isTrue# (Int# -> Word#
int2Word# Int#
pos Word# -> Word# -> Int#
`ltWord#` Word#
8192##) = case SmallArray Int
positionBoxes of
SmallArray SmallArray# Int
boxes -> case SmallArray# Int -> Int# -> (# Int #)
forall a. SmallArray# a -> Int# -> (# a #)
indexSmallArray# SmallArray# Int
boxes Int#
pos of (# Int
box #) -> Int
box
| Bool
otherwise = Int# -> Int
I# Int#
pos
{-# INLINE boxPosition #-}
positionBoxes :: SmallArray Int
positionBoxes :: SmallArray Int
positionBoxes = Int -> [Int] -> SmallArray Int
forall a. Int -> [a] -> SmallArray a
smallArrayFromListN Int
8192 [Int
0 .. Int
8191]
{-# NOINLINE positionBoxes #-}
instance Functor (Recipe env) where
fmap :: forall a b. (a -> b) -> Recipe env a -> Recipe env b
fmap a -> b
f (Recipe env -> ByteString -> Int -> Result a
p) = (env -> ByteString -> Int -> Result b) -> Recipe env b
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result b) -> Recipe env b)
-> (env -> ByteString -> Int -> Result b) -> Recipe env b
forall a b. (a -> b) -> a -> b
$ \env
env ByteString
bs Int
pos -> case env -> ByteString -> Int -> Result a
p env
env ByteString
bs Int
pos of
Parsed a
a Int
end -> b -> Int -> Result b
forall a. a -> Int -> Result a
Parsed (a -> b
f a
a) Int
end
Suspended Stream Await IO (Outcome a)
suspended -> Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
forall a b.
Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
resume Stream Await IO (Outcome a)
suspended (\a
a ByteString
_ -> b -> Int -> Result b
forall a. a -> Int -> Result a
Parsed (a -> b
f a
a) Int
0)
Failed ReadFailure
failure Int
end -> ReadFailure -> Int -> Result b
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure Int
end
{-# INLINE fmap #-}
instance Applicative (Recipe env) where
pure :: forall a. a -> Recipe env a
pure a
a = (env -> ByteString -> Int -> Result a) -> Recipe env a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result a) -> Recipe env a)
-> (env -> ByteString -> Int -> Result a) -> Recipe env a
forall a b. (a -> b) -> a -> b
$ \env
_ ByteString
_ Int
pos -> a -> Int -> Result a
forall a. a -> Int -> Result a
Parsed a
a Int
pos
{-# INLINE pure #-}
Recipe env -> ByteString -> Int -> Result (a -> b)
pf <*> :: forall a b. Recipe env (a -> b) -> Recipe env a -> Recipe env b
<*> Recipe env -> ByteString -> Int -> Result a
pa = (env -> ByteString -> Int -> Result b) -> Recipe env b
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result b) -> Recipe env b)
-> (env -> ByteString -> Int -> Result b) -> Recipe env b
forall a b. (a -> b) -> a -> b
$ \env
env ByteString
bs Int
pos -> case env -> ByteString -> Int -> Result (a -> b)
pf env
env ByteString
bs Int
pos of
Parsed a -> b
f Int
next -> case env -> ByteString -> Int -> Result a
pa env
env ByteString
bs Int
next of
Parsed a
a Int
end -> b -> Int -> Result b
forall a. a -> Int -> Result a
Parsed (a -> b
f a
a) Int
end
Suspended Stream Await IO (Outcome a)
suspended -> Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
forall a b.
Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
resume Stream Await IO (Outcome a)
suspended (\a
a ByteString
_ -> b -> Int -> Result b
forall a. a -> Int -> Result a
Parsed (a -> b
f a
a) Int
0)
Failed ReadFailure
failure Int
end -> ReadFailure -> Int -> Result b
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure Int
end
Suspended Stream Await IO (Outcome (a -> b))
suspended -> Stream Await IO (Outcome (a -> b))
-> ((a -> b) -> ByteString -> Result b) -> Result b
forall a b.
Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
resume Stream Await IO (Outcome (a -> b))
suspended (\a -> b
f ByteString
rest -> Recipe env b -> env -> ByteString -> Int -> Result b
forall env a. Recipe env a -> env -> ByteString -> Int -> Result a
runRecipe ((a -> b) -> Recipe env a -> Recipe env b
forall a b. (a -> b) -> Recipe env a -> Recipe env b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f ((env -> ByteString -> Int -> Result a) -> Recipe env a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe env -> ByteString -> Int -> Result a
pa)) env
env ByteString
rest Int
0)
Failed ReadFailure
failure Int
next -> ReadFailure -> Int -> Result b
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure Int
next
{-# INLINE (<*>) #-}
liftA2 :: forall a b c.
(a -> b -> c) -> Recipe env a -> Recipe env b -> Recipe env c
liftA2 a -> b -> c
f (Recipe env -> ByteString -> Int -> Result a
pa) (Recipe env -> ByteString -> Int -> Result b
pb) = (env -> ByteString -> Int -> Result c) -> Recipe env c
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result c) -> Recipe env c)
-> (env -> ByteString -> Int -> Result c) -> Recipe env c
forall a b. (a -> b) -> a -> b
$ \env
env ByteString
bs Int
pos -> case env -> ByteString -> Int -> Result a
pa env
env ByteString
bs Int
pos of
Parsed a
a Int
next -> case env -> ByteString -> Int -> Result b
pb env
env ByteString
bs Int
next of
Parsed b
b Int
end -> c -> Int -> Result c
forall a. a -> Int -> Result a
Parsed (a -> b -> c
f a
a b
b) Int
end
Suspended Stream Await IO (Outcome b)
suspended -> Stream Await IO (Outcome b)
-> (b -> ByteString -> Result c) -> Result c
forall a b.
Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
resume Stream Await IO (Outcome b)
suspended (\b
b ByteString
_ -> c -> Int -> Result c
forall a. a -> Int -> Result a
Parsed (a -> b -> c
f a
a b
b) Int
0)
Failed ReadFailure
failure Int
end -> ReadFailure -> Int -> Result c
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure Int
end
Suspended Stream Await IO (Outcome a)
suspended -> Stream Await IO (Outcome a)
-> (a -> ByteString -> Result c) -> Result c
forall a b.
Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
resume Stream Await IO (Outcome a)
suspended (\a
a ByteString
rest -> Recipe env c -> env -> ByteString -> Int -> Result c
forall env a. Recipe env a -> env -> ByteString -> Int -> Result a
runRecipe ((b -> c) -> Recipe env b -> Recipe env c
forall a b. (a -> b) -> Recipe env a -> Recipe env b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> b -> c
f a
a) ((env -> ByteString -> Int -> Result b) -> Recipe env b
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe env -> ByteString -> Int -> Result b
pb)) env
env ByteString
rest Int
0)
Failed ReadFailure
failure Int
next -> ReadFailure -> Int -> Result c
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure Int
next
{-# INLINE liftA2 #-}
instance Monad (Recipe env) where
Recipe env -> ByteString -> Int -> Result a
p >>= :: forall a b. Recipe env a -> (a -> Recipe env b) -> Recipe env b
>>= a -> Recipe env b
k = (env -> ByteString -> Int -> Result b) -> Recipe env b
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result b) -> Recipe env b)
-> (env -> ByteString -> Int -> Result b) -> Recipe env b
forall a b. (a -> b) -> a -> b
$ \env
env ByteString
bs Int
pos -> case env -> ByteString -> Int -> Result a
p env
env ByteString
bs Int
pos of
Parsed a
a Int
next -> Recipe env b -> env -> ByteString -> Int -> Result b
forall env a. Recipe env a -> env -> ByteString -> Int -> Result a
runRecipe (a -> Recipe env b
k a
a) env
env ByteString
bs Int
next
Suspended Stream Await IO (Outcome a)
suspended -> Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
forall a b.
Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
resume Stream Await IO (Outcome a)
suspended (\a
a ByteString
rest -> Recipe env b -> env -> ByteString -> Int -> Result b
forall env a. Recipe env a -> env -> ByteString -> Int -> Result a
runRecipe (a -> Recipe env b
k a
a) env
env ByteString
rest Int
0)
Failed ReadFailure
failure Int
next -> ReadFailure -> Int -> Result b
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure Int
next
{-# INLINE (>>=) #-}
resume :: Stream Await IO (Outcome a) -> (a -> B.ByteString -> Result b) -> Result b
resume :: forall a b.
Stream Await IO (Outcome a)
-> (a -> ByteString -> Result b) -> Result b
resume Stream Await IO (Outcome a)
suspended a -> ByteString -> Result b
k = Stream Await IO (Outcome b) -> Result b
forall a. Stream Await IO (Outcome a) -> Result a
Suspended (Stream Await IO (Outcome b) -> Result b)
-> Stream Await IO (Outcome b) -> Result b
forall a b. (a -> b) -> a -> b
$ Stream Await IO (Outcome a)
suspended Stream Await IO (Outcome a)
-> (Outcome a -> Stream Await IO (Outcome b))
-> Stream Await IO (Outcome b)
forall a b.
Stream Await IO a -> (a -> Stream Await IO b) -> Stream Await IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Done a
a ByteString
rest -> ByteString -> Result b -> Stream Await IO (Outcome b)
forall a. ByteString -> Result a -> Stream Await IO (Outcome a)
stream ByteString
rest (a -> ByteString -> Result b
k a
a ByteString
rest)
Stopped ReadFailure
failure ByteString
rest -> Outcome b -> Stream Await IO (Outcome b)
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (ReadFailure -> ByteString -> Outcome b
forall a. ReadFailure -> ByteString -> Outcome a
Stopped ReadFailure
failure ByteString
rest)
{-# NOINLINE resume #-}
failValue :: ReadFailure -> Recipe env a
failValue :: forall env a. ReadFailure -> Recipe env a
failValue ReadFailure
failure = (env -> ByteString -> Int -> Result a) -> Recipe env a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result a) -> Recipe env a)
-> (env -> ByteString -> Int -> Result a) -> Recipe env a
forall a b. (a -> b) -> a -> b
$ \env
_ ByteString
_ Int
pos -> ReadFailure -> Int -> Result a
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure Int
pos
{-# INLINE failValue #-}
recover :: Recipe env a -> (ReadFailure -> Recipe env a) -> Recipe env a
recover :: forall env a.
Recipe env a -> (ReadFailure -> Recipe env a) -> Recipe env a
recover (Recipe env -> ByteString -> Int -> Result a
p) ReadFailure -> Recipe env a
handler = (env -> ByteString -> Int -> Result a) -> Recipe env a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result a) -> Recipe env a)
-> (env -> ByteString -> Int -> Result a) -> Recipe env a
forall a b. (a -> b) -> a -> b
$ \env
env ByteString
bs Int
pos -> case env -> ByteString -> Int -> Result a
p env
env ByteString
bs Int
pos of
Parsed a
a Int
end -> a -> Int -> Result a
forall a. a -> Int -> Result a
Parsed a
a Int
end
Suspended Stream Await IO (Outcome a)
suspended -> Stream Await IO (Outcome a)
-> (ReadFailure -> ByteString -> Result a) -> Result a
forall a.
Stream Await IO (Outcome a)
-> (ReadFailure -> ByteString -> Result a) -> Result a
recoverSuspended Stream Await IO (Outcome a)
suspended (\ReadFailure
failure ByteString
rest -> Recipe env a -> env -> ByteString -> Int -> Result a
forall env a. Recipe env a -> env -> ByteString -> Int -> Result a
runRecipe (ReadFailure -> Recipe env a
handler ReadFailure
failure) env
env ByteString
rest Int
0)
Failed ReadFailure
failure Int
end -> Recipe env a -> env -> ByteString -> Int -> Result a
forall env a. Recipe env a -> env -> ByteString -> Int -> Result a
runRecipe (ReadFailure -> Recipe env a
handler ReadFailure
failure) env
env ByteString
bs Int
end
{-# INLINE recover #-}
recoverSuspended :: Stream Await IO (Outcome a) -> (ReadFailure -> B.ByteString -> Result a) -> Result a
recoverSuspended :: forall a.
Stream Await IO (Outcome a)
-> (ReadFailure -> ByteString -> Result a) -> Result a
recoverSuspended Stream Await IO (Outcome a)
suspended ReadFailure -> ByteString -> Result a
handler = Stream Await IO (Outcome a) -> Result a
forall a. Stream Await IO (Outcome a) -> Result a
Suspended (Stream Await IO (Outcome a) -> Result a)
-> Stream Await IO (Outcome a) -> Result a
forall a b. (a -> b) -> a -> b
$ Stream Await IO (Outcome a)
suspended Stream Await IO (Outcome a)
-> (Outcome a -> Stream Await IO (Outcome a))
-> Stream Await IO (Outcome a)
forall a b.
Stream Await IO a -> (a -> Stream Await IO b) -> Stream Await IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
done :: Outcome a
done@(Done a
_ ByteString
_) -> Outcome a -> Stream Await IO (Outcome a)
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return Outcome a
done
Stopped ReadFailure
failure ByteString
rest -> ByteString -> Result a -> Stream Await IO (Outcome a)
forall a. ByteString -> Result a -> Stream Await IO (Outcome a)
stream ByteString
rest (ReadFailure -> ByteString -> Result a
handler ReadFailure
failure ByteString
rest)
{-# NOINLINE recoverSuspended #-}
attempt :: Recipe env a -> Recipe env (Either ReadFailure a)
attempt :: forall env a. Recipe env a -> Recipe env (Either ReadFailure a)
attempt Recipe env a
p = Recipe env (Either ReadFailure a)
-> (ReadFailure -> Recipe env (Either ReadFailure a))
-> Recipe env (Either ReadFailure a)
forall env a.
Recipe env a -> (ReadFailure -> Recipe env a) -> Recipe env a
recover (a -> Either ReadFailure a
forall a b. b -> Either a b
Right (a -> Either ReadFailure a)
-> Recipe env a -> Recipe env (Either ReadFailure a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Recipe env a
p) (Either ReadFailure a -> Recipe env (Either ReadFailure a)
forall a. a -> Recipe env a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ReadFailure a -> Recipe env (Either ReadFailure a))
-> (ReadFailure -> Either ReadFailure a)
-> ReadFailure
-> Recipe env (Either ReadFailure a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReadFailure -> Either ReadFailure a
forall a b. a -> Either a b
Left)
{-# INLINE attempt #-}
instance MonadFail (Recipe env) where
fail :: forall a. String -> Recipe env a
fail String
msg = Parser a -> Recipe env a
forall a env. Parser a -> Recipe env a
liftParser (IO a -> Parser a
forall a. IO a -> Parser a
effect (ProtocolError -> IO a
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO (String -> ProtocolError
ProtocolError String
msg)))
effect :: IO a -> Parser a
effect :: forall a. IO a -> Parser a
effect IO a
io = (ByteString -> Int -> Result a) -> Parser a
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result a) -> Parser a)
-> (ByteString -> Int -> Result a) -> Parser a
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos -> Stream Await IO (Outcome a) -> Result a
forall a. Stream Await IO (Outcome a) -> Result a
Suspended (Stream Await IO (Outcome a) -> Result a)
-> Stream Await IO (Outcome a) -> Result a
forall a b. (a -> b) -> a -> b
$ IO (Stream Await IO (Outcome a)) -> Stream Await IO (Outcome a)
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (IO (Stream Await IO (Outcome a)) -> Stream Await IO (Outcome a))
-> IO (Stream Await IO (Outcome a)) -> Stream Await IO (Outcome a)
forall a b. (a -> b) -> a -> b
$ do
!a <- IO a
io
pure (Return (Done a (unread bs pos)))
await :: Parser a -> Result a
await :: forall a. Parser a -> Result a
await Parser a
p = Stream Await IO (Outcome a) -> Result a
forall a. Stream Await IO (Outcome a) -> Result a
Suspended (Stream Await IO (Outcome a) -> Result a)
-> Stream Await IO (Outcome a) -> Result a
forall a b. (a -> b) -> a -> b
$ Await (Stream Await IO (Outcome a)) -> Stream Await IO (Outcome a)
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (Await (Stream Await IO (Outcome a))
-> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a))
-> Stream Await IO (Outcome a)
forall a b. (a -> b) -> a -> b
$ (Feed -> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a))
forall next. (Feed -> next) -> Await next
NeedMore ((Feed -> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a)))
-> (Feed -> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a))
forall a b. (a -> b) -> a -> b
$ \Feed
feed -> case Feed -> Maybe ByteString
feedBytes Feed
feed of
Just ByteString
bs | ByteString -> Bool
B.null ByteString
bs -> ByteString -> Result a -> Stream Await IO (Outcome a)
forall a. ByteString -> Result a -> Stream Await IO (Outcome a)
stream ByteString
bs (Parser a -> Result a
forall a. Parser a -> Result a
await Parser a
p)
| Bool
otherwise -> ByteString -> Result a -> Stream Await IO (Outcome a)
forall a. ByteString -> Result a -> Stream Await IO (Outcome a)
stream ByteString
bs (Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run Parser a
p ByteString
bs Int
0)
Maybe ByteString
Nothing -> ByteString -> Result a -> Stream Await IO (Outcome a)
forall a. ByteString -> Result a -> Stream Await IO (Outcome a)
stream ByteString
B.empty (Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run (String -> Parser a
forall a. String -> Recipe () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"message ended inside a token") ByteString
B.empty Int
0)
peekToken :: Parser (Maybe Word8)
peekToken :: Parser (Maybe Word8)
peekToken = (ByteString -> Int -> Result (Maybe Word8)) -> Parser (Maybe Word8)
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result (Maybe Word8))
-> Parser (Maybe Word8))
-> (ByteString -> Int -> Result (Maybe Word8))
-> Parser (Maybe Word8)
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos ->
if Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
B.length ByteString
bs then Maybe Word8 -> Int -> Result (Maybe Word8)
forall a. a -> Int -> Result a
Parsed (Word8 -> Maybe Word8
forall a. a -> Maybe a
Just (ByteString -> Int -> Word8
Read.word8At ByteString
bs Int
pos)) Int
pos
else Stream Await IO (Outcome (Maybe Word8)) -> Result (Maybe Word8)
forall a. Stream Await IO (Outcome a) -> Result a
Suspended (Stream Await IO (Outcome (Maybe Word8)) -> Result (Maybe Word8))
-> Stream Await IO (Outcome (Maybe Word8)) -> Result (Maybe Word8)
forall a b. (a -> b) -> a -> b
$ Await (Stream Await IO (Outcome (Maybe Word8)))
-> Stream Await IO (Outcome (Maybe Word8))
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (Await (Stream Await IO (Outcome (Maybe Word8)))
-> Stream Await IO (Outcome (Maybe Word8)))
-> Await (Stream Await IO (Outcome (Maybe Word8)))
-> Stream Await IO (Outcome (Maybe Word8))
forall a b. (a -> b) -> a -> b
$ (Feed -> Stream Await IO (Outcome (Maybe Word8)))
-> Await (Stream Await IO (Outcome (Maybe Word8)))
forall next. (Feed -> next) -> Await next
NeedMore ((Feed -> Stream Await IO (Outcome (Maybe Word8)))
-> Await (Stream Await IO (Outcome (Maybe Word8))))
-> (Feed -> Stream Await IO (Outcome (Maybe Word8)))
-> Await (Stream Await IO (Outcome (Maybe Word8)))
forall a b. (a -> b) -> a -> b
$ \Feed
feed -> case Feed -> Maybe ByteString
feedBytes Feed
feed of
Maybe ByteString
Nothing -> Outcome (Maybe Word8) -> Stream Await IO (Outcome (Maybe Word8))
forall a. a -> Stream Await IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Word8 -> ByteString -> Outcome (Maybe Word8)
forall a. a -> ByteString -> Outcome a
Done Maybe Word8
forall a. Maybe a
Nothing ByteString
B.empty)
Just ByteString
next -> ByteString
-> Result (Maybe Word8) -> Stream Await IO (Outcome (Maybe Word8))
forall a. ByteString -> Result a -> Stream Await IO (Outcome a)
stream ByteString
next (Parser (Maybe Word8) -> ByteString -> Int -> Result (Maybe Word8)
forall a. Parser a -> ByteString -> Int -> Result a
run Parser (Maybe Word8)
peekToken ByteString
next Int
0)
peekWord8 :: Parser Word8
peekWord8 :: Parser Word8
peekWord8 = (ByteString -> Int -> Result Word8) -> Parser Word8
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result Word8) -> Parser Word8)
-> (ByteString -> Int -> Result Word8) -> Parser Word8
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos -> if Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= ByteString -> Int
B.length ByteString
bs then Parser Word8 -> Result Word8
forall a. Parser a -> Result a
await Parser Word8
peekWord8 else Word8 -> Int -> Result Word8
forall a. a -> Int -> Result a
Parsed (ByteString -> Int -> Word8
Read.word8At ByteString
bs Int
pos) Int
pos
primitive :: Int -> (B.ByteString -> Int -> a) -> Parser a
primitive :: forall a. Int -> (ByteString -> Int -> a) -> Parser a
primitive Int
n ByteString -> Int -> a
read = (ByteString -> Int -> Result a) -> Parser a
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result a) -> Parser a)
-> (ByteString -> Int -> Result a) -> Parser a
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos ->
if ByteString -> Int -> Int
remaining ByteString
bs Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n
then a -> Int -> Result a
forall a. a -> Int -> Result a
Parsed (ByteString -> Int -> a
read ByteString
bs Int
pos) (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
else Int -> (ByteString -> Int -> a) -> ByteString -> Int -> Result a
forall a.
Int -> (ByteString -> Int -> a) -> ByteString -> Int -> Result a
primitiveSlow Int
n ByteString -> Int -> a
read ByteString
bs Int
pos
{-# INLINE primitive #-}
primitiveSlow :: Int -> (B.ByteString -> Int -> a) -> B.ByteString -> Int -> Result a
primitiveSlow :: forall a.
Int -> (ByteString -> Int -> a) -> ByteString -> Int -> Result a
primitiveSlow Int
n ByteString -> Int -> a
read = Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run ((ByteString -> a) -> Recipe () ByteString -> Parser a
forall a b. (a -> b) -> Recipe () a -> Recipe () b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\ByteString
bytes -> ByteString -> Int -> a
read ByteString
bytes Int
0) (Int -> Recipe () ByteString
boundedBytes Int
n))
{-# NOINLINE primitiveSlow #-}
word8 :: Parser Word8
word8 :: Parser Word8
word8 = Int -> (ByteString -> Int -> Word8) -> Parser Word8
forall a. Int -> (ByteString -> Int -> a) -> Parser a
primitive Int
1 ByteString -> Int -> Word8
Read.word8At
{-# INLINE word8 #-}
word16le :: Parser Word16
word16le :: Parser Word16
word16le = Int -> (ByteString -> Int -> Word16) -> Parser Word16
forall a. Int -> (ByteString -> Int -> a) -> Parser a
primitive Int
2 ByteString -> Int -> Word16
Read.word16LeAt
{-# INLINE word16le #-}
word32le :: Parser Word32
word32le :: Parser Word32
word32le = Int -> (ByteString -> Int -> Word32) -> Parser Word32
forall a. Int -> (ByteString -> Int -> a) -> Parser a
primitive Int
4 ByteString -> Int -> Word32
Read.word32LeAt
{-# INLINE word32le #-}
word64le :: Parser Word64
word64le :: Parser Word64
word64le = Int -> (ByteString -> Int -> Word64) -> Parser Word64
forall a. Int -> (ByteString -> Int -> a) -> Parser a
primitive Int
8 ByteString -> Int -> Word64
Read.word64LeAt
{-# INLINE word64le #-}
word32be :: Parser Word32
word32be :: Parser Word32
word32be = (Word32 -> Word8 -> Word32) -> Word32 -> ByteString -> Word32
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
B.foldl' (\Word32
a Word8
b -> (Word32
a Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b) Word32
0 (ByteString -> Word32) -> Recipe () ByteString -> Parser Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Recipe () ByteString
boundedBytes Int
4
bytes :: Int -> Int -> Parser B.ByteString
bytes :: Int -> Int -> Recipe () ByteString
bytes Int
ahead Int
n = (ByteString -> ByteString) -> Int -> Int -> Recipe () ByteString
contiguous ByteString -> ByteString
forall a. a -> a
id Int
ahead Int
n
{-# INLINE bytes #-}
ownedBytes :: Int -> Int -> Parser B.ByteString
ownedBytes :: Int -> Int -> Recipe () ByteString
ownedBytes Int
ahead Int
n = (ByteString -> ByteString) -> Int -> Int -> Recipe () ByteString
contiguous ByteString -> ByteString
B.copy Int
ahead Int
n
{-# INLINE ownedBytes #-}
boundedBytes :: Int -> Parser B.ByteString
boundedBytes :: Int -> Recipe () ByteString
boundedBytes Int
n = Int -> Int -> Recipe () ByteString
bytes Int
n Int
n
ownedBoundedBytes :: Int -> Parser B.ByteString
ownedBoundedBytes :: Int -> Recipe () ByteString
ownedBoundedBytes Int
n = Int -> Int -> Recipe () ByteString
ownedBytes Int
n Int
n
contiguous :: (B.ByteString -> B.ByteString) -> Int -> Int -> Parser B.ByteString
contiguous :: (ByteString -> ByteString) -> Int -> Int -> Recipe () ByteString
contiguous ByteString -> ByteString
borrowed Int
ahead Int
n = (ByteString -> Int -> Result ByteString) -> Recipe () ByteString
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result ByteString) -> Recipe () ByteString)
-> (ByteString -> Int -> Result ByteString) -> Recipe () ByteString
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos ->
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then Recipe () ByteString -> ByteString -> Int -> Result ByteString
forall a. Parser a -> ByteString -> Int -> Result a
run (String -> Recipe () ByteString
forall a. String -> Recipe () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"negative byte count") ByteString
bs Int
pos
else if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteString -> Int -> Int
remaining ByteString
bs Int
pos
then ByteString -> Int -> Result ByteString
forall a. a -> Int -> Result a
Parsed (ByteString -> ByteString
borrowed (ByteString -> Int -> Int -> ByteString
slice ByteString
bs Int
pos Int
n)) (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
else Int -> Int -> ByteString -> Int -> Result ByteString
contiguousSlow Int
ahead Int
n ByteString
bs Int
pos
{-# INLINE contiguous #-}
contiguousSlow :: Int -> Int -> B.ByteString -> Int -> Result B.ByteString
contiguousSlow :: Int -> Int -> ByteString -> Int -> Result ByteString
contiguousSlow Int
ahead Int
n = Recipe () ByteString -> ByteString -> Int -> Result ByteString
forall a. Parser a -> ByteString -> Int -> Result a
run (Int -> Accumulator -> Recipe () ByteString
gather Int
n (Maybe Word64 -> Accumulator
accumulator (Word64 -> Maybe Word64
forall a. a -> Maybe a
Just (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n))))
where
gather :: Int -> Accumulator -> Recipe () ByteString
gather Int
0 Accumulator
a = IO ByteString -> Recipe () ByteString
forall a. IO a -> Parser a
effect (Accumulator -> IO ByteString
finish Accumulator
a)
gather Int
remaining Accumulator
a = do
bytes <- Int -> Recipe () ByteString
chunk Int
remaining
next <- effect (append ahead a bytes)
gather (remaining - B.length bytes) next
{-# NOINLINE contiguousSlow #-}
chunk :: Int -> Parser B.ByteString
chunk :: Int -> Recipe () ByteString
chunk Int
n = (ByteString -> Int -> Result ByteString) -> Recipe () ByteString
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result ByteString) -> Recipe () ByteString)
-> (ByteString -> Int -> Result ByteString) -> Recipe () ByteString
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos ->
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then Recipe () ByteString -> ByteString -> Int -> Result ByteString
forall a. Parser a -> ByteString -> Int -> Result a
run (String -> Recipe () ByteString
forall a. String -> Recipe () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"negative byte count") ByteString
bs Int
pos
else if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then ByteString -> Int -> Result ByteString
forall a. a -> Int -> Result a
Parsed ByteString
B.empty Int
pos
else if Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= ByteString -> Int
B.length ByteString
bs then Recipe () ByteString -> Result ByteString
forall a. Parser a -> Result a
await (Int -> Recipe () ByteString
chunk Int
n)
else let k :: Int
k = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
n (ByteString -> Int -> Int
remaining ByteString
bs Int
pos)
in ByteString -> Int -> Result ByteString
forall a. a -> Int -> Result a
Parsed (ByteString -> Int -> Int -> ByteString
slice ByteString
bs Int
pos Int
k) (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k)
chunkOrDiscard :: Int -> Parser (Maybe B.ByteString)
chunkOrDiscard :: Int -> Parser (Maybe ByteString)
chunkOrDiscard Int
n = (ByteString -> Int -> Result (Maybe ByteString))
-> Parser (Maybe ByteString)
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result (Maybe ByteString))
-> Parser (Maybe ByteString))
-> (ByteString -> Int -> Result (Maybe ByteString))
-> Parser (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos ->
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
B.length ByteString
bs then Parser (Maybe ByteString)
-> ByteString -> Int -> Result (Maybe ByteString)
forall a. Parser a -> ByteString -> Int -> Result a
run (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> Recipe () ByteString -> Parser (Maybe ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Recipe () ByteString
chunk Int
n) ByteString
bs Int
pos
else Stream Await IO (Outcome (Maybe ByteString))
-> Result (Maybe ByteString)
forall a. Stream Await IO (Outcome a) -> Result a
Suspended (Stream Await IO (Outcome (Maybe ByteString))
-> Result (Maybe ByteString))
-> Stream Await IO (Outcome (Maybe ByteString))
-> Result (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ Await (Stream Await IO (Outcome (Maybe ByteString)))
-> Stream Await IO (Outcome (Maybe ByteString))
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (Await (Stream Await IO (Outcome (Maybe ByteString)))
-> Stream Await IO (Outcome (Maybe ByteString)))
-> Await (Stream Await IO (Outcome (Maybe ByteString)))
-> Stream Await IO (Outcome (Maybe ByteString))
forall a b. (a -> b) -> a -> b
$ (Feed -> Stream Await IO (Outcome (Maybe ByteString)))
-> Await (Stream Await IO (Outcome (Maybe ByteString)))
forall next. (Feed -> next) -> Await next
NeedMore ((Feed -> Stream Await IO (Outcome (Maybe ByteString)))
-> Await (Stream Await IO (Outcome (Maybe ByteString))))
-> (Feed -> Stream Await IO (Outcome (Maybe ByteString)))
-> Await (Stream Await IO (Outcome (Maybe ByteString)))
forall a b. (a -> b) -> a -> b
$ \Feed
feed -> case Feed
feed of
Discard ByteString
next -> Outcome (Maybe ByteString)
-> Stream Await IO (Outcome (Maybe ByteString))
forall a. a -> Stream Await IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe ByteString -> ByteString -> Outcome (Maybe ByteString)
forall a. a -> ByteString -> Outcome a
Done Maybe ByteString
forall a. Maybe a
Nothing ByteString
next)
More ByteString
next -> ByteString
-> Result (Maybe ByteString)
-> Stream Await IO (Outcome (Maybe ByteString))
forall a. ByteString -> Result a -> Stream Await IO (Outcome a)
stream ByteString
next (Parser (Maybe ByteString)
-> ByteString -> Int -> Result (Maybe ByteString)
forall a. Parser a -> ByteString -> Int -> Result a
run (Int -> Parser (Maybe ByteString)
chunkOrDiscard Int
n) ByteString
next Int
0)
Feed
EndOfMessage -> ByteString
-> Result (Maybe ByteString)
-> Stream Await IO (Outcome (Maybe ByteString))
forall a. ByteString -> Result a -> Stream Await IO (Outcome a)
stream ByteString
B.empty (Parser (Maybe ByteString)
-> ByteString -> Int -> Result (Maybe ByteString)
forall a. Parser a -> ByteString -> Int -> Result a
run (String -> Parser (Maybe ByteString)
forall a. String -> Recipe () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"message ended inside a value") ByteString
B.empty Int
0)
skip :: Int -> Parser ()
skip :: Int -> Parser ()
skip Int
n = (ByteString -> Int -> Result ()) -> Parser ()
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result ()) -> Parser ())
-> (ByteString -> Int -> Result ()) -> Parser ()
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos ->
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then Parser () -> ByteString -> Int -> Result ()
forall a. Parser a -> ByteString -> Int -> Result a
run (String -> Parser ()
forall a. String -> Recipe () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"negative byte count") ByteString
bs Int
pos
else if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteString -> Int -> Int
remaining ByteString
bs Int
pos then () -> Int -> Result ()
forall a. a -> Int -> Result a
Parsed () (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
else Parser () -> Result ()
forall a. Parser a -> Result a
await (Int -> Parser ()
skip (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int -> Int
remaining ByteString
bs Int
pos))
bVarChar :: Parser Text
bVarChar :: Parser Text
bVarChar = Parser Word8
word8 Parser Word8 -> (Word8 -> Parser Text) -> Parser Text
forall a b. Recipe () a -> (a -> Recipe () b) -> Recipe () b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word8
n -> ByteString -> Text
Utf16.decodeUtf16LE (ByteString -> Text) -> Recipe () ByteString -> Parser Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Recipe () ByteString
boundedBytes (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
n)
usVarChar :: Parser Text
usVarChar :: Parser Text
usVarChar = Parser Word16
word16le Parser Word16 -> (Word16 -> Parser Text) -> Parser Text
forall a b. Recipe () a -> (a -> Recipe () b) -> Recipe () b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word16
n -> ByteString -> Text
Utf16.decodeUtf16LE (ByteString -> Text) -> Recipe () ByteString -> Parser Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Recipe () ByteString
boundedBytes (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
n)
count :: Int -> Parser a -> Parser [a]
count :: forall a. Int -> Parser a -> Parser [a]
count Int
n Parser a
recipe
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = String -> Recipe () [a]
forall a. String -> Recipe () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"negative item count"
| Bool
otherwise = Int -> [a] -> Recipe () [a]
forall {t}. (Eq t, Num t) => t -> [a] -> Recipe () [a]
go Int
n []
where
go :: t -> [a] -> Recipe () [a]
go t
0 [a]
acc = [a] -> Recipe () [a]
forall a. a -> Recipe () a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([a] -> [a]
forall a. [a] -> [a]
reverse [a]
acc)
go t
remaining [a]
acc = Parser a
recipe Parser a -> (a -> Recipe () [a]) -> Recipe () [a]
forall a b. Recipe () a -> (a -> Recipe () b) -> Recipe () b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
a -> t -> [a] -> Recipe () [a]
go (t
remaining t -> t -> t
forall a. Num a => a -> a -> a
- t
1) (a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc)
isolate :: Int -> Parser a -> Parser a
isolate :: forall a. Int -> Parser a -> Parser a
isolate Int
n Parser a
p = do
bs <- Int -> Recipe () ByteString
boundedBytes Int
n
effect $ do
(a, rest) <- parseChunks p [bs]
if all B.null rest then pure a else throwIO (ProtocolError "unconsumed bytes in token envelope")
limited :: Int -> Parser a -> Parser a
limited :: forall a. Int -> Parser a -> Parser a
limited Int
limit Parser a
p = (ByteString -> Int -> Result a) -> Parser a
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result a) -> Parser a)
-> (ByteString -> Int -> Result a) -> Parser a
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos -> case Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run Parser a
p ByteString
bs Int
pos of
Parsed a
a Int
end
| Int
end Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
limit -> a -> Int -> Result a
forall a. a -> Int -> Result a
Parsed a
a Int
end
| Bool
otherwise -> Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run (String -> Parser a
forall a. String -> Recipe () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"metadata token exceeds its size limit") ByteString
bs Int
pos
Suspended Stream Await IO (Outcome a)
s -> Stream Await IO (Outcome a) -> Result a
forall a. Stream Await IO (Outcome a) -> Result a
Suspended (Int -> Stream Await IO (Outcome a) -> Stream Await IO (Outcome a)
forall {a}.
Int -> Stream Await IO (Outcome a) -> Stream Await IO (Outcome a)
bound (ByteString -> Int -> Int
remaining ByteString
bs Int
pos) Stream Await IO (Outcome a)
s)
Failed ReadFailure
failure Int
end -> ReadFailure -> Int -> Result a
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure Int
end
where
bound :: Int -> Stream Await IO (Outcome a) -> Stream Await IO (Outcome a)
bound Int
received Stream Await IO (Outcome a)
s = IO (Stream Await IO (Outcome a)) -> Stream Await IO (Outcome a)
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (IO (Stream Await IO (Outcome a)) -> Stream Await IO (Outcome a))
-> IO (Stream Await IO (Outcome a)) -> Stream Await IO (Outcome a)
forall a b. (a -> b) -> a -> b
$ Stream Await IO (Outcome a)
-> IO (Either (Outcome a) (Await (Stream Await IO (Outcome a))))
forall (m :: * -> *) (f :: * -> *) r.
Monad m =>
Stream f m r -> m (Either r (f (Stream f m r)))
inspect Stream Await IO (Outcome a)
s IO (Either (Outcome a) (Await (Stream Await IO (Outcome a))))
-> (Either (Outcome a) (Await (Stream Await IO (Outcome a)))
-> IO (Stream Await IO (Outcome a)))
-> IO (Stream Await IO (Outcome a))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left Outcome a
outcome
| Int
received Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
B.length (Outcome a -> ByteString
forall a. Outcome a -> ByteString
outcomeRest Outcome a
outcome) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
limit -> Stream Await IO (Outcome a) -> IO (Stream Await IO (Outcome a))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Outcome a -> Stream Await IO (Outcome a)
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return Outcome a
outcome)
| Bool
otherwise -> ProtocolError -> IO (Stream Await IO (Outcome a))
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO (String -> ProtocolError
ProtocolError (String
"token still unfinished after " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
received String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" bytes"))
Right (NeedMore Feed -> Stream Await IO (Outcome a)
k)
| Int
received Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
limit -> ProtocolError -> IO (Stream Await IO (Outcome a))
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO (String -> ProtocolError
ProtocolError (String
"token still unfinished after " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
received String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" bytes"))
| Bool
otherwise -> Stream Await IO (Outcome a) -> IO (Stream Await IO (Outcome a))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Stream Await IO (Outcome a) -> IO (Stream Await IO (Outcome a)))
-> Stream Await IO (Outcome a) -> IO (Stream Await IO (Outcome a))
forall a b. (a -> b) -> a -> b
$ Await (Stream Await IO (Outcome a)) -> Stream Await IO (Outcome a)
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (Await (Stream Await IO (Outcome a))
-> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a))
-> Stream Await IO (Outcome a)
forall a b. (a -> b) -> a -> b
$ (Feed -> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a))
forall next. (Feed -> next) -> Await next
NeedMore ((Feed -> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a)))
-> (Feed -> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a))
forall a b. (a -> b) -> a -> b
$ \Feed
feed ->
Int -> Stream Await IO (Outcome a) -> Stream Await IO (Outcome a)
bound (Int
received Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> (ByteString -> Int) -> Maybe ByteString -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 ByteString -> Int
B.length (Feed -> Maybe ByteString
feedBytes Feed
feed)) (Feed -> Stream Await IO (Outcome a)
k Feed
feed)
Right (RunConsumer Bool
live Runner -> IO x
io Maybe x -> Stream Await IO (Outcome a)
k) -> Stream Await IO (Outcome a) -> IO (Stream Await IO (Outcome a))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Stream Await IO (Outcome a) -> IO (Stream Await IO (Outcome a)))
-> Stream Await IO (Outcome a) -> IO (Stream Await IO (Outcome a))
forall a b. (a -> b) -> a -> b
$ Await (Stream Await IO (Outcome a)) -> Stream Await IO (Outcome a)
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (Await (Stream Await IO (Outcome a))
-> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a))
-> Stream Await IO (Outcome a)
forall a b. (a -> b) -> a -> b
$ Bool
-> (Runner -> IO x)
-> (Maybe x -> Stream Await IO (Outcome a))
-> Await (Stream Await IO (Outcome a))
forall next x.
Bool -> (Runner -> IO x) -> (Maybe x -> next) -> Await next
RunConsumer Bool
live Runner -> IO x
io (Int -> Stream Await IO (Outcome a) -> Stream Await IO (Outcome a)
bound Int
received (Stream Await IO (Outcome a) -> Stream Await IO (Outcome a))
-> (Maybe x -> Stream Await IO (Outcome a))
-> Maybe x
-> Stream Await IO (Outcome a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe x -> Stream Await IO (Outcome a)
k)
data ValueBytes = Borrowed !B.ByteString | Owned !B.ByteString
valueBytes :: ValueBytes -> B.ByteString
valueBytes :: ValueBytes -> ByteString
valueBytes (Borrowed ByteString
bs) = ByteString
bs
valueBytes (Owned ByteString
bs) = ByteString
bs
{-# INLINE valueBytes #-}
keepBytes :: ValueBytes -> B.ByteString
keepBytes :: ValueBytes -> ByteString
keepBytes (Borrowed ByteString
bs) = ByteString -> ByteString
B.copy ByteString
bs
keepBytes (Owned ByteString
bs) = ByteString
bs
{-# INLINE keepBytes #-}
bytesValue :: Int -> Int -> Parser (Maybe ValueBytes)
bytesValue :: Int -> Int -> Parser (Maybe ValueBytes)
bytesValue Int
ahead Int
n = (ByteString -> Int -> Result (Maybe ValueBytes))
-> Parser (Maybe ValueBytes)
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result (Maybe ValueBytes))
-> Parser (Maybe ValueBytes))
-> (ByteString -> Int -> Result (Maybe ValueBytes))
-> Parser (Maybe ValueBytes)
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos ->
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then Parser (Maybe ValueBytes)
-> ByteString -> Int -> Result (Maybe ValueBytes)
forall a. Parser a -> ByteString -> Int -> Result a
run (String -> Parser (Maybe ValueBytes)
forall a. String -> Recipe () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"negative byte count") ByteString
bs Int
pos
else if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteString -> Int -> Int
remaining ByteString
bs Int
pos then Maybe ValueBytes -> Int -> Result (Maybe ValueBytes)
forall a. a -> Int -> Result a
Parsed (ValueBytes -> Maybe ValueBytes
forall a. a -> Maybe a
Just (ByteString -> ValueBytes
Borrowed (ByteString -> Int -> Int -> ByteString
slice ByteString
bs Int
pos Int
n))) (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
else Int -> Int -> ByteString -> Int -> Result (Maybe ValueBytes)
bytesValueSlow Int
ahead Int
n ByteString
bs Int
pos
{-# INLINE bytesValue #-}
convertBytes :: Int -> Int -> (B.ByteString -> Either ReadFailure a)
-> (B.ByteString -> Either ReadFailure a) -> Parser a
convertBytes :: forall a.
Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> (ByteString -> Either ReadFailure a)
-> Parser a
convertBytes Int
ahead Int
n ByteString -> Either ReadFailure a
borrowed ByteString -> Either ReadFailure a
owned = (ByteString -> Int -> Result a) -> Parser a
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result a) -> Parser a)
-> (ByteString -> Int -> Result a) -> Parser a
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos ->
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteString -> Int -> Int
remaining ByteString
bs Int
pos
then case ByteString -> Either ReadFailure a
borrowed (ByteString -> Int -> Int -> ByteString
slice ByteString
bs Int
pos Int
n) of
Right a
a -> a -> Int -> Result a
forall a. a -> Int -> Result a
Parsed a
a (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
Left ReadFailure
failure -> ReadFailure -> Int -> Result a
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
else Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> (ByteString -> Either ReadFailure a)
-> ByteString
-> Int
-> Result a
forall a.
Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> (ByteString -> Either ReadFailure a)
-> ByteString
-> Int
-> Result a
convertBytesSlow Int
ahead Int
n ByteString -> Either ReadFailure a
borrowed ByteString -> Either ReadFailure a
owned ByteString
bs Int
pos
{-# INLINE convertBytes #-}
prefixedValue :: Int -> Int -> (B.ByteString -> Either ReadFailure a) -> Recipe env a -> Recipe env a -> Recipe env a
prefixedValue :: forall a env.
Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> Recipe env a
-> Recipe env a
-> Recipe env a
prefixedValue Int
width Int
marker ByteString -> Either ReadFailure a
convert (Recipe env -> ByteString -> Int -> Result a
null) (Recipe env -> ByteString -> Int -> Result a
other) = (env -> ByteString -> Int -> Result a) -> Recipe env a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((env -> ByteString -> Int -> Result a) -> Recipe env a)
-> (env -> ByteString -> Int -> Result a) -> Recipe env a
forall a b. (a -> b) -> a -> b
$ \env
env ByteString
bs Int
pos ->
Int
-> ByteString
-> Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> (env -> ByteString -> Int -> Result a)
-> (env -> ByteString -> Int -> Result a)
-> env
-> ByteString
-> Int
-> Result a
forall a env.
Int
-> ByteString
-> Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> (env -> ByteString -> Int -> Result a)
-> (env -> ByteString -> Int -> Result a)
-> env
-> ByteString
-> Int
-> Result a
prefixedAt Int
0 ByteString
B.empty Int
width Int
marker ByteString -> Either ReadFailure a
convert env -> ByteString -> Int -> Result a
null env -> ByteString -> Int -> Result a
other env
env ByteString
bs Int
pos
{-# INLINE prefixedValue #-}
prefixedRowValue :: Int -> Int -> Int -> (B.ByteString -> Either ReadFailure a) -> Recipe B.ByteString a -> Recipe B.ByteString a -> Recipe B.ByteString a
prefixedRowValue :: forall a.
Int
-> Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> Recipe ByteString a
-> Recipe ByteString a
-> Recipe ByteString a
prefixedRowValue Int
column Int
width Int
marker ByteString -> Either ReadFailure a
convert (Recipe ByteString -> ByteString -> Int -> Result a
null) (Recipe ByteString -> ByteString -> Int -> Result a
other) = (ByteString -> ByteString -> Int -> Result a)
-> Recipe ByteString a
forall env a.
(env -> ByteString -> Int -> Result a) -> Recipe env a
Recipe ((ByteString -> ByteString -> Int -> Result a)
-> Recipe ByteString a)
-> (ByteString -> ByteString -> Int -> Result a)
-> Recipe ByteString a
forall a b. (a -> b) -> a -> b
$ \ByteString
bitmap ByteString
bs Int
pos ->
Int
-> ByteString
-> Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> (ByteString -> ByteString -> Int -> Result a)
-> (ByteString -> ByteString -> Int -> Result a)
-> ByteString
-> ByteString
-> Int
-> Result a
forall a env.
Int
-> ByteString
-> Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> (env -> ByteString -> Int -> Result a)
-> (env -> ByteString -> Int -> Result a)
-> env
-> ByteString
-> Int
-> Result a
prefixedAt Int
column ByteString
bitmap Int
width Int
marker ByteString -> Either ReadFailure a
convert ByteString -> ByteString -> Int -> Result a
null ByteString -> ByteString -> Int -> Result a
other ByteString
bitmap ByteString
bs Int
pos
{-# INLINE prefixedRowValue #-}
prefixedAt :: Int -> B.ByteString -> Int -> Int
-> (B.ByteString -> Either ReadFailure a)
-> (env -> B.ByteString -> Int -> Result a)
-> (env -> B.ByteString -> Int -> Result a)
-> env -> B.ByteString -> Int -> Result a
prefixedAt :: forall a env.
Int
-> ByteString
-> Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> (env -> ByteString -> Int -> Result a)
-> (env -> ByteString -> Int -> Result a)
-> env
-> ByteString
-> Int
-> Result a
prefixedAt Int
column ByteString
bitmap Int
width Int
marker ByteString -> Either ReadFailure a
convert env -> ByteString -> Int -> Result a
null env -> ByteString -> Int -> Result a
other env
env ByteString
bs Int
pos =
case Int
-> ByteString
-> Int
-> Int
-> ByteString
-> Int
-> (# Int#, Int# #)
valueSpan Int
column ByteString
bitmap Int
width Int
marker ByteString
bs Int
pos of
(# Int#
start, Int#
n #)
| Int# -> Bool
isTrue# (Int#
n Int# -> Int# -> Int#
>=# Int#
0#) -> case ByteString -> Either ReadFailure a
convert (ByteString -> Int -> Int -> ByteString
slice ByteString
bs (Int# -> Int
I# Int#
start) (Int# -> Int
I# Int#
n)) of
Right a
a -> a -> Int -> Result a
forall a. a -> Int -> Result a
Parsed a
a (Int# -> Int
I# (Int#
start Int# -> Int# -> Int#
+# Int#
n))
Left ReadFailure
failure -> ReadFailure -> Int -> Result a
forall a. ReadFailure -> Int -> Result a
Failed ReadFailure
failure (Int# -> Int
I# (Int#
start Int# -> Int# -> Int#
+# Int#
n))
| Int# -> Bool
isTrue# (Int#
n Int# -> Int# -> Int#
==# Int#
-1#) -> env -> ByteString -> Int -> Result a
null env
env ByteString
bs (Int# -> Int
I# Int#
start)
| Bool
otherwise -> env -> ByteString -> Int -> Result a
other env
env ByteString
bs Int
pos
{-# INLINE prefixedAt #-}
valueSpan :: Int -> B.ByteString -> Int -> Int -> B.ByteString -> Int -> (# Int#, Int# #)
valueSpan :: Int
-> ByteString
-> Int
-> Int
-> ByteString
-> Int
-> (# Int#, Int# #)
valueSpan Int
column ByteString
bitmap Int
width Int
marker ByteString
bs Int
pos
| Bool -> Bool
not (ByteString -> Bool
B.null ByteString
bitmap) Bool -> Bool -> Bool
&& Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit (HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
B.index ByteString
bitmap (Int
column Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
8)) (Int
column Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
8) = Int -> Int -> (# Int#, Int# #)
found Int
pos (-Int
1)
| Bool
otherwise = case Int
width of
Int
0 | Int
marker Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteString -> Int -> Int
remaining ByteString
bs Int
pos -> Int -> Int -> (# Int#, Int# #)
found Int
pos Int
marker
Int
1 | ByteString -> Int -> Int
remaining ByteString
bs Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
1 -> Int -> Int -> (# Int#, Int# #)
prefixed Int
1 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int -> Word8
Read.word8At ByteString
bs Int
pos))
Int
2 | ByteString -> Int -> Int
remaining ByteString
bs Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 -> Int -> Int -> (# Int#, Int# #)
prefixed Int
2 (Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int -> Word16
Read.word16LeAt ByteString
bs Int
pos))
Int
_ -> (# Int#, Int# #)
other
where
prefixed :: Int -> Int -> (# Int#, Int# #)
prefixed Int
w Int
n
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
marker = Int -> Int -> (# Int#, Int# #)
found (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
w) (-Int
1)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteString -> Int -> Int
remaining ByteString
bs (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
w) = Int -> Int -> (# Int#, Int# #)
found (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
w) Int
n
| Bool
otherwise = (# Int#, Int# #)
other
found :: Int -> Int -> (# Int#, Int# #)
found (I# Int#
start) (I# Int#
n) = (# Int#
start, Int#
n #)
other :: (# Int#, Int# #)
other = (# Int#
0#, Int#
-2# #)
{-# NOINLINE valueSpan #-}
convertBytesSlow :: Int -> Int -> (B.ByteString -> Either ReadFailure a)
-> (B.ByteString -> Either ReadFailure a) -> B.ByteString -> Int -> Result a
convertBytesSlow :: forall a.
Int
-> Int
-> (ByteString -> Either ReadFailure a)
-> (ByteString -> Either ReadFailure a)
-> ByteString
-> Int
-> Result a
convertBytesSlow Int
ahead Int
n ByteString -> Either ReadFailure a
borrowed ByteString -> Either ReadFailure a
owned = Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run (Parser a -> ByteString -> Int -> Result a)
-> Parser a -> ByteString -> Int -> Result a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Parser (Maybe ValueBytes)
bytesValue Int
ahead Int
n Parser (Maybe ValueBytes)
-> (Maybe ValueBytes -> Parser a) -> Parser a
forall a b. Recipe () a -> (a -> Recipe () b) -> Recipe () b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just (Borrowed ByteString
bytes) -> (ReadFailure -> Parser a)
-> (a -> Parser a) -> Either ReadFailure a -> Parser a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ReadFailure -> Parser a
forall env a. ReadFailure -> Recipe env a
failValue a -> Parser a
forall a. a -> Recipe () a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Either ReadFailure a
borrowed ByteString
bytes)
Just (Owned ByteString
bytes) -> (ReadFailure -> Parser a)
-> (a -> Parser a) -> Either ReadFailure a -> Parser a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ReadFailure -> Parser a
forall env a. ReadFailure -> Recipe env a
failValue a -> Parser a
forall a. a -> Recipe () a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Either ReadFailure a
owned ByteString
bytes)
Maybe ValueBytes
Nothing -> ReadFailure -> Parser a
forall env a. ReadFailure -> Recipe env a
failValue ReadFailure
ReadDiscarded
{-# NOINLINE convertBytesSlow #-}
bytesValueSlow :: Int -> Int -> B.ByteString -> Int -> Result (Maybe ValueBytes)
bytesValueSlow :: Int -> Int -> ByteString -> Int -> Result (Maybe ValueBytes)
bytesValueSlow Int
ahead Int
n = Parser (Maybe ValueBytes)
-> ByteString -> Int -> Result (Maybe ValueBytes)
forall a. Parser a -> ByteString -> Int -> Result a
run (Int -> Accumulator -> Parser (Maybe ValueBytes)
gather Int
n (Maybe Word64 -> Accumulator
accumulator (Word64 -> Maybe Word64
forall a. a -> Maybe a
Just (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n))))
where
gather :: Int -> Accumulator -> Parser (Maybe ValueBytes)
gather Int
0 Accumulator
a = ValueBytes -> Maybe ValueBytes
forall a. a -> Maybe a
Just (ValueBytes -> Maybe ValueBytes)
-> (ByteString -> ValueBytes) -> ByteString -> Maybe ValueBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ValueBytes
Owned (ByteString -> Maybe ValueBytes)
-> Recipe () ByteString -> Parser (Maybe ValueBytes)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO ByteString -> Recipe () ByteString
forall a. IO a -> Parser a
effect (Accumulator -> IO ByteString
finish Accumulator
a)
gather Int
remaining Accumulator
a = Int -> Parser (Maybe ByteString)
chunkOrDiscard Int
remaining Parser (Maybe ByteString)
-> (Maybe ByteString -> Parser (Maybe ValueBytes))
-> Parser (Maybe ValueBytes)
forall a b. Recipe () a -> (a -> Recipe () b) -> Recipe () b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe ByteString
Nothing -> Int -> Parser ()
skip Int
remaining Parser () -> Parser (Maybe ValueBytes) -> Parser (Maybe ValueBytes)
forall a b. Recipe () a -> Recipe () b -> Recipe () b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe ValueBytes -> Parser (Maybe ValueBytes)
forall a. a -> Recipe () a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe ValueBytes
forall a. Maybe a
Nothing
Just ByteString
bytes -> do
next <- IO Accumulator -> Parser Accumulator
forall a. IO a -> Parser a
effect (Int -> Accumulator -> ByteString -> IO Accumulator
append Int
ahead Accumulator
a ByteString
bytes)
gather (remaining - B.length bytes) next
{-# NOINLINE bytesValueSlow #-}
data Buffer = Buffer !(ForeignPtr Word8) !Int !Int
data Accumulator
= Known !Int !Buffer
| Unknown !Int ![B.ByteString] !Buffer
accumulator :: Maybe Word64 -> Accumulator
accumulator :: Maybe Word64 -> Accumulator
accumulator Maybe Word64
total = case Maybe Word64
total of
Just Word64
n -> Int -> Buffer -> Accumulator
Known (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word64 -> Word64
forall a. Ord a => a -> a -> a
min Word64
n (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
forall a. Bounded a => a
maxBound :: Int)))) Buffer
empty
Maybe Word64
Nothing -> Int -> [ByteString] -> Buffer -> Accumulator
Unknown Int
0 [] Buffer
empty
where empty :: Buffer
empty = ForeignPtr Word8 -> Int -> Int -> Buffer
Buffer ForeignPtr Word8
BI.nullForeignPtr Int
0 Int
0
append :: Int -> Accumulator -> B.ByteString -> IO Accumulator
append :: Int -> Accumulator -> ByteString -> IO Accumulator
append Int
ahead Accumulator
a ByteString
src = case Accumulator
a of
Known Int
total (Buffer ForeignPtr Word8
fp Int
cap Int
len)
| Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
forall a. Bounded a => a
maxBound Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len -> ProtocolError -> IO Accumulator
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO (String -> ProtocolError
ProtocolError String
"value length exceeds addressable memory")
| Int
needed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
cap -> do
ForeignPtr Word8 -> Int -> Int -> ByteString -> IO ()
copy ForeignPtr Word8
fp Int
cap Int
len ByteString
src
Accumulator -> IO Accumulator
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> Buffer -> Accumulator
Known Int
total (ForeignPtr Word8 -> Int -> Int -> Buffer
Buffer ForeignPtr Word8
fp Int
cap Int
needed))
| Int
cap Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
|| Int
needed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
total -> do
let size :: Int
size | Int
cap Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
k ((Int -> Bool) -> (Int -> Int) -> Int -> Int
forall a. (a -> Bool) -> (a -> a) -> a -> a
until (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
ahead) (Int -> Int -> Int
forall a. Integral a => a -> a -> a
`quot` Int
4) Int
total)
| Bool
otherwise = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
needed (if Int
cap Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
total Int -> Int -> Int
forall a. Integral a => a -> a -> a
`quot` Int
4 then Int
total else Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
cap)
fp' <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
BI.mallocByteString Int
size
copy fp' size 0 (BI.BS fp len)
copy fp' size len src
pure (Known total (Buffer fp' size needed))
| Bool
otherwise -> Int -> Accumulator -> ByteString -> IO Accumulator
append Int
ahead (Int -> [ByteString] -> Buffer -> Accumulator
Unknown Int
0 [] (ForeignPtr Word8 -> Int -> Int -> Buffer
Buffer ForeignPtr Word8
fp Int
cap Int
len)) ByteString
src
where needed :: Int
needed = Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k
Unknown Int
before [ByteString]
full (Buffer ForeignPtr Word8
fp Int
cap Int
len)
| Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
forall a. Bounded a => a
maxBound Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len Bool -> Bool -> Bool
|| Int
cap Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
forall a. Bounded a => a
maxBound Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
before -> ProtocolError -> IO Accumulator
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO (String -> ProtocolError
ProtocolError String
"value length exceeds addressable memory")
| Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
cap -> do
ForeignPtr Word8 -> Int -> Int -> ByteString -> IO ()
copy ForeignPtr Word8
fp Int
cap Int
len ByteString
src
Accumulator -> IO Accumulator
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> [ByteString] -> Buffer -> Accumulator
Unknown Int
before [ByteString]
full (ForeignPtr Word8 -> Int -> Int -> Buffer
Buffer ForeignPtr Word8
fp Int
cap (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k)))
| Bool
otherwise -> do
let m :: Int
m = Int
cap Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len
size :: Int
size = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
m) (if Int
cap Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
65536 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
ahead) else Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
1048576 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
65536 (Int
before Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
cap)))
ForeignPtr Word8 -> Int -> Int -> ByteString -> IO ()
copy ForeignPtr Word8
fp Int
cap Int
len (Int -> ByteString -> ByteString
B.take Int
m ByteString
src)
fp' <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
BI.mallocByteString Int
size
copy fp' size 0 (B.drop m src)
let full' = if Int
cap Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then [ByteString]
full else ForeignPtr Word8 -> Int -> ByteString
BI.BS ForeignPtr Word8
fp Int
cap ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
full
pure (Unknown (before + cap) full' (Buffer fp' size (k - m)))
where k :: Int
k = ByteString -> Int
B.length ByteString
src
copy :: ForeignPtr Word8 -> Int -> Int -> B.ByteString -> IO ()
copy :: ForeignPtr Word8 -> Int -> Int -> ByteString -> IO ()
copy ForeignPtr Word8
dst Int
capacity Int
at (BI.BS ForeignPtr Word8
src Int
n)
| Int
at Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
at Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
capacity Bool -> Bool -> Bool
|| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
capacity Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
at = ProtocolError -> IO ()
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO (String -> ProtocolError
ProtocolError String
"value copy outside allocated buffer")
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
| Bool
otherwise = ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
BI.unsafeWithForeignPtr ForeignPtr Word8
dst ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
d -> ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
BI.unsafeWithForeignPtr ForeignPtr Word8
src ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
s ->
Ptr Word8 -> Ptr Word8 -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes (Ptr Word8
d Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
at) Ptr Word8
s Int
n
finish :: Accumulator -> IO B.ByteString
finish :: Accumulator -> IO ByteString
finish = \case
Known Int
_ Buffer
b -> ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> IO ByteString) -> ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$! Buffer -> ByteString
finishBuffer Buffer
b
Unknown Int
_ [] Buffer
b -> ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> IO ByteString) -> ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$! Buffer -> ByteString
finishBuffer Buffer
b
Unknown Int
_ [ByteString]
full (Buffer ForeignPtr Word8
fp Int
_ Int
len) -> ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> IO ByteString) -> ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$! [ByteString] -> ByteString
B.concat ([ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse (ForeignPtr Word8 -> Int -> ByteString
BI.BS ForeignPtr Word8
fp Int
len ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
full))
where
finishBuffer :: Buffer -> ByteString
finishBuffer (Buffer ForeignPtr Word8
fp Int
cap Int
len)
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = ByteString
B.empty
| Int
cap Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
16 (Int
len Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
16) = ForeignPtr Word8 -> Int -> ByteString
BI.BS ForeignPtr Word8
fp Int
len
| Bool
otherwise = ByteString -> ByteString
B.copy (ForeignPtr Word8 -> Int -> ByteString
BI.BS ForeignPtr Word8
fp Int
len)
parse :: Parser a -> B.ByteString -> Stream Await IO (Got a)
parse :: forall a. Parser a -> ByteString -> Stream Await IO (Got a)
parse Parser a
p ByteString
bs = case Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run Parser a
p ByteString
bs Int
0 of
Parsed a
a Int
pos -> Got a -> Stream Await IO (Got a)
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (a -> ByteString -> Got a
forall a. a -> ByteString -> Got a
Got a
a (ByteString -> Int -> ByteString
unread ByteString
bs Int
pos))
Suspended Stream Await IO (Outcome a)
s -> Stream Await IO (Outcome a) -> Stream Await IO (Got a)
forall a. Stream Await IO (Outcome a) -> Stream Await IO (Got a)
got Stream Await IO (Outcome a)
s
Failed ReadFailure
failure Int
_ -> ReadFailure -> Stream Await IO (Got a)
forall r. ReadFailure -> Stream Await IO r
uncaught ReadFailure
failure
runParser :: Parser a -> B.ByteString -> Either (Stream Await IO (Got a)) (Got a)
runParser :: forall a.
Parser a -> ByteString -> Either (Stream Await IO (Got a)) (Got a)
runParser Parser a
p ByteString
bytes = case Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run Parser a
p ByteString
bytes Int
0 of
Parsed a
value Int
pos -> Got a -> Either (Stream Await IO (Got a)) (Got a)
forall a b. b -> Either a b
Right (a -> ByteString -> Got a
forall a. a -> ByteString -> Got a
Got a
value (ByteString -> Int -> ByteString
unread ByteString
bytes Int
pos))
Suspended Stream Await IO (Outcome a)
continuation -> Stream Await IO (Got a) -> Either (Stream Await IO (Got a)) (Got a)
forall a b. a -> Either a b
Left (Stream Await IO (Outcome a) -> Stream Await IO (Got a)
forall a. Stream Await IO (Outcome a) -> Stream Await IO (Got a)
got Stream Await IO (Outcome a)
continuation)
Failed ReadFailure
failure Int
_ -> Stream Await IO (Got a) -> Either (Stream Await IO (Got a)) (Got a)
forall a b. a -> Either a b
Left (ReadFailure -> Stream Await IO (Got a)
forall r. ReadFailure -> Stream Await IO r
uncaught ReadFailure
failure)
{-# INLINE runParser #-}
runParserAt :: Parser a -> B.ByteString -> Int -> Either (Stream Await IO (Got (Either ReadFailure a))) (At a)
runParserAt :: forall a.
Parser a
-> ByteString
-> Int
-> Either (Stream Await IO (Got (Either ReadFailure a))) (At a)
runParserAt Parser a
p ByteString
bytes (I# Int#
pos) = let !box :: Int
box = Int# -> Int
boxPosition Int#
pos in case Parser a -> ByteString -> Int -> Result a
forall a. Parser a -> ByteString -> Int -> Result a
run Parser a
p ByteString
bytes Int
box of
Parsed a
value Int
end -> At a
-> Either (Stream Await IO (Got (Either ReadFailure a))) (At a)
forall a b. b -> Either a b
Right (a -> Int -> At a
forall a. a -> Int -> At a
At a
value Int
end)
Suspended Stream Await IO (Outcome a)
continuation -> Stream Await IO (Got (Either ReadFailure a))
-> Either (Stream Await IO (Got (Either ReadFailure a))) (At a)
forall a b. a -> Either a b
Left (Stream Await IO (Outcome a)
-> Stream Await IO (Got (Either ReadFailure a))
forall a.
Stream Await IO (Outcome a)
-> Stream Await IO (Got (Either ReadFailure a))
gotEither Stream Await IO (Outcome a)
continuation)
Failed ReadFailure
failure Int
end -> At a
-> Either (Stream Await IO (Got (Either ReadFailure a))) (At a)
forall a b. b -> Either a b
Right (ReadFailure -> Int -> At a
forall a. ReadFailure -> Int -> At a
FailedAt ReadFailure
failure Int
end)
{-# INLINE runParserAt #-}
got :: Stream Await IO (Outcome a) -> Stream Await IO (Got a)
got :: forall a. Stream Await IO (Outcome a) -> Stream Await IO (Got a)
got Stream Await IO (Outcome a)
s = Stream Await IO (Outcome a)
s Stream Await IO (Outcome a)
-> (Outcome a -> Stream Await IO (Got a))
-> Stream Await IO (Got a)
forall a b.
Stream Await IO a -> (a -> Stream Await IO b) -> Stream Await IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Done a
a ByteString
rest -> Got a -> Stream Await IO (Got a)
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (a -> ByteString -> Got a
forall a. a -> ByteString -> Got a
Got a
a ByteString
rest)
Stopped ReadFailure
failure ByteString
_ -> ReadFailure -> Stream Await IO (Got a)
forall r. ReadFailure -> Stream Await IO r
uncaught ReadFailure
failure
gotEither :: Stream Await IO (Outcome a) -> Stream Await IO (Got (Either ReadFailure a))
gotEither :: forall a.
Stream Await IO (Outcome a)
-> Stream Await IO (Got (Either ReadFailure a))
gotEither Stream Await IO (Outcome a)
s = Stream Await IO (Outcome a)
s Stream Await IO (Outcome a)
-> (Outcome a -> Stream Await IO (Got (Either ReadFailure a)))
-> Stream Await IO (Got (Either ReadFailure a))
forall a b.
Stream Await IO a -> (a -> Stream Await IO b) -> Stream Await IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Done a
a ByteString
rest -> Got (Either ReadFailure a)
-> Stream Await IO (Got (Either ReadFailure a))
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (Either ReadFailure a -> ByteString -> Got (Either ReadFailure a)
forall a. a -> ByteString -> Got a
Got (a -> Either ReadFailure a
forall a b. b -> Either a b
Right a
a) ByteString
rest)
Stopped ReadFailure
failure ByteString
rest -> Got (Either ReadFailure a)
-> Stream Await IO (Got (Either ReadFailure a))
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (Either ReadFailure a -> ByteString -> Got (Either ReadFailure a)
forall a. a -> ByteString -> Got a
Got (ReadFailure -> Either ReadFailure a
forall a b. a -> Either a b
Left ReadFailure
failure) ByteString
rest)
uncaught :: ReadFailure -> Stream Await IO r
uncaught :: forall r. ReadFailure -> Stream Await IO r
uncaught ReadFailure
failure = IO (Stream Await IO r) -> Stream Await IO r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (ProtocolError -> IO (Stream Await IO r)
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO (String -> ProtocolError
ProtocolError (String
"a failed value reached the driver: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ ReadFailure -> String
forall a. Show a => a -> String
show ReadFailure
failure)))
stream :: B.ByteString -> Result a -> Stream Await IO (Outcome a)
stream :: forall a. ByteString -> Result a -> Stream Await IO (Outcome a)
stream ByteString
bs (Parsed a
a Int
pos) = Outcome a -> Stream Await IO (Outcome a)
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (a -> ByteString -> Outcome a
forall a. a -> ByteString -> Outcome a
Done a
a (ByteString -> Int -> ByteString
unread ByteString
bs Int
pos))
stream ByteString
_ (Suspended Stream Await IO (Outcome a)
s) = Stream Await IO (Outcome a)
s
stream ByteString
bs (Failed ReadFailure
failure Int
pos) = Outcome a -> Stream Await IO (Outcome a)
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (ReadFailure -> ByteString -> Outcome a
forall a. ReadFailure -> ByteString -> Outcome a
Stopped ReadFailure
failure (ByteString -> Int -> ByteString
unread ByteString
bs Int
pos))
{-# INLINE stream #-}
outcomeRest :: Outcome a -> B.ByteString
outcomeRest :: forall a. Outcome a -> ByteString
outcomeRest (Done a
_ ByteString
rest) = ByteString
rest
outcomeRest (Stopped ReadFailure
_ ByteString
rest) = ByteString
rest
parseChunks :: Parser a -> [B.ByteString] -> IO (a, [B.ByteString])
parseChunks :: forall a. Parser a -> [ByteString] -> IO (a, [ByteString])
parseChunks Parser a
p [ByteString]
chunks = do
input <- [ByteString] -> IO (IORef [ByteString])
forall a. a -> IO (IORef a)
newIORef [ByteString]
chunks
let feed = IORef [ByteString]
-> ([ByteString] -> ([ByteString], Feed)) -> IO Feed
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef [ByteString]
input (([ByteString] -> ([ByteString], Feed)) -> IO Feed)
-> ([ByteString] -> ([ByteString], Feed)) -> IO Feed
forall a b. (a -> b) -> a -> b
$ \case
[] -> ([], Feed
EndOfMessage)
ByteString
c : [ByteString]
cs -> ([ByteString]
cs, ByteString -> Feed
More ByteString
c)
Got a rest <- runFrom feed p B.empty
later <- readIORef input
pure (a, if B.null rest then later else rest : later)
feedRunner :: IO Feed -> Runner
feedRunner :: IO Feed -> Runner
feedRunner IO Feed
feed = (forall a. IORef (Stream Await IO (Got a)) -> IO (Got a)) -> Runner
Runner ((forall a. IORef (Stream Await IO (Got a)) -> IO (Got a))
-> Runner)
-> (forall a. IORef (Stream Await IO (Got a)) -> IO (Got a))
-> Runner
forall a b. (a -> b) -> a -> b
$ \IORef (Stream Await IO (Got a))
current ->
let loop :: IO (Got a)
loop = IORef (Stream Await IO (Got a)) -> IO (Stream Await IO (Got a))
forall a. IORef a -> IO a
readIORef IORef (Stream Await IO (Got a))
current IO (Stream Await IO (Got a))
-> (Stream Await IO (Got a)
-> IO (Either (Got a) (Await (Stream Await IO (Got a)))))
-> IO (Either (Got a) (Await (Stream Await IO (Got a))))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Stream Await IO (Got a)
-> IO (Either (Got a) (Await (Stream Await IO (Got a))))
forall (m :: * -> *) (f :: * -> *) r.
Monad m =>
Stream f m r -> m (Either r (f (Stream f m r)))
inspect IO (Either (Got a) (Await (Stream Await IO (Got a))))
-> (Either (Got a) (Await (Stream Await IO (Got a))) -> IO (Got a))
-> IO (Got a)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left Got a
got -> IORef (Stream Await IO (Got a)) -> Stream Await IO (Got a) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Stream Await IO (Got a))
current (Got a -> Stream Await IO (Got a)
forall a. a -> Stream Await IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Got a
got) IO () -> IO (Got a) -> IO (Got a)
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Got a -> IO (Got a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Got a
got
Right await :: Await (Stream Await IO (Got a))
await@(NeedMore Feed -> Stream Await IO (Got a)
k) -> do
IORef (Stream Await IO (Got a)) -> Stream Await IO (Got a) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Stream Await IO (Got a))
current (Await (Stream Await IO (Got a)) -> Stream Await IO (Got a)
forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
f (Stream f m r) -> Stream f m r
S.wrap Await (Stream Await IO (Got a))
await)
next <- IO Feed
feed
writeIORef current (k next)
loop
Right RunConsumer{} -> do
let err :: ProtocolError
err = String -> ProtocolError
ProtocolError String
"a value recipe cannot invoke a nested consumer"
IORef (Stream Await IO (Got a)) -> Stream Await IO (Got a) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Stream Await IO (Got a))
current (IO (Stream Await IO (Got a)) -> Stream Await IO (Got a)
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (ProtocolError -> IO (Stream Await IO (Got a))
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO ProtocolError
err))
ProtocolError -> IO (Got a)
forall e a. (HasCallStack, Exception e) => e -> IO a
throwIO ProtocolError
err
in IO (Got a)
loop
runFrom :: IO Feed -> Parser a -> B.ByteString -> IO (Got a)
runFrom :: forall a. IO Feed -> Parser a -> ByteString -> IO (Got a)
runFrom IO Feed
feed Parser a
p ByteString
initial = do
current <- Stream Await IO (Got a) -> IO (IORef (Stream Await IO (Got a)))
forall a. a -> IO (IORef a)
newIORef (Parser a -> ByteString -> Stream Await IO (Got a)
forall a. Parser a -> ByteString -> Stream Await IO (Got a)
parse Parser a
p ByteString
initial)
let runner = IO Feed -> Runner
feedRunner IO Feed
feed
loop = IORef (Stream Await IO (Got a)) -> IO (Stream Await IO (Got a))
forall a. IORef a -> IO a
readIORef IORef (Stream Await IO (Got a))
current IO (Stream Await IO (Got a))
-> (Stream Await IO (Got a)
-> IO (Either (Got a) (Await (Stream Await IO (Got a)))))
-> IO (Either (Got a) (Await (Stream Await IO (Got a))))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Stream Await IO (Got a)
-> IO (Either (Got a) (Await (Stream Await IO (Got a))))
forall (m :: * -> *) (f :: * -> *) r.
Monad m =>
Stream f m r -> m (Either r (f (Stream f m r)))
inspect IO (Either (Got a) (Await (Stream Await IO (Got a))))
-> (Either (Got a) (Await (Stream Await IO (Got a))) -> IO (Got a))
-> IO (Got a)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left Got a
got -> IORef (Stream Await IO (Got a)) -> Stream Await IO (Got a) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Stream Await IO (Got a))
current (Got a -> Stream Await IO (Got a)
forall a. a -> Stream Await IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Got a
got) IO () -> IO (Got a) -> IO (Got a)
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Got a -> IO (Got a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Got a
got
Right await :: Await (Stream Await IO (Got a))
await@(NeedMore Feed -> Stream Await IO (Got a)
k) -> do
IORef (Stream Await IO (Got a)) -> Stream Await IO (Got a) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Stream Await IO (Got a))
current (Await (Stream Await IO (Got a)) -> Stream Await IO (Got a)
forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
f (Stream f m r) -> Stream f m r
S.wrap Await (Stream Await IO (Got a))
await)
next <- IO Feed
feed
writeIORef current (k next)
loop
Right await :: Await (Stream Await IO (Got a))
await@(RunConsumer Bool
_ Runner -> IO x
io Maybe x -> Stream Await IO (Got a)
k) -> do
IORef (Stream Await IO (Got a)) -> Stream Await IO (Got a) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Stream Await IO (Got a))
current (Await (Stream Await IO (Got a)) -> Stream Await IO (Got a)
forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
f (Stream f m r) -> Stream f m r
S.wrap Await (Stream Await IO (Got a))
await)
result <- Runner -> IO x
io Runner
runner
writeIORef current (k (Just result))
loop
loop
consume :: Stream (Of B.ByteString) Parser ()
-> (Stream (Of B.ByteString) IO () -> IO a) -> Parser (Maybe a)
consume :: forall a.
Stream (Of ByteString) (Recipe ()) ()
-> (Stream (Of ByteString) IO () -> IO a) -> Parser (Maybe a)
consume Stream (Of ByteString) (Recipe ()) ()
source Stream (Of ByteString) IO () -> IO a
use = (ByteString -> Int -> Result (Maybe a)) -> Parser (Maybe a)
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result (Maybe a)) -> Parser (Maybe a))
-> (ByteString -> Int -> Result (Maybe a)) -> Parser (Maybe a)
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos -> Stream Await IO (Outcome (Maybe a)) -> Result (Maybe a)
forall a. Stream Await IO (Outcome a) -> Result a
Suspended (Stream Await IO (Outcome (Maybe a)) -> Result (Maybe a))
-> Stream Await IO (Outcome (Maybe a)) -> Result (Maybe a)
forall a b. (a -> b) -> a -> b
$ IO (Stream Await IO (Outcome (Maybe a)))
-> Stream Await IO (Outcome (Maybe a))
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (IO (Stream Await IO (Outcome (Maybe a)))
-> Stream Await IO (Outcome (Maybe a)))
-> IO (Stream Await IO (Outcome (Maybe a)))
-> Stream Await IO (Outcome (Maybe a))
forall a b. (a -> b) -> a -> b
$ do
current <- Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ()))))
-> IO
(IORef
(Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ()))))))
forall a. a -> IO (IORef a)
newIORef (Parser
(Either () (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))
-> ByteString
-> Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ()))))
forall a. Parser a -> ByteString -> Stream Await IO (Got a)
parse (Stream (Of ByteString) (Recipe ()) ()
-> Parser
(Either () (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))
forall (m :: * -> *) (f :: * -> *) r.
Monad m =>
Stream f m r -> m (Either r (f (Stream f m r)))
S.inspect Stream (Of ByteString) (Recipe ()) ()
source) (ByteString -> Int -> ByteString
unread ByteString
bs Int
pos))
active <- newIORef (Just (0 :: Int))
let pull Runner
runner Int
generation = IO (Stream (Of ByteString) IO ()) -> Stream (Of ByteString) IO ()
forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
m (Stream f m r) -> Stream f m r
S.effect (IO (Stream (Of ByteString) IO ()) -> Stream (Of ByteString) IO ())
-> IO (Stream (Of ByteString) IO ())
-> Stream (Of ByteString) IO ()
forall a b. (a -> b) -> a -> b
$ IO (Stream (Of ByteString) IO ())
-> IO (Stream (Of ByteString) IO ())
forall a. IO a -> IO a
mask_ (IO (Stream (Of ByteString) IO ())
-> IO (Stream (Of ByteString) IO ()))
-> IO (Stream (Of ByteString) IO ())
-> IO (Stream (Of ByteString) IO ())
forall a b. (a -> b) -> a -> b
$ do
valid <- IORef (Maybe Int) -> (Maybe Int -> (Maybe Int, Bool)) -> IO Bool
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef (Maybe Int)
active ((Maybe Int -> (Maybe Int, Bool)) -> IO Bool)
-> (Maybe Int -> (Maybe Int, Bool)) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Maybe Int
state -> case Maybe Int
state of
Just Int
n | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
generation -> (Int -> Maybe Int
forall a. a -> Maybe a
Just (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1), Bool
True)
Maybe Int
_ -> (Maybe Int
state, Bool
False)
unless valid (throwIO ResultAbandoned)
Got step rest <- runAwait runner current
case step of
Left () -> Stream (Of ByteString) IO () -> IO (Stream (Of ByteString) IO ())
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (() -> Stream (Of ByteString) IO ()
forall a. a -> Stream (Of ByteString) IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
Right (ByteString
chunk :> Stream (Of ByteString) (Recipe ()) ()
next) -> do
IORef
(Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))))
-> Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ()))))
-> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef
(Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))))
current (Parser
(Either () (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))
-> ByteString
-> Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ()))))
forall a. Parser a -> ByteString -> Stream Await IO (Got a)
parse (Stream (Of ByteString) (Recipe ()) ()
-> Parser
(Either () (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))
forall (m :: * -> *) (f :: * -> *) r.
Monad m =>
Stream f m r -> m (Either r (f (Stream f m r)))
S.inspect Stream (Of ByteString) (Recipe ()) ()
next) ByteString
rest)
Stream (Of ByteString) IO () -> IO (Stream (Of ByteString) IO ())
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Stream (Of ByteString) IO ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield (ByteString -> ByteString
B.copy ByteString
chunk) Stream (Of ByteString) IO ()
-> Stream (Of ByteString) IO () -> Stream (Of ByteString) IO ()
forall a b.
Stream (Of ByteString) IO a
-> Stream (Of ByteString) IO b -> Stream (Of ByteString) IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Runner -> Int -> Stream (Of ByteString) IO ()
pull Runner
runner (Int
generation Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
finishConsumer t
result = IO (Stream Await IO (Outcome t)) -> Stream Await IO (Outcome t)
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (IO (Stream Await IO (Outcome t)) -> Stream Await IO (Outcome t))
-> IO (Stream Await IO (Outcome t)) -> Stream Await IO (Outcome t)
forall a b. (a -> b) -> a -> b
$ do
remaining <- IORef
(Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))))
-> IO
(Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))))
forall a. IORef a -> IO a
readIORef IORef
(Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))))
current
pure (drain remaining result)
drain Stream
Await IO (Got (Either () (Of a (Stream (Of a) (Recipe ()) ()))))
remaining t
result = Stream
Await IO (Got (Either () (Of a (Stream (Of a) (Recipe ()) ()))))
remaining Stream
Await IO (Got (Either () (Of a (Stream (Of a) (Recipe ()) ()))))
-> (Got (Either () (Of a (Stream (Of a) (Recipe ()) ())))
-> Stream Await IO (Outcome t))
-> Stream Await IO (Outcome t)
forall a b.
Stream Await IO a -> (a -> Stream Await IO b) -> Stream Await IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(Got Either () (Of a (Stream (Of a) (Recipe ()) ()))
step ByteString
rest) -> case Either () (Of a (Stream (Of a) (Recipe ()) ()))
step of
Left () -> IO (Stream Await IO (Outcome t)) -> Stream Await IO (Outcome t)
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (IO (Stream Await IO (Outcome t)) -> Stream Await IO (Outcome t))
-> IO (Stream Await IO (Outcome t)) -> Stream Await IO (Outcome t)
forall a b. (a -> b) -> a -> b
$ do
IORef
(Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))))
-> Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ()))))
-> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef
(Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))))
current (Got
(Either () (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))
-> Stream
Await
IO
(Got
(Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ()))))
forall a. a -> Stream Await IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either () (Of ByteString (Stream (Of ByteString) (Recipe ()) ()))
-> ByteString
-> Got
(Either () (Of ByteString (Stream (Of ByteString) (Recipe ()) ())))
forall a. a -> ByteString -> Got a
Got (()
-> Either
() (Of ByteString (Stream (Of ByteString) (Recipe ()) ()))
forall a b. a -> Either a b
Left ()) ByteString
B.empty))
Stream Await IO (Outcome t) -> IO (Stream Await IO (Outcome t))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Outcome t -> Stream Await IO (Outcome t)
forall a. a -> Stream Await IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (t -> ByteString -> Outcome t
forall a. a -> ByteString -> Outcome a
Done t
result ByteString
rest))
Right (a
_ :> Stream (Of a) (Recipe ()) ()
next) -> Stream
Await IO (Got (Either () (Of a (Stream (Of a) (Recipe ()) ()))))
-> t -> Stream Await IO (Outcome t)
drain (Parser (Either () (Of a (Stream (Of a) (Recipe ()) ())))
-> ByteString
-> Stream
Await IO (Got (Either () (Of a (Stream (Of a) (Recipe ()) ()))))
forall a. Parser a -> ByteString -> Stream Await IO (Got a)
parse (Stream (Of a) (Recipe ()) ()
-> Parser (Either () (Of a (Stream (Of a) (Recipe ()) ())))
forall (m :: * -> *) (f :: * -> *) r.
Monad m =>
Stream f m r -> m (Either r (f (Stream f m r)))
S.inspect Stream (Of a) (Recipe ()) ()
next) ByteString
rest) t
result
pure $ Step $ RunConsumer True (\Runner
runner -> Stream (Of ByteString) IO () -> IO a
use (Runner -> Int -> Stream (Of ByteString) IO ()
pull Runner
runner Int
0) IO a -> IO () -> IO a
forall a b. IO a -> IO b -> IO a
`finally` IORef (Maybe Int) -> Maybe Int -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe Int)
active Maybe Int
forall a. Maybe a
Nothing) finishConsumer
consumeWhole :: B.ByteString -> (Stream (Of B.ByteString) IO () -> IO a) -> Parser (Maybe a)
consumeWhole :: forall a.
ByteString
-> (Stream (Of ByteString) IO () -> IO a) -> Parser (Maybe a)
consumeWhole ByteString
bytes Stream (Of ByteString) IO () -> IO a
use = (ByteString -> Int -> Result (Maybe a)) -> Parser (Maybe a)
forall a. (ByteString -> Int -> Result a) -> Parser a
parser ((ByteString -> Int -> Result (Maybe a)) -> Parser (Maybe a))
-> (ByteString -> Int -> Result (Maybe a)) -> Parser (Maybe a)
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Int
pos ->
Stream Await IO (Outcome (Maybe a)) -> Result (Maybe a)
forall a. Stream Await IO (Outcome a) -> Result a
Suspended (Stream Await IO (Outcome (Maybe a)) -> Result (Maybe a))
-> Stream Await IO (Outcome (Maybe a)) -> Result (Maybe a)
forall a b. (a -> b) -> a -> b
$ Await (Stream Await IO (Outcome (Maybe a)))
-> Stream Await IO (Outcome (Maybe a))
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (Await (Stream Await IO (Outcome (Maybe a)))
-> Stream Await IO (Outcome (Maybe a)))
-> Await (Stream Await IO (Outcome (Maybe a)))
-> Stream Await IO (Outcome (Maybe a))
forall a b. (a -> b) -> a -> b
$ Bool
-> (Runner -> IO a)
-> (Maybe a -> Stream Await IO (Outcome (Maybe a)))
-> Await (Stream Await IO (Outcome (Maybe a)))
forall next x.
Bool -> (Runner -> IO x) -> (Maybe x -> next) -> Await next
RunConsumer Bool
False Runner -> IO a
forall {p}. p -> IO a
start (\Maybe a
result -> Outcome (Maybe a) -> Stream Await IO (Outcome (Maybe a))
forall a. a -> Stream Await IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe a -> ByteString -> Outcome (Maybe a)
forall a. a -> ByteString -> Outcome a
Done Maybe a
result (ByteString -> Int -> ByteString
unread ByteString
bs Int
pos)))
where
start :: p -> IO a
start p
_ = do
active <- Bool -> IO (IORef Bool)
forall a. a -> IO (IORef a)
newIORef Bool
True
let once = IO (Stream (Of ByteString) IO ()) -> Stream (Of ByteString) IO ()
forall (m :: * -> *) (f :: * -> *) r.
(Monad m, Functor f) =>
m (Stream f m r) -> Stream f m r
S.effect (IO (Stream (Of ByteString) IO ()) -> Stream (Of ByteString) IO ())
-> IO (Stream (Of ByteString) IO ())
-> Stream (Of ByteString) IO ()
forall a b. (a -> b) -> a -> b
$ do
valid <- IORef Bool -> (Bool -> (Bool, Bool)) -> IO Bool
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef Bool
active (\Bool
v -> (Bool
False, Bool
v))
unless valid (throwIO ResultAbandoned)
pure (if B.null bytes then pure () else S.yield bytes)
use once `finally` writeIORef active False
data ReadFailure
= DecodeFailed !DecodeError
| ReadDiscarded
instance Show ReadFailure where
showsPrec :: Int -> ReadFailure -> String -> String
showsPrec Int
p = \case
DecodeFailed DecodeError
a -> Int -> Addr# -> DecodeError -> String -> String
forall a. Show a => Int -> Addr# -> a -> String -> String
showCon1 Int
p Addr#
"DecodeFailed"# DecodeError
a
ReadFailure
ReadDiscarded -> String -> String -> String
showString String
"ReadDiscarded"
{-# OPAQUE showsPrec #-}
data DecodeError = DecodeError
{ DecodeError -> Maybe Text
decodeErrorColumn :: !(Maybe Text)
, DecodeError -> String
decodeErrorMessage :: !String
}
instance Show DecodeError where
showsPrec :: Int -> DecodeError -> String -> String
showsPrec Int
p (DecodeError Maybe Text
a String
b) =
Int -> Addr# -> [Field] -> String -> String
showRecord Int
p Addr#
"DecodeError"# [Addr#
"decodeErrorColumn"# Addr# -> Maybe Text -> Field
forall a. Show a => Addr# -> a -> Field
:= Maybe Text
a, Addr#
"decodeErrorMessage"# Addr# -> String -> Field
forall a. Show a => Addr# -> a -> Field
:= String
b]
{-# OPAQUE showsPrec #-}
instance Eq DecodeError where
DecodeError Maybe Text
a String
b == :: DecodeError -> DecodeError -> Bool
== DecodeError Maybe Text
a' String
b' = Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
eq Maybe Text
a Maybe Text
a' Bool -> Bool -> Bool
&& String -> String -> Bool
forall a. Eq a => a -> a -> Bool
eq String
b String
b'
{-# OPAQUE (==) #-}
instance Exception DecodeError
newtype ProtocolError = ProtocolError String
instance Show ProtocolError where
showsPrec :: Int -> ProtocolError -> String -> String
showsPrec Int
p (ProtocolError String
a) = Int -> Addr# -> String -> String -> String
forall a. Show a => Int -> Addr# -> a -> String -> String
showCon1 Int
p Addr#
"ProtocolError"# String
a
{-# OPAQUE showsPrec #-}
instance Exception ProtocolError
data ResultAbandoned = ResultAbandoned
deriving stock (Int -> ResultAbandoned -> String -> String
[ResultAbandoned] -> String -> String
ResultAbandoned -> String
(Int -> ResultAbandoned -> String -> String)
-> (ResultAbandoned -> String)
-> ([ResultAbandoned] -> String -> String)
-> Show ResultAbandoned
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> ResultAbandoned -> String -> String
showsPrec :: Int -> ResultAbandoned -> String -> String
$cshow :: ResultAbandoned -> String
show :: ResultAbandoned -> String
$cshowList :: [ResultAbandoned] -> String -> String
showList :: [ResultAbandoned] -> String -> String
Show)
instance Exception ResultAbandoned