    -- |
    -- Module      : Data.ASN1.BinaryEncoding.Parse
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : unknown
    --
    -- Generic parsing facility for ASN1.
    --
    module Data.ASN1.BinaryEncoding.Parse
        (
        -- * incremental parsing interfaces
          runParseState
        , isParseDone
        , newParseState
        , ParseState
        , ParseCursor
        -- * simple parsing interfaces
        , parseLBS
        , parseBS
        ) where

    import Control.Arrow (first)
    import Data.ByteString (ByteString)
    import qualified Data.ByteString as B
    import qualified Data.ByteString.Lazy as L
    import Data.ASN1.Error
    import Data.ASN1.Types
    import Data.ASN1.Types.Lowlevel
    import Data.ASN1.Get
    import Data.ASN1.Serialize
    import Data.Word
    import Data.Maybe (fromJust)

    -- | nothing means the parser stop this construction on
    -- an ASN1 end tag, otherwise specify the position
    -- where the construction terminate.
    type ConstructionEndAt = Maybe Word64

    data ParseExpect = ExpectHeader (Maybe (B.ByteString -> Result ASN1Header))
                     | ExpectPrimitive Word64 (Maybe (B.ByteString -> Result ByteString))

    type ParsePosition = Word64

    -- | represent the parsing state of an ASN1 stream.
    --
    -- * the stack of constructed elements.
    -- * the next expected type.
    -- * the position in the stream.
    --
    data ParseState = ParseState [ConstructionEndAt] ParseExpect ParsePosition

    -- | create a new empty parse state. position is 0
    newParseState :: ParseState
    newParseState :: ParseState
    newParseState = [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState [] (Maybe (ByteString -> Result ASN1Header) -> ParseExpect
    ExpectHeader Maybe (ByteString -> Result ASN1Header)
    forall a. Maybe a
    Nothing) Word64
    0

    isEOC :: ASN1Header -> Bool
    isEOC :: ASN1Header -> Bool
    isEOC (ASN1Header ASN1Class
    cl Int
    t Bool
    _ ASN1Length
    _) = ASN1Class
    cl ASN1Class -> ASN1Class -> Bool
    forall a. Eq a => a -> a -> Bool
    == ASN1Class
    Universal Bool -> Bool -> Bool
    && Int
    t Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0

    asn1LengthToConst :: ASN1Length -> Maybe Word64
    asn1LengthToConst :: ASN1Length -> ConstructionEndAt
    asn1LengthToConst (LenShort Int
    n)  = Word64 -> ConstructionEndAt
    forall a. a -> Maybe a
    Just (Word64 -> ConstructionEndAt) -> Word64 -> ConstructionEndAt
    forall a b. (a -> b) -> a -> b
    $ Int -> Word64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n
    asn1LengthToConst (LenLong Int
    _ Int
    n) = Word64 -> ConstructionEndAt
    forall a. a -> Maybe a
    Just (Word64 -> ConstructionEndAt) -> Word64 -> ConstructionEndAt
    forall a b. (a -> b) -> a -> b
    $ Int -> Word64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n
    asn1LengthToConst ASN1Length
    LenIndefinite = ConstructionEndAt
    forall a. Maybe a
    Nothing

    -- in the future, drop this for the `mplus` with Either.
    mplusEither :: Either b a -> (a -> Either b c) -> Either b c
    mplusEither :: forall b a c. Either b a -> (a -> Either b c) -> Either b c
    mplusEither (Left b
    e) a -> Either b c
    _  = b -> Either b c
    forall a b. a -> Either a b
    Left b
    e
    mplusEither (Right a
    e) a -> Either b c
    f = a -> Either b c
    f a
    e

    -- | Represent the events and state thus far.
    type ParseCursor = ([ASN1Event], ParseState)

    -- | run incrementally the ASN1 parser on a bytestring.
    -- the result can be either an error, or on success a list
    -- of events, and the new parsing state.
    runParseState :: ParseState -- ^ parser state
                  -> ByteString -- ^ input data as bytes
                  -> Either ASN1Error ParseCursor
    runParseState :: ParseState -> ByteString -> Either ASN1Error ParseCursor
    runParseState = ParseState -> ByteString -> Either ASN1Error ParseCursor
    loop
         where
               loop :: ParseState -> ByteString -> Either ASN1Error ParseCursor
    loop ParseState
    iniState ByteString
    bs
                    | ByteString -> Bool
    B.null ByteString
    bs = (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall {b}. (ParseCursor, b) -> Either ASN1Error (ParseCursor, b)
    terminateAugment (([], ParseState
    iniState), ByteString
    bs) Either ASN1Error (ParseCursor, ByteString)
    -> ((ParseCursor, ByteString) -> Either ASN1Error ParseCursor)
    -> Either ASN1Error ParseCursor
    forall b a c. Either b a -> (a -> Either b c) -> Either b c
    `mplusEither` (ParseCursor -> Either ASN1Error ParseCursor
    forall a b. b -> Either a b
    Right (ParseCursor -> Either ASN1Error ParseCursor)
    -> ((ParseCursor, ByteString) -> ParseCursor)
    -> (ParseCursor, ByteString)
    -> Either ASN1Error ParseCursor
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ParseCursor, ByteString) -> ParseCursor
    forall a b. (a, b) -> a
    fst)
                    | Bool
    otherwise = ParseState
    -> ByteString -> Either ASN1Error (ParseCursor, ByteString)
    go ParseState
    iniState ByteString
    bs Either ASN1Error (ParseCursor, ByteString)
    -> ((ParseCursor, ByteString)
        -> Either ASN1Error (ParseCursor, ByteString))
    -> Either ASN1Error (ParseCursor, ByteString)
    forall b a c. Either b a -> (a -> Either b c) -> Either b c
    `mplusEither` (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall {b}. (ParseCursor, b) -> Either ASN1Error (ParseCursor, b)
    terminateAugment
                                                 Either ASN1Error (ParseCursor, ByteString)
    -> ((ParseCursor, ByteString) -> Either ASN1Error ParseCursor)
    -> Either ASN1Error ParseCursor
    forall b a c. Either b a -> (a -> Either b c) -> Either b c
    `mplusEither` \(([ASN1Event]
    evs, ParseState
    newState), ByteString
    nbs) -> ParseState -> ByteString -> Either ASN1Error ParseCursor
    loop ParseState
    newState ByteString
    nbs
                                                 Either ASN1Error ParseCursor
    -> (ParseCursor -> Either ASN1Error ParseCursor)
    -> Either ASN1Error ParseCursor
    forall b a c. Either b a -> (a -> Either b c) -> Either b c
    `mplusEither` (ParseCursor -> Either ASN1Error ParseCursor
    forall a b. b -> Either a b
    Right (ParseCursor -> Either ASN1Error ParseCursor)
    -> (ParseCursor -> ParseCursor)
    -> ParseCursor
    -> Either ASN1Error ParseCursor
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([ASN1Event] -> [ASN1Event]) -> ParseCursor -> ParseCursor
    forall b c d. (b -> c) -> (b, d) -> (c, d)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first ([ASN1Event]
    evs [ASN1Event] -> [ASN1Event] -> [ASN1Event]
    forall a. [a] -> [a] -> [a]
    ++))

               terminateAugment :: (ParseCursor, b) -> Either ASN1Error (ParseCursor, b)
    terminateAugment ret :: (ParseCursor, b)
    ret@(([ASN1Event]
    evs, ParseState [ConstructionEndAt]
    stackEnd ParseExpect
    pe Word64
    pos), b
    r) =
                    case [ConstructionEndAt]
    stackEnd of
                        Just Word64
    endPos:[ConstructionEndAt]
    xs
                             | Word64
    pos Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Word64
    endPos  -> ASN1Error -> Either ASN1Error (ParseCursor, b)
    forall a b. a -> Either a b
    Left ASN1Error
    StreamConstructionWrongSize
                             | Word64
    pos Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    endPos -> (ParseCursor, b) -> Either ASN1Error (ParseCursor, b)
    terminateAugment (([ASN1Event]
    evs [ASN1Event] -> [ASN1Event] -> [ASN1Event]
    forall a. [a] -> [a] -> [a]
    ++ [ASN1Event
    ConstructionEnd], [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState [ConstructionEndAt]
    xs ParseExpect
    pe Word64
    pos), b
    r)
                             | Bool
    otherwise     -> (ParseCursor, b) -> Either ASN1Error (ParseCursor, b)
    forall a b. b -> Either a b
    Right (ParseCursor, b)
    ret
                        [ConstructionEndAt]
    _                    -> (ParseCursor, b) -> Either ASN1Error (ParseCursor, b)
    forall a b. b -> Either a b
    Right (ParseCursor, b)
    ret

               -- go get one element (either a primitive or a header) from the bytes
               -- and returns the new cursor and the remaining byte.
               go :: ParseState -> ByteString -> Either ASN1Error (ParseCursor, ByteString)
               go :: ParseState
    -> ByteString -> Either ASN1Error (ParseCursor, ByteString)
    go (ParseState [ConstructionEndAt]
    stackEnd (ExpectHeader Maybe (ByteString -> Result ASN1Header)
    cont) Word64
    pos) ByteString
    bs =
                    case Maybe (ByteString -> Result ASN1Header)
    -> Word64 -> ByteString -> Result ASN1Header
    runGetHeader Maybe (ByteString -> Result ASN1Header)
    cont Word64
    pos ByteString
    bs of
                         Fail String
    s                 -> ASN1Error -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. a -> Either a b
    Left (ASN1Error -> Either ASN1Error (ParseCursor, ByteString))
    -> ASN1Error -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. (a -> b) -> a -> b
    $ String -> ASN1Error
    ParsingHeaderFail String
    s
                         Partial ByteString -> Result ASN1Header
    f              -> (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. b -> Either a b
    Right (([], [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState [ConstructionEndAt]
    stackEnd (Maybe (ByteString -> Result ASN1Header) -> ParseExpect
    ExpectHeader (Maybe (ByteString -> Result ASN1Header) -> ParseExpect)
    -> Maybe (ByteString -> Result ASN1Header) -> ParseExpect
    forall a b. (a -> b) -> a -> b
    $ (ByteString -> Result ASN1Header)
    -> Maybe (ByteString -> Result ASN1Header)
    forall a. a -> Maybe a
    Just ByteString -> Result ASN1Header
    f) Word64
    pos), ByteString
    B.empty)
                         Done ASN1Header
    hdr Word64
    nPos ByteString
    remBytes
                            | ASN1Header -> Bool
    isEOC ASN1Header
    hdr -> case [ConstructionEndAt]
    stackEnd of
                                               []                  -> (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. b -> Either a b
    Right (([], [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState [] (Maybe (ByteString -> Result ASN1Header) -> ParseExpect
    ExpectHeader Maybe (ByteString -> Result ASN1Header)
    forall a. Maybe a
    Nothing) Word64
    nPos), ByteString
    remBytes)
                                               Just Word64
    _:[ConstructionEndAt]
    _            -> ASN1Error -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. a -> Either a b
    Left ASN1Error
    StreamUnexpectedEOC
                                               ConstructionEndAt
    Nothing:[ConstructionEndAt]
    newStackEnd -> (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. b -> Either a b
    Right ( ( [ASN1Event
    ConstructionEnd]
                                                                              , [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState [ConstructionEndAt]
    newStackEnd (Maybe (ByteString -> Result ASN1Header) -> ParseExpect
    ExpectHeader Maybe (ByteString -> Result ASN1Header)
    forall a. Maybe a
    Nothing) Word64
    nPos)
                                                                            , ByteString
    remBytes)
                            | Bool
    otherwise -> case ASN1Header
    hdr of
                                           (ASN1Header ASN1Class
    _ Int
    _ Bool
    True ASN1Length
    len)  ->
                                               let nEnd :: ConstructionEndAt
    nEnd = (Word64
    nPos Word64 -> Word64 -> Word64
    forall a. Num a => a -> a -> a
    +) (Word64 -> Word64) -> ConstructionEndAt -> ConstructionEndAt
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` ASN1Length -> ConstructionEndAt
    asn1LengthToConst ASN1Length
    len
                                               in (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. b -> Either a b
    Right ( ( [ASN1Header -> ASN1Event
    Header ASN1Header
    hdr,ASN1Event
    ConstructionBegin]
                                                          , [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState (ConstructionEndAt
    nEndConstructionEndAt -> [ConstructionEndAt] -> [ConstructionEndAt]
    forall a. a -> [a] -> [a]
    :[ConstructionEndAt]
    stackEnd) (Maybe (ByteString -> Result ASN1Header) -> ParseExpect
    ExpectHeader Maybe (ByteString -> Result ASN1Header)
    forall a. Maybe a
    Nothing) Word64
    nPos)
                                                        , ByteString
    remBytes)
                                           (ASN1Header ASN1Class
    _ Int
    _ Bool
    False ASN1Length
    LenIndefinite) -> ASN1Error -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. a -> Either a b
    Left ASN1Error
    StreamInfinitePrimitive
                                           (ASN1Header ASN1Class
    _ Int
    _ Bool
    False ASN1Length
    len) ->
                                               let pLength :: Word64
    pLength = ConstructionEndAt -> Word64
    forall a. HasCallStack => Maybe a -> a
    fromJust (ConstructionEndAt -> Word64) -> ConstructionEndAt -> Word64
    forall a b. (a -> b) -> a -> b
    $ ASN1Length -> ConstructionEndAt
    asn1LengthToConst ASN1Length
    len
                                               in if Word64
    pLength Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    0
                                                     then (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. b -> Either a b
    Right ( ( [ASN1Header -> ASN1Event
    Header ASN1Header
    hdr,ByteString -> ASN1Event
    Primitive ByteString
    B.empty]
                                                                  , [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState [ConstructionEndAt]
    stackEnd (Maybe (ByteString -> Result ASN1Header) -> ParseExpect
    ExpectHeader Maybe (ByteString -> Result ASN1Header)
    forall a. Maybe a
    Nothing) Word64
    nPos)
                                                                , ByteString
    remBytes)
                                                     else (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. b -> Either a b
    Right ( ( [ASN1Header -> ASN1Event
    Header ASN1Header
    hdr]
                                                                  , [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState [ConstructionEndAt]
    stackEnd (Word64 -> Maybe (ByteString -> Result ByteString) -> ParseExpect
    ExpectPrimitive Word64
    pLength Maybe (ByteString -> Result ByteString)
    forall a. Maybe a
    Nothing) Word64
    nPos)
                                                                , ByteString
    remBytes)
               go (ParseState [ConstructionEndAt]
    stackEnd (ExpectPrimitive Word64
    len Maybe (ByteString -> Result ByteString)
    cont) Word64
    pos) ByteString
    bs =
                    case Maybe (ByteString -> Result ByteString)
    -> Word64 -> Word64 -> ByteString -> Result ByteString
    forall {a}.
    Integral a =>
    Maybe (ByteString -> Result ByteString)
    -> a -> Word64 -> ByteString -> Result ByteString
    runGetPrimitive Maybe (ByteString -> Result ByteString)
    cont Word64
    len Word64
    pos ByteString
    bs of
                         Fail String
    _               -> ASN1Error -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. a -> Either a b
    Left ASN1Error
    ParsingPartial
                         Partial ByteString -> Result ByteString
    f            -> (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. b -> Either a b
    Right (([], [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState [ConstructionEndAt]
    stackEnd (Word64 -> Maybe (ByteString -> Result ByteString) -> ParseExpect
    ExpectPrimitive Word64
    len (Maybe (ByteString -> Result ByteString) -> ParseExpect)
    -> Maybe (ByteString -> Result ByteString) -> ParseExpect
    forall a b. (a -> b) -> a -> b
    $ (ByteString -> Result ByteString)
    -> Maybe (ByteString -> Result ByteString)
    forall a. a -> Maybe a
    Just ByteString -> Result ByteString
    f) Word64
    pos), ByteString
    B.empty)
                         Done ByteString
    p Word64
    nPos ByteString
    remBytes -> (ParseCursor, ByteString)
    -> Either ASN1Error (ParseCursor, ByteString)
    forall a b. b -> Either a b
    Right (([ByteString -> ASN1Event
    Primitive ByteString
    p], [ConstructionEndAt] -> ParseExpect -> Word64 -> ParseState
    ParseState [ConstructionEndAt]
    stackEnd (Maybe (ByteString -> Result ASN1Header) -> ParseExpect
    ExpectHeader Maybe (ByteString -> Result ASN1Header)
    forall a. Maybe a
    Nothing) Word64
    nPos), ByteString
    remBytes)

               runGetHeader :: Maybe (ByteString -> Result ASN1Header)
    -> Word64 -> ByteString -> Result ASN1Header
    runGetHeader Maybe (ByteString -> Result ASN1Header)
    Nothing  = \Word64
    pos -> Word64 -> Get ASN1Header -> ByteString -> Result ASN1Header
    forall a. Word64 -> Get a -> ByteString -> Result a
    runGetPos Word64
    pos Get ASN1Header
    getHeader
               runGetHeader (Just ByteString -> Result ASN1Header
    f) = (ByteString -> Result ASN1Header)
    -> Word64 -> ByteString -> Result ASN1Header
    forall a b. a -> b -> a
    const ByteString -> Result ASN1Header
    f

               runGetPrimitive :: Maybe (ByteString -> Result ByteString)
    -> a -> Word64 -> ByteString -> Result ByteString
    runGetPrimitive Maybe (ByteString -> Result ByteString)
    Nothing  a
    n = \Word64
    pos -> Word64 -> Get ByteString -> ByteString -> Result ByteString
    forall a. Word64 -> Get a -> ByteString -> Result a
    runGetPos Word64
    pos (Int -> Get ByteString
    getBytes (Int -> Get ByteString) -> Int -> Get ByteString
    forall a b. (a -> b) -> a -> b
    $ a -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    n)
               runGetPrimitive (Just ByteString -> Result ByteString
    f) a
    _ = (ByteString -> Result ByteString)
    -> Word64 -> ByteString -> Result ByteString
    forall a b. a -> b -> a
    const ByteString -> Result ByteString
    f

    -- | when no more input is available, it's important to check that the parser is
    -- in a finish state too.
    isParseDone :: ParseState -> Bool
    isParseDone :: ParseState -> Bool
    isParseDone (ParseState [] (ExpectHeader Maybe (ByteString -> Result ASN1Header)
    Nothing) Word64
    _) = Bool
    True
    isParseDone ParseState
    _                                        = Bool
    False

    -- | Parse one lazy bytestring and returns on success all ASN1 events associated.
    parseLBS :: L.ByteString -> Either ASN1Error [ASN1Event]
    parseLBS :: ByteString -> Either ASN1Error [ASN1Event]
    parseLBS ByteString
    lbs = (([[ASN1Event]], ParseState)
     -> ByteString -> Either ASN1Error ([[ASN1Event]], ParseState))
    -> ([[ASN1Event]], ParseState)
    -> [ByteString]
    -> Either ASN1Error ([[ASN1Event]], ParseState)
    forall a.
    (a -> ByteString -> Either ASN1Error a)
    -> a -> [ByteString] -> Either ASN1Error a
    foldrEither ([[ASN1Event]], ParseState)
    -> ByteString -> Either ASN1Error ([[ASN1Event]], ParseState)
    process ([], ParseState
    newParseState) (ByteString -> [ByteString]
    L.toChunks ByteString
    lbs) Either ASN1Error ([[ASN1Event]], ParseState)
    -> (([[ASN1Event]], ParseState) -> Either ASN1Error [ASN1Event])
    -> Either ASN1Error [ASN1Event]
    forall b a c. Either b a -> (a -> Either b c) -> Either b c
    `mplusEither` ([[ASN1Event]], ParseState) -> Either ASN1Error [ASN1Event]
    forall {a}. ([[a]], ParseState) -> Either ASN1Error [a]
    onSuccess
        where
              onSuccess :: ([[a]], ParseState) -> Either ASN1Error [a]
    onSuccess ([[a]]
    allEvs, ParseState
    finalState)
                      | ParseState -> Bool
    isParseDone ParseState
    finalState = [a] -> Either ASN1Error [a]
    forall a b. b -> Either a b
    Right ([a] -> Either ASN1Error [a]) -> [a] -> Either ASN1Error [a]
    forall a b. (a -> b) -> a -> b
    $ [[a]] -> [a]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[a]] -> [a]) -> [[a]] -> [a]
    forall a b. (a -> b) -> a -> b
    $ [[a]] -> [[a]]
    forall a. [a] -> [a]
    reverse [[a]]
    allEvs
                      | Bool
    otherwise              = ASN1Error -> Either ASN1Error [a]
    forall a b. a -> Either a b
    Left ASN1Error
    ParsingPartial

              process :: ([[ASN1Event]], ParseState) -> ByteString -> Either ASN1Error ([[ASN1Event]], ParseState)
              process :: ([[ASN1Event]], ParseState)
    -> ByteString -> Either ASN1Error ([[ASN1Event]], ParseState)
    process ([[ASN1Event]]
    pevs, ParseState
    cState) ByteString
    bs = ParseState -> ByteString -> Either ASN1Error ParseCursor
    runParseState ParseState
    cState ByteString
    bs Either ASN1Error ParseCursor
    -> (ParseCursor -> Either ASN1Error ([[ASN1Event]], ParseState))
    -> Either ASN1Error ([[ASN1Event]], ParseState)
    forall b a c. Either b a -> (a -> Either b c) -> Either b c
    `mplusEither` \([ASN1Event]
    es, ParseState
    cState') -> ([[ASN1Event]], ParseState)
    -> Either ASN1Error ([[ASN1Event]], ParseState)
    forall a b. b -> Either a b
    Right ([ASN1Event]
    es [ASN1Event] -> [[ASN1Event]] -> [[ASN1Event]]
    forall a. a -> [a] -> [a]
    : [[ASN1Event]]
    pevs, ParseState
    cState')

              foldrEither :: (a -> ByteString -> Either ASN1Error a) -> a -> [ByteString] -> Either ASN1Error a
              foldrEither :: forall a.
    (a -> ByteString -> Either ASN1Error a)
    -> a -> [ByteString] -> Either ASN1Error a
    foldrEither a -> ByteString -> Either ASN1Error a
    _ a
    acc []     = a -> Either ASN1Error a
    forall a b. b -> Either a b
    Right a
    acc
              foldrEither a -> ByteString -> Either ASN1Error a
    f a
    acc (ByteString
    x:[ByteString]
    xs) = a -> ByteString -> Either ASN1Error a
    f a
    acc ByteString
    x Either ASN1Error a
    -> (a -> Either ASN1Error a) -> Either ASN1Error a
    forall b a c. Either b a -> (a -> Either b c) -> Either b c
    `mplusEither` \a
    nacc -> (a -> ByteString -> Either ASN1Error a)
    -> a -> [ByteString] -> Either ASN1Error a
    forall a.
    (a -> ByteString -> Either ASN1Error a)
    -> a -> [ByteString] -> Either ASN1Error a
    foldrEither a -> ByteString -> Either ASN1Error a
    f a
    nacc [ByteString]
    xs

    -- | Parse one strict bytestring and returns on success all ASN1 events associated.
    parseBS :: ByteString -> Either ASN1Error [ASN1Event]
    parseBS :: ByteString -> Either ASN1Error [ASN1Event]
    parseBS ByteString
    bs = ParseState -> ByteString -> Either ASN1Error ParseCursor
    runParseState ParseState
    newParseState ByteString
    bs Either ASN1Error ParseCursor
    -> (ParseCursor -> Either ASN1Error [ASN1Event])
    -> Either ASN1Error [ASN1Event]
    forall b a c. Either b a -> (a -> Either b c) -> Either b c
    `mplusEither` ParseCursor -> Either ASN1Error [ASN1Event]
    forall {b}. (b, ParseState) -> Either ASN1Error b
    onSuccess
        where onSuccess :: (b, ParseState) -> Either ASN1Error b
    onSuccess (b
    evs, ParseState
    pstate)
                        | ParseState -> Bool
    isParseDone ParseState
    pstate = b -> Either ASN1Error b
    forall a b. b -> Either a b
    Right b
    evs
                        | Bool
    otherwise          = ASN1Error -> Either ASN1Error b
    forall a b. a -> Either a b
    Left ASN1Error
    ParsingPartial