    -- |
    -- Module      : Data.ASN1.Types.Lowlevel
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : unknown
    --
    {-# LANGUAGE BangPatterns #-}
    module Data.ASN1.Types.Lowlevel
        (
        -- * Raw types
          ASN1Class(..)
        , ASN1Tag
        , ASN1Length(..)
        , ASN1Header(..)
        -- * Events types
        , ASN1Event(..)
        ) where

    import Data.ByteString (ByteString)

    -- | Element class
    data ASN1Class = Universal
                   | Application
                   | Context
                   | Private
                   deriving (Int -> ASN1Class -> ShowS
    [ASN1Class] -> ShowS
    ASN1Class -> String
    (Int -> ASN1Class -> ShowS)
    -> (ASN1Class -> String)
    -> ([ASN1Class] -> ShowS)
    -> Show ASN1Class
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ASN1Class -> ShowS
    showsPrec :: Int -> ASN1Class -> ShowS
    $cshow :: ASN1Class -> String
    show :: ASN1Class -> String
    $cshowList :: [ASN1Class] -> ShowS
    showList :: [ASN1Class] -> ShowS
    Show,ASN1Class -> ASN1Class -> Bool
    (ASN1Class -> ASN1Class -> Bool)
    -> (ASN1Class -> ASN1Class -> Bool) -> Eq ASN1Class
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ASN1Class -> ASN1Class -> Bool
    == :: ASN1Class -> ASN1Class -> Bool
    $c/= :: ASN1Class -> ASN1Class -> Bool
    /= :: ASN1Class -> ASN1Class -> Bool
    Eq,Eq ASN1Class
    Eq ASN1Class =>
    (ASN1Class -> ASN1Class -> Ordering)
    -> (ASN1Class -> ASN1Class -> Bool)
    -> (ASN1Class -> ASN1Class -> Bool)
    -> (ASN1Class -> ASN1Class -> Bool)
    -> (ASN1Class -> ASN1Class -> Bool)
    -> (ASN1Class -> ASN1Class -> ASN1Class)
    -> (ASN1Class -> ASN1Class -> ASN1Class)
    -> Ord ASN1Class
    ASN1Class -> ASN1Class -> Bool
    ASN1Class -> ASN1Class -> Ordering
    ASN1Class -> ASN1Class -> ASN1Class
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ASN1Class -> ASN1Class -> Ordering
    compare :: ASN1Class -> ASN1Class -> Ordering
    $c< :: ASN1Class -> ASN1Class -> Bool
    < :: ASN1Class -> ASN1Class -> Bool
    $c<= :: ASN1Class -> ASN1Class -> Bool
    <= :: ASN1Class -> ASN1Class -> Bool
    $c> :: ASN1Class -> ASN1Class -> Bool
    > :: ASN1Class -> ASN1Class -> Bool
    $c>= :: ASN1Class -> ASN1Class -> Bool
    >= :: ASN1Class -> ASN1Class -> Bool
    $cmax :: ASN1Class -> ASN1Class -> ASN1Class
    max :: ASN1Class -> ASN1Class -> ASN1Class
    $cmin :: ASN1Class -> ASN1Class -> ASN1Class
    min :: ASN1Class -> ASN1Class -> ASN1Class
    Ord,Int -> ASN1Class
    ASN1Class -> Int
    ASN1Class -> [ASN1Class]
    ASN1Class -> ASN1Class
    ASN1Class -> ASN1Class -> [ASN1Class]
    ASN1Class -> ASN1Class -> ASN1Class -> [ASN1Class]
    (ASN1Class -> ASN1Class)
    -> (ASN1Class -> ASN1Class)
    -> (Int -> ASN1Class)
    -> (ASN1Class -> Int)
    -> (ASN1Class -> [ASN1Class])
    -> (ASN1Class -> ASN1Class -> [ASN1Class])
    -> (ASN1Class -> ASN1Class -> [ASN1Class])
    -> (ASN1Class -> ASN1Class -> ASN1Class -> [ASN1Class])
    -> Enum ASN1Class
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: ASN1Class -> ASN1Class
    succ :: ASN1Class -> ASN1Class
    $cpred :: ASN1Class -> ASN1Class
    pred :: ASN1Class -> ASN1Class
    $ctoEnum :: Int -> ASN1Class
    toEnum :: Int -> ASN1Class
    $cfromEnum :: ASN1Class -> Int
    fromEnum :: ASN1Class -> Int
    $cenumFrom :: ASN1Class -> [ASN1Class]
    enumFrom :: ASN1Class -> [ASN1Class]
    $cenumFromThen :: ASN1Class -> ASN1Class -> [ASN1Class]
    enumFromThen :: ASN1Class -> ASN1Class -> [ASN1Class]
    $cenumFromTo :: ASN1Class -> ASN1Class -> [ASN1Class]
    enumFromTo :: ASN1Class -> ASN1Class -> [ASN1Class]
    $cenumFromThenTo :: ASN1Class -> ASN1Class -> ASN1Class -> [ASN1Class]
    enumFromThenTo :: ASN1Class -> ASN1Class -> ASN1Class -> [ASN1Class]
    Enum)

    -- | ASN1 Tag
    type ASN1Tag = Int

    -- | ASN1 Length with all different formats
    data ASN1Length = LenShort Int      -- ^ Short form with only one byte. length has to be < 127.
                    | LenLong Int Int   -- ^ Long form of N bytes
                    | LenIndefinite     -- ^ Length is indefinite expect an EOC in the stream to finish the type
                    deriving (Int -> ASN1Length -> ShowS
    [ASN1Length] -> ShowS
    ASN1Length -> String
    (Int -> ASN1Length -> ShowS)
    -> (ASN1Length -> String)
    -> ([ASN1Length] -> ShowS)
    -> Show ASN1Length
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ASN1Length -> ShowS
    showsPrec :: Int -> ASN1Length -> ShowS
    $cshow :: ASN1Length -> String
    show :: ASN1Length -> String
    $cshowList :: [ASN1Length] -> ShowS
    showList :: [ASN1Length] -> ShowS
    Show,ASN1Length -> ASN1Length -> Bool
    (ASN1Length -> ASN1Length -> Bool)
    -> (ASN1Length -> ASN1Length -> Bool) -> Eq ASN1Length
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ASN1Length -> ASN1Length -> Bool
    == :: ASN1Length -> ASN1Length -> Bool
    $c/= :: ASN1Length -> ASN1Length -> Bool
    /= :: ASN1Length -> ASN1Length -> Bool
    Eq)

    -- | ASN1 Header with the class, tag, constructed flag and length.
    data ASN1Header = ASN1Header !ASN1Class !ASN1Tag !Bool !ASN1Length
        deriving (Int -> ASN1Header -> ShowS
    [ASN1Header] -> ShowS
    ASN1Header -> String
    (Int -> ASN1Header -> ShowS)
    -> (ASN1Header -> String)
    -> ([ASN1Header] -> ShowS)
    -> Show ASN1Header
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ASN1Header -> ShowS
    showsPrec :: Int -> ASN1Header -> ShowS
    $cshow :: ASN1Header -> String
    show :: ASN1Header -> String
    $cshowList :: [ASN1Header] -> ShowS
    showList :: [ASN1Header] -> ShowS
    Show,ASN1Header -> ASN1Header -> Bool
    (ASN1Header -> ASN1Header -> Bool)
    -> (ASN1Header -> ASN1Header -> Bool) -> Eq ASN1Header
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ASN1Header -> ASN1Header -> Bool
    == :: ASN1Header -> ASN1Header -> Bool
    $c/= :: ASN1Header -> ASN1Header -> Bool
    /= :: ASN1Header -> ASN1Header -> Bool
    Eq)

    -- | represent one event from an asn1 data stream
    data ASN1Event = Header ASN1Header     -- ^ ASN1 Header
                   | Primitive !ByteString -- ^ Primitive
                   | ConstructionBegin     -- ^ Constructed value start
                   | ConstructionEnd       -- ^ Constructed value end
                   deriving (Int -> ASN1Event -> ShowS
    [ASN1Event] -> ShowS
    ASN1Event -> String
    (Int -> ASN1Event -> ShowS)
    -> (ASN1Event -> String)
    -> ([ASN1Event] -> ShowS)
    -> Show ASN1Event
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ASN1Event -> ShowS
    showsPrec :: Int -> ASN1Event -> ShowS
    $cshow :: ASN1Event -> String
    show :: ASN1Event -> String
    $cshowList :: [ASN1Event] -> ShowS
    showList :: [ASN1Event] -> ShowS
    Show,ASN1Event -> ASN1Event -> Bool
    (ASN1Event -> ASN1Event -> Bool)
    -> (ASN1Event -> ASN1Event -> Bool) -> Eq ASN1Event
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ASN1Event -> ASN1Event -> Bool
    == :: ASN1Event -> ASN1Event -> Bool
    $c/= :: ASN1Event -> ASN1Event -> Bool
    /= :: ASN1Event -> ASN1Event -> Bool
    Eq)