{-# LANGUAGE BangPatterns, CPP, GADTs, OverloadedStrings, RankNTypes,
    RecordWildCards #-}
-- |
-- Module      :  Data.Attoparsec.ByteString.Internal
-- Copyright   :  Bryan O'Sullivan 2007-2015
-- License     :  BSD3
--
-- Maintainer  :  bos@serpentine.com
-- Stability   :  experimental
-- Portability :  unknown
--
-- Simple, efficient parser combinators for 'ByteString' strings,
-- loosely based on the Parsec library.

module Data.Attoparsec.ByteString.Internal
    (
    -- * Parser types
      Parser
    , Result

    -- * Running parsers
    , parse
    , parseOnly

    -- * Combinators
    , module Data.Attoparsec.Combinator

    -- * Parsing individual bytes
    , satisfy
    , satisfyWith
    , anyWord8
    , skip
    , word8
    , notWord8

    -- ** Lookahead
    , peekWord8
    , peekWord8'

    -- ** Byte classes
    , inClass
    , notInClass

    -- * Parsing more complicated structures
    , storable

    -- * Efficient string handling
    , skipWhile
    , string
    , stringCI
    , take
    , scan
    , runScanner
    , takeWhile
    , takeWhile1
    , takeWhileIncluding
    , takeTill
    , getChunk

    -- ** Consume all remaining input
    , takeByteString
    , takeLazyByteString

    -- * Utilities
    , endOfLine
    , endOfInput
    , match
    , atEnd
    ) where

#if !MIN_VERSION_base(4,8,0)
import Control.Applicative ((<$>))
#endif
import Control.Applicative ((<|>))
import Control.Monad (when)
import Data.Attoparsec.ByteString.Buffer (Buffer, buffer)
import Data.Attoparsec.ByteString.FastSet (charClass, memberWord8)
import Data.Attoparsec.Combinator ((<?>))
import Data.Attoparsec.Internal
import Data.Attoparsec.Internal.Compat
import Data.Attoparsec.Internal.Fhthagn (inlinePerformIO)
import Data.Attoparsec.Internal.Types hiding (Parser, Failure, Success)
import Data.ByteString (ByteString)
import Data.List (intercalate)
import Data.Word (Word8)
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (castPtr, minusPtr, plusPtr)
import Foreign.Storable (Storable(peek, sizeOf))
import Prelude hiding (getChar, succ, take, takeWhile)
import qualified Data.Attoparsec.ByteString.Buffer as Buf
import qualified Data.Attoparsec.Internal.Types as T
import qualified Data.ByteString as B8
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Internal as B
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Unsafe as B

type Parser = T.Parser ByteString
type Result = IResult ByteString
type Failure r = T.Failure ByteString Buffer r
type Success a r = T.Success ByteString Buffer a r

-- | The parser @satisfy p@ succeeds for any byte for which the
-- predicate @p@ returns 'True'. Returns the byte that is actually
-- parsed.
--
-- >digit = satisfy isDigit
-- >    where isDigit w = w >= 48 && w <= 57
satisfy :: (Word8 -> Bool) -> Parser Word8
satisfy :: (Word8 -> Bool) -> Parser Word8
satisfy Word8 -> Bool
p = do
  Word8
h <- Parser Word8
peekWord8'
  if Word8 -> Bool
p Word8
h
    then Int -> Parser ()
advance Int
1 Parser () -> Parser Word8 -> Parser Word8
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word8 -> Parser Word8
forall (m :: * -> *) a. Monad m => a -> m a
return Word8
h
    else String -> Parser Word8
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"satisfy"
{-# INLINE satisfy #-}

-- | The parser @skip p@ succeeds for any byte for which the predicate
-- @p@ returns 'True'.
--
-- >skipDigit = skip isDigit
-- >    where isDigit w = w >= 48 && w <= 57
skip :: (Word8 -> Bool) -> Parser ()
skip :: (Word8 -> Bool) -> Parser ()
skip Word8 -> Bool
p = do
  Word8
h <- Parser Word8
peekWord8'
  if Word8 -> Bool
p Word8
h
    then Int -> Parser ()
advance Int
1
    else String -> Parser ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"skip"

-- | The parser @satisfyWith f p@ transforms a byte, and succeeds if
-- the predicate @p@ returns 'True' on the transformed value. The
-- parser returns the transformed byte that was parsed.
satisfyWith :: (Word8 -> a) -> (a -> Bool) -> Parser a
satisfyWith :: (Word8 -> a) -> (a -> Bool) -> Parser a
satisfyWith Word8 -> a
f a -> Bool
p = do
  Word8
h <- Parser Word8
peekWord8'
  let c :: a
c = Word8 -> a
f Word8
h
  if a -> Bool
p a
c
    then Int -> Parser ()
advance Int
1 Parser () -> Parser a -> Parser a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return a
c
    else String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"satisfyWith"
{-# INLINE satisfyWith #-}

storable :: Storable a => Parser a
storable :: Parser a
storable = a -> Parser a
forall b. Storable b => b -> Parser b
hack a
forall a. HasCallStack => a
undefined
 where
  hack :: Storable b => b -> Parser b
  hack :: b -> Parser b
hack b
dummy = do
    (ForeignPtr Word8
fp,Int
o,Int
_) <- ByteString -> (ForeignPtr Word8, Int, Int)
B.toForeignPtr (ByteString -> (ForeignPtr Word8, Int, Int))
-> Parser ByteString ByteString
-> Parser ByteString (ForeignPtr Word8, Int, Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Int -> Parser ByteString ByteString
take (b -> Int
forall a. Storable a => a -> Int
sizeOf b
dummy)
    b -> Parser b
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> Parser b)
-> ((Ptr Word8 -> IO b) -> b) -> (Ptr Word8 -> IO b) -> Parser b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO b -> b
forall a. IO a -> a
inlinePerformIO (IO b -> b)
-> ((Ptr Word8 -> IO b) -> IO b) -> (Ptr Word8 -> IO b) -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Word8 -> (Ptr Word8 -> IO b) -> IO b
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp ((Ptr Word8 -> IO b) -> Parser b)
-> (Ptr Word8 -> IO b) -> Parser b
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p ->
        Ptr b -> IO b
forall a. Storable a => Ptr a -> IO a
peek (Ptr Any -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr (Ptr Any -> Ptr b) -> Ptr Any -> Ptr b
forall a b. (a -> b) -> a -> b
$ Ptr Word8
p Ptr Word8 -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
o)

-- | Consume exactly @n@ bytes of input.
take :: Int -> Parser ByteString
take :: Int -> Parser ByteString ByteString
take Int
n0 = do
  let n :: Int
n = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n0 Int
0
  ByteString
s <- Int -> Parser ByteString ByteString
ensure Int
n
  Int -> Parser ()
advance Int
n Parser ()
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
s
{-# INLINE take #-}

-- | @string s@ parses a sequence of bytes that identically match
-- @s@. Returns the parsed string (i.e. @s@).  This parser consumes no
-- input if it fails (even if a partial match).
--
-- /Note/: The behaviour of this parser is different to that of the
-- similarly-named parser in Parsec, as this one is all-or-nothing.
-- To illustrate the difference, the following parser will fail under
-- Parsec given an input of @\"for\"@:
--
-- >string "foo" <|> string "for"
--
-- The reason for its failure is that the first branch is a
-- partial match, and will consume the letters @\'f\'@ and @\'o\'@
-- before failing.  In attoparsec, the above parser will /succeed/ on
-- that input, because the failed first branch will consume nothing.
string :: ByteString -> Parser ByteString
string :: ByteString -> Parser ByteString ByteString
string ByteString
s = (forall r.
 ByteString
 -> ByteString
 -> Buffer
 -> Pos
 -> More
 -> Failure r
 -> Success ByteString r
 -> Result r)
-> (ByteString -> ByteString)
-> ByteString
-> Parser ByteString ByteString
string_ ((ByteString -> ByteString)
-> ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
forall r.
(ByteString -> ByteString)
-> ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
stringSuspended ByteString -> ByteString
forall a. a -> a
id) ByteString -> ByteString
forall a. a -> a
id ByteString
s
{-# INLINE string #-}

-- ASCII-specific but fast, oh yes.
toLower :: Word8 -> Word8
toLower :: Word8 -> Word8
toLower Word8
w | Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
65 Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
90 = Word8
w Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
32
          | Bool
otherwise          = Word8
w

-- | Satisfy a literal string, ignoring case.
stringCI :: ByteString -> Parser ByteString
stringCI :: ByteString -> Parser ByteString ByteString
stringCI ByteString
s = (forall r.
 ByteString
 -> ByteString
 -> Buffer
 -> Pos
 -> More
 -> Failure r
 -> Success ByteString r
 -> Result r)
-> (ByteString -> ByteString)
-> ByteString
-> Parser ByteString ByteString
string_ ((ByteString -> ByteString)
-> ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
forall r.
(ByteString -> ByteString)
-> ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
stringSuspended ByteString -> ByteString
lower) ByteString -> ByteString
lower ByteString
s
  where lower :: ByteString -> ByteString
lower = (Word8 -> Word8) -> ByteString -> ByteString
B8.map Word8 -> Word8
toLower
{-# INLINE stringCI #-}

string_ :: (forall r. ByteString -> ByteString -> Buffer -> Pos -> More
            -> Failure r -> Success ByteString r -> Result r)
        -> (ByteString -> ByteString)
        -> ByteString -> Parser ByteString
string_ :: (forall r.
 ByteString
 -> ByteString
 -> Buffer
 -> Pos
 -> More
 -> Failure r
 -> Success ByteString r
 -> Result r)
-> (ByteString -> ByteString)
-> ByteString
-> Parser ByteString ByteString
string_ forall r.
ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
suspended ByteString -> ByteString
f ByteString
s0 = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) ByteString r
 -> IResult ByteString r)
-> Parser ByteString ByteString
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) ByteString r
  -> IResult ByteString r)
 -> Parser ByteString ByteString)
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) ByteString r
    -> IResult ByteString r)
-> Parser ByteString ByteString
forall a b. (a -> b) -> a -> b
$ \State ByteString
t Pos
pos More
more Failure ByteString (State ByteString) r
lose Success ByteString (State ByteString) ByteString r
succ ->
  let n :: Int
n = ByteString -> Int
B.length ByteString
s
      s :: ByteString
s = ByteString -> ByteString
f ByteString
s0
  in if Pos -> Int -> Buffer -> Bool
lengthAtLeast Pos
pos Int
n Buffer
State ByteString
t
     then let t' :: ByteString
t' = Pos -> Pos -> Buffer -> ByteString
substring Pos
pos (Int -> Pos
Pos Int
n) Buffer
State ByteString
t
          in if ByteString
s ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString -> ByteString
f ByteString
t'
             then Success ByteString (State ByteString) ByteString r
succ State ByteString
t (Pos
pos Pos -> Pos -> Pos
forall a. Num a => a -> a -> a
+ Int -> Pos
Pos Int
n) More
more ByteString
t'
             else Failure ByteString (State ByteString) r
lose State ByteString
t Pos
pos More
more [] String
"string"
     else let t' :: ByteString
t' = Int -> Buffer -> ByteString
Buf.unsafeDrop (Pos -> Int
fromPos Pos
pos) Buffer
State ByteString
t
          in if ByteString -> ByteString
f ByteString
t' ByteString -> ByteString -> Bool
`B.isPrefixOf` ByteString
s
             then ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> IResult ByteString r
forall r.
ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
suspended ByteString
s (Int -> ByteString -> ByteString
B.drop (ByteString -> Int
B.length ByteString
t') ByteString
s) Buffer
State ByteString
t Pos
pos More
more Failure r
Failure ByteString (State ByteString) r
lose Success ByteString r
Success ByteString (State ByteString) ByteString r
succ
             else Failure ByteString (State ByteString) r
lose State ByteString
t Pos
pos More
more [] String
"string"
{-# INLINE string_ #-}

stringSuspended :: (ByteString -> ByteString)
                -> ByteString -> ByteString -> Buffer -> Pos -> More
                -> Failure r
                -> Success ByteString r
                -> Result r
stringSuspended :: (ByteString -> ByteString)
-> ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
stringSuspended ByteString -> ByteString
f ByteString
s0 ByteString
s Buffer
t Pos
pos More
more Failure r
lose Success ByteString r
succ =
    Parser ByteString ByteString
-> State ByteString
-> Pos
-> More
-> Failure ByteString (State ByteString) r
-> Success ByteString (State ByteString) ByteString r
-> Result r
forall i a.
Parser i a
-> forall r.
   State i
   -> Pos
   -> More
   -> Failure i (State i) r
   -> Success i (State i) a r
   -> IResult i r
runParser (Parser ByteString ByteString
forall t. Chunk t => Parser t t
demandInput_ Parser ByteString ByteString
-> (ByteString -> Parser ByteString ByteString)
-> Parser ByteString ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> Parser ByteString ByteString
go) Buffer
State ByteString
t Pos
pos More
more Failure r
Failure ByteString (State ByteString) r
lose Success ByteString r
Success ByteString (State ByteString) ByteString r
succ
  where go :: ByteString -> Parser ByteString ByteString
go ByteString
s'0   = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) ByteString r
 -> IResult ByteString r)
-> Parser ByteString ByteString
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) ByteString r
  -> IResult ByteString r)
 -> Parser ByteString ByteString)
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) ByteString r
    -> IResult ByteString r)
-> Parser ByteString ByteString
forall a b. (a -> b) -> a -> b
$ \State ByteString
t' Pos
pos' More
more' Failure ByteString (State ByteString) r
lose' Success ByteString (State ByteString) ByteString r
succ' ->
          let m :: Int
m  = ByteString -> Int
B.length ByteString
s
              s' :: ByteString
s' = ByteString -> ByteString
f ByteString
s'0
              n :: Int
n  = ByteString -> Int
B.length ByteString
s'
          in if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
m
             then if Int -> ByteString -> ByteString
B.unsafeTake Int
m ByteString
s' ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
s
                  then let o :: Pos
o = Int -> Pos
Pos (ByteString -> Int
B.length ByteString
s0)
                       in Success ByteString (State ByteString) ByteString r
succ' State ByteString
t' (Pos
pos' Pos -> Pos -> Pos
forall a. Num a => a -> a -> a
+ Pos
o) More
more'
                          (Pos -> Pos -> Buffer -> ByteString
substring Pos
pos' Pos
o Buffer
State ByteString
t')
                  else Failure ByteString (State ByteString) r
lose' State ByteString
t' Pos
pos' More
more' [] String
"string"
             else if ByteString
s' ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> ByteString -> ByteString
B.unsafeTake Int
n ByteString
s
                  then (ByteString -> ByteString)
-> ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> IResult ByteString r
forall r.
(ByteString -> ByteString)
-> ByteString
-> ByteString
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
stringSuspended ByteString -> ByteString
f ByteString
s0 (Int -> ByteString -> ByteString
B.unsafeDrop Int
n ByteString
s)
                       Buffer
State ByteString
t' Pos
pos' More
more' Failure r
Failure ByteString (State ByteString) r
lose' Success ByteString r
Success ByteString (State ByteString) ByteString r
succ'
                  else Failure ByteString (State ByteString) r
lose' State ByteString
t' Pos
pos' More
more' [] String
"string"

-- | Skip past input for as long as the predicate returns 'True'.
skipWhile :: (Word8 -> Bool) -> Parser ()
skipWhile :: (Word8 -> Bool) -> Parser ()
skipWhile Word8 -> Bool
p = Parser ()
go
 where
  go :: Parser ()
go = do
    ByteString
t <- (Word8 -> Bool) -> ByteString -> ByteString
B8.takeWhile Word8 -> Bool
p (ByteString -> ByteString)
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
get
    Bool
continue <- Int -> Parser Bool
inputSpansChunks (ByteString -> Int
B.length ByteString
t)
    Bool -> Parser () -> Parser ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
continue Parser ()
go
{-# INLINE skipWhile #-}

-- | Consume input as long as the predicate returns 'False'
-- (i.e. until it returns 'True'), and return the consumed input.
--
-- This parser does not fail.  It will return an empty string if the
-- predicate returns 'True' on the first byte of input.
--
-- /Note/: Because this parser does not fail, do not use it with
-- combinators such as 'Control.Applicative.many', because such
-- parsers loop until a failure occurs.  Careless use will thus result
-- in an infinite loop.
takeTill :: (Word8 -> Bool) -> Parser ByteString
takeTill :: (Word8 -> Bool) -> Parser ByteString ByteString
takeTill Word8 -> Bool
p = (Word8 -> Bool) -> Parser ByteString ByteString
takeWhile (Bool -> Bool
not (Bool -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Bool
p)
{-# INLINE takeTill #-}

-- | Consume input as long as the predicate returns 'True', and return
-- the consumed input.
--
-- This parser does not fail.  It will return an empty string if the
-- predicate returns 'False' on the first byte of input.
--
-- /Note/: Because this parser does not fail, do not use it with
-- combinators such as 'Control.Applicative.many', because such
-- parsers loop until a failure occurs.  Careless use will thus result
-- in an infinite loop.
takeWhile :: (Word8 -> Bool) -> Parser ByteString
takeWhile :: (Word8 -> Bool) -> Parser ByteString ByteString
takeWhile Word8 -> Bool
p = do
    ByteString
s <- (Word8 -> Bool) -> ByteString -> ByteString
B8.takeWhile Word8 -> Bool
p (ByteString -> ByteString)
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
get
    Bool
continue <- Int -> Parser Bool
inputSpansChunks (ByteString -> Int
B.length ByteString
s)
    if Bool
continue
      then (Word8 -> Bool) -> [ByteString] -> Parser ByteString ByteString
takeWhileAcc Word8 -> Bool
p [ByteString
s]
      else ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
s
{-# INLINE takeWhile #-}

takeWhileAcc :: (Word8 -> Bool) -> [ByteString] -> Parser ByteString
takeWhileAcc :: (Word8 -> Bool) -> [ByteString] -> Parser ByteString ByteString
takeWhileAcc Word8 -> Bool
p = [ByteString] -> Parser ByteString ByteString
go
 where
  go :: [ByteString] -> Parser ByteString ByteString
go [ByteString]
acc = do
    ByteString
s <- (Word8 -> Bool) -> ByteString -> ByteString
B8.takeWhile Word8 -> Bool
p (ByteString -> ByteString)
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
get
    Bool
continue <- Int -> Parser Bool
inputSpansChunks (ByteString -> Int
B.length ByteString
s)
    if Bool
continue
      then [ByteString] -> Parser ByteString ByteString
go (ByteString
sByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
acc)
      else ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Parser ByteString ByteString)
-> ByteString -> Parser ByteString ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
forall m. Monoid m => [m] -> m
concatReverse (ByteString
sByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
acc)
{-# INLINE takeWhileAcc #-}

-- | Consume input until immediately after the predicate returns 'True', and return
-- the consumed input.
--
-- This parser will consume at least one 'Word8' or fail.
takeWhileIncluding :: (Word8 -> Bool) -> Parser B.ByteString
takeWhileIncluding :: (Word8 -> Bool) -> Parser ByteString ByteString
takeWhileIncluding Word8 -> Bool
p = do
  (ByteString
s', ByteString
t) <- (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
B8.span Word8 -> Bool
p (ByteString -> (ByteString, ByteString))
-> Parser ByteString ByteString
-> Parser ByteString (ByteString, ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
get
  case ByteString -> Maybe (Word8, ByteString)
B8.uncons ByteString
t of
    -- Since we reached a break point and managed to get the next byte,
    -- input can not have been exhausted thus we succed and advance unconditionally.
    Just (Word8
h, ByteString
_) -> do
      let s :: ByteString
s = ByteString
s' ByteString -> Word8 -> ByteString
`B8.snoc` Word8
h
      Int -> Parser ()
advance (ByteString -> Int
B8.length ByteString
s)
      ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
s
    -- The above isn't true so either we ran out of input or we need to process the next chunk.
    Maybe (Word8, ByteString)
Nothing -> do
      Bool
continue <- Int -> Parser Bool
inputSpansChunks (ByteString -> Int
B8.length ByteString
s')
      if Bool
continue
        then (Word8 -> Bool) -> [ByteString] -> Parser ByteString ByteString
takeWhileIncAcc Word8 -> Bool
p [ByteString
s']
        -- Our spec says that if we run out of input we fail.
        else String -> Parser ByteString ByteString
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"takeWhileIncluding reached end of input"
{-# INLINE takeWhileIncluding #-}

takeWhileIncAcc :: (Word8 -> Bool) -> [B.ByteString] -> Parser B.ByteString
takeWhileIncAcc :: (Word8 -> Bool) -> [ByteString] -> Parser ByteString ByteString
takeWhileIncAcc Word8 -> Bool
p = [ByteString] -> Parser ByteString ByteString
go
 where
   go :: [ByteString] -> Parser ByteString ByteString
go [ByteString]
acc = do
     (ByteString
s', ByteString
t) <- (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
B8.span Word8 -> Bool
p (ByteString -> (ByteString, ByteString))
-> Parser ByteString ByteString
-> Parser ByteString (ByteString, ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
get
     case ByteString -> Maybe (Word8, ByteString)
B8.uncons ByteString
t of
       Just (Word8
h, ByteString
_) -> do
         let s :: ByteString
s = ByteString
s' ByteString -> Word8 -> ByteString
`B8.snoc` Word8
h
         Int -> Parser ()
advance (ByteString -> Int
B8.length ByteString
s)
         ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ([ByteString] -> ByteString
forall m. Monoid m => [m] -> m
concatReverse ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
sByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
acc)
       Maybe (Word8, ByteString)
Nothing -> do
         Bool
continue <- Int -> Parser Bool
inputSpansChunks (ByteString -> Int
B8.length ByteString
s')
         if Bool
continue
           then [ByteString] -> Parser ByteString ByteString
go (ByteString
s'ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
acc)
           else String -> Parser ByteString ByteString
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"takeWhileIncAcc reached end of input"
{-# INLINE takeWhileIncAcc #-}

takeRest :: Parser [ByteString]
takeRest :: Parser [ByteString]
takeRest = [ByteString] -> Parser [ByteString]
go []
 where
  go :: [ByteString] -> Parser [ByteString]
go [ByteString]
acc = do
    Bool
input <- Parser Bool
forall t. Chunk t => Parser t Bool
wantInput
    if Bool
input
      then do
        ByteString
s <- Parser ByteString ByteString
get
        Int -> Parser ()
advance (ByteString -> Int
B.length ByteString
s)
        [ByteString] -> Parser [ByteString]
go (ByteString
sByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
acc)
      else [ByteString] -> Parser [ByteString]
forall (m :: * -> *) a. Monad m => a -> m a
return ([ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse [ByteString]
acc)

-- | Consume all remaining input and return it as a single string.
takeByteString :: Parser ByteString
takeByteString :: Parser ByteString ByteString
takeByteString = [ByteString] -> ByteString
B.concat ([ByteString] -> ByteString)
-> Parser [ByteString] -> Parser ByteString ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Parser [ByteString]
takeRest

-- | Consume all remaining input and return it as a single string.
takeLazyByteString :: Parser L.ByteString
takeLazyByteString :: Parser ByteString
takeLazyByteString = [ByteString] -> ByteString
L.fromChunks ([ByteString] -> ByteString)
-> Parser [ByteString] -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Parser [ByteString]
takeRest

-- | Return the rest of the current chunk without consuming anything.
--
-- If the current chunk is empty, then ask for more input.
-- If there is no more input, then return 'Nothing'
getChunk :: Parser (Maybe ByteString)
getChunk :: Parser (Maybe ByteString)
getChunk = do
  Bool
input <- Parser Bool
forall t. Chunk t => Parser t Bool
wantInput
  if Bool
input
    then ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> Parser ByteString ByteString -> Parser (Maybe ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
get
    else Maybe ByteString -> Parser (Maybe ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ByteString
forall a. Maybe a
Nothing

data T s = T {-# UNPACK #-} !Int s

scan_ :: (s -> [ByteString] -> Parser r) -> s -> (s -> Word8 -> Maybe s)
         -> Parser r
scan_ :: (s -> [ByteString] -> Parser r)
-> s -> (s -> Word8 -> Maybe s) -> Parser r
scan_ s -> [ByteString] -> Parser r
f s
s0 s -> Word8 -> Maybe s
p = [ByteString] -> s -> Parser r
go [] s
s0
 where
  go :: [ByteString] -> s -> Parser r
go [ByteString]
acc s
s1 = do
    let scanner :: ByteString -> IO (T s)
scanner ByteString
bs = ByteString
-> (ForeignPtr Word8 -> Int -> Int -> IO (T s)) -> IO (T s)
forall r. ByteString -> (ForeignPtr Word8 -> Int -> Int -> r) -> r
withPS ByteString
bs ((ForeignPtr Word8 -> Int -> Int -> IO (T s)) -> IO (T s))
-> (ForeignPtr Word8 -> Int -> Int -> IO (T s)) -> IO (T s)
forall a b. (a -> b) -> a -> b
$ \ForeignPtr Word8
fp Int
off Int
len ->
          ForeignPtr Word8 -> (Ptr Word8 -> IO (T s)) -> IO (T s)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp ((Ptr Word8 -> IO (T s)) -> IO (T s))
-> (Ptr Word8 -> IO (T s)) -> IO (T s)
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr0 -> do
            let start :: Ptr Word8
start = Ptr Word8
ptr0 Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off
                end :: Ptr Word8
end   = Ptr Word8
start Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len
                inner :: Ptr Word8 -> s -> IO (T s)
inner Ptr Word8
ptr !s
s
                  | Ptr Word8
ptr Ptr Word8 -> Ptr Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Ptr Word8
end = do
                    Word8
w <- Ptr Word8 -> IO Word8
forall a. Storable a => Ptr a -> IO a
peek Ptr Word8
ptr
                    case s -> Word8 -> Maybe s
p s
s Word8
w of
                      Just s
s' -> Ptr Word8 -> s -> IO (T s)
inner (Ptr Word8
ptr Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1) s
s'
                      Maybe s
_       -> Int -> s -> IO (T s)
forall (m :: * -> *) s. Monad m => Int -> s -> m (T s)
done (Ptr Word8
ptr Ptr Word8 -> Ptr Word8 -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr Word8
start) s
s
                  | Bool
otherwise = Int -> s -> IO (T s)
forall (m :: * -> *) s. Monad m => Int -> s -> m (T s)
done (Ptr Word8
ptr Ptr Word8 -> Ptr Word8 -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr Word8
start) s
s
                done :: Int -> s -> m (T s)
done !Int
i !s
s = T s -> m (T s)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> s -> T s
forall s. Int -> s -> T s
T Int
i s
s)
            Ptr Word8 -> s -> IO (T s)
inner Ptr Word8
start s
s1
    ByteString
bs <- Parser ByteString ByteString
get
    let T Int
i s
s' = IO (T s) -> T s
forall a. IO a -> a
inlinePerformIO (IO (T s) -> T s) -> IO (T s) -> T s
forall a b. (a -> b) -> a -> b
$ ByteString -> IO (T s)
scanner ByteString
bs
        !h :: ByteString
h = Int -> ByteString -> ByteString
B.unsafeTake Int
i ByteString
bs
    Bool
continue <- Int -> Parser Bool
inputSpansChunks Int
i
    if Bool
continue
      then [ByteString] -> s -> Parser r
go (ByteString
hByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
acc) s
s'
      else s -> [ByteString] -> Parser r
f s
s' (ByteString
hByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
acc)
{-# INLINE scan_ #-}

-- | A stateful scanner.  The predicate consumes and transforms a
-- state argument, and each transformed state is passed to successive
-- invocations of the predicate on each byte of the input until one
-- returns 'Nothing' or the input ends.
--
-- This parser does not fail.  It will return an empty string if the
-- predicate returns 'Nothing' on the first byte of input.
--
-- /Note/: Because this parser does not fail, do not use it with
-- combinators such as 'Control.Applicative.many', because such
-- parsers loop until a failure occurs.  Careless use will thus result
-- in an infinite loop.
scan :: s -> (s -> Word8 -> Maybe s) -> Parser ByteString
scan :: s -> (s -> Word8 -> Maybe s) -> Parser ByteString ByteString
scan = (s -> [ByteString] -> Parser ByteString ByteString)
-> s -> (s -> Word8 -> Maybe s) -> Parser ByteString ByteString
forall s r.
(s -> [ByteString] -> Parser r)
-> s -> (s -> Word8 -> Maybe s) -> Parser r
scan_ ((s -> [ByteString] -> Parser ByteString ByteString)
 -> s -> (s -> Word8 -> Maybe s) -> Parser ByteString ByteString)
-> (s -> [ByteString] -> Parser ByteString ByteString)
-> s
-> (s -> Word8 -> Maybe s)
-> Parser ByteString ByteString
forall a b. (a -> b) -> a -> b
$ \s
_ [ByteString]
chunks -> ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Parser ByteString ByteString)
-> ByteString -> Parser ByteString ByteString
forall a b. (a -> b) -> a -> b
$! [ByteString] -> ByteString
forall m. Monoid m => [m] -> m
concatReverse [ByteString]
chunks
{-# INLINE scan #-}

-- | Like 'scan', but generalized to return the final state of the
-- scanner.
runScanner :: s -> (s -> Word8 -> Maybe s) -> Parser (ByteString, s)
runScanner :: s -> (s -> Word8 -> Maybe s) -> Parser (ByteString, s)
runScanner = (s -> [ByteString] -> Parser (ByteString, s))
-> s -> (s -> Word8 -> Maybe s) -> Parser (ByteString, s)
forall s r.
(s -> [ByteString] -> Parser r)
-> s -> (s -> Word8 -> Maybe s) -> Parser r
scan_ ((s -> [ByteString] -> Parser (ByteString, s))
 -> s -> (s -> Word8 -> Maybe s) -> Parser (ByteString, s))
-> (s -> [ByteString] -> Parser (ByteString, s))
-> s
-> (s -> Word8 -> Maybe s)
-> Parser (ByteString, s)
forall a b. (a -> b) -> a -> b
$ \s
s [ByteString]
xs -> let !sx :: ByteString
sx = [ByteString] -> ByteString
forall m. Monoid m => [m] -> m
concatReverse [ByteString]
xs in (ByteString, s) -> Parser (ByteString, s)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
sx, s
s)
{-# INLINE runScanner #-}

-- | Consume input as long as the predicate returns 'True', and return
-- the consumed input.
--
-- This parser requires the predicate to succeed on at least one byte
-- of input: it will fail if the predicate never returns 'True' or if
-- there is no input left.
takeWhile1 :: (Word8 -> Bool) -> Parser ByteString
takeWhile1 :: (Word8 -> Bool) -> Parser ByteString ByteString
takeWhile1 Word8 -> Bool
p = do
  (Bool -> Parser () -> Parser ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
`when` Parser ()
forall t. Chunk t => Parser t ()
demandInput) (Bool -> Parser ()) -> Parser Bool -> Parser ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Parser Bool
endOfChunk
  ByteString
s <- (Word8 -> Bool) -> ByteString -> ByteString
B8.takeWhile Word8 -> Bool
p (ByteString -> ByteString)
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
get
  let len :: Int
len = ByteString -> Int
B.length ByteString
s
  if Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
    then String -> Parser ByteString ByteString
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"takeWhile1"
    else do
      Int -> Parser ()
advance Int
len
      Bool
eoc <- Parser Bool
endOfChunk
      if Bool
eoc
        then (Word8 -> Bool) -> [ByteString] -> Parser ByteString ByteString
takeWhileAcc Word8 -> Bool
p [ByteString
s]
        else ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
s
{-# INLINE takeWhile1 #-}

-- | Match any byte in a set.
--
-- >vowel = inClass "aeiou"
--
-- Range notation is supported.
--
-- >halfAlphabet = inClass "a-nA-N"
--
-- To add a literal @\'-\'@ to a set, place it at the beginning or end
-- of the string.
inClass :: String -> Word8 -> Bool
inClass :: String -> Word8 -> Bool
inClass String
s = (Word8 -> FastSet -> Bool
`memberWord8` FastSet
mySet)
    where mySet :: FastSet
mySet = String -> FastSet
charClass String
s
          {-# NOINLINE mySet #-}
{-# INLINE inClass #-}

-- | Match any byte not in a set.
notInClass :: String -> Word8 -> Bool
notInClass :: String -> Word8 -> Bool
notInClass String
s = Bool -> Bool
not (Bool -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Word8 -> Bool
inClass String
s
{-# INLINE notInClass #-}

-- | Match any byte.
anyWord8 :: Parser Word8
anyWord8 :: Parser Word8
anyWord8 = (Word8 -> Bool) -> Parser Word8
satisfy ((Word8 -> Bool) -> Parser Word8)
-> (Word8 -> Bool) -> Parser Word8
forall a b. (a -> b) -> a -> b
$ Bool -> Word8 -> Bool
forall a b. a -> b -> a
const Bool
True
{-# INLINE anyWord8 #-}

-- | Match a specific byte.
word8 :: Word8 -> Parser Word8
word8 :: Word8 -> Parser Word8
word8 Word8
c = (Word8 -> Bool) -> Parser Word8
satisfy (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
c) Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
<?> Word8 -> String
forall a. Show a => a -> String
show Word8
c
{-# INLINE word8 #-}

-- | Match any byte except the given one.
notWord8 :: Word8 -> Parser Word8
notWord8 :: Word8 -> Parser Word8
notWord8 Word8
c = (Word8 -> Bool) -> Parser Word8
satisfy (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
c) Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
<?> String
"not " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show Word8
c
{-# INLINE notWord8 #-}

-- | Match any byte, to perform lookahead. Returns 'Nothing' if end of
-- input has been reached. Does not consume any input.
--
-- /Note/: Because this parser does not fail, do not use it with
-- combinators such as 'Control.Applicative.many', because such
-- parsers loop until a failure occurs.  Careless use will thus result
-- in an infinite loop.
peekWord8 :: Parser (Maybe Word8)
peekWord8 :: Parser (Maybe Word8)
peekWord8 = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) (Maybe Word8) r
 -> IResult ByteString r)
-> Parser (Maybe Word8)
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) (Maybe Word8) r
  -> IResult ByteString r)
 -> Parser (Maybe Word8))
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) (Maybe Word8) r
    -> IResult ByteString r)
-> Parser (Maybe Word8)
forall a b. (a -> b) -> a -> b
$ \State ByteString
t pos :: Pos
pos@(Pos Int
pos_) More
more Failure ByteString (State ByteString) r
_lose Success ByteString (State ByteString) (Maybe Word8) r
succ ->
  case () of
    ()
_| Int
pos_ Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Buffer -> Int
Buf.length Buffer
State ByteString
t ->
       let !w :: Word8
w = Buffer -> Int -> Word8
Buf.unsafeIndex Buffer
State ByteString
t Int
pos_
       in Success ByteString (State ByteString) (Maybe Word8) r
succ State ByteString
t Pos
pos More
more (Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
w)
     | More
more More -> More -> Bool
forall a. Eq a => a -> a -> Bool
== More
Complete ->
       Success ByteString (State ByteString) (Maybe Word8) r
succ State ByteString
t Pos
pos More
more Maybe Word8
forall a. Maybe a
Nothing
     | Bool
otherwise ->
       let succ' :: Buffer -> Pos -> More -> IResult ByteString r
succ' Buffer
t' Pos
pos' More
more' = let !w :: Word8
w = Buffer -> Int -> Word8
Buf.unsafeIndex Buffer
t' Int
pos_
                                 in Success ByteString (State ByteString) (Maybe Word8) r
succ Buffer
State ByteString
t' Pos
pos' More
more' (Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
w)
           lose' :: Buffer -> Pos -> More -> IResult ByteString r
lose' Buffer
t' Pos
pos' More
more' = Success ByteString (State ByteString) (Maybe Word8) r
succ Buffer
State ByteString
t' Pos
pos' More
more' Maybe Word8
forall a. Maybe a
Nothing
       in State ByteString
-> Pos
-> More
-> (State ByteString -> Pos -> More -> IResult ByteString r)
-> (State ByteString -> Pos -> More -> IResult ByteString r)
-> IResult ByteString r
forall t r.
Chunk t =>
State t
-> Pos
-> More
-> (State t -> Pos -> More -> IResult t r)
-> (State t -> Pos -> More -> IResult t r)
-> IResult t r
prompt State ByteString
t Pos
pos More
more Buffer -> Pos -> More -> IResult ByteString r
State ByteString -> Pos -> More -> IResult ByteString r
lose' Buffer -> Pos -> More -> IResult ByteString r
State ByteString -> Pos -> More -> IResult ByteString r
succ'
{-# INLINE peekWord8 #-}

-- | Match any byte, to perform lookahead.  Does not consume any
-- input, but will fail if end of input has been reached.
peekWord8' :: Parser Word8
peekWord8' :: Parser Word8
peekWord8' = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) Word8 r
 -> IResult ByteString r)
-> Parser Word8
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) Word8 r
  -> IResult ByteString r)
 -> Parser Word8)
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) Word8 r
    -> IResult ByteString r)
-> Parser Word8
forall a b. (a -> b) -> a -> b
$ \State ByteString
t Pos
pos More
more Failure ByteString (State ByteString) r
lose Success ByteString (State ByteString) Word8 r
succ ->
    if Pos -> Int -> Buffer -> Bool
lengthAtLeast Pos
pos Int
1 Buffer
State ByteString
t
    then Success ByteString (State ByteString) Word8 r
succ State ByteString
t Pos
pos More
more (Buffer -> Int -> Word8
Buf.unsafeIndex Buffer
State ByteString
t (Pos -> Int
fromPos Pos
pos))
    else let succ' :: Buffer -> Pos -> More -> ByteString -> IResult ByteString r
succ' Buffer
t' Pos
pos' More
more' ByteString
bs' = Success ByteString (State ByteString) Word8 r
succ Buffer
State ByteString
t' Pos
pos' More
more' (Word8 -> IResult ByteString r) -> Word8 -> IResult ByteString r
forall a b. (a -> b) -> a -> b
$! ByteString -> Word8
B.unsafeHead ByteString
bs'
         in Int
-> Buffer
-> Pos
-> More
-> Failure r
-> (Buffer -> Pos -> More -> ByteString -> IResult ByteString r)
-> IResult ByteString r
forall r.
Int
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
ensureSuspended Int
1 Buffer
State ByteString
t Pos
pos More
more Failure r
Failure ByteString (State ByteString) r
lose Buffer -> Pos -> More -> ByteString -> IResult ByteString r
succ'
{-# INLINE peekWord8' #-}

-- | Match either a single newline character @\'\\n\'@, or a carriage
-- return followed by a newline character @\"\\r\\n\"@.
endOfLine :: Parser ()
endOfLine :: Parser ()
endOfLine = (Word8 -> Parser Word8
word8 Word8
10 Parser Word8 -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Parser ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) Parser () -> Parser () -> Parser ()
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Parser ByteString ByteString
string ByteString
"\r\n" Parser ByteString ByteString -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Parser ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

-- | Terminal failure continuation.
failK :: Failure a
failK :: Failure a
failK Buffer
t (Pos Int
pos) More
_more [String]
stack String
msg = ByteString -> [String] -> String -> IResult ByteString a
forall i r. i -> [String] -> String -> IResult i r
Fail (Int -> Buffer -> ByteString
Buf.unsafeDrop Int
pos Buffer
t) [String]
stack String
msg
{-# INLINE failK #-}

-- | Terminal success continuation.
successK :: Success a a
successK :: Success a a
successK Buffer
t (Pos Int
pos) More
_more a
a = ByteString -> a -> IResult ByteString a
forall i r. i -> r -> IResult i r
Done (Int -> Buffer -> ByteString
Buf.unsafeDrop Int
pos Buffer
t) a
a
{-# INLINE successK #-}

-- | Run a parser.
parse :: Parser a -> ByteString -> Result a
parse :: Parser a -> ByteString -> Result a
parse Parser a
m ByteString
s = Parser a
-> State ByteString
-> Pos
-> More
-> Failure ByteString (State ByteString) a
-> Success ByteString (State ByteString) a a
-> Result a
forall i a.
Parser i a
-> forall r.
   State i
   -> Pos
   -> More
   -> Failure i (State i) r
   -> Success i (State i) a r
   -> IResult i r
T.runParser Parser a
m (ByteString -> Buffer
buffer ByteString
s) (Int -> Pos
Pos Int
0) More
Incomplete Failure ByteString (State ByteString) a
forall a. Failure a
failK Success ByteString (State ByteString) a a
forall a. Success a a
successK
{-# INLINE parse #-}

-- | Run a parser that cannot be resupplied via a 'Partial' result.
--
-- This function does not force a parser to consume all of its input.
-- Instead, any residual input will be discarded.  To force a parser
-- to consume all of its input, use something like this:
--
-- @
--'parseOnly' (myParser 'Control.Applicative.<*' 'endOfInput')
-- @
parseOnly :: Parser a -> ByteString -> Either String a
parseOnly :: Parser a -> ByteString -> Either String a
parseOnly Parser a
m ByteString
s = case Parser a
-> State ByteString
-> Pos
-> More
-> Failure ByteString (State ByteString) a
-> Success ByteString (State ByteString) a a
-> IResult ByteString a
forall i a.
Parser i a
-> forall r.
   State i
   -> Pos
   -> More
   -> Failure i (State i) r
   -> Success i (State i) a r
   -> IResult i r
T.runParser Parser a
m (ByteString -> Buffer
buffer ByteString
s) (Int -> Pos
Pos Int
0) More
Complete Failure ByteString (State ByteString) a
forall a. Failure a
failK Success ByteString (State ByteString) a a
forall a. Success a a
successK of
                  Fail ByteString
_ [] String
err   -> String -> Either String a
forall a b. a -> Either a b
Left String
err
                  Fail ByteString
_ [String]
ctxs String
err -> String -> Either String a
forall a b. a -> Either a b
Left (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" > " [String]
ctxs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
err)
                  Done ByteString
_ a
a        -> a -> Either String a
forall a b. b -> Either a b
Right a
a
                  IResult ByteString a
_               -> String -> Either String a
forall a. HasCallStack => String -> a
error String
"parseOnly: impossible error!"
{-# INLINE parseOnly #-}

get :: Parser ByteString
get :: Parser ByteString ByteString
get = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) ByteString r
 -> IResult ByteString r)
-> Parser ByteString ByteString
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) ByteString r
  -> IResult ByteString r)
 -> Parser ByteString ByteString)
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) ByteString r
    -> IResult ByteString r)
-> Parser ByteString ByteString
forall a b. (a -> b) -> a -> b
$ \State ByteString
t Pos
pos More
more Failure ByteString (State ByteString) r
_lose Success ByteString (State ByteString) ByteString r
succ ->
  Success ByteString (State ByteString) ByteString r
succ State ByteString
t Pos
pos More
more (Int -> Buffer -> ByteString
Buf.unsafeDrop (Pos -> Int
fromPos Pos
pos) Buffer
State ByteString
t)
{-# INLINE get #-}

endOfChunk :: Parser Bool
endOfChunk :: Parser Bool
endOfChunk = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) Bool r
 -> IResult ByteString r)
-> Parser Bool
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) Bool r
  -> IResult ByteString r)
 -> Parser Bool)
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) Bool r
    -> IResult ByteString r)
-> Parser Bool
forall a b. (a -> b) -> a -> b
$ \State ByteString
t Pos
pos More
more Failure ByteString (State ByteString) r
_lose Success ByteString (State ByteString) Bool r
succ ->
  Success ByteString (State ByteString) Bool r
succ State ByteString
t Pos
pos More
more (Pos -> Int
fromPos Pos
pos Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Buffer -> Int
Buf.length Buffer
State ByteString
t)
{-# INLINE endOfChunk #-}

inputSpansChunks :: Int -> Parser Bool
inputSpansChunks :: Int -> Parser Bool
inputSpansChunks Int
i = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) Bool r
 -> IResult ByteString r)
-> Parser Bool
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) Bool r
  -> IResult ByteString r)
 -> Parser Bool)
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) Bool r
    -> IResult ByteString r)
-> Parser Bool
forall a b. (a -> b) -> a -> b
$ \State ByteString
t Pos
pos_ More
more Failure ByteString (State ByteString) r
_lose Success ByteString (State ByteString) Bool r
succ ->
  let pos :: Pos
pos = Pos
pos_ Pos -> Pos -> Pos
forall a. Num a => a -> a -> a
+ Int -> Pos
Pos Int
i
  in if Pos -> Int
fromPos Pos
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Buffer -> Int
Buf.length Buffer
State ByteString
t Bool -> Bool -> Bool
|| More
more More -> More -> Bool
forall a. Eq a => a -> a -> Bool
== More
Complete
     then Success ByteString (State ByteString) Bool r
succ State ByteString
t Pos
pos More
more Bool
False
     else let lose' :: Buffer -> Pos -> More -> IResult ByteString r
lose' Buffer
t' Pos
pos' More
more' = Success ByteString (State ByteString) Bool r
succ Buffer
State ByteString
t' Pos
pos' More
more' Bool
False
              succ' :: Buffer -> Pos -> More -> IResult ByteString r
succ' Buffer
t' Pos
pos' More
more' = Success ByteString (State ByteString) Bool r
succ Buffer
State ByteString
t' Pos
pos' More
more' Bool
True
          in State ByteString
-> Pos
-> More
-> (State ByteString -> Pos -> More -> IResult ByteString r)
-> (State ByteString -> Pos -> More -> IResult ByteString r)
-> IResult ByteString r
forall t r.
Chunk t =>
State t
-> Pos
-> More
-> (State t -> Pos -> More -> IResult t r)
-> (State t -> Pos -> More -> IResult t r)
-> IResult t r
prompt State ByteString
t Pos
pos More
more Buffer -> Pos -> More -> IResult ByteString r
State ByteString -> Pos -> More -> IResult ByteString r
lose' Buffer -> Pos -> More -> IResult ByteString r
State ByteString -> Pos -> More -> IResult ByteString r
succ'
{-# INLINE inputSpansChunks #-}

advance :: Int -> Parser ()
advance :: Int -> Parser ()
advance Int
n = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) () r
 -> IResult ByteString r)
-> Parser ()
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) () r
  -> IResult ByteString r)
 -> Parser ())
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) () r
    -> IResult ByteString r)
-> Parser ()
forall a b. (a -> b) -> a -> b
$ \State ByteString
t Pos
pos More
more Failure ByteString (State ByteString) r
_lose Success ByteString (State ByteString) () r
succ ->
  Success ByteString (State ByteString) () r
succ State ByteString
t (Pos
pos Pos -> Pos -> Pos
forall a. Num a => a -> a -> a
+ Int -> Pos
Pos Int
n) More
more ()
{-# INLINE advance #-}

ensureSuspended :: Int -> Buffer -> Pos -> More
                -> Failure r
                -> Success ByteString r
                -> Result r
ensureSuspended :: Int
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
ensureSuspended Int
n Buffer
t Pos
pos More
more Failure r
lose Success ByteString r
succ =
    Parser ByteString ByteString
-> State ByteString
-> Pos
-> More
-> Failure ByteString (State ByteString) r
-> Success ByteString (State ByteString) ByteString r
-> Result r
forall i a.
Parser i a
-> forall r.
   State i
   -> Pos
   -> More
   -> Failure i (State i) r
   -> Success i (State i) a r
   -> IResult i r
runParser (Parser ()
forall t. Chunk t => Parser t ()
demandInput Parser ()
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ByteString ByteString
go) Buffer
State ByteString
t Pos
pos More
more Failure r
Failure ByteString (State ByteString) r
lose Success ByteString r
Success ByteString (State ByteString) ByteString r
succ
  where go :: Parser ByteString ByteString
go = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) ByteString r
 -> IResult ByteString r)
-> Parser ByteString ByteString
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) ByteString r
  -> IResult ByteString r)
 -> Parser ByteString ByteString)
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) ByteString r
    -> IResult ByteString r)
-> Parser ByteString ByteString
forall a b. (a -> b) -> a -> b
$ \State ByteString
t' Pos
pos' More
more' Failure ByteString (State ByteString) r
lose' Success ByteString (State ByteString) ByteString r
succ' ->
          if Pos -> Int -> Buffer -> Bool
lengthAtLeast Pos
pos' Int
n Buffer
State ByteString
t'
          then Success ByteString (State ByteString) ByteString r
succ' State ByteString
t' Pos
pos' More
more' (Pos -> Pos -> Buffer -> ByteString
substring Pos
pos (Int -> Pos
Pos Int
n) Buffer
State ByteString
t')
          else Parser ByteString ByteString
-> State ByteString
-> Pos
-> More
-> Failure ByteString (State ByteString) r
-> Success ByteString (State ByteString) ByteString r
-> IResult ByteString r
forall i a.
Parser i a
-> forall r.
   State i
   -> Pos
   -> More
   -> Failure i (State i) r
   -> Success i (State i) a r
   -> IResult i r
runParser (Parser ()
forall t. Chunk t => Parser t ()
demandInput Parser ()
-> Parser ByteString ByteString -> Parser ByteString ByteString
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ByteString ByteString
go) State ByteString
t' Pos
pos' More
more' Failure ByteString (State ByteString) r
lose' Success ByteString (State ByteString) ByteString r
succ'

-- | If at least @n@ elements of input are available, return the
-- current input, otherwise fail.
ensure :: Int -> Parser ByteString
ensure :: Int -> Parser ByteString ByteString
ensure Int
n = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) ByteString r
 -> IResult ByteString r)
-> Parser ByteString ByteString
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) ByteString r
  -> IResult ByteString r)
 -> Parser ByteString ByteString)
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) ByteString r
    -> IResult ByteString r)
-> Parser ByteString ByteString
forall a b. (a -> b) -> a -> b
$ \State ByteString
t Pos
pos More
more Failure ByteString (State ByteString) r
lose Success ByteString (State ByteString) ByteString r
succ ->
    if Pos -> Int -> Buffer -> Bool
lengthAtLeast Pos
pos Int
n Buffer
State ByteString
t
    then Success ByteString (State ByteString) ByteString r
succ State ByteString
t Pos
pos More
more (Pos -> Pos -> Buffer -> ByteString
substring Pos
pos (Int -> Pos
Pos Int
n) Buffer
State ByteString
t)
    -- The uncommon case is kept out-of-line to reduce code size:
    else Int
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> IResult ByteString r
forall r.
Int
-> Buffer
-> Pos
-> More
-> Failure r
-> Success ByteString r
-> Result r
ensureSuspended Int
n Buffer
State ByteString
t Pos
pos More
more Failure r
Failure ByteString (State ByteString) r
lose Success ByteString r
Success ByteString (State ByteString) ByteString r
succ
{-# INLINE ensure #-}

-- | Return both the result of a parse and the portion of the input
-- that was consumed while it was being parsed.
match :: Parser a -> Parser (ByteString, a)
match :: Parser a -> Parser (ByteString, a)
match Parser a
p = (forall r.
 State ByteString
 -> Pos
 -> More
 -> Failure ByteString (State ByteString) r
 -> Success ByteString (State ByteString) (ByteString, a) r
 -> IResult ByteString r)
-> Parser (ByteString, a)
forall i a.
(forall r.
 State i
 -> Pos
 -> More
 -> Failure i (State i) r
 -> Success i (State i) a r
 -> IResult i r)
-> Parser i a
T.Parser ((forall r.
  State ByteString
  -> Pos
  -> More
  -> Failure ByteString (State ByteString) r
  -> Success ByteString (State ByteString) (ByteString, a) r
  -> IResult ByteString r)
 -> Parser (ByteString, a))
-> (forall r.
    State ByteString
    -> Pos
    -> More
    -> Failure ByteString (State ByteString) r
    -> Success ByteString (State ByteString) (ByteString, a) r
    -> IResult ByteString r)
-> Parser (ByteString, a)
forall a b. (a -> b) -> a -> b
$ \State ByteString
t Pos
pos More
more Failure ByteString (State ByteString) r
lose Success ByteString (State ByteString) (ByteString, a) r
succ ->
  let succ' :: Buffer -> Pos -> More -> a -> IResult ByteString r
succ' Buffer
t' Pos
pos' More
more' a
a =
        Success ByteString (State ByteString) (ByteString, a) r
succ Buffer
State ByteString
t' Pos
pos' More
more' (Pos -> Pos -> Buffer -> ByteString
substring Pos
pos (Pos
pos'Pos -> Pos -> Pos
forall a. Num a => a -> a -> a
-Pos
pos) Buffer
t', a
a)
  in Parser a
-> State ByteString
-> Pos
-> More
-> Failure ByteString (State ByteString) r
-> Success ByteString (State ByteString) a r
-> IResult ByteString r
forall i a.
Parser i a
-> forall r.
   State i
   -> Pos
   -> More
   -> Failure i (State i) r
   -> Success i (State i) a r
   -> IResult i r
runParser Parser a
p State ByteString
t Pos
pos More
more Failure ByteString (State ByteString) r
lose Buffer -> Pos -> More -> a -> IResult ByteString r
Success ByteString (State ByteString) a r
succ'

lengthAtLeast :: Pos -> Int -> Buffer -> Bool
lengthAtLeast :: Pos -> Int -> Buffer -> Bool
lengthAtLeast (Pos Int
pos) Int
n Buffer
bs = Buffer -> Int
Buf.length Buffer
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n
{-# INLINE lengthAtLeast #-}

substring :: Pos -> Pos -> Buffer -> ByteString
substring :: Pos -> Pos -> Buffer -> ByteString
substring (Pos Int
pos) (Pos Int
n) = Int -> Int -> Buffer -> ByteString
Buf.substring Int
pos Int
n
{-# INLINE substring #-}