{-# language BangPatterns #-}
{-# language BinaryLiterals #-}
{-# language DataKinds #-}
{-# language DeriveFunctor #-}
{-# language DerivingStrategies #-}
{-# language GADTSyntax #-}
{-# language KindSignatures #-}
{-# language LambdaCase #-}
{-# language MagicHash #-}
{-# language MultiWayIf #-}
{-# language PolyKinds #-}
{-# language RankNTypes #-}
{-# language ScopedTypeVariables #-}
{-# language StandaloneDeriving #-}
{-# language TypeApplications #-}
{-# language UnboxedSums #-}
{-# language UnboxedTuples #-}
{-# language CPP #-}

-- | Parse non-resumable sequence of bytes. To parse a byte sequence
-- as text, use the @Ascii@, @Latin@, and @Utf8@ modules instead.
-- Functions for parsing decimal-encoded numbers are found in those
-- modules.
module Data.Bytes.Parser
  ( -- * Types
    Parser
  , Result(..)
  , Slice(..)
    -- * Run Parsers
    -- ** Result
  , parseByteArray
  , parseBytes
  , parseBytesEffectfully
  , parseBytesEither
  , parseBytesMaybe
    -- * One Byte
  , any
    -- * Many Bytes
  , take
  , takeWhile
  , takeTrailedBy
    -- * Skip
  , skipWhile
  , skipTrailedBy
  , skipTrailedBy2
  , skipTrailedBy2#
  , skipTrailedBy3#
    -- * Match
  , byteArray
  , bytes
  , satisfy
  , satisfyWith
  , cstring
    -- * End of Input
  , endOfInput
  , isEndOfInput
  , remaining
  , peekRemaining
    -- * Scanning
  , scan
    -- * Lookahead
  , peek
  , peek'
    -- * Control Flow
  , fail
  , orElse
  , annotate
  , (<?>)
    -- * Repetition
  , replicate
    -- * Subparsing
  , delimit
  , measure
  , measure_
  , measure_#
    -- * Lift Effects
  , effect
    -- * Box Result
  , boxWord32
  , boxIntPair
    -- * Unbox Result
  , unboxWord32
  , unboxIntPair
    -- * Specialized Bind
    -- | Sometimes, GHC ends up building join points in a way that
    -- boxes arguments unnecessarily. In this situation, special variants
    -- of monadic @>>=@ can be helpful. If @C#@, @I#@, etc. never
    -- get used in your original source code, GHC will not introduce them.
  , bindFromCharToLifted
  , bindFromLiftedToIntPair
  , bindFromLiftedToInt
  , bindFromIntToIntPair
  , bindFromCharToIntPair
  , bindFromMaybeCharToIntPair
  , bindFromMaybeCharToLifted
    -- * Specialized Pure
  , pureIntPair
    -- * Specialized Fail
  , failIntPair
  ) where

import Prelude hiding (length,any,fail,takeWhile,take,replicate)

import Data.Bytes.Parser.Internal (Parser(..),ST#,unboxBytes)
import Data.Bytes.Parser.Internal (boxBytes,Result#,uneffectful,fail)
import Data.Bytes.Parser.Internal (uneffectful#,uneffectfulInt#)
import Data.Bytes.Parser.Types (Result(Failure,Success),Slice(Slice))
import Data.Bytes.Parser.Unsafe (unconsume,expose,cursor)
import Data.Bytes.Types (Bytes(..))
import Data.Primitive (ByteArray(..))
import Foreign.C.String (CString)
import GHC.Exts (Int(I#),Word#,Int#,Char#,runRW#,(+#),(-#),(>=#))
import GHC.ST (ST(..))
import GHC.Word (Word32(W32#),Word8)
import Data.Primitive.Contiguous (Contiguous,Element)

import qualified Data.Bytes as B
import qualified Data.Bytes.Parser.Internal as Internal
import qualified Data.Primitive as PM
import qualified Data.Primitive.Contiguous as C
import qualified GHC.Exts as Exts

-- | Parse a byte sequence. This can succeed even if the
-- entire slice was not consumed by the parser.
parseBytes :: forall e a. (forall s. Parser e s a) -> Bytes -> Result e a
{-# inline parseBytes #-}
parseBytes :: forall e a. (forall s. Parser e s a) -> Bytes -> Result e a
parseBytes forall s. Parser e s a
p !Bytes
b = forall e x. (forall s. ST# s (Result# e x)) -> Result e x
runResultST forall s. ST# s (Result# e a)
action
  where
  action :: forall s. ST# s (Result# e a)
  action :: forall s. ST# s (Result# e a)
action State# s
s0 = case forall s. Parser e s a
p @s of
    Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (Bytes -> (# ByteArray#, Int#, Int# #)
unboxBytes Bytes
b) State# s
s0

-- | Variant of 'parseBytesEither' that discards the error message on failure.
-- Just like 'parseBytesEither', this does not impose any checks on the length
-- of the remaining input.
parseBytesMaybe :: forall e a. (forall s. Parser e s a) -> Bytes -> Maybe a
{-# inline parseBytesMaybe #-}
parseBytesMaybe :: forall e a. (forall s. Parser e s a) -> Bytes -> Maybe a
parseBytesMaybe forall s. Parser e s a
p !Bytes
b = forall e x. (forall s. ST# s (Result# e x)) -> Maybe x
runMaybeST forall s. ST# s (Result# e a)
action
  where
  action :: forall s. ST# s (Result# e a)
  action :: forall s. ST# s (Result# e a)
action State# s
s0 = case forall s. Parser e s a
p @s of
    Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (Bytes -> (# ByteArray#, Int#, Int# #)
unboxBytes Bytes
b) State# s
s0

-- | Variant of 'parseBytes' that discards the new offset and the
-- remaining length. This does not, however, require the remaining
-- length to be zero. Use 'endOfInput' to accomplish that.
parseBytesEither :: forall e a. (forall s. Parser e s a) -> Bytes -> Either e a
{-# inline parseBytesEither #-}
parseBytesEither :: forall e a. (forall s. Parser e s a) -> Bytes -> Either e a
parseBytesEither forall s. Parser e s a
p !Bytes
b = forall e x. (forall s. ST# s (Result# e x)) -> Either e x
runEitherST forall s. ST# s (Result# e a)
action
  where
  action :: forall s. ST# s (Result# e a)
  action :: forall s. ST# s (Result# e a)
action State# s
s0 = case forall s. Parser e s a
p @s of
    Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (Bytes -> (# ByteArray#, Int#, Int# #)
unboxBytes Bytes
b) State# s
s0

-- Similar to runResultST
runMaybeST :: (forall s. ST# s (Result# e x)) -> Maybe x
{-# inline runMaybeST #-}
runMaybeST :: forall e x. (forall s. ST# s (Result# e x)) -> Maybe x
runMaybeST forall s. ST# s (Result# e x)
f = case (forall o. (State# RealWorld -> o) -> o
runRW# (\State# RealWorld
s0 -> case forall s. ST# s (Result# e x)
f State# RealWorld
s0 of { (# State# RealWorld
_, Result# e x
r #) -> Result# e x
r })) of
  (# e
_ | #) -> forall a. Maybe a
Nothing
  (# | (# x
x, Int#
_, Int#
_ #) #) -> forall a. a -> Maybe a
Just x
x

-- Similar to runResultST
runEitherST :: (forall s. ST# s (Result# e x)) -> Either e x
{-# inline runEitherST #-}
runEitherST :: forall e x. (forall s. ST# s (Result# e x)) -> Either e x
runEitherST forall s. ST# s (Result# e x)
f = case (forall o. (State# RealWorld -> o) -> o
runRW# (\State# RealWorld
s0 -> case forall s. ST# s (Result# e x)
f State# RealWorld
s0 of { (# State# RealWorld
_, Result# e x
r #) -> Result# e x
r })) of
  (# e
e | #) -> forall a b. a -> Either a b
Left e
e
  (# | (# x
x, Int#
_, Int#
_ #) #) -> forall a b. b -> Either a b
Right x
x

-- This is used internally to help reduce boxing when a parser
-- gets run. Due to the late inlining of runRW#, this variant
-- of runST still cause the result value to be boxed. However,
-- it avoids the additional boxing that the Success data
-- constructor would normally cause.
runResultST :: (forall s. ST# s (Result# e x)) -> Result e x
{-# inline runResultST #-}
runResultST :: forall e x. (forall s. ST# s (Result# e x)) -> Result e x
runResultST forall s. ST# s (Result# e x)
f = case (forall o. (State# RealWorld -> o) -> o
runRW# (\State# RealWorld
s0 -> case forall s. ST# s (Result# e x)
f State# RealWorld
s0 of { (# State# RealWorld
_, Result# e x
r #) -> Result# e x
r })) of
  (# e
e | #) -> forall e a. e -> Result e a
Failure e
e
  (# | (# x
x, Int#
off, Int#
len #) #) -> forall e a. Slice a -> Result e a
Success (forall a. Int -> Int -> a -> Slice a
Slice (Int# -> Int
I# Int#
off) (Int# -> Int
I# Int#
len) x
x)

-- | Variant of 'parseBytes' that accepts an unsliced 'ByteArray'.
parseByteArray :: (forall s. Parser e s a) -> ByteArray -> Result e a
{-# inline parseByteArray #-}
parseByteArray :: forall e a. (forall s. Parser e s a) -> ByteArray -> Result e a
parseByteArray forall s. Parser e s a
p ByteArray
b =
  forall e a. (forall s. Parser e s a) -> Bytes -> Result e a
parseBytes forall s. Parser e s a
p (ByteArray -> Int -> Int -> Bytes
Bytes ByteArray
b Int
0 (ByteArray -> Int
PM.sizeofByteArray ByteArray
b))

-- | Variant of 'parseBytes' that allows the parser to be run
-- as part of an existing effectful context.
parseBytesEffectfully :: Parser e s a -> Bytes -> ST s (Result e a)
{-# inline parseBytesEffectfully #-}
parseBytesEffectfully :: forall e s a. Parser e s a -> Bytes -> ST s (Result e a)
parseBytesEffectfully (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f) !Bytes
b = forall s a. STRep s a -> ST s a
ST
  (\State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (Bytes -> (# ByteArray#, Int#, Int# #)
unboxBytes Bytes
b) State# s
s0 of
    (# State# s
s1, Result# e a
r #) -> (# State# s
s1, forall e a. Result# e a -> Result e a
boxPublicResult Result# e a
r #)
  )

-- | Lift an effectful computation into a parser.
effect :: ST s a -> Parser e s a
{-# inline effect #-}
effect :: forall s a e. ST s a -> Parser e s a
effect (ST STRep s a
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  ( \(# ByteArray#
_, Int#
off, Int#
len #) State# s
s0 -> case STRep s a
f State# s
s0 of
    (# State# s
s1, a
a #) -> (# State# s
s1, (# | (# a
a, Int#
off, Int#
len #) #) #)
  )

byteArray :: e -> ByteArray -> Parser e s ()
{-# inline byteArray #-}
byteArray :: forall e s. e -> ByteArray -> Parser e s ()
byteArray e
e !ByteArray
expected = forall e s. e -> Bytes -> Parser e s ()
bytes e
e (ByteArray -> Bytes
B.fromByteArray ByteArray
expected)

-- | Consume input matching the byte sequence.
bytes :: e -> Bytes -> Parser e s ()
bytes :: forall e s. e -> Bytes -> Parser e s ()
bytes e
e !Bytes
expected = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  ( \actual :: (# ByteArray#, Int#, Int# #)
actual@(# ByteArray#
_, Int#
off, Int#
len #) State# s
s ->
    let r :: Result# e ()
r = if Bytes -> Bytes -> Bool
B.isPrefixOf Bytes
expected ((# ByteArray#, Int#, Int# #) -> Bytes
boxBytes (# ByteArray#, Int#, Int# #)
actual)
          then let !(I# Int#
movement) = Bytes -> Int
length Bytes
expected in
            (# | (# (), Int#
off Int# -> Int# -> Int#
+# Int#
movement, Int#
len Int# -> Int# -> Int#
-# Int#
movement #) #)
          else (# e
e | #)
     in (# State# s
s, Result# e ()
r #)
  )

-- | Consume input matching the @NUL@-terminated C String.
cstring :: e -> CString -> Parser e s ()
cstring :: forall e s. e -> CString -> Parser e s ()
cstring e
e (Exts.Ptr Addr#
ptr0) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  ( \(# ByteArray#
arr, Int#
off0, Int#
len0 #) State# s
s ->
    let go :: Addr# -> Int# -> Int# -> (# State# s, Result# e () #)
go !Addr#
ptr !Int#
off !Int#
len = case
#if MIN_VERSION_base(4,16,0)
                 Word8# -> Word#
Exts.word8ToWord#
#endif
            (Addr# -> Int# -> Word8#
Exts.indexWord8OffAddr# Addr#
ptr Int#
0#) of
          Word#
0## -> (# State# s
s, (# | (# (), Int#
off, Int#
len #) #) #)
          Word#
c -> case Int#
len of
            Int#
0# -> (# State# s
s, (# e
e | #) #)
            Int#
_ -> case Word# -> Word# -> Int#
Exts.eqWord# Word#
c (
#if MIN_VERSION_base(4,16,0)
                 Word8# -> Word#
Exts.word8ToWord#
#endif
              (ByteArray# -> Int# -> Word8#
Exts.indexWord8Array# ByteArray#
arr Int#
off)) of
              Int#
1# -> Addr# -> Int# -> Int# -> (# State# s, Result# e () #)
go (Addr# -> Int# -> Addr#
Exts.plusAddr# Addr#
ptr Int#
1# ) (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) (Int#
len Int# -> Int# -> Int#
-# Int#
1# )
              Int#
_ -> (# State# s
s, (# e
e | #) #)
     in Addr# -> Int# -> Int# -> (# State# s, Result# e () #)
go Addr#
ptr0 Int#
off0 Int#
len0
  )

infix 0 <?>

-- | Infix version of 'annotate'.
(<?>) :: Parser x s a -> e -> Parser e s a
<?> :: forall x s a e. Parser x s a -> e -> Parser e s a
(<?>) = forall x s a e. Parser x s a -> e -> Parser e s a
annotate

-- | Annotate a parser. If the parser fails, the error will
--   be returned.
annotate :: Parser x s a -> e -> Parser e s a
annotate :: forall x s a e. Parser x s a -> e -> Parser e s a
annotate Parser x s a
p e
e = Parser x s a
p forall x s a e. Parser x s a -> Parser e s a -> Parser e s a
`orElse` forall e s a. e -> Parser e s a
fail e
e

-- | Consumes and returns the next byte in the input.
-- Fails if no characters are left.
any :: e -> Parser e s Word8
{-# inline any #-}
any :: forall e s. e -> Parser e s Word8
any e
e = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> if Bytes -> Int
length Bytes
chunk forall a. Ord a => a -> a -> Bool
> Int
0
  then
    let w :: Word8
w = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk) :: Word8
     in forall e a. a -> Int -> Int -> Result e a
Internal.Success Word8
w (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
1) (Bytes -> Int
length Bytes
chunk forall a. Num a => a -> a -> a
- Int
1)
  else forall e a. e -> Result e a
Internal.Failure e
e

-- | 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 'many', because such as 'many',
--   because such parsers loop until a failure occurs. Careless
--   use will thus result in an infinite loop.
peek :: Parser e s (Maybe Word8)
{-# inline peek #-}
peek :: forall e s. Parser e s (Maybe Word8)
peek = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  let v :: Maybe Word8
v = if Bytes -> Int
length Bytes
chunk forall a. Ord a => a -> a -> Bool
> Int
0
        then forall a. a -> Maybe a
Just (Bytes -> Int -> Word8
B.unsafeIndex Bytes
chunk Int
0)
        else forall a. Maybe a
Nothing
  in forall e a. a -> Int -> Int -> Result e a
Internal.Success Maybe Word8
v (Bytes -> Int
offset Bytes
chunk) (Bytes -> Int
length Bytes
chunk)

-- | Match any byte, to perform lookahead. Does not consume any
--   input, but will fail if end of input has been reached.
peek' :: e -> Parser e s Word8
{-# inline peek' #-}
peek' :: forall e s. e -> Parser e s Word8
peek' e
e = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> if Bytes -> Int
length Bytes
chunk forall a. Ord a => a -> a -> Bool
> Int
0
  then forall e a. a -> Int -> Int -> Result e a
Internal.Success (Bytes -> Int -> Word8
B.unsafeIndex Bytes
chunk Int
0) (Bytes -> Int
offset Bytes
chunk) (Bytes -> Int
length Bytes
chunk)
  else forall e a. e -> Result e a
Internal.Failure e
e

-- | 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 the initial state
--   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 a 'many', because such parsers loop until a
--   failure occurs. Careless use will thus result in an infinite loop.
scan :: state -> (state -> Word8 -> Maybe state) -> Parser e s state
{-# inline scan #-}
scan :: forall state e s.
state -> (state -> Word8 -> Maybe state) -> Parser e s state
scan state
s0 state -> Word8 -> Maybe state
t = do
  let go :: state -> Parser e s state
go state
s = do
        Maybe Word8
mw <- forall e s. Parser e s (Maybe Word8)
peek
        case Maybe Word8
mw of
          Maybe Word8
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure state
s
          Just Word8
w -> case state -> Word8 -> Maybe state
t state
s Word8
w of
            Just state
s' -> state -> Parser e s state
go state
s'
            Maybe state
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure state
s
  forall {e} {s}. state -> Parser e s state
go state
s0

-- Interpret the next byte as an ASCII-encoded character.
-- Does not check to see if any characters are left. This
-- is not exported.
anyUnsafe :: Parser e s Word8
{-# inline anyUnsafe #-}
anyUnsafe :: forall e s. Parser e s Word8
anyUnsafe = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  let w :: Word8
w = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk) :: Word8
   in forall e a. a -> Int -> Int -> Result e a
Internal.Success Word8
w (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
1) (Bytes -> Int
length Bytes
chunk forall a. Num a => a -> a -> a
- Int
1)

-- | Take while the predicate is matched. This is always inlined. This
-- always succeeds.
takeWhile :: (Word8 -> Bool) -> Parser e s Bytes
{-# inline takeWhile #-}
takeWhile :: forall e s. (Word8 -> Bool) -> Parser e s Bytes
takeWhile Word8 -> Bool
f = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> case (Word8 -> Bool) -> Bytes -> Bytes
B.takeWhile Word8 -> Bool
f Bytes
chunk of
  Bytes
bs -> forall e a. a -> Int -> Int -> Result e a
Internal.Success Bytes
bs (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Bytes -> Int
length Bytes
bs) (Bytes -> Int
length Bytes
chunk forall a. Num a => a -> a -> a
- Bytes -> Int
length Bytes
bs)

-- | Take bytes until the specified byte is encountered. Consumes
-- the matched byte as well. Fails if the byte is not present.
-- Visually, the cursor advancement and resulting @Bytes@ for
-- @takeTrailedBy 0x19@ look like this:
--
-- >  0x10 0x13 0x08 0x15 0x19 0x23 0x17 | input
-- > |---->---->---->---->----|          | cursor
-- > {----*----*----*----}               | result bytes
takeTrailedBy :: e -> Word8 -> Parser e s Bytes
takeTrailedBy :: forall e s. e -> Word8 -> Parser e s Bytes
takeTrailedBy e
e !Word8
w = do
  !Int
start <- forall e s. Parser e s Int
cursor
  forall e s. e -> Word8 -> Parser e s ()
skipTrailedBy e
e Word8
w
  !Int
end <- forall e s. Parser e s Int
cursor
  !ByteArray
arr <- forall e s. Parser e s ByteArray
expose
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteArray -> Int -> Int -> Bytes
Bytes ByteArray
arr Int
start (Int
end forall a. Num a => a -> a -> a
- (Int
start forall a. Num a => a -> a -> a
+ Int
1)))

-- | Skip all characters until the character from the is encountered
-- and then consume the matching byte as well.
skipTrailedBy :: e -> Word8 -> Parser e s ()
{-# inline skipTrailedBy #-}
skipTrailedBy :: forall e s. e -> Word8 -> Parser e s ()
skipTrailedBy e
e !Word8
w = forall e a s. (Bytes -> Result# e a) -> Parser e s a
uneffectful# (\Bytes
c -> forall e. e -> Word8 -> Bytes -> Result# e ()
skipUntilConsumeByteLoop e
e Word8
w Bytes
c)

skipUntilConsumeByteLoop ::
     e -- Error message
  -> Word8 -- byte to match
  -> Bytes -- Chunk
  -> Result# e ()
skipUntilConsumeByteLoop :: forall e. e -> Word8 -> Bytes -> Result# e ()
skipUntilConsumeByteLoop e
e !Word8
w !Bytes
c = if Bytes -> Int
length Bytes
c forall a. Ord a => a -> a -> Bool
> Int
0
  then if forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
c) (Bytes -> Int
offset Bytes
c) forall a. Eq a => a -> a -> Bool
/= (Word8
w :: Word8)
    then forall e. e -> Word8 -> Bytes -> Result# e ()
skipUntilConsumeByteLoop e
e Word8
w (Int -> Bytes -> Bytes
B.unsafeDrop Int
1 Bytes
c)
    else (# | (# (), Int -> Int#
unI (Bytes -> Int
offset Bytes
c forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c forall a. Num a => a -> a -> a
- Int
1) #) #)
  else (# e
e | #)

-- | Skip all bytes until either of the bytes in encountered. Then,
-- consume the matched byte. @True@ indicates that the first argument
-- byte was encountered. @False@ indicates that the second argument
-- byte was encountered.
skipTrailedBy2 ::
     e -- ^ Error message
  -> Word8 -- ^ First trailer, @False@ indicates that this was encountered
  -> Word8 -- ^ Second trailer, @True@ indicates that this was encountered
  -> Parser e s Bool
{-# inline skipTrailedBy2 #-}
skipTrailedBy2 :: forall e s. e -> Word8 -> Word8 -> Parser e s Bool
skipTrailedBy2 e
e !Word8
wa !Word8
wb = forall e s. Parser e s Int# -> Parser e s Bool
boxBool (forall e s. e -> Word8 -> Word8 -> Parser e s Int#
skipTrailedBy2# e
e Word8
wa Word8
wb)

skipTrailedBy2# ::
     e -- ^ Error message
  -> Word8 -- ^ First trailer, 0 indicates that this was encountered
  -> Word8 -- ^ Second trailer, 1 indicates that this was encountered
  -> Parser e s Int#
{-# inline skipTrailedBy2# #-}
skipTrailedBy2# :: forall e s. e -> Word8 -> Word8 -> Parser e s Int#
skipTrailedBy2# e
e !Word8
wa !Word8
wb =
  forall e s. (Bytes -> Result# e Int#) -> Parser e s Int#
uneffectfulInt# (\Bytes
c -> forall e. e -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByteEitherLoop e
e Word8
wa Word8
wb Bytes
c)

skipTrailedBy3# ::
     e -- ^ Error message
  -> Word8 -- ^ First trailer, 0 indicates that this was encountered
  -> Word8 -- ^ Second trailer, 1 indicates that this was encountered
  -> Word8 -- ^ Third trailer, 2 indicates that this was encountered
  -> Parser e s Int#
{-# inline skipTrailedBy3# #-}
skipTrailedBy3# :: forall e s. e -> Word8 -> Word8 -> Word8 -> Parser e s Int#
skipTrailedBy3# e
e !Word8
wa !Word8
wb !Word8
wc =
  forall e s. (Bytes -> Result# e Int#) -> Parser e s Int#
uneffectfulInt# (\Bytes
c -> forall e. e -> Word8 -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByte3Loop e
e Word8
wa Word8
wb Word8
wc Bytes
c)

skipUntilConsumeByteEitherLoop ::
     e -- Error message
  -> Word8 -- first trailer
  -> Word8 -- second trailer
  -> Bytes -- Chunk
  -> Result# e Int#
skipUntilConsumeByteEitherLoop :: forall e. e -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByteEitherLoop e
e !Word8
wa !Word8
wb !Bytes
c = if Bytes -> Int
length Bytes
c forall a. Ord a => a -> a -> Bool
> Int
0
  then let byte :: Word8
byte = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
c) (Bytes -> Int
offset Bytes
c) in
    if | Word8
byte forall a. Eq a => a -> a -> Bool
== Word8
wa -> (# | (# Int#
0#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c forall a. Num a => a -> a -> a
- Int
1) #) #)
       | Word8
byte forall a. Eq a => a -> a -> Bool
== Word8
wb -> (# | (# Int#
1#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c forall a. Num a => a -> a -> a
- Int
1) #) #)
       | Bool
otherwise -> forall e. e -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByteEitherLoop e
e Word8
wa Word8
wb (Int -> Bytes -> Bytes
B.unsafeDrop Int
1 Bytes
c)
  else (# e
e | #)

skipUntilConsumeByte3Loop ::
     e -- Error message
  -> Word8 -- first trailer
  -> Word8 -- second trailer
  -> Word8 -- third trailer
  -> Bytes -- Chunk
  -> Result# e Int#
skipUntilConsumeByte3Loop :: forall e. e -> Word8 -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByte3Loop e
e !Word8
wa !Word8
wb !Word8
wc !Bytes
c = if Bytes -> Int
length Bytes
c forall a. Ord a => a -> a -> Bool
> Int
0
  then let byte :: Word8
byte = forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
c) (Bytes -> Int
offset Bytes
c) in
    if | Word8
byte forall a. Eq a => a -> a -> Bool
== Word8
wa -> (# | (# Int#
0#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c forall a. Num a => a -> a -> a
- Int
1) #) #)
       | Word8
byte forall a. Eq a => a -> a -> Bool
== Word8
wb -> (# | (# Int#
1#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c forall a. Num a => a -> a -> a
- Int
1) #) #)
       | Word8
byte forall a. Eq a => a -> a -> Bool
== Word8
wc -> (# | (# Int#
2#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c forall a. Num a => a -> a -> a
- Int
1) #) #)
       | Bool
otherwise -> forall e. e -> Word8 -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByte3Loop e
e Word8
wa Word8
wb Word8
wc (Int -> Bytes -> Bytes
B.unsafeDrop Int
1 Bytes
c)
  else (# e
e | #)

-- | Take the given number of bytes. Fails if there is not enough
--   remaining input.
take :: e -> Int -> Parser e s Bytes
{-# inline take #-}
take :: forall e s. e -> Int -> Parser e s Bytes
take e
e Int
n = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> if Int
n forall a. Ord a => a -> a -> Bool
<= Bytes -> Int
B.length Bytes
chunk
  then case Int -> Bytes -> Bytes
B.unsafeTake Int
n Bytes
chunk of
    Bytes
bs -> forall e a. a -> Int -> Int -> Result e a
Internal.Success Bytes
bs (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
n) (Bytes -> Int
length Bytes
chunk forall a. Num a => a -> a -> a
- Int
n)
  else forall e a. e -> Result e a
Internal.Failure e
e

-- | Consume all remaining bytes in the input.
remaining :: Parser e s Bytes
{-# inline remaining #-}
remaining :: forall e s. Parser e s Bytes
remaining = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  forall e a. a -> Int -> Int -> Result e a
Internal.Success Bytes
chunk (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Bytes -> Int
length Bytes
chunk) Int
0

-- | Return all remaining bytes in the input without consuming them.
peekRemaining :: Parser e s Bytes
{-# inline peekRemaining #-}
peekRemaining :: forall e s. Parser e s Bytes
peekRemaining = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \b :: Bytes
b@(Bytes ByteArray
_ Int
off Int
len) ->
  forall e a. a -> Int -> Int -> Result e a
Internal.Success Bytes
b Int
off Int
len

-- | Skip while the predicate is matched. This is always inlined.
skipWhile :: (Word8 -> Bool) -> Parser e s ()
{-# inline skipWhile #-}
skipWhile :: forall e s. (Word8 -> Bool) -> Parser e s ()
skipWhile Word8 -> Bool
f = forall {e} {s}. Parser e s ()
go where
  go :: Parser e s ()
go = forall e s. Parser e s Bool
isEndOfInput forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Bool
True -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    Bool
False -> do
      Word8
w <- forall e s. Parser e s Word8
anyUnsafe
      if Word8 -> Bool
f Word8
w
        then Parser e s ()
go
        else forall e s. Int -> Parser e s ()
unconsume Int
1

-- | The parser @satisfy p@ succeeds for any byte for which the
--   predicate @p@ returns 'True'. Returns the byte that is
--   actually parsed.
satisfy :: e -> (Word8 -> Bool) -> Parser e s Word8
satisfy :: forall e s. e -> (Word8 -> Bool) -> Parser e s Word8
satisfy e
e Word8 -> Bool
p = forall e a s. e -> (Word8 -> a) -> (a -> Bool) -> Parser e s a
satisfyWith e
e forall a. a -> a
id Word8 -> Bool
p
{-# inline satisfy #-}

-- | 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 :: e -> (Word8 -> a) -> (a -> Bool) -> Parser e s a
{-# inline satisfyWith #-}
satisfyWith :: forall e a s. e -> (Word8 -> a) -> (a -> Bool) -> Parser e s a
satisfyWith e
e Word8 -> a
f a -> Bool
p = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> if Bytes -> Int
length Bytes
chunk forall a. Ord a => a -> a -> Bool
> Int
1
  then case Bytes -> Int -> Word8
B.unsafeIndex Bytes
chunk Int
1 of
    Word8
w ->
      let v :: a
v = Word8 -> a
f Word8
w
      in if a -> Bool
p a
v
        then forall e a. a -> Int -> Int -> Result e a
Internal.Success a
v (Bytes -> Int
offset Bytes
chunk forall a. Num a => a -> a -> a
+ Int
1) (Bytes -> Int
length Bytes
chunk forall a. Num a => a -> a -> a
- Int
1)
        else forall e a. e -> Result e a
Internal.Failure e
e
  else forall e a. e -> Result e a
Internal.Failure e
e

-- | Fails if there is still more input remaining.
endOfInput :: e -> Parser e s ()
{-# inline endOfInput #-}
endOfInput :: forall e s. e -> Parser e s ()
endOfInput e
e = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> if Bytes -> Int
length Bytes
chunk forall a. Eq a => a -> a -> Bool
== Int
0
  then forall e a. a -> Int -> Int -> Result e a
Internal.Success () (Bytes -> Int
offset Bytes
chunk) Int
0
  else forall e a. e -> Result e a
Internal.Failure e
e

-- | Returns true if there are no more bytes in the input. Returns
-- false otherwise. Always succeeds.
isEndOfInput :: Parser e s Bool
{-# inline isEndOfInput #-}
isEndOfInput :: forall e s. Parser e s Bool
isEndOfInput = forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  forall e a. a -> Int -> Int -> Result e a
Internal.Success (Bytes -> Int
length Bytes
chunk forall a. Eq a => a -> a -> Bool
== Int
0) (Bytes -> Int
offset Bytes
chunk) (Bytes -> Int
length Bytes
chunk)

boxPublicResult :: Result# e a -> Result e a
{-# inline boxPublicResult #-}
boxPublicResult :: forall e a. Result# e a -> Result e a
boxPublicResult (# | (# a
a, Int#
b, Int#
c #) #) = forall e a. Slice a -> Result e a
Success (forall a. Int -> Int -> a -> Slice a
Slice (Int# -> Int
I# Int#
b) (Int# -> Int
I# Int#
c) a
a)
boxPublicResult (# e
e | #) = forall e a. e -> Result e a
Failure e
e

-- | Convert a 'Word32' parser to a 'Word#' parser.
unboxWord32 :: Parser e s Word32 -> Parser e s Word#
{-# inline unboxWord32 #-}
unboxWord32 :: forall e s. Parser e s Word32 -> Parser e s Word#
unboxWord32 (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word32)
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word32)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e Word32
r #) -> case Result# e Word32
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# W32# Word32#
a, Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (#
#if MIN_VERSION_base(4,16,0)
        Word32# -> Word#
Exts.word32ToWord#
#endif
        Word32#
a, Int#
b, Int#
c #) #) #)
  )

-- | Convert a @(Int,Int)@ parser to a @(# Int#, Int# #)@ parser.
unboxIntPair :: Parser e s (Int,Int) -> Parser e s (# Int#, Int# #)
{-# inline unboxIntPair #-}
unboxIntPair :: forall e s. Parser e s (Int, Int) -> Parser e s (# Int#, Int# #)
unboxIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e (Int, Int))
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e (Int, Int))
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e (Int, Int)
r #) -> case Result# e (Int, Int)
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# (I# Int#
y, I# Int#
z), Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# (# Int#
y, Int#
z #), Int#
b, Int#
c #) #) #)
  )

-- | Convert a 'Word#' parser to a 'Word32' parser. Precondition:
-- the argument parser only returns words less than 4294967296.
boxWord32 :: Parser e s Word# -> Parser e s Word32
{-# inline boxWord32 #-}
boxWord32 :: forall e s. Parser e s Word# -> Parser e s Word32
boxWord32 (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word#)
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word#)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e Word#
r #) -> case Result# e Word#
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# Word#
a, Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# Word32# -> Word32
W32# (
#if MIN_VERSION_base(4,16,0)
        Word# -> Word32#
Exts.wordToWord32#
#endif
        Word#
a), Int#
b, Int#
c #) #) #)
  )

-- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser.
boxInt :: Parser e s Int# -> Parser e s Int
{-# inline boxInt #-}
boxInt :: forall e s. Parser e s Int# -> Parser e s Int
boxInt (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#)
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e Int#
r #) -> case Result# e Int#
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# Int#
y, Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# Int# -> Int
I# Int#
y, Int#
b, Int#
c #) #) #)
  )

-- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser.
boxBool :: Parser e s Int# -> Parser e s Bool
{-# inline boxBool #-}
boxBool :: forall e s. Parser e s Int# -> Parser e s Bool
boxBool (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#)
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e Int#
r #) -> case Result# e Int#
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# Int#
y, Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# case Int#
y of {Int#
1# -> Bool
True; Int#
_ -> Bool
False}, Int#
b, Int#
c #) #) #)
  )

-- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser.
boxIntPair :: Parser e s (# Int#, Int# #) -> Parser e s (Int,Int)
{-# inline boxIntPair #-}
boxIntPair :: forall e s. Parser e s (# Int#, Int# #) -> Parser e s (Int, Int)
boxIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e (# Int#, Int# #))
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e (# Int#, Int# #))
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e (# Int#, Int# #)
r #) -> case Result# e (# Int#, Int# #)
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# (# Int#
y, Int#
z #), Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# (Int# -> Int
I# Int#
y, Int# -> Int
I# Int#
z), Int#
b, Int#
c #) #) #)
  )


-- | There is a law-abiding instance of 'Alternative' for 'Parser'.
-- However, it is not terribly useful since error messages seldom
-- have a 'Monoid' instance. This function is a variant of @\<|\>@
-- that is right-biased in its treatment of error messages.
-- Consequently, @orElse@ lacks an identity.
-- See <https://github.com/bos/attoparsec/issues/122 attoparsec issue #122>
-- for more discussion of this topic.
infixl 3 `orElse`
orElse :: Parser x s a -> Parser e s a -> Parser e s a
{-# inline orElse #-}
orElse :: forall x s a e. Parser x s a -> Parser e s a -> Parser e s a
orElse (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# x a)
f) (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
g) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# x a)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# x a
r0 #) -> case Result# x a
r0 of
      (# x
_ | #) -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
g (# ByteArray#, Int#, Int# #)
x State# s
s1
      (# | (# a, Int#, Int# #)
r #) -> (# State# s
s1, (# | (# a, Int#, Int# #)
r #) #)
  )

bindFromCharToLifted :: Parser s e Char# -> (Char# -> Parser s e a) -> Parser s e a
{-# inline bindFromCharToLifted #-}
bindFromCharToLifted :: forall s e a.
Parser s e Char# -> (Char# -> Parser s e a) -> Parser s e a
bindFromCharToLifted (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Char#)
f) Char# -> Parser s e a
g = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Char#)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
    (# State# e
s1, Result# s Char#
r0 #) -> case Result# s Char#
r0 of
      (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
      (# | (# Char#
y, Int#
b, Int#
c #) #) ->
        forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (Char# -> Parser s e a
g Char#
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
  )

bindFromCharToIntPair :: Parser s e Char# -> (Char# -> Parser s e (# Int#, Int# #)) -> Parser s e (# Int#, Int# #)
{-# inline bindFromCharToIntPair #-}
bindFromCharToIntPair :: forall s e.
Parser s e Char#
-> (Char# -> Parser s e (# Int#, Int# #))
-> Parser s e (# Int#, Int# #)
bindFromCharToIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Char#)
f) Char# -> Parser s e (# Int#, Int# #)
g = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Char#)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
    (# State# e
s1, Result# s Char#
r0 #) -> case Result# s Char#
r0 of
      (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
      (# | (# Char#
y, Int#
b, Int#
c #) #) ->
        forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (Char# -> Parser s e (# Int#, Int# #)
g Char#
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
  )

bindFromLiftedToInt :: Parser s e a -> (a -> Parser s e Int#) -> Parser s e Int#
{-# inline bindFromLiftedToInt #-}
bindFromLiftedToInt :: forall s e a.
Parser s e a -> (a -> Parser s e Int#) -> Parser s e Int#
bindFromLiftedToInt (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
f) a -> Parser s e Int#
g = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
    (# State# e
s1, Result# s a
r0 #) -> case Result# s a
r0 of
      (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
      (# | (# a
y, Int#
b, Int#
c #) #) ->
        forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (a -> Parser s e Int#
g a
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
  )

bindFromLiftedToIntPair :: Parser s e a -> (a -> Parser s e (# Int#, Int# #)) -> Parser s e (# Int#, Int# #)
{-# inline bindFromLiftedToIntPair #-}
bindFromLiftedToIntPair :: forall s e a.
Parser s e a
-> (a -> Parser s e (# Int#, Int# #))
-> Parser s e (# Int#, Int# #)
bindFromLiftedToIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
f) a -> Parser s e (# Int#, Int# #)
g = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
    (# State# e
s1, Result# s a
r0 #) -> case Result# s a
r0 of
      (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
      (# | (# a
y, Int#
b, Int#
c #) #) ->
        forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (a -> Parser s e (# Int#, Int# #)
g a
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
  )

bindFromIntToIntPair :: Parser s e Int# -> (Int# -> Parser s e (# Int#, Int# #)) -> Parser s e (# Int#, Int# #)
{-# inline bindFromIntToIntPair #-}
bindFromIntToIntPair :: forall s e.
Parser s e Int#
-> (Int# -> Parser s e (# Int#, Int# #))
-> Parser s e (# Int#, Int# #)
bindFromIntToIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Int#)
f) Int# -> Parser s e (# Int#, Int# #)
g = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Int#)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
    (# State# e
s1, Result# s Int#
r0 #) -> case Result# s Int#
r0 of
      (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
      (# | (# Int#
y, Int#
b, Int#
c #) #) ->
        forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (Int# -> Parser s e (# Int#, Int# #)
g Int#
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
  )

bindFromMaybeCharToIntPair ::
     Parser s e (# (# #) | Char# #)
  -> ((# (# #) | Char# #) -> Parser s e (# Int#, Int# #))
  -> Parser s e (# Int#, Int# #)
{-# inline bindFromMaybeCharToIntPair #-}
bindFromMaybeCharToIntPair :: forall s e.
Parser s e (# (# #) | Char# #)
-> ((# (# #) | Char# #) -> Parser s e (# Int#, Int# #))
-> Parser s e (# Int#, Int# #)
bindFromMaybeCharToIntPair (Parser (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# (# #) | Char# #))
f) (# (# #) | Char# #) -> Parser s e (# Int#, Int# #)
g = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# (# #) | Char# #))
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
    (# State# e
s1, Result# s (# (# #) | Char# #)
r0 #) -> case Result# s (# (# #) | Char# #)
r0 of
      (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
      (# | (# (# (# #) | Char# #)
y, Int#
b, Int#
c #) #) ->
        forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser ((# (# #) | Char# #) -> Parser s e (# Int#, Int# #)
g (# (# #) | Char# #)
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
  )

bindFromMaybeCharToLifted ::
     Parser s e (# (# #) | Char# #)
  -> ((# (# #) | Char# #) -> Parser s e a)
  -> Parser s e a
{-# inline bindFromMaybeCharToLifted #-}
bindFromMaybeCharToLifted :: forall s e a.
Parser s e (# (# #) | Char# #)
-> ((# (# #) | Char# #) -> Parser s e a) -> Parser s e a
bindFromMaybeCharToLifted (Parser (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# (# #) | Char# #))
f) (# (# #) | Char# #) -> Parser s e a
g = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# (# #) | Char# #))
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
    (# State# e
s1, Result# s (# (# #) | Char# #)
r0 #) -> case Result# s (# (# #) | Char# #)
r0 of
      (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
      (# | (# (# (# #) | Char# #)
y, Int#
b, Int#
c #) #) ->
        forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser ((# (# #) | Char# #) -> Parser s e a
g (# (# #) | Char# #)
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
  )

pureIntPair ::
     (# Int#, Int# #)
  -> Parser s e (# Int#, Int# #)
{-# inline pureIntPair #-}
pureIntPair :: forall s e. (# Int#, Int# #) -> Parser s e (# Int#, Int# #)
pureIntPair (# Int#, Int# #)
a = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\(# ByteArray#
_, Int#
b, Int#
c #) State# e
s -> (# State# e
s, (# | (# (# Int#, Int# #)
a, Int#
b, Int#
c #) #) #))

failIntPair :: e -> Parser e s (# Int#, Int# #)
{-# inline failIntPair #-}
failIntPair :: forall e s. e -> Parser e s (# Int#, Int# #)
failIntPair e
e = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\(# ByteArray#
_, Int#
_, Int#
_ #) State# s
s -> (# State# s
s, (# e
e | #) #))

-- | Augment a parser with the number of bytes that were consume while
-- it executed.
measure :: Parser e s a -> Parser e s (Int,a)
{-# inline measure #-}
measure :: forall e s a. Parser e s a -> Parser e s (Int, a)
measure (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
_, Int#
pre, Int#
_ #) State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e a
r #) -> case Result# e a
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# a
y, Int#
post, Int#
c #) #) -> (# State# s
s1, (# | (# (Int# -> Int
I# (Int#
post Int# -> Int# -> Int#
-# Int#
pre), a
y),Int#
post,Int#
c #) #) #)
  )

-- | Run a parser and discard the result, returning instead the number
-- of bytes that the parser consumed.
measure_ :: Parser e s a -> Parser e s Int
{-# inline measure_ #-}
measure_ :: forall e s a. Parser e s a -> Parser e s Int
measure_ Parser e s a
p = forall e s. Parser e s Int# -> Parser e s Int
boxInt (forall e s a. Parser e s a -> Parser e s Int#
measure_# Parser e s a
p)

-- | Variant of 'measure_' with an unboxed result.
measure_# :: Parser e s a -> Parser e s Int#
{-# inline measure_# #-}
measure_# :: forall e s a. Parser e s a -> Parser e s Int#
measure_# (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  (\x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
_, Int#
pre, Int#
_ #) State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e a
r #) -> case Result# e a
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# a
_, Int#
post, Int#
c #) #) -> (# State# s
s1, (# | (# Int#
post Int# -> Int# -> Int#
-# Int#
pre,Int#
post,Int#
c #) #) #)
  )



-- | Run a parser in a delimited context, failing if the requested number
-- of bytes are not available or if the delimited parser does not
-- consume all input. This combinator can be understood as a composition
-- of 'take', 'effect', 'parseBytesEffectfully', and 'endOfInput'. It is
-- provided as a single combinator because for convenience and because it is
-- easy to make mistakes when manually assembling the aforementioned parsers.
-- The pattern of prefixing an encoding with its length is common.
-- This is discussed more in
-- <https://github.com/bos/attoparsec/issues/129 attoparsec issue #129>.
--
-- > delimit e1 e2 n remaining === take e1 n
delimit ::
     e -- ^ Error message when not enough bytes are present
  -> e -- ^ Error message when delimited parser does not consume all input
  -> Int -- ^ Exact number of bytes delimited parser is expected to consume
  -> Parser e s a -- ^ Parser to execute in delimited context
  -> Parser e s a
{-# inline delimit #-}
delimit :: forall e s a. e -> e -> Int -> Parser e s a -> Parser e s a
delimit e
esz e
eleftovers (I# Int#
n) (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f) = forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
  ( \(# ByteArray#
arr, Int#
off, Int#
len #) State# s
s0 -> case Int#
len Int# -> Int# -> Int#
>=# Int#
n of
    Int#
1# -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (# ByteArray#
arr, Int#
off, Int#
n #) State# s
s0 of
      (# State# s
s1, Result# e a
r #) -> case Result# e a
r of
        (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
        (# | (# a
a, Int#
newOff, Int#
leftovers #) #) -> case Int#
leftovers of
          Int#
0# -> (# State# s
s1, (# | (# a
a, Int#
newOff, Int#
len Int# -> Int# -> Int#
-# Int#
n #) #) #)
          Int#
_ -> (# State# s
s1, (# e
eleftovers | #) #)
    Int#
_ -> (# State# s
s0, (# e
esz | #) #)
  )

-- | Replicate a parser @n@ times, writing the results into
-- an array of length @n@. For @Array@ and @SmallArray@, this
-- is lazy in the elements, so be sure the they result of the
-- parser is evaluated appropriately to avoid unwanted thunks.
replicate :: forall arr e s a. (Contiguous arr, Element arr a)
  => Int -- ^ Number of times to run the parser
  -> Parser e s a -- ^ Parser
  -> Parser e s (arr a)
{-# inline replicate #-}
replicate :: forall (arr :: * -> *) e s a.
(Contiguous arr, Element arr a) =>
Int -> Parser e s a -> Parser e s (arr a)
replicate !Int
len Parser e s a
p = do
  Mutable arr s a
marr <- forall s a e. ST s a -> Parser e s a
effect (forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Int -> m (Mutable arr (PrimState m) b)
C.new Int
len)
  let go :: Int -> Parser e s (arr a)
      go :: Int -> Parser e s (arr a)
go !Int
ix = if Int
ix forall a. Ord a => a -> a -> Bool
< Int
len
        then do
          a
a <- Parser e s a
p
          forall s a e. ST s a -> Parser e s a
effect (forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> Int -> b -> m ()
C.write Mutable arr s a
marr Int
ix a
a)
          Int -> Parser e s (arr a)
go (Int
ix forall a. Num a => a -> a -> a
+ Int
1)
        else forall s a e. ST s a -> Parser e s a
effect (forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> m (arr b)
C.unsafeFreeze Mutable arr s a
marr)
  Int -> Parser e s (arr a)
go Int
0

unI :: Int -> Int#
{-# inline unI #-}
unI :: Int -> Int#
unI (I# Int#
w) = Int#
w