    {-# LANGUAGE CPP               #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE Rank2Types        #-}

    {- |
    Module      : Network.Socks5.Parse
    License     : BSD-style
    Copyright   : (c) 2010-2019 Vincent Hanquez <vincent@snarc.org>
    Stability   : experimental
    Portability : portable

    A very simple bytestring parser related to Parsec and Attoparsec.

    Simple example:

    > > parse ((,) <$> take 2 <*> byte 0x20 <*> (bytes "abc" *> anyByte)) "xx abctest"
    > ParseOK "est" ("xx", 116)
    -}

    module Network.Socks5.Parse
      ( Parser
      , Result (..)
        -- * run the Parser

      , parse
      , parseFeed
        -- * Parser methods

      , byte
      , anyByte
      , bytes
      , take
      , takeWhile
      , takeAll
      , skip
      , skipWhile
      , skipAll
      , takeStorable
      ) where

    import           Control.Applicative ( Alternative (..) )
    import           Control.Monad ( MonadPlus (..) )
    import           Data.ByteString ( ByteString )
    import qualified Data.ByteString as B
    import qualified Data.ByteString.Internal as B ( toForeignPtr )
    import           Data.Word ( Word8 )
    import           Foreign.ForeignPtr ( withForeignPtr )
    import           Foreign.Storable ( Storable, peekByteOff, sizeOf )
    import           Prelude hiding ( take, takeWhile )
    import           System.IO.Unsafe ( unsafePerformIO )

    -- | Simple parsing result, that represent respectively:

    --

    -- * failure: with the error message

    --

    -- * continuation: that need for more input data

    --

    -- * success: the remaining unparsed data and the parser value

    data Result a =
        ParseFail String
      | ParseMore (ByteString -> Result a)
      | ParseOK   ByteString a

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

    type Failure r = ByteString -> String -> Result r

    type Success a r = ByteString -> a -> Result r

    -- | Simple ByteString parser structure.

    newtype Parser a = Parser
      { forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser :: forall r . ByteString -> Failure r -> Success a r -> Result r
      }

    instance Monad Parser where
      Parser a
    m >>= :: forall a b. Parser a -> (a -> Parser b) -> Parser b
    >>= a -> Parser b
    k = (forall r. ByteString -> Failure r -> Success b r -> Result r)
    -> Parser b
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success b r -> Result r)
     -> Parser b)
    -> (forall r. ByteString -> Failure r -> Success b r -> Result r)
    -> Parser b
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success b r
    ok ->
        Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser Parser a
    m ByteString
    buf Failure r
    err (\ByteString
    buf' a
    a -> Parser b
    -> forall r. ByteString -> Failure r -> Success b r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser (a -> Parser b
    k a
    a) ByteString
    buf' Failure r
    err Success b r
    ok)

    #if MIN_VERSION_base(4,13,0)
    instance MonadFail Parser where
    #endif
      fail :: forall a. String -> Parser a
    fail String
    errorMsg = (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success a r -> Result r)
     -> Parser a)
    -> (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success a r
    _ -> Failure r
    err ByteString
    buf (String
    "failed: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    errorMsg)

    instance MonadPlus Parser where
      mzero :: forall a. Parser a
    mzero = String -> Parser a
    forall a. String -> Parser a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Parser.MonadPlus.mzero"
      mplus :: forall a. Parser a -> Parser a -> Parser a
    mplus Parser a
    f Parser a
    g = (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success a r -> Result r)
     -> Parser a)
    -> (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success a r
    ok ->
        -- rewrite the err callback of @f to call @g

        Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser Parser a
    f ByteString
    buf (\ByteString
    _ String
    _ -> Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser Parser a
    g ByteString
    buf Failure r
    err Success a r
    ok) Success a r
    ok

    instance Functor Parser where
      fmap :: forall a b. (a -> b) -> Parser a -> Parser b
    fmap a -> b
    f Parser a
    p = (forall r. ByteString -> Failure r -> Success b r -> Result r)
    -> Parser b
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success b r -> Result r)
     -> Parser b)
    -> (forall r. ByteString -> Failure r -> Success b r -> Result r)
    -> Parser b
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success b r
    ok ->
        Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser Parser a
    p ByteString
    buf Failure r
    err (\ByteString
    b a
    a -> Success b r
    ok ByteString
    b (a -> b
    f a
    a))

    instance Applicative Parser where
      pure :: forall a. a -> Parser a
    pure a
    v = (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success a r -> Result r)
     -> Parser a)
    -> (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    _ Success a r
    ok -> Success a r
    ok ByteString
    buf a
    v
      <*> :: forall a b. Parser (a -> b) -> Parser a -> Parser b
    (<*>) Parser (a -> b)
    d Parser a
    e = Parser (a -> b)
    d Parser (a -> b) -> ((a -> b) -> Parser b) -> Parser b
    forall a b. Parser a -> (a -> Parser b) -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \a -> b
    b -> Parser a
    e Parser a -> (a -> Parser b) -> Parser b
    forall a b. Parser a -> (a -> Parser b) -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \a
    a -> b -> Parser b
    forall a. a -> Parser a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a -> b
    b a
    a)

    instance Alternative Parser where
      empty :: forall a. Parser a
    empty = String -> Parser a
    forall a. String -> Parser a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Parser.Alternative.empty"
      <|> :: forall a. Parser a -> Parser a -> Parser a
    (<|>) = Parser a -> Parser a -> Parser a
    forall a. Parser a -> Parser a -> Parser a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    mplus

    -- | Run a parser on an @initial ByteString.

    --

    -- If the Parser needs more data than available, the @feeder function is

    -- automatically called and fed to the More continuation.

    parseFeed ::
         Monad m
      => m B.ByteString
      -> Parser a
      -> B.ByteString
      -> m (Result a)
    parseFeed :: forall (m :: * -> *) a.
    Monad m =>
    m ByteString -> Parser a -> ByteString -> m (Result a)
    parseFeed m ByteString
    feeder Parser a
    p ByteString
    initial = Result a -> m (Result a)
    forall {a}. Result a -> m (Result a)
    loop (Result a -> m (Result a)) -> Result a -> m (Result a)
    forall a b. (a -> b) -> a -> b
    $ Parser a -> ByteString -> Result a
    forall a. Parser a -> ByteString -> Result a
    parse Parser a
    p ByteString
    initial
     where
      loop :: Result a -> m (Result a)
    loop (ParseMore ByteString -> Result a
    k) = m ByteString
    feeder m ByteString -> (ByteString -> m (Result a)) -> m (Result a)
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Result a -> m (Result a)
    loop (Result a -> m (Result a))
    -> (ByteString -> Result a) -> ByteString -> m (Result a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Result a
    k)
      loop Result a
    r             = Result a -> m (Result a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Result a
    r

    -- | Run a Parser on a ByteString and return a 'Result'.

    parse :: Parser a -> ByteString -> Result a
    parse :: forall a. Parser a -> ByteString -> Result a
    parse Parser a
    p ByteString
    s = Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser Parser a
    p ByteString
    s (\ByteString
    _ String
    msg -> String -> Result a
    forall a. String -> Result a
    ParseFail String
    msg) Success a a
    forall a. ByteString -> a -> Result a
    ParseOK

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

    getMore :: Parser ()
    getMore :: Parser ()
    getMore = (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success () r -> Result r)
     -> Parser ())
    -> (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success () r
    ok -> (ByteString -> Result r) -> Result r
    forall a. (ByteString -> Result a) -> Result a
    ParseMore ((ByteString -> Result r) -> Result r)
    -> (ByteString -> Result r) -> Result r
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    nextChunk ->
      if ByteString -> Bool
    B.null ByteString
    nextChunk
        then Failure r
    err ByteString
    buf String
    "EOL: need more data"
        else Success () r
    ok (ByteString -> ByteString -> ByteString
    B.append ByteString
    buf ByteString
    nextChunk) ()

    getAll :: Parser ()
    getAll :: Parser ()
    getAll = (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success () r -> Result r)
     -> Parser ())
    -> (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success () r
    ok -> (ByteString -> Result r) -> Result r
    forall a. (ByteString -> Result a) -> Result a
    ParseMore ((ByteString -> Result r) -> Result r)
    -> (ByteString -> Result r) -> Result r
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    nextChunk ->
      if ByteString -> Bool
    B.null ByteString
    nextChunk
        then Success () r
    ok ByteString
    buf ()
        else Parser ()
    -> forall r. ByteString -> Failure r -> Success () r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser Parser ()
    getAll (ByteString -> ByteString -> ByteString
    B.append ByteString
    buf ByteString
    nextChunk) Failure r
    err Success () r
    ok

    flushAll :: Parser ()
    flushAll :: Parser ()
    flushAll = (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success () r -> Result r)
     -> Parser ())
    -> (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success () r
    ok -> (ByteString -> Result r) -> Result r
    forall a. (ByteString -> Result a) -> Result a
    ParseMore ((ByteString -> Result r) -> Result r)
    -> (ByteString -> Result r) -> Result r
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    nextChunk ->
      if ByteString -> Bool
    B.null ByteString
    nextChunk
        then Success () r
    ok ByteString
    buf ()
        else Parser ()
    -> forall r. ByteString -> Failure r -> Success () r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser Parser ()
    getAll ByteString
    B.empty Failure r
    err Success () r
    ok

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

    -- | Get the next byte from the parser.

    anyByte :: Parser Word8
    anyByte :: Parser Word8
    anyByte = (forall r. ByteString -> Failure r -> Success Word8 r -> Result r)
    -> Parser Word8
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success Word8 r -> Result r)
     -> Parser Word8)
    -> (forall r.
        ByteString -> Failure r -> Success Word8 r -> Result r)
    -> Parser Word8
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success Word8 r
    ok ->
      case ByteString -> Maybe (Word8, ByteString)
    B.uncons ByteString
    buf of
        Maybe (Word8, ByteString)
    Nothing -> Parser Word8
    -> forall r. ByteString -> Failure r -> Success Word8 r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser (Parser ()
    getMore Parser () -> Parser Word8 -> Parser Word8
    forall a b. Parser a -> Parser b -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Parser Word8
    anyByte) ByteString
    buf Failure r
    err Success Word8 r
    ok
        Just (Word8
    c1,ByteString
    b2) -> Success Word8 r
    ok ByteString
    b2 Word8
    c1

    -- | Parse a specific byte at current position.

    --

    -- If the byte is different than the expected one, this parser will raise a

    -- failure.

    byte :: Word8 -> Parser ()
    byte :: Word8 -> Parser ()
    byte Word8
    w = (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success () r -> Result r)
     -> Parser ())
    -> (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success () r
    ok ->
      case ByteString -> Maybe (Word8, ByteString)
    B.uncons ByteString
    buf of
        Maybe (Word8, ByteString)
    Nothing -> Parser ()
    -> forall r. ByteString -> Failure r -> Success () r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser (Parser ()
    getMore Parser () -> Parser () -> Parser ()
    forall a b. Parser a -> Parser b -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Word8 -> Parser ()
    byte Word8
    w) ByteString
    buf Failure r
    err Success () r
    ok
        Just (Word8
    c1,ByteString
    b2)
          | Word8
    c1 Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    w -> Success () r
    ok ByteString
    b2 ()
          | Bool
    otherwise -> Failure r
    err ByteString
    buf (String
    "byte " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    w String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " : failed")

    -- | Parse a sequence of bytes from current position.

    --

    -- If the following bytes don't match the expected bytestring completely, the

    -- parser will raise a failure.

    bytes :: ByteString -> Parser ()
    bytes :: ByteString -> Parser ()
    bytes ByteString
    allExpected = ByteString -> Parser ()
    consumeEq ByteString
    allExpected
     where
      errMsg :: String
    errMsg = String
    "bytes " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ByteString -> String
    forall a. Show a => a -> String
    show ByteString
    allExpected String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " : failed"

      -- Partially consume as much as possible or raise an error.

      consumeEq :: ByteString -> Parser ()
    consumeEq ByteString
    expected = (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success () r -> Result r)
     -> Parser ())
    -> (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    actual Failure r
    err Success () r
    ok ->
        let eLen :: Int
    eLen = ByteString -> Int
    B.length ByteString
    expected
        in  if ByteString -> Int
    B.length ByteString
    actual Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    eLen
              then -- enough data for doing a full match

                let (ByteString
    aMatch,ByteString
    aRem) = Int -> ByteString -> (ByteString, ByteString)
    B.splitAt Int
    eLen ByteString
    actual
                in  if ByteString
    aMatch ByteString -> ByteString -> Bool
    forall a. Eq a => a -> a -> Bool
    == ByteString
    expected
                      then Success () r
    ok ByteString
    aRem ()
                      else Failure r
    err ByteString
    actual String
    errMsg
              else -- not enough data, match as much as we have, and then recurse.

                let (ByteString
    eMatch, ByteString
    eRem) = Int -> ByteString -> (ByteString, ByteString)
    B.splitAt (ByteString -> Int
    B.length ByteString
    actual) ByteString
    expected
                in  if ByteString
    actual ByteString -> ByteString -> Bool
    forall a. Eq a => a -> a -> Bool
    == ByteString
    eMatch
                      then Parser ()
    -> forall r. ByteString -> Failure r -> Success () r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser (Parser ()
    getMore Parser () -> Parser () -> Parser ()
    forall a b. Parser a -> Parser b -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ByteString -> Parser ()
    consumeEq ByteString
    eRem) ByteString
    B.empty Failure r
    err Success () r
    ok
                      else Failure r
    err ByteString
    actual String
    errMsg

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

    -- | Take a storable from the current position in the stream.

    takeStorable :: Storable d => Parser d
    takeStorable :: forall d. Storable d => Parser d
    takeStorable = d -> Parser d
    forall d. Storable d => d -> Parser d
    anyStorable d
    forall a. HasCallStack => a
    undefined
     where
      anyStorable :: Storable d => d -> Parser d
      anyStorable :: forall d. Storable d => d -> Parser d
    anyStorable d
    a = do
        (fptr, off, _) <- ByteString -> (ForeignPtr Word8, Int, Int)
    B.toForeignPtr (ByteString -> (ForeignPtr Word8, Int, Int))
    -> Parser ByteString -> Parser (ForeignPtr Word8, Int, Int)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> Parser ByteString
    take (d -> Int
    forall a. Storable a => a -> Int
    sizeOf d
    a)
        return $ unsafePerformIO $ withForeignPtr fptr $ \Ptr Word8
    ptr -> Ptr Word8 -> Int -> IO d
    forall b. Ptr b -> Int -> IO d
    forall a b. Storable a => Ptr b -> Int -> IO a
    peekByteOff Ptr Word8
    ptr Int
    off

    -- | Take @n@ bytes from the current position in the stream.

    take :: Int -> Parser ByteString
    take :: Int -> Parser ByteString
    take Int
    n = (forall r.
     ByteString -> Failure r -> Success ByteString r -> Result r)
    -> Parser ByteString
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r.
      ByteString -> Failure r -> Success ByteString r -> Result r)
     -> Parser ByteString)
    -> (forall r.
        ByteString -> Failure r -> Success ByteString r -> Result r)
    -> Parser ByteString
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success ByteString r
    ok ->
      if ByteString -> Int
    B.length ByteString
    buf Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    n
        then
          let (ByteString
    b1,ByteString
    b2) = Int -> ByteString -> (ByteString, ByteString)
    B.splitAt Int
    n ByteString
    buf
          in  Success ByteString r
    ok ByteString
    b2 ByteString
    b1
        else Parser ByteString
    -> forall r.
       ByteString -> Failure r -> Success ByteString r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser (Parser ()
    getMore Parser () -> Parser ByteString -> Parser ByteString
    forall a b. Parser a -> Parser b -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Int -> Parser ByteString
    take Int
    n) ByteString
    buf Failure r
    err Success ByteString r
    ok

    -- | Take bytes while the @predicate hold from the current position in the

    -- stream.

    takeWhile :: (Word8 -> Bool) -> Parser ByteString
    takeWhile :: (Word8 -> Bool) -> Parser ByteString
    takeWhile Word8 -> Bool
    predicate = (forall r.
     ByteString -> Failure r -> Success ByteString r -> Result r)
    -> Parser ByteString
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r.
      ByteString -> Failure r -> Success ByteString r -> Result r)
     -> Parser ByteString)
    -> (forall r.
        ByteString -> Failure r -> Success ByteString r -> Result r)
    -> Parser ByteString
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success ByteString r
    ok ->
      case (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
    B.span Word8 -> Bool
    predicate ByteString
    buf of
        (ByteString
    _, ByteString
    b2) | ByteString -> Bool
    B.null ByteString
    b2 -> Parser ByteString
    -> forall r.
       ByteString -> Failure r -> Success ByteString r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser (Parser ()
    getMore Parser () -> Parser ByteString -> Parser ByteString
    forall a b. Parser a -> Parser b -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Word8 -> Bool) -> Parser ByteString
    takeWhile Word8 -> Bool
    predicate) ByteString
    buf Failure r
    err Success ByteString r
    ok
        (ByteString
    b1, ByteString
    b2) -> Success ByteString r
    ok ByteString
    b2 ByteString
    b1

    -- | Take the remaining bytes from the current position in the stream.

    takeAll :: Parser ByteString
    takeAll :: Parser ByteString
    takeAll = (forall r.
     ByteString -> Failure r -> Success ByteString r -> Result r)
    -> Parser ByteString
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r.
      ByteString -> Failure r -> Success ByteString r -> Result r)
     -> Parser ByteString)
    -> (forall r.
        ByteString -> Failure r -> Success ByteString r -> Result r)
    -> Parser ByteString
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success ByteString r
    ok ->
      Parser ByteString
    -> forall r.
       ByteString -> Failure r -> Success ByteString r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser (Parser ()
    getAll Parser () -> Parser ByteString -> Parser ByteString
    forall a b. Parser a -> Parser b -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Parser ByteString
    returnBuffer) ByteString
    buf Failure r
    err Success ByteString r
    ok
     where
      returnBuffer :: Parser ByteString
    returnBuffer = (forall r.
     ByteString -> Failure r -> Success ByteString r -> Result r)
    -> Parser ByteString
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r.
      ByteString -> Failure r -> Success ByteString r -> Result r)
     -> Parser ByteString)
    -> (forall r.
        ByteString -> Failure r -> Success ByteString r -> Result r)
    -> Parser ByteString
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    _ Success ByteString r
    ok -> Success ByteString r
    ok ByteString
    B.empty ByteString
    buf

    -- | Skip @n@ bytes from the current position in the stream.

    skip :: Int -> Parser ()
    skip :: Int -> Parser ()
    skip Int
    n = (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success () r -> Result r)
     -> Parser ())
    -> (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success () r
    ok ->
      if ByteString -> Int
    B.length ByteString
    buf Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    n
        then Success () r
    ok (Int -> ByteString -> ByteString
    B.drop Int
    n ByteString
    buf) ()
        else Parser ()
    -> forall r. ByteString -> Failure r -> Success () r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser (Parser ()
    getMore Parser () -> Parser () -> Parser ()
    forall a b. Parser a -> Parser b -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Int -> Parser ()
    skip (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - ByteString -> Int
    B.length ByteString
    buf)) ByteString
    B.empty Failure r
    err Success () r
    ok

    -- | Skip bytes while the @predicate@ holds from the current position in the

    -- stream.

    skipWhile :: (Word8 -> Bool) -> Parser ()
    skipWhile :: (Word8 -> Bool) -> Parser ()
    skipWhile Word8 -> Bool
    p = (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success () r -> Result r)
     -> Parser ())
    -> (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success () r
    ok ->
      case (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
    B.span Word8 -> Bool
    p ByteString
    buf of
        (ByteString
    _, ByteString
    b2) | ByteString -> Bool
    B.null ByteString
    b2 -> Parser ()
    -> forall r. ByteString -> Failure r -> Success () r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser (Parser ()
    getMore Parser () -> Parser () -> Parser ()
    forall a b. Parser a -> Parser b -> Parser b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (Word8 -> Bool) -> Parser ()
    skipWhile Word8 -> Bool
    p) ByteString
    B.empty Failure r
    err Success () r
    ok
        (ByteString
    _, ByteString
    b2) -> Success () r
    ok ByteString
    b2 ()

    -- | Skip all the remaining bytes from the current position in the stream.

    skipAll :: Parser ()
    skipAll :: Parser ()
    skipAll = (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a.
    (forall r. ByteString -> Failure r -> Success a r -> Result r)
    -> Parser a
    Parser ((forall r. ByteString -> Failure r -> Success () r -> Result r)
     -> Parser ())
    -> (forall r. ByteString -> Failure r -> Success () r -> Result r)
    -> Parser ()
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    buf Failure r
    err Success () r
    ok -> Parser ()
    -> forall r. ByteString -> Failure r -> Success () r -> Result r
    forall a.
    Parser a
    -> forall r. ByteString -> Failure r -> Success a r -> Result r
    runParser Parser ()
    flushAll ByteString
    buf Failure r
    err Success () r
    ok