module Network.HPACK.Table (
DynamicTable
, newDynamicTableForEncoding
, newDynamicTableForDecoding
, renewDynamicTable
, printDynamicTable
, isDynamicTableEmpty
, isSuitableSize
, TableSizeAction(..)
, needChangeTableSize
, setLimitForEncoding
, resetLimitForEncoding
, insertEntry
, HeaderCache(..)
, lookupTable
, module Network.HPACK.Table.Entry
, WhichTable(..)
, which
) where
#if __GLASGOW_HASKELL__ < 709
import Control.Applicative ((<$>))
#endif
import Control.Exception (throwIO)
import qualified Data.Map as M
import Network.HPACK.Table.Dynamic
import Network.HPACK.Table.Entry
import Network.HPACK.Table.RevIndex
import Network.HPACK.Table.Static
import Network.HPACK.Types
data WhichTable = InDynamicTable | InStaticTable deriving (Eq,Show)
data HeaderCache = None
| KeyOnly !WhichTable !Index
| KeyValue !WhichTable !Index
deriving Show
lookupTable :: Header -> DynamicTable -> HeaderCache
lookupTable (k,v) dyntbl = case reverseIndex dyntbl of
Nothing -> None
Just (Outer rev) -> case M.lookup k rev of
Nothing -> None
Just (Inner ss ds) -> case lookup v ss of
Just sidx -> KeyValue InStaticTable $ fromSIndexToIndex sidx
Nothing -> case lookup v ds of
Just didx -> KeyValue InDynamicTable $ fromDIndexToIndex dyntbl didx
Nothing -> case ss of
((_,sidx):_) -> KeyOnly InStaticTable $ fromSIndexToIndex sidx
[] -> case ds of
((_,didx):_) -> KeyOnly InDynamicTable $ fromDIndexToIndex dyntbl didx
_ -> error "search"
isIn :: Int -> DynamicTable -> Bool
isIn idx DynamicTable{..} = idx > staticTableSize
which :: DynamicTable -> Index -> IO (WhichTable, Entry)
which dyntbl idx
| idx `isIn` dyntbl = (InDynamicTable,) <$> toHeaderEntry dyntbl hidx
| isSIndexValid sidx = return (InStaticTable, toStaticEntry sidx)
| otherwise = throwIO $ IndexOverrun idx
where
hidx = fromIndexToDIndex dyntbl idx
sidx = fromIndexToSIndex idx