    {-# LANGUAGE DeriveDataTypeable #-}

    module Network.HPACK.Types (
        -- * Header
        FieldValue,
        TokenHeader,
        TokenHeaderList,

        -- * Misc
        Index,
        HIndex (..),

        -- * Encoding and decoding
        CompressionAlgo (..),
        EncodeStrategy (..),
        defaultEncodeStrategy,
        DecodeError (..),

        -- * Buffer
        Buffer,
        BufferSize,
        BufferOverrun (..),
    ) where

    import Control.Exception as E
    import Network.ByteOrder (Buffer, BufferOverrun (..), BufferSize)

    import Imports

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

    -- | Index for table.
    type Index = Int

    data HIndex = SIndex Int | DIndex Int deriving (HIndex -> HIndex -> Bool
    (HIndex -> HIndex -> Bool)
    -> (HIndex -> HIndex -> Bool) -> Eq HIndex
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: HIndex -> HIndex -> Bool
    == :: HIndex -> HIndex -> Bool
    $c/= :: HIndex -> HIndex -> Bool
    /= :: HIndex -> HIndex -> Bool
    Eq, Eq HIndex
    Eq HIndex =>
    (HIndex -> HIndex -> Ordering)
    -> (HIndex -> HIndex -> Bool)
    -> (HIndex -> HIndex -> Bool)
    -> (HIndex -> HIndex -> Bool)
    -> (HIndex -> HIndex -> Bool)
    -> (HIndex -> HIndex -> HIndex)
    -> (HIndex -> HIndex -> HIndex)
    -> Ord HIndex
    HIndex -> HIndex -> Bool
    HIndex -> HIndex -> Ordering
    HIndex -> HIndex -> HIndex
    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 :: HIndex -> HIndex -> Ordering
    compare :: HIndex -> HIndex -> Ordering
    $c< :: HIndex -> HIndex -> Bool
    < :: HIndex -> HIndex -> Bool
    $c<= :: HIndex -> HIndex -> Bool
    <= :: HIndex -> HIndex -> Bool
    $c> :: HIndex -> HIndex -> Bool
    > :: HIndex -> HIndex -> Bool
    $c>= :: HIndex -> HIndex -> Bool
    >= :: HIndex -> HIndex -> Bool
    $cmax :: HIndex -> HIndex -> HIndex
    max :: HIndex -> HIndex -> HIndex
    $cmin :: HIndex -> HIndex -> HIndex
    min :: HIndex -> HIndex -> HIndex
    Ord, Int -> HIndex -> ShowS
    [HIndex] -> ShowS
    HIndex -> String
    (Int -> HIndex -> ShowS)
    -> (HIndex -> String) -> ([HIndex] -> ShowS) -> Show HIndex
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> HIndex -> ShowS
    showsPrec :: Int -> HIndex -> ShowS
    $cshow :: HIndex -> String
    show :: HIndex -> String
    $cshowList :: [HIndex] -> ShowS
    showList :: [HIndex] -> ShowS
    Show)

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

    -- | Compression algorithms for HPACK encoding.
    data CompressionAlgo
        = -- | No compression
          Naive
        | -- | Using indices in the static table only
          Static
        | -- | Using indices
          Linear
        deriving (CompressionAlgo -> CompressionAlgo -> Bool
    (CompressionAlgo -> CompressionAlgo -> Bool)
    -> (CompressionAlgo -> CompressionAlgo -> Bool)
    -> Eq CompressionAlgo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CompressionAlgo -> CompressionAlgo -> Bool
    == :: CompressionAlgo -> CompressionAlgo -> Bool
    $c/= :: CompressionAlgo -> CompressionAlgo -> Bool
    /= :: CompressionAlgo -> CompressionAlgo -> Bool
    Eq, Int -> CompressionAlgo -> ShowS
    [CompressionAlgo] -> ShowS
    CompressionAlgo -> String
    (Int -> CompressionAlgo -> ShowS)
    -> (CompressionAlgo -> String)
    -> ([CompressionAlgo] -> ShowS)
    -> Show CompressionAlgo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> CompressionAlgo -> ShowS
    showsPrec :: Int -> CompressionAlgo -> ShowS
    $cshow :: CompressionAlgo -> String
    show :: CompressionAlgo -> String
    $cshowList :: [CompressionAlgo] -> ShowS
    showList :: [CompressionAlgo] -> ShowS
    Show)

    -- | Strategy for HPACK encoding.
    data EncodeStrategy = EncodeStrategy
        { EncodeStrategy -> CompressionAlgo
    compressionAlgo :: CompressionAlgo
        -- ^ Which compression algorithm is used.
        , EncodeStrategy -> Bool
    useHuffman :: Bool
        -- ^ Whether or not to use Huffman encoding for strings.
        }
        deriving (EncodeStrategy -> EncodeStrategy -> Bool
    (EncodeStrategy -> EncodeStrategy -> Bool)
    -> (EncodeStrategy -> EncodeStrategy -> Bool) -> Eq EncodeStrategy
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: EncodeStrategy -> EncodeStrategy -> Bool
    == :: EncodeStrategy -> EncodeStrategy -> Bool
    $c/= :: EncodeStrategy -> EncodeStrategy -> Bool
    /= :: EncodeStrategy -> EncodeStrategy -> Bool
    Eq, Int -> EncodeStrategy -> ShowS
    [EncodeStrategy] -> ShowS
    EncodeStrategy -> String
    (Int -> EncodeStrategy -> ShowS)
    -> (EncodeStrategy -> String)
    -> ([EncodeStrategy] -> ShowS)
    -> Show EncodeStrategy
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> EncodeStrategy -> ShowS
    showsPrec :: Int -> EncodeStrategy -> ShowS
    $cshow :: EncodeStrategy -> String
    show :: EncodeStrategy -> String
    $cshowList :: [EncodeStrategy] -> ShowS
    showList :: [EncodeStrategy] -> ShowS
    Show)

    -- | Default 'EncodeStrategy'.
    --
    -- >>> defaultEncodeStrategy
    -- EncodeStrategy {compressionAlgo = Linear, useHuffman = False}
    defaultEncodeStrategy :: EncodeStrategy
    defaultEncodeStrategy :: EncodeStrategy
    defaultEncodeStrategy =
        EncodeStrategy
            { compressionAlgo :: CompressionAlgo
    compressionAlgo = CompressionAlgo
    Linear
            , useHuffman :: Bool
    useHuffman = Bool
    False
            }

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

    -- | Errors for decoder.
    data DecodeError
        = -- | Index is out of range
          IndexOverrun Index
        | -- | Eos appears in the middle of huffman string
          EosInTheMiddle
        | -- | Non-eos appears in the end of huffman string
          IllegalEos
        | -- | Eos of huffman string is more than 7 bits
          TooLongEos
        | -- | A peer set the dynamic table size less than 32
          TooSmallTableSize
        | -- | A peer tried to change the dynamic table size over the limit
          TooLargeTableSize
        | -- | Table size update at the non-beginning
          IllegalTableSizeUpdate
        | HeaderBlockTruncated
        | IllegalHeaderName
        | TooLargeHeader
        deriving (DecodeError -> DecodeError -> Bool
    (DecodeError -> DecodeError -> Bool)
    -> (DecodeError -> DecodeError -> Bool) -> Eq DecodeError
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DecodeError -> DecodeError -> Bool
    == :: DecodeError -> DecodeError -> Bool
    $c/= :: DecodeError -> DecodeError -> Bool
    /= :: DecodeError -> DecodeError -> Bool
    Eq, Int -> DecodeError -> ShowS
    [DecodeError] -> ShowS
    DecodeError -> String
    (Int -> DecodeError -> ShowS)
    -> (DecodeError -> String)
    -> ([DecodeError] -> ShowS)
    -> Show DecodeError
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> DecodeError -> ShowS
    showsPrec :: Int -> DecodeError -> ShowS
    $cshow :: DecodeError -> String
    show :: DecodeError -> String
    $cshowList :: [DecodeError] -> ShowS
    showList :: [DecodeError] -> ShowS
    Show)

    instance Exception DecodeError