-- |
-- Module      : Data.ByteArray.Parse
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : portable
--
-- A very simple bytearray parser related to Parsec and Attoparsec
--
-- Simple example:
--
-- > > parse ((,,) <$> take 2 <*> byte 0x20 <*> (bytes "abc" *> anyByte)) "xx abctest"
-- > ParseOK "est" ("xx", 116)
--
{-# LANGUAGE CPP #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.ByteArray.Parse
    ( Parser
    , Result(..)
    -- * run the Parser
    , parse
    , parseFeed
    -- * Parser methods
    , hasMore
    , byte
    , anyByte
    , bytes
    , take
    , takeWhile
    , takeAll
    , skip
    , skipWhile
    , skipAll
    , takeStorable
    ) where

import           Control.Monad
import qualified Control.Monad.Fail as Fail
import           Foreign.Storable              (Storable, peek, sizeOf)
import           Data.Word

import           Data.Memory.Internal.Imports
import           Data.Memory.Internal.Compat
import           Data.ByteArray.Types          (ByteArrayAccess, ByteArray)
import qualified Data.ByteArray.Types     as B
import qualified Data.ByteArray.Methods   as B

import           Prelude hiding (take, takeWhile)

-- | Simple parsing result, that represent respectively:
--
-- * failure: with the error message
--
-- * continuation: that need for more input data
--
-- * success: the remaining unparsed data and the parser value
data Result byteArray a =
      ParseFail String
    | ParseMore (Maybe byteArray -> Result byteArray a)
    | ParseOK   byteArray a

instance (Show ba, Show a) => Show (Result ba a) where
    show :: Result ba a -> String
show (ParseFail String
err) = String
"ParseFailure: " forall a. [a] -> [a] -> [a]
++ String
err
    show (ParseMore Maybe ba -> Result ba a
_)   = String
"ParseMore _"
    show (ParseOK ba
b a
a)   = String
"ParseOK " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
a forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ba
b

-- | The continuation of the current buffer, and the error string
type Failure byteArray r = byteArray -> String -> Result byteArray r

-- | The continuation of the next buffer value, and the parsed value
type Success byteArray a r = byteArray -> a -> Result byteArray r

-- | Simple ByteString parser structure
newtype Parser byteArray a = Parser
    { forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser :: forall r . byteArray
                           -> Failure byteArray r
                           -> Success byteArray a r
                           -> Result byteArray r }

instance Functor (Parser byteArray) where
    fmap :: forall a b. (a -> b) -> Parser byteArray a -> Parser byteArray b
fmap a -> b
f Parser byteArray a
p = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray b r
ok ->
        forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser Parser byteArray a
p byteArray
buf Failure byteArray r
err (\byteArray
b a
a -> Success byteArray b r
ok byteArray
b (a -> b
f a
a))
instance Applicative (Parser byteArray) where
    pure :: forall a. a -> Parser byteArray a
pure a
v    = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
_ Success byteArray a r
ok -> Success byteArray a r
ok byteArray
buf a
v
    <*> :: forall a b.
Parser byteArray (a -> b)
-> Parser byteArray a -> Parser byteArray b
(<*>) Parser byteArray (a -> b)
d Parser byteArray a
e = Parser byteArray (a -> b)
d forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a -> b
b -> Parser byteArray a
e forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
a -> forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b
b a
a)
instance Monad (Parser byteArray) where
#if !(MIN_VERSION_base(4,13,0))
    fail          = Fail.fail
#endif
    return :: forall a. a -> Parser byteArray a
return        = forall (f :: * -> *) a. Applicative f => a -> f a
pure
    Parser byteArray a
m >>= :: forall a b.
Parser byteArray a
-> (a -> Parser byteArray b) -> Parser byteArray b
>>= a -> Parser byteArray b
k       = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray b r
ok ->
         forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser Parser byteArray a
m byteArray
buf Failure byteArray r
err (\byteArray
buf' a
a -> forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser (a -> Parser byteArray b
k a
a) byteArray
buf' Failure byteArray r
err Success byteArray b r
ok)
instance Fail.MonadFail (Parser byteArray) where
    fail :: forall a. String -> Parser byteArray a
fail String
errorMsg = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray a r
_ -> Failure byteArray r
err byteArray
buf (String
"Parser failed: " forall a. [a] -> [a] -> [a]
++ String
errorMsg)
instance MonadPlus (Parser byteArray) where
    mzero :: forall a. Parser byteArray a
mzero = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"MonadPlus.mzero"
    mplus :: forall a.
Parser byteArray a -> Parser byteArray a -> Parser byteArray a
mplus Parser byteArray a
f Parser byteArray a
g = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray a r
ok ->
        -- rewrite the err callback of @f to call @g
        forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser Parser byteArray a
f byteArray
buf (\byteArray
_ String
_ -> forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser Parser byteArray a
g byteArray
buf Failure byteArray r
err Success byteArray a r
ok) Success byteArray a r
ok
instance Alternative (Parser byteArray) where
    empty :: forall a. Parser byteArray a
empty = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Alternative.empty"
    <|> :: forall a.
Parser byteArray a -> Parser byteArray a -> Parser byteArray a
(<|>) = forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus

-- | Run a parser on an @initial byteArray.
--
-- If the Parser need more data than available, the @feeder function
-- is automatically called and fed to the More continuation.
parseFeed :: (ByteArrayAccess byteArray, Monad m)
          => m (Maybe byteArray)
          -> Parser byteArray a
          -> byteArray
          -> m (Result byteArray a)
parseFeed :: forall byteArray (m :: * -> *) a.
(ByteArrayAccess byteArray, Monad m) =>
m (Maybe byteArray)
-> Parser byteArray a -> byteArray -> m (Result byteArray a)
parseFeed m (Maybe byteArray)
feeder Parser byteArray a
p byteArray
initial = forall {a}. Result byteArray a -> m (Result byteArray a)
loop forall a b. (a -> b) -> a -> b
$ forall byteArray a.
ByteArrayAccess byteArray =>
Parser byteArray a -> byteArray -> Result byteArray a
parse Parser byteArray a
p byteArray
initial
  where loop :: Result byteArray a -> m (Result byteArray a)
loop (ParseMore Maybe byteArray -> Result byteArray a
k) = m (Maybe byteArray)
feeder forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Result byteArray a -> m (Result byteArray a)
loop forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe byteArray -> Result byteArray a
k)
        loop Result byteArray a
r             = forall (m :: * -> *) a. Monad m => a -> m a
return Result byteArray a
r

-- | Run a Parser on a ByteString and return a 'Result'
parse :: ByteArrayAccess byteArray
      => Parser byteArray a -> byteArray -> Result byteArray a
parse :: forall byteArray a.
ByteArrayAccess byteArray =>
Parser byteArray a -> byteArray -> Result byteArray a
parse Parser byteArray a
p byteArray
s = forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser Parser byteArray a
p byteArray
s (\byteArray
_ String
msg -> forall byteArray a. String -> Result byteArray a
ParseFail String
msg) (\byteArray
b a
a -> forall byteArray a. byteArray -> a -> Result byteArray a
ParseOK byteArray
b a
a)

------------------------------------------------------------

-- When needing more data, getMore append the next data
-- to the current buffer. if no further data, then
-- the err callback is called.
getMore :: ByteArray byteArray => Parser byteArray ()
getMore :: forall byteArray. ByteArray byteArray => Parser byteArray ()
getMore = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray () r
ok -> forall byteArray a.
(Maybe byteArray -> Result byteArray a) -> Result byteArray a
ParseMore forall a b. (a -> b) -> a -> b
$ \Maybe byteArray
nextChunk ->
    case Maybe byteArray
nextChunk of
        Maybe byteArray
Nothing -> Failure byteArray r
err byteArray
buf String
"EOL: need more data"
        Just byteArray
nc
            | forall a. ByteArrayAccess a => a -> Bool
B.null byteArray
nc -> forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser forall byteArray. ByteArray byteArray => Parser byteArray ()
getMore byteArray
buf Failure byteArray r
err Success byteArray () r
ok
            | Bool
otherwise -> Success byteArray () r
ok (forall bs. ByteArray bs => bs -> bs -> bs
B.append byteArray
buf byteArray
nc) ()

-- Only used by takeAll, which accumulate all the remaining data
-- until ParseMore is fed a Nothing value.
--
-- getAll cannot fail.
getAll :: ByteArray byteArray => Parser byteArray ()
getAll :: forall byteArray. ByteArray byteArray => Parser byteArray ()
getAll = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray () r
ok -> forall byteArray a.
(Maybe byteArray -> Result byteArray a) -> Result byteArray a
ParseMore forall a b. (a -> b) -> a -> b
$ \Maybe byteArray
nextChunk ->
    case Maybe byteArray
nextChunk of
        Maybe byteArray
Nothing -> Success byteArray () r
ok byteArray
buf ()
        Just byteArray
nc -> forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser forall byteArray. ByteArray byteArray => Parser byteArray ()
getAll (forall bs. ByteArray bs => bs -> bs -> bs
B.append byteArray
buf byteArray
nc) Failure byteArray r
err Success byteArray () r
ok

-- Only used by skipAll, which flush all the remaining data
-- until ParseMore is fed a Nothing value.
--
-- flushAll cannot fail.
flushAll :: ByteArray byteArray => Parser byteArray ()
flushAll :: forall byteArray. ByteArray byteArray => Parser byteArray ()
flushAll = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray () r
ok -> forall byteArray a.
(Maybe byteArray -> Result byteArray a) -> Result byteArray a
ParseMore forall a b. (a -> b) -> a -> b
$ \Maybe byteArray
nextChunk ->
    case Maybe byteArray
nextChunk of
        Maybe byteArray
Nothing -> Success byteArray () r
ok byteArray
buf ()
        Just byteArray
_  -> forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser forall byteArray. ByteArray byteArray => Parser byteArray ()
flushAll forall a. ByteArray a => a
B.empty Failure byteArray r
err Success byteArray () r
ok

------------------------------------------------------------
hasMore :: ByteArray byteArray => Parser byteArray Bool
hasMore :: forall byteArray. ByteArray byteArray => Parser byteArray Bool
hasMore = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray Bool r
ok ->
    if forall a. ByteArrayAccess a => a -> Bool
B.null byteArray
buf
        then forall byteArray a.
(Maybe byteArray -> Result byteArray a) -> Result byteArray a
ParseMore forall a b. (a -> b) -> a -> b
$ \Maybe byteArray
nextChunk ->
                case Maybe byteArray
nextChunk of
                    Maybe byteArray
Nothing -> Success byteArray Bool r
ok byteArray
buf Bool
False
                    Just byteArray
nc -> forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser forall byteArray. ByteArray byteArray => Parser byteArray Bool
hasMore byteArray
nc Failure byteArray r
err Success byteArray Bool r
ok
        else Success byteArray Bool r
ok byteArray
buf Bool
True

-- | Get the next byte from the parser
anyByte :: ByteArray byteArray => Parser byteArray Word8
anyByte :: forall byteArray. ByteArray byteArray => Parser byteArray Word8
anyByte = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray Word8 r
ok ->
    case forall a. ByteArray a => a -> Maybe (Word8, a)
B.uncons byteArray
buf of
        Maybe (Word8, byteArray)
Nothing      -> forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser (forall byteArray. ByteArray byteArray => Parser byteArray ()
getMore forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall byteArray. ByteArray byteArray => Parser byteArray Word8
anyByte) byteArray
buf Failure byteArray r
err Success byteArray Word8 r
ok
        Just (Word8
c1,byteArray
b2) -> Success byteArray Word8 r
ok byteArray
b2 Word8
c1

-- | Parse a specific byte at current position
--
-- if the byte is different than the expected on,
-- this parser will raise a failure.
byte :: ByteArray byteArray => Word8 -> Parser byteArray ()
byte :: forall byteArray.
ByteArray byteArray =>
Word8 -> Parser byteArray ()
byte Word8
w = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray () r
ok ->
    case forall a. ByteArray a => a -> Maybe (Word8, a)
B.uncons byteArray
buf of
        Maybe (Word8, byteArray)
Nothing      -> forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser (forall byteArray. ByteArray byteArray => Parser byteArray ()
getMore forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall byteArray.
ByteArray byteArray =>
Word8 -> Parser byteArray ()
byte Word8
w) byteArray
buf Failure byteArray r
err Success byteArray () r
ok
        Just (Word8
c1,byteArray
b2) | Word8
c1 forall a. Eq a => a -> a -> Bool
== Word8
w   -> Success byteArray () r
ok byteArray
b2 ()
                     | Bool
otherwise -> Failure byteArray r
err byteArray
buf (String
"byte " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Word8
w forall a. [a] -> [a] -> [a]
++ String
" : failed : got " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Word8
c1)

-- | Parse a sequence of bytes from current position
--
-- if the following bytes don't match the expected
-- bytestring completely, the parser will raise a failure
bytes :: (Show ba, Eq ba, ByteArray ba) => ba -> Parser ba ()
bytes :: forall ba. (Show ba, Eq ba, ByteArray ba) => ba -> Parser ba ()
bytes ba
allExpected = forall {byteArray}.
ByteArray byteArray =>
byteArray -> Parser byteArray ()
consumeEq ba
allExpected
  where errMsg :: String
errMsg = String
"bytes " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ba
allExpected forall a. [a] -> [a] -> [a]
++ String
" : failed"

        -- partially consume as much as possible or raise an error.
        consumeEq :: byteArray -> Parser byteArray ()
consumeEq byteArray
expected = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
actual Failure byteArray r
err Success byteArray () r
ok ->
            let eLen :: Int
eLen = forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
expected in
            if forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
actual forall a. Ord a => a -> a -> Bool
>= Int
eLen
                then    -- enough data for doing a full match
                        let (byteArray
aMatch,byteArray
aRem) = forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt Int
eLen byteArray
actual
                         in if byteArray
aMatch forall a. Eq a => a -> a -> Bool
== byteArray
expected
                                then Success byteArray () r
ok byteArray
aRem ()
                                else Failure byteArray r
err byteArray
actual String
errMsg
                else    -- not enough data, match as much as we have, and then recurse.
                        let (byteArray
eMatch, byteArray
eRem) = forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt (forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
actual) byteArray
expected
                         in if byteArray
actual forall a. Eq a => a -> a -> Bool
== byteArray
eMatch
                                then forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser (forall byteArray. ByteArray byteArray => Parser byteArray ()
getMore forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> byteArray -> Parser byteArray ()
consumeEq byteArray
eRem) forall a. ByteArray a => a
B.empty Failure byteArray r
err Success byteArray () r
ok
                                else Failure byteArray r
err byteArray
actual String
errMsg

------------------------------------------------------------

-- | Take a storable from the current position in the stream
takeStorable :: (ByteArray byteArray, Storable d)
             => Parser byteArray d
takeStorable :: forall byteArray d.
(ByteArray byteArray, Storable d) =>
Parser byteArray d
takeStorable = forall byteArray d.
(ByteArray byteArray, Storable d) =>
d -> Parser byteArray d
anyStorable forall a. HasCallStack => a
undefined
  where
    anyStorable :: ByteArray byteArray => Storable d => d -> Parser byteArray d
    anyStorable :: forall byteArray d.
(ByteArray byteArray, Storable d) =>
d -> Parser byteArray d
anyStorable d
a = do
        byteArray
buf <- forall byteArray.
ByteArray byteArray =>
Int -> Parser byteArray byteArray
take (forall a. Storable a => a -> Int
sizeOf d
a)
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. IO a -> a
unsafeDoIO forall a b. (a -> b) -> a -> b
$ forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
B.withByteArray byteArray
buf forall a b. (a -> b) -> a -> b
$ \Ptr d
ptr -> forall a. Storable a => Ptr a -> IO a
peek Ptr d
ptr

-- | Take @n bytes from the current position in the stream
take :: ByteArray byteArray => Int -> Parser byteArray byteArray
take :: forall byteArray.
ByteArray byteArray =>
Int -> Parser byteArray byteArray
take Int
n = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray byteArray r
ok ->
    if forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
buf forall a. Ord a => a -> a -> Bool
>= Int
n
        then let (byteArray
b1,byteArray
b2) = forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt Int
n byteArray
buf in Success byteArray byteArray r
ok byteArray
b2 byteArray
b1
        else forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser (forall byteArray. ByteArray byteArray => Parser byteArray ()
getMore forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall byteArray.
ByteArray byteArray =>
Int -> Parser byteArray byteArray
take Int
n) byteArray
buf Failure byteArray r
err Success byteArray byteArray r
ok

-- | Take bytes while the @predicate hold from the current position in the stream
takeWhile :: ByteArray byteArray => (Word8 -> Bool) -> Parser byteArray byteArray
takeWhile :: forall byteArray.
ByteArray byteArray =>
(Word8 -> Bool) -> Parser byteArray byteArray
takeWhile Word8 -> Bool
predicate = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray byteArray r
ok ->
    let (byteArray
b1, byteArray
b2) = forall bs. ByteArray bs => (Word8 -> Bool) -> bs -> (bs, bs)
B.span Word8 -> Bool
predicate byteArray
buf
     in if forall a. ByteArrayAccess a => a -> Bool
B.null byteArray
b2
            then forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser (forall byteArray. ByteArray byteArray => Parser byteArray ()
getMore forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall byteArray.
ByteArray byteArray =>
(Word8 -> Bool) -> Parser byteArray byteArray
takeWhile Word8 -> Bool
predicate) byteArray
buf Failure byteArray r
err Success byteArray byteArray r
ok
            else Success byteArray byteArray r
ok byteArray
b2 byteArray
b1

-- | Take the remaining bytes from the current position in the stream
takeAll :: ByteArray byteArray => Parser byteArray byteArray
takeAll :: forall byteArray. ByteArray byteArray => Parser byteArray byteArray
takeAll = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray byteArray r
ok ->
    forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser (forall byteArray. ByteArray byteArray => Parser byteArray ()
getAll forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser byteArray byteArray
returnBuffer) byteArray
buf Failure byteArray r
err Success byteArray byteArray r
ok
  where
    returnBuffer :: Parser byteArray byteArray
returnBuffer = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
_ Success byteArray byteArray r
ok -> Success byteArray byteArray r
ok forall a. ByteArray a => a
B.empty byteArray
buf

-- | Skip @n bytes from the current position in the stream
skip :: ByteArray byteArray => Int -> Parser byteArray ()
skip :: forall byteArray. ByteArray byteArray => Int -> Parser byteArray ()
skip Int
n = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray () r
ok ->
    if forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
buf forall a. Ord a => a -> a -> Bool
>= Int
n
        then Success byteArray () r
ok (forall bs. ByteArray bs => Int -> bs -> bs
B.drop Int
n byteArray
buf) ()
        else forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser (forall byteArray. ByteArray byteArray => Parser byteArray ()
getMore forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall byteArray. ByteArray byteArray => Int -> Parser byteArray ()
skip (Int
n forall a. Num a => a -> a -> a
- forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
buf)) forall a. ByteArray a => a
B.empty Failure byteArray r
err Success byteArray () r
ok

-- | Skip bytes while the @predicate hold from the current position in the stream
skipWhile :: ByteArray byteArray => (Word8 -> Bool) -> Parser byteArray ()
skipWhile :: forall byteArray.
ByteArray byteArray =>
(Word8 -> Bool) -> Parser byteArray ()
skipWhile Word8 -> Bool
p = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray () r
ok ->
    let (byteArray
_, byteArray
b2) = forall bs. ByteArray bs => (Word8 -> Bool) -> bs -> (bs, bs)
B.span Word8 -> Bool
p byteArray
buf 
     in if forall a. ByteArrayAccess a => a -> Bool
B.null byteArray
b2
            then forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser (forall byteArray. ByteArray byteArray => Parser byteArray ()
getMore forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall byteArray.
ByteArray byteArray =>
(Word8 -> Bool) -> Parser byteArray ()
skipWhile Word8 -> Bool
p) forall a. ByteArray a => a
B.empty Failure byteArray r
err Success byteArray () r
ok
            else Success byteArray () r
ok byteArray
b2 ()

-- | Skip all the remaining bytes from the current position in the stream
skipAll :: ByteArray byteArray => Parser byteArray ()
skipAll :: forall byteArray. ByteArray byteArray => Parser byteArray ()
skipAll = forall byteArray a.
(forall r.
 byteArray
 -> Failure byteArray r
 -> Success byteArray a r
 -> Result byteArray r)
-> Parser byteArray a
Parser forall a b. (a -> b) -> a -> b
$ \byteArray
buf Failure byteArray r
err Success byteArray () r
ok -> forall byteArray a.
Parser byteArray a
-> forall r.
   byteArray
   -> Failure byteArray r
   -> Success byteArray a r
   -> Result byteArray r
runParser forall byteArray. ByteArray byteArray => Parser byteArray ()
flushAll byteArray
buf Failure byteArray r
err Success byteArray () r
ok