{-# LANGUAGE DeriveDataTypeable #-}

module Network.HPACK.Types (
  -- * Header
    HeaderName
  , HeaderValue
  , Header
  , HeaderList
  , TokenHeader
  , TokenHeaderList
  -- * Misc
  , Index
  , HIndex(..)
  -- * Encoding and decoding
  , CompressionAlgo(..)
  , EncodeStrategy(..)
  , defaultEncodeStrategy
  , DecodeError(..)
  -- * Buffer
  , Buffer
  , BufferSize
  , BufferOverrun(..)
  ) where

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

import Imports
import Network.HPACK.Token (Token)

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

-- | Header name.
type HeaderName = ByteString

-- | Header value.
type HeaderValue = ByteString

-- | Header.
type Header = (HeaderName, HeaderValue)

-- | Header list.
type HeaderList = [Header]

-- | TokenBased header.
type TokenHeader = (Token, HeaderValue)

-- | TokenBased header list.
type TokenHeaderList = [TokenHeader]

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

-- | 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
/= :: HIndex -> HIndex -> Bool
$c/= :: HIndex -> HIndex -> Bool
== :: HIndex -> HIndex -> Bool
$c== :: 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
min :: HIndex -> HIndex -> HIndex
$cmin :: HIndex -> HIndex -> HIndex
max :: HIndex -> HIndex -> HIndex
$cmax :: HIndex -> HIndex -> HIndex
>= :: HIndex -> HIndex -> Bool
$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
compare :: HIndex -> HIndex -> Ordering
$ccompare :: HIndex -> HIndex -> Ordering
$cp1Ord :: Eq 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
showList :: [HIndex] -> ShowS
$cshowList :: [HIndex] -> ShowS
show :: HIndex -> String
$cshow :: HIndex -> String
showsPrec :: Int -> HIndex -> ShowS
$cshowsPrec :: Int -> HIndex -> ShowS
Show)

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

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

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

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

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

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

instance Exception DecodeError