module Ptr.Parse where
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Short.Internal as E
import qualified Ptr.IO as D
import qualified Ptr.PokeAndPeek as A
import Ptr.Prelude hiding (peek, take)
import qualified Ptr.Prelude as C
newtype Parse output
= Parse (Int -> Ptr Word8 -> forall result. (Int -> IO result) -> (Text -> IO result) -> (output -> Int -> Ptr Word8 -> IO result) -> IO result)
deriving instance Functor Parse
instance Applicative Parse where
pure :: forall a. a -> Parse a
pure a
x =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse (\Int
availableAmount Ptr Word8
ptr Int -> IO result
_ Text -> IO result
_ a -> Int -> Ptr Word8 -> IO result
succeed -> a -> Int -> Ptr Word8 -> IO result
succeed a
x Int
availableAmount Ptr Word8
ptr)
{-# INLINE (<*>) #-}
<*> :: forall a b. Parse (a -> b) -> Parse a -> Parse b
(<*>) (Parse Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> ((a -> b) -> Int -> Ptr Word8 -> IO result)
-> IO result
left) (Parse Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (a -> Int -> Ptr Word8 -> IO result)
-> IO result
right) =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage b -> Int -> Ptr Word8 -> IO result
succeed ->
Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> ((a -> b) -> Int -> Ptr Word8 -> IO result)
-> IO result
left Int
availableAmount Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage forall a b. (a -> b) -> a -> b
$ \a -> b
leftOutput !Int
leftAvailableAmount !Ptr Word8
leftPtr ->
Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (a -> Int -> Ptr Word8 -> IO result)
-> IO result
right Int
leftAvailableAmount Ptr Word8
leftPtr Int -> IO result
failWithEOI Text -> IO result
failWithMessage forall a b. (a -> b) -> a -> b
$ \a
rightOutput !Int
rightAvailableAmount !Ptr Word8
rightPtr ->
b -> Int -> Ptr Word8 -> IO result
succeed (a -> b
leftOutput a
rightOutput) Int
rightAvailableAmount Ptr Word8
rightPtr
instance Alternative Parse where
empty :: forall a. Parse a
empty =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse (\Int
_ Ptr Word8
_ Int -> IO result
failWithEOI Text -> IO result
_ a -> Int -> Ptr Word8 -> IO result
_ -> Int -> IO result
failWithEOI Int
0)
{-# INLINE (<|>) #-}
<|> :: forall a. Parse a -> Parse a -> Parse a
(<|>) (Parse Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (a -> Int -> Ptr Word8 -> IO result)
-> IO result
left) (Parse Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (a -> Int -> Ptr Word8 -> IO result)
-> IO result
right) =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage a -> Int -> Ptr Word8 -> IO result
succeed ->
Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (a -> Int -> Ptr Word8 -> IO result)
-> IO result
left
Int
availableAmount
Ptr Word8
ptr
(\Int
_ -> Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (a -> Int -> Ptr Word8 -> IO result)
-> IO result
right Int
availableAmount Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage a -> Int -> Ptr Word8 -> IO result
succeed)
Text -> IO result
failWithMessage
a -> Int -> Ptr Word8 -> IO result
succeed
instance Monad Parse where
return :: forall a. a -> Parse a
return = forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE (>>=) #-}
>>= :: forall a b. Parse a -> (a -> Parse b) -> Parse b
(>>=) (Parse Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (a -> Int -> Ptr Word8 -> IO result)
-> IO result
left) a -> Parse b
rightK =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage b -> Int -> Ptr Word8 -> IO result
succeed ->
Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (a -> Int -> Ptr Word8 -> IO result)
-> IO result
left Int
availableAmount Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage forall a b. (a -> b) -> a -> b
$ \a
leftOutput !Int
leftAvailableAmount !Ptr Word8
leftPtr ->
case a -> Parse b
rightK a
leftOutput of
Parse Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (b -> Int -> Ptr Word8 -> IO result)
-> IO result
right ->
Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (b -> Int -> Ptr Word8 -> IO result)
-> IO result
right Int
leftAvailableAmount Ptr Word8
leftPtr Int -> IO result
failWithEOI Text -> IO result
failWithMessage b -> Int -> Ptr Word8 -> IO result
succeed
instance MonadPlus Parse where
mzero :: forall a. Parse a
mzero = forall (f :: * -> *) a. Alternative f => f a
empty
mplus :: forall a. Parse a -> Parse a -> Parse a
mplus = forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)
instance MonadIO Parse where
{-# INLINE liftIO #-}
liftIO :: forall a. IO a -> Parse a
liftIO IO a
io =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \Int
availableAmount Ptr Word8
ptr Int -> IO result
_ Text -> IO result
_ a -> Int -> Ptr Word8 -> IO result
succeed -> IO a
io forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
output -> a -> Int -> Ptr Word8 -> IO result
succeed a
output Int
availableAmount Ptr Word8
ptr
{-# INLINE fail #-}
fail :: Text -> Parse output
fail :: forall output. Text -> Parse output
fail Text
message =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \Int
_ Ptr Word8
_ Int -> IO result
_ Text -> IO result
failWithMessage output -> Int -> Ptr Word8 -> IO result
_ -> Text -> IO result
failWithMessage Text
message
{-# INLINE io #-}
io :: Int -> (Ptr Word8 -> IO output) -> Parse output
io :: forall output. Int -> (Ptr Word8 -> IO output) -> Parse output
io !Int
requiredAmount Ptr Word8 -> IO output
ptrIO =
{-# SCC "io" #-}
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage output -> Int -> Ptr Word8 -> IO result
succeed ->
if Int
availableAmount forall a. Ord a => a -> a -> Bool
>= Int
requiredAmount
then do
!output
result <- Ptr Word8 -> IO output
ptrIO Ptr Word8
ptr
output -> Int -> Ptr Word8 -> IO result
succeed output
result (Int
availableAmount forall a. Num a => a -> a -> a
- Int
requiredAmount) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
requiredAmount)
else Int -> IO result
failWithEOI (Int
requiredAmount forall a. Num a => a -> a -> a
- Int
availableAmount)
{-# INLINE mapInIO #-}
mapInIO :: (output -> IO newOutput) -> Parse output -> Parse newOutput
mapInIO :: forall output newOutput.
(output -> IO newOutput) -> Parse output -> Parse newOutput
mapInIO output -> IO newOutput
io (Parse Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result
parseIO) =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage newOutput -> Int -> Ptr Word8 -> IO result
succeed ->
Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result
parseIO
Int
availableAmount
Ptr Word8
ptr
Int -> IO result
failWithEOI
Text -> IO result
failWithMessage
(\output
output Int
newAvailableAmount Ptr Word8
newPtr -> output -> IO newOutput
io output
output forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \newOutput
newOutput -> newOutput -> Int -> Ptr Word8 -> IO result
succeed newOutput
newOutput Int
newAvailableAmount Ptr Word8
newPtr)
{-# INLINE pokeAndPeek #-}
pokeAndPeek :: A.PokeAndPeek input output -> Parse output
pokeAndPeek :: forall input output. PokeAndPeek input output -> Parse output
pokeAndPeek (A.PokeAndPeek Int
requiredAmount Ptr Word8 -> input -> IO ()
_ Ptr Word8 -> IO output
ptrIO) =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage output -> Int -> Ptr Word8 -> IO result
succeed ->
if Int
availableAmount forall a. Ord a => a -> a -> Bool
>= Int
requiredAmount
then do
!output
result <- Ptr Word8 -> IO output
ptrIO Ptr Word8
ptr
output -> Int -> Ptr Word8 -> IO result
succeed output
result (Int
availableAmount forall a. Num a => a -> a -> a
- Int
requiredAmount) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
requiredAmount)
else Int -> IO result
failWithEOI (Int
requiredAmount forall a. Num a => a -> a -> a
- Int
availableAmount)
{-# INLINE limiting #-}
limiting :: Int -> Parse output -> Parse output
limiting :: forall output. Int -> Parse output -> Parse output
limiting Int
limitAmount (Parse Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result
io) =
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage output -> Int -> Ptr Word8 -> IO result
succeed ->
if Int
availableAmount forall a. Ord a => a -> a -> Bool
>= Int
limitAmount
then Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result
io Int
limitAmount Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage output -> Int -> Ptr Word8 -> IO result
succeed
else Int -> IO result
failWithEOI (Int
limitAmount forall a. Num a => a -> a -> a
- Int
availableAmount)
{-# INLINE peekRemainders #-}
peekRemainders :: Parse ByteString
peekRemainders :: Parse ByteString
peekRemainders =
{-# SCC "peekRemainders" #-}
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage ByteString -> Int -> Ptr Word8 -> IO result
succeed -> do
!ByteString
bytes <- Ptr Word8 -> Int -> IO ByteString
D.peekBytes Ptr Word8
ptr Int
availableAmount
ByteString -> Int -> Ptr Word8 -> IO result
succeed ByteString
bytes Int
availableAmount Ptr Word8
ptr
{-# INLINE word8 #-}
word8 :: Parse Word8
word8 :: Parse Word8
word8 =
{-# SCC "word8" #-}
forall output. Int -> (Ptr Word8 -> IO output) -> Parse output
io Int
1 Ptr Word8 -> IO Word8
D.peekWord8
{-# INLINE beWord16 #-}
beWord16 :: Parse Word16
beWord16 :: Parse Word16
beWord16 =
{-# SCC "beWord16" #-}
forall output. Int -> (Ptr Word8 -> IO output) -> Parse output
io Int
2 Ptr Word8 -> IO Word16
D.peekBEWord16
{-# INLINE beWord32 #-}
beWord32 :: Parse Word32
beWord32 :: Parse Word32
beWord32 =
{-# SCC "beWord32" #-}
forall output. Int -> (Ptr Word8 -> IO output) -> Parse output
io Int
4 Ptr Word8 -> IO Word32
D.peekBEWord32
{-# INLINE beWord64 #-}
beWord64 :: Parse Word64
beWord64 :: Parse Word64
beWord64 =
{-# SCC "beWord64" #-}
forall output. Int -> (Ptr Word8 -> IO output) -> Parse output
io Int
8 Ptr Word8 -> IO Word64
D.peekBEWord64
{-# INLINE bytes #-}
bytes :: Int -> Parse ByteString
bytes :: Int -> Parse ByteString
bytes Int
amount =
{-# SCC "bytes" #-}
forall output. Int -> (Ptr Word8 -> IO output) -> Parse output
io Int
amount (\Ptr Word8
ptr -> Ptr Word8 -> Int -> IO ByteString
D.peekBytes Ptr Word8
ptr Int
amount)
{-# INLINE allBytes #-}
allBytes :: Parse ByteString
allBytes :: Parse ByteString
allBytes =
{-# SCC "allBytes" #-}
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage ByteString -> Int -> Ptr Word8 -> IO result
succeed -> do
!ByteString
bytes <- Ptr Word8 -> Int -> IO ByteString
D.peekBytes Ptr Word8
ptr Int
availableAmount
ByteString -> Int -> Ptr Word8 -> IO result
succeed ByteString
bytes Int
0 (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
availableAmount)
{-# INLINE nullTerminatedBytes #-}
nullTerminatedBytes :: Parse ByteString
nullTerminatedBytes :: Parse ByteString
nullTerminatedBytes =
{-# SCC "nullTerminatedBytes" #-}
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage ByteString -> Int -> Ptr Word8 -> IO result
succeed -> do
!ByteString
bytes <- CString -> IO ByteString
B.packCString (forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
ptr)
case forall a. Enum a => a -> a
succ (ByteString -> Int
B.length ByteString
bytes) of
Int
consumedAmount ->
if Int
consumedAmount forall a. Ord a => a -> a -> Bool
<= Int
availableAmount
then ByteString -> Int -> Ptr Word8 -> IO result
succeed ByteString
bytes (Int
availableAmount forall a. Num a => a -> a -> a
- Int
consumedAmount) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
consumedAmount)
else Int -> IO result
failWithEOI (Int
consumedAmount forall a. Num a => a -> a -> a
- Int
availableAmount)
{-# INLINE nullTerminatedShortByteString #-}
nullTerminatedShortByteString :: Parse ShortByteString
nullTerminatedShortByteString :: Parse ShortByteString
nullTerminatedShortByteString =
{-# SCC "nullTerminatedShortByteString" #-}
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage ShortByteString -> Int -> Ptr Word8 -> IO result
succeed ->
forall a. Ptr Word8 -> (Int -> IO ShortByteString -> IO a) -> IO a
D.peekNullTerminatedShortByteString Ptr Word8
ptr forall a b. (a -> b) -> a -> b
$ \Int
length IO ShortByteString
create ->
if Int
length forall a. Ord a => a -> a -> Bool
<= Int
availableAmount
then do
!ShortByteString
result <- IO ShortByteString
create
ShortByteString -> Int -> Ptr Word8 -> IO result
succeed ShortByteString
result (Int
availableAmount forall a. Num a => a -> a -> a
- Int
length) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
length)
else Int -> IO result
failWithEOI (Int
length forall a. Num a => a -> a -> a
- Int
availableAmount)
{-# INLINE bytesWhile #-}
bytesWhile :: (Word8 -> Bool) -> Parse ByteString
bytesWhile :: (Word8 -> Bool) -> Parse ByteString
bytesWhile Word8 -> Bool
predicate =
{-# SCC "bytesWhile" #-}
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage ByteString -> Int -> Ptr Word8 -> IO result
succeed ->
let iterate :: Int -> Int -> Ptr Word8 -> IO result
iterate !Int
availableAmount !Int
unconsumedAmount !Ptr Word8
currentPtr =
if Int
unconsumedAmount forall a. Ord a => a -> a -> Bool
> Int
0
then do
Word8
byte <- forall a. Storable a => Ptr a -> IO a
C.peek Ptr Word8
currentPtr
if Word8 -> Bool
predicate Word8
byte
then Int -> Int -> Ptr Word8 -> IO result
iterate Int
availableAmount (forall a. Enum a => a -> a
pred Int
unconsumedAmount) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
currentPtr Int
1)
else do
ByteString
bytes <- CStringLen -> IO ByteString
B.packCStringLen (forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
ptr, Int
availableAmount forall a. Num a => a -> a -> a
- Int
unconsumedAmount)
ByteString -> Int -> Ptr Word8 -> IO result
succeed ByteString
bytes Int
unconsumedAmount Ptr Word8
currentPtr
else do
ByteString
bytes <- CStringLen -> IO ByteString
B.packCStringLen (forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
ptr, Int
availableAmount forall a. Num a => a -> a -> a
- Int
unconsumedAmount)
ByteString -> Int -> Ptr Word8 -> IO result
succeed ByteString
bytes Int
unconsumedAmount Ptr Word8
currentPtr
in Int -> Int -> Ptr Word8 -> IO result
iterate Int
availableAmount Int
availableAmount Ptr Word8
ptr
{-# INLINE skipWhile #-}
skipWhile :: (Word8 -> Bool) -> Parse ()
skipWhile :: (Word8 -> Bool) -> Parse ()
skipWhile Word8 -> Bool
predicate =
{-# SCC "skipWhile" #-}
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage () -> Int -> Ptr Word8 -> IO result
succeed ->
let iterate :: Int -> Int -> Ptr Word8 -> IO result
iterate !Int
availableAmount !Int
unconsumedAmount !Ptr Word8
ptr =
if Int
unconsumedAmount forall a. Ord a => a -> a -> Bool
> Int
0
then do
Word8
byte <- forall a. Storable a => Ptr a -> IO a
C.peek Ptr Word8
ptr
if Word8 -> Bool
predicate Word8
byte
then Int -> Int -> Ptr Word8 -> IO result
iterate Int
availableAmount (forall a. Enum a => a -> a
pred Int
unconsumedAmount) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
1)
else () -> Int -> Ptr Word8 -> IO result
succeed () Int
unconsumedAmount Ptr Word8
ptr
else () -> Int -> Ptr Word8 -> IO result
succeed () Int
unconsumedAmount Ptr Word8
ptr
in Int -> Int -> Ptr Word8 -> IO result
iterate Int
availableAmount Int
availableAmount Ptr Word8
ptr
{-# INLINE foldWhile #-}
foldWhile :: (Word8 -> Bool) -> (state -> Word8 -> state) -> state -> Parse state
foldWhile :: forall state.
(Word8 -> Bool)
-> (state -> Word8 -> state) -> state -> Parse state
foldWhile Word8 -> Bool
predicate state -> Word8 -> state
step state
start =
{-# SCC "foldWhile" #-}
forall output.
(Int
-> Ptr Word8
-> forall result.
(Int -> IO result)
-> (Text -> IO result)
-> (output -> Int -> Ptr Word8 -> IO result)
-> IO result)
-> Parse output
Parse forall a b. (a -> b) -> a -> b
$ \ !Int
availableAmount !Ptr Word8
ptr Int -> IO result
failWithEOI Text -> IO result
failWithMessage state -> Int -> Ptr Word8 -> IO result
succeed ->
let iterate :: state -> Int -> Ptr Word8 -> IO result
iterate !state
state !Int
unconsumedAmount !Ptr Word8
ptr =
if Int
unconsumedAmount forall a. Ord a => a -> a -> Bool
> Int
0
then do
Word8
byte <- forall a. Storable a => Ptr a -> IO a
C.peek Ptr Word8
ptr
if Word8 -> Bool
predicate Word8
byte
then state -> Int -> Ptr Word8 -> IO result
iterate (state -> Word8 -> state
step state
state Word8
byte) (forall a. Enum a => a -> a
pred Int
unconsumedAmount) (forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
1)
else state -> Int -> Ptr Word8 -> IO result
succeed state
state Int
unconsumedAmount Ptr Word8
ptr
else Int -> IO result
failWithEOI Int
0
in state -> Int -> Ptr Word8 -> IO result
iterate state
start Int
availableAmount Ptr Word8
ptr
{-# INLINE unsignedASCIIIntegral #-}
unsignedASCIIIntegral :: Integral a => Parse a
unsignedASCIIIntegral :: forall a. Integral a => Parse a
unsignedASCIIIntegral =
{-# SCC "unsignedASCIIIntegral" #-}
forall state.
(Word8 -> Bool)
-> (state -> Word8 -> state) -> state -> Parse state
foldWhile forall {a}. (Ord a, Num a) => a -> Bool
byteIsDigit forall {a} {a}. (Integral a, Num a) => a -> a -> a
step a
0
where
byteIsDigit :: a -> Bool
byteIsDigit a
byte =
a
byte forall a. Num a => a -> a -> a
- a
48 forall a. Ord a => a -> a -> Bool
<= a
9
step :: a -> a -> a
step !a
state !a
byte =
a
state forall a. Num a => a -> a -> a
* a
10 forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral a
byte forall a. Num a => a -> a -> a
- a
48