{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RecordWildCards #-}
module Network.HPACK.Table.Dynamic (
DynamicTable(..)
, newDynamicTableForEncoding
, newDynamicTableForDecoding
, renewDynamicTable
, huffmanDecoder
, printDynamicTable
, isDynamicTableEmpty
, isSuitableSize
, TableSizeAction(..)
, needChangeTableSize
, setLimitForEncoding
, resetLimitForEncoding
, insertEntry
, toDynamicEntry
, CodeInfo(..)
, withDynamicTableForEncoding
, withDynamicTableForDecoding
, toIndexedEntry
, fromHIndexToIndex
, getRevIndex
) where
import Control.Exception (throwIO)
import Data.Array.Base (unsafeRead, unsafeWrite)
import Data.Array.IO (IOArray, newArray)
import qualified Data.ByteString.Char8 as BS
import Data.IORef
import Imports
import Network.HPACK.Huffman
import Network.HPACK.Table.Entry
import Network.HPACK.Table.RevIndex
import Network.HPACK.Table.Static
import Network.HPACK.Types
{-# INLINE toIndexedEntry #-}
toIndexedEntry :: DynamicTable -> Index -> IO Entry
toIndexedEntry :: DynamicTable -> Index -> IO Entry
toIndexedEntry DynamicTable
dyntbl Index
idx
| Index
idx Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
0 = DecodeError -> IO Entry
forall e a. Exception e => e -> IO a
throwIO (DecodeError -> IO Entry) -> DecodeError -> IO Entry
forall a b. (a -> b) -> a -> b
$ Index -> DecodeError
IndexOverrun Index
idx
| Index
idx Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
staticTableSize = Entry -> IO Entry
forall (m :: * -> *) a. Monad m => a -> m a
return (Entry -> IO Entry) -> Entry -> IO Entry
forall a b. (a -> b) -> a -> b
$ Index -> Entry
toStaticEntry Index
idx
| Bool
otherwise = DynamicTable -> Index -> IO Entry
toDynamicEntry DynamicTable
dyntbl Index
idx
{-# INLINE fromHIndexToIndex #-}
fromHIndexToIndex :: DynamicTable -> HIndex -> IO Index
fromHIndexToIndex :: DynamicTable -> HIndex -> IO Index
fromHIndexToIndex DynamicTable
_ (SIndex Index
idx) = Index -> IO Index
forall (m :: * -> *) a. Monad m => a -> m a
return Index
idx
fromHIndexToIndex DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
..} (DIndex Index
didx) = do
Index
maxN <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxNumOfEntries
Index
off <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
offset
Index
x <- Index -> Index -> IO Index
adj Index
maxN (Index
didx Index -> Index -> Index
forall a. Num a => a -> a -> a
- Index
off)
Index -> IO Index
forall (m :: * -> *) a. Monad m => a -> m a
return (Index -> IO Index) -> Index -> IO Index
forall a b. (a -> b) -> a -> b
$ Index
x Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
staticTableSize
type Table = IOArray Index Entry
data CodeInfo =
EncodeInfo RevIndex
(IORef (Maybe Size))
| DecodeInfo HuffmanDecoder
(IORef Size)
data DynamicTable = DynamicTable {
DynamicTable -> CodeInfo
codeInfo :: CodeInfo
, DynamicTable -> IORef Table
circularTable :: IORef Table
, DynamicTable -> IORef Index
offset :: IORef Index
, DynamicTable -> IORef Index
numOfEntries :: IORef Int
, DynamicTable -> IORef Index
maxNumOfEntries :: IORef Int
, DynamicTable -> IORef Index
dynamicTableSize :: IORef Size
, DynamicTable -> IORef Index
maxDynamicTableSize :: IORef Size
}
{-# INLINE adj #-}
adj :: Int -> Int -> IO Int
adj :: Index -> Index -> IO Index
adj Index
maxN Index
x
| Index
maxN Index -> Index -> Bool
forall a. Eq a => a -> a -> Bool
== Index
0 = DecodeError -> IO Index
forall e a. Exception e => e -> IO a
throwIO DecodeError
TooSmallTableSize
| Bool
otherwise = let ret :: Index
ret = (Index
x Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
maxN) Index -> Index -> Index
forall a. Integral a => a -> a -> a
`mod` Index
maxN
in Index -> IO Index
forall (m :: * -> *) a. Monad m => a -> m a
return Index
ret
huffmanDecoder :: DynamicTable -> HuffmanDecoder
huffmanDecoder :: DynamicTable -> HuffmanDecoder
huffmanDecoder DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = HuffmanDecoder
dec
where
DecodeInfo HuffmanDecoder
dec IORef Index
_ = CodeInfo
codeInfo
printDynamicTable :: DynamicTable -> IO ()
printDynamicTable :: DynamicTable -> IO ()
printDynamicTable DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
Index
maxN <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxNumOfEntries
Index
off <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
offset
Index
n <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
numOfEntries
let beg :: Index
beg = Index
off Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
1
end :: Index
end = Index
off Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
n
Table
tbl <- IORef Table -> IO Table
forall a. IORef a -> IO a
readIORef IORef Table
circularTable
[Entry]
es <- (Index -> IO Entry) -> [Index] -> IO [Entry]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Index -> Index -> IO Index
adj Index
maxN (Index -> IO Index) -> (Index -> IO Entry) -> Index -> IO Entry
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Table -> Index -> IO Entry
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Index -> m e
unsafeRead Table
tbl) [Index
beg .. Index
end]
let ts :: [(Index, Entry)]
ts = [Index] -> [Entry] -> [(Index, Entry)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Index
1..] [Entry]
es
((Index, Entry) -> IO ()) -> [(Index, Entry)] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Index, Entry) -> IO ()
printEntry [(Index, Entry)]
ts
Index
dsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
dynamicTableSize
Index
maxdsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxDynamicTableSize
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
" Table size: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Index -> String
forall a. Show a => a -> String
show Index
dsize String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Index -> String
forall a. Show a => a -> String
show Index
maxdsize
printEntry :: (Index,Entry) -> IO ()
printEntry :: (Index, Entry) -> IO ()
printEntry (Index
i,Entry
e) = do
String -> IO ()
putStr String
"[ "
String -> IO ()
putStr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Index -> String
forall a. Show a => a -> String
show Index
i
String -> IO ()
putStr String
"] (s = "
String -> IO ()
putStr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Index -> String
forall a. Show a => a -> String
show (Index -> String) -> Index -> String
forall a b. (a -> b) -> a -> b
$ Entry -> Index
entrySize Entry
e
String -> IO ()
putStr String
") "
ByteString -> IO ()
BS.putStr (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ Entry -> ByteString
entryHeaderName Entry
e
String -> IO ()
putStr String
": "
ByteString -> IO ()
BS.putStrLn (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ Entry -> ByteString
entryHeaderValue Entry
e
isDynamicTableEmpty :: DynamicTable -> IO Bool
isDynamicTableEmpty :: DynamicTable -> IO Bool
isDynamicTableEmpty DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
Index
n <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
numOfEntries
Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ Index
n Index -> Index -> Bool
forall a. Eq a => a -> a -> Bool
== Index
0
isSuitableSize :: Size -> DynamicTable -> IO Bool
isSuitableSize :: Index -> DynamicTable -> IO Bool
isSuitableSize Index
siz DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
let DecodeInfo HuffmanDecoder
_ IORef Index
limref = CodeInfo
codeInfo
Index
lim <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
limref
Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ Index
siz Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
lim
data TableSizeAction = Keep | Change Size | Ignore Size
needChangeTableSize :: DynamicTable -> IO TableSizeAction
needChangeTableSize :: DynamicTable -> IO TableSizeAction
needChangeTableSize DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
let EncodeInfo RevIndex
_ IORef (Maybe Index)
limref = CodeInfo
codeInfo
Maybe Index
mlim <- IORef (Maybe Index) -> IO (Maybe Index)
forall a. IORef a -> IO a
readIORef IORef (Maybe Index)
limref
Index
maxsiz <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxDynamicTableSize
TableSizeAction -> IO TableSizeAction
forall (m :: * -> *) a. Monad m => a -> m a
return (TableSizeAction -> IO TableSizeAction)
-> TableSizeAction -> IO TableSizeAction
forall a b. (a -> b) -> a -> b
$ case Maybe Index
mlim of
Maybe Index
Nothing -> TableSizeAction
Keep
Just Index
lim
| Index
lim Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
< Index
maxsiz -> Index -> TableSizeAction
Change Index
lim
| Bool
otherwise -> Index -> TableSizeAction
Ignore Index
maxsiz
setLimitForEncoding :: Size -> DynamicTable -> IO ()
setLimitForEncoding :: Index -> DynamicTable -> IO ()
setLimitForEncoding Index
siz DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
let EncodeInfo RevIndex
_ IORef (Maybe Index)
limref = CodeInfo
codeInfo
IORef (Maybe Index) -> Maybe Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe Index)
limref (Maybe Index -> IO ()) -> Maybe Index -> IO ()
forall a b. (a -> b) -> a -> b
$ Index -> Maybe Index
forall a. a -> Maybe a
Just Index
siz
resetLimitForEncoding :: DynamicTable -> IO ()
resetLimitForEncoding :: DynamicTable -> IO ()
resetLimitForEncoding DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
let EncodeInfo RevIndex
_ IORef (Maybe Index)
limref = CodeInfo
codeInfo
IORef (Maybe Index) -> Maybe Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe Index)
limref Maybe Index
forall a. Maybe a
Nothing
newDynamicTableForEncoding :: Size
-> IO DynamicTable
newDynamicTableForEncoding :: Index -> IO DynamicTable
newDynamicTableForEncoding Index
maxsiz = do
RevIndex
rev <- IO RevIndex
newRevIndex
IORef (Maybe Index)
lim <- Maybe Index -> IO (IORef (Maybe Index))
forall a. a -> IO (IORef a)
newIORef Maybe Index
forall a. Maybe a
Nothing
let info :: CodeInfo
info = RevIndex -> IORef (Maybe Index) -> CodeInfo
EncodeInfo RevIndex
rev IORef (Maybe Index)
lim
Index -> CodeInfo -> IO DynamicTable
newDynamicTable Index
maxsiz CodeInfo
info
newDynamicTableForDecoding :: Size
-> Size
-> IO DynamicTable
newDynamicTableForDecoding :: Index -> Index -> IO DynamicTable
newDynamicTableForDecoding Index
maxsiz Index
huftmpsiz = do
IORef Index
lim <- Index -> IO (IORef Index)
forall a. a -> IO (IORef a)
newIORef Index
maxsiz
ForeignPtr Word8
buf <- Index -> IO (ForeignPtr Word8)
forall a. Index -> IO (ForeignPtr a)
mallocPlainForeignPtrBytes Index
huftmpsiz
let decoder :: HuffmanDecoder
decoder = ForeignPtr Word8 -> Index -> HuffmanDecoder
decodeH ForeignPtr Word8
buf Index
huftmpsiz
info :: CodeInfo
info = HuffmanDecoder -> IORef Index -> CodeInfo
DecodeInfo HuffmanDecoder
decoder IORef Index
lim
Index -> CodeInfo -> IO DynamicTable
newDynamicTable Index
maxsiz CodeInfo
info
newDynamicTable :: Size -> CodeInfo -> IO DynamicTable
newDynamicTable :: Index -> CodeInfo -> IO DynamicTable
newDynamicTable Index
maxsiz CodeInfo
info = do
Table
tbl <- (Index, Index) -> Entry -> IO Table
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> e -> m (a i e)
newArray (Index
0,Index
end) Entry
dummyEntry
CodeInfo
-> IORef Table
-> IORef Index
-> IORef Index
-> IORef Index
-> IORef Index
-> IORef Index
-> DynamicTable
DynamicTable CodeInfo
info (IORef Table
-> IORef Index
-> IORef Index
-> IORef Index
-> IORef Index
-> IORef Index
-> DynamicTable)
-> IO (IORef Table)
-> IO
(IORef Index
-> IORef Index
-> IORef Index
-> IORef Index
-> IORef Index
-> DynamicTable)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Table -> IO (IORef Table)
forall a. a -> IO (IORef a)
newIORef Table
tbl
IO
(IORef Index
-> IORef Index
-> IORef Index
-> IORef Index
-> IORef Index
-> DynamicTable)
-> IO (IORef Index)
-> IO
(IORef Index
-> IORef Index -> IORef Index -> IORef Index -> DynamicTable)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Index -> IO (IORef Index)
forall a. a -> IO (IORef a)
newIORef Index
end
IO
(IORef Index
-> IORef Index -> IORef Index -> IORef Index -> DynamicTable)
-> IO (IORef Index)
-> IO (IORef Index -> IORef Index -> IORef Index -> DynamicTable)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Index -> IO (IORef Index)
forall a. a -> IO (IORef a)
newIORef Index
0
IO (IORef Index -> IORef Index -> IORef Index -> DynamicTable)
-> IO (IORef Index)
-> IO (IORef Index -> IORef Index -> DynamicTable)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Index -> IO (IORef Index)
forall a. a -> IO (IORef a)
newIORef Index
maxN
IO (IORef Index -> IORef Index -> DynamicTable)
-> IO (IORef Index) -> IO (IORef Index -> DynamicTable)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Index -> IO (IORef Index)
forall a. a -> IO (IORef a)
newIORef Index
0
IO (IORef Index -> DynamicTable)
-> IO (IORef Index) -> IO DynamicTable
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Index -> IO (IORef Index)
forall a. a -> IO (IORef a)
newIORef Index
maxsiz
where
maxN :: Index
maxN = Index -> Index
maxNumbers Index
maxsiz
end :: Index
end = Index
maxN Index -> Index -> Index
forall a. Num a => a -> a -> a
- Index
1
renewDynamicTable :: Size -> DynamicTable -> IO ()
renewDynamicTable :: Index -> DynamicTable -> IO ()
renewDynamicTable Index
maxsiz dyntbl :: DynamicTable
dyntbl@DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
Bool
renew <- DynamicTable -> Index -> IO Bool
shouldRenew DynamicTable
dyntbl Index
maxsiz
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
renew (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
[Entry]
entries <- DynamicTable -> IO [Entry]
getEntries DynamicTable
dyntbl
let maxN :: Index
maxN = Index -> Index
maxNumbers Index
maxsiz
end :: Index
end = Index
maxN Index -> Index -> Index
forall a. Num a => a -> a -> a
- Index
1
Table
newtbl <- (Index, Index) -> Entry -> IO Table
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> e -> m (a i e)
newArray (Index
0,Index
end) Entry
dummyEntry
IORef Table -> Table -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Table
circularTable Table
newtbl
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
offset Index
end
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
numOfEntries Index
0
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
maxNumOfEntries Index
maxN
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
dynamicTableSize Index
0
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
maxDynamicTableSize Index
maxsiz
case CodeInfo
codeInfo of
EncodeInfo RevIndex
rev IORef (Maybe Index)
_ -> RevIndex -> IO ()
renewRevIndex RevIndex
rev
CodeInfo
_ -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
DynamicTable -> [Entry] -> IO ()
copyEntries DynamicTable
dyntbl [Entry]
entries
getEntries :: DynamicTable -> IO [Entry]
getEntries :: DynamicTable -> IO [Entry]
getEntries DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
Index
maxN <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxNumOfEntries
Index
off <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
offset
Index
n <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
numOfEntries
Table
table <- IORef Table -> IO Table
forall a. IORef a -> IO a
readIORef IORef Table
circularTable
let readTable :: Index -> IO Entry
readTable Index
i = Index -> Index -> IO Index
adj Index
maxN (Index
off Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
i) IO Index -> (Index -> IO Entry) -> IO Entry
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Table -> Index -> IO Entry
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Index -> m e
unsafeRead Table
table
[Index] -> (Index -> IO Entry) -> IO [Entry]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Index
1 .. Index
n] Index -> IO Entry
readTable
copyEntries :: DynamicTable -> [Entry] -> IO ()
copyEntries :: DynamicTable -> [Entry] -> IO ()
copyEntries DynamicTable
_ [] = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
copyEntries dyntbl :: DynamicTable
dyntbl@DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} (Entry
e:[Entry]
es) = do
Index
dsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
dynamicTableSize
Index
maxdsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxDynamicTableSize
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Index
dsize Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Entry -> Index
entrySize Entry
e Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
maxdsize) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Entry -> DynamicTable -> IO ()
insertEnd Entry
e DynamicTable
dyntbl
DynamicTable -> [Entry] -> IO ()
copyEntries DynamicTable
dyntbl [Entry]
es
shouldRenew :: DynamicTable -> Size -> IO Bool
shouldRenew :: DynamicTable -> Index -> IO Bool
shouldRenew DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} Index
maxsiz = do
Index
maxdsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxDynamicTableSize
Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ Index
maxdsize Index -> Index -> Bool
forall a. Eq a => a -> a -> Bool
/= Index
maxsiz
withDynamicTableForEncoding :: Size
-> (DynamicTable -> IO a)
-> IO a
withDynamicTableForEncoding :: Index -> (DynamicTable -> IO a) -> IO a
withDynamicTableForEncoding Index
maxsiz DynamicTable -> IO a
action =
Index -> IO DynamicTable
newDynamicTableForEncoding Index
maxsiz IO DynamicTable -> (DynamicTable -> IO a) -> IO a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DynamicTable -> IO a
action
withDynamicTableForDecoding :: Size
-> Size
-> (DynamicTable -> IO a)
-> IO a
withDynamicTableForDecoding :: Index -> Index -> (DynamicTable -> IO a) -> IO a
withDynamicTableForDecoding Index
maxsiz Index
huftmpsiz DynamicTable -> IO a
action =
Index -> Index -> IO DynamicTable
newDynamicTableForDecoding Index
maxsiz Index
huftmpsiz IO DynamicTable -> (DynamicTable -> IO a) -> IO a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DynamicTable -> IO a
action
insertEntry :: Entry -> DynamicTable -> IO ()
insertEntry :: Entry -> DynamicTable -> IO ()
insertEntry Entry
e dyntbl :: DynamicTable
dyntbl@DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
Entry -> DynamicTable -> IO ()
insertFront Entry
e DynamicTable
dyntbl
[Entry]
es <- DynamicTable -> IO [Entry]
adjustTableSize DynamicTable
dyntbl
case CodeInfo
codeInfo of
EncodeInfo RevIndex
rev IORef (Maybe Index)
_ -> [Entry] -> RevIndex -> IO ()
deleteRevIndexList [Entry]
es RevIndex
rev
CodeInfo
_ -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
insertFront :: Entry -> DynamicTable -> IO ()
insertFront :: Entry -> DynamicTable -> IO ()
insertFront Entry
e DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
Index
maxN <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxNumOfEntries
Index
off <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
offset
Index
n <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
numOfEntries
Index
dsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
dynamicTableSize
Table
table <- IORef Table -> IO Table
forall a. IORef a -> IO a
readIORef IORef Table
circularTable
let i :: Index
i = Index
off
dsize' :: Index
dsize' = Index
dsize Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Entry -> Index
entrySize Entry
e
if Index
maxN Index -> Index -> Bool
forall a. Eq a => a -> a -> Bool
== Index
0
then () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
else do
Index
off' <- Index -> Index -> IO Index
adj Index
maxN (Index
off Index -> Index -> Index
forall a. Num a => a -> a -> a
- Index
1)
Table -> Index -> Entry -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Index -> e -> m ()
unsafeWrite Table
table Index
i Entry
e
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
offset Index
off'
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
numOfEntries (Index -> IO ()) -> Index -> IO ()
forall a b. (a -> b) -> a -> b
$ Index
n Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
1
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
dynamicTableSize Index
dsize'
case CodeInfo
codeInfo of
EncodeInfo RevIndex
rev IORef (Maybe Index)
_ -> Entry -> HIndex -> RevIndex -> IO ()
insertRevIndex Entry
e (Index -> HIndex
DIndex Index
i) RevIndex
rev
CodeInfo
_ -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
adjustTableSize :: DynamicTable -> IO [Entry]
adjustTableSize :: DynamicTable -> IO [Entry]
adjustTableSize dyntbl :: DynamicTable
dyntbl@DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = [Entry] -> IO [Entry]
adjust []
where
adjust :: [Entry] -> IO [Entry]
adjust :: [Entry] -> IO [Entry]
adjust [Entry]
es = do
Index
dsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
dynamicTableSize
Index
maxdsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxDynamicTableSize
if Index
dsize Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
maxdsize then
[Entry] -> IO [Entry]
forall (m :: * -> *) a. Monad m => a -> m a
return [Entry]
es
else do
Entry
e <- DynamicTable -> IO Entry
removeEnd DynamicTable
dyntbl
[Entry] -> IO [Entry]
adjust (Entry
eEntry -> [Entry] -> [Entry]
forall a. a -> [a] -> [a]
:[Entry]
es)
insertEnd :: Entry -> DynamicTable -> IO ()
insertEnd :: Entry -> DynamicTable -> IO ()
insertEnd Entry
e DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
Index
maxN <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxNumOfEntries
Index
off <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
offset
Index
n <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
numOfEntries
Index
dsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
dynamicTableSize
Table
table <- IORef Table -> IO Table
forall a. IORef a -> IO a
readIORef IORef Table
circularTable
Index
i <- Index -> Index -> IO Index
adj Index
maxN (Index
off Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
n Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
1)
let dsize' :: Index
dsize' = Index
dsize Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Entry -> Index
entrySize Entry
e
Table -> Index -> Entry -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Index -> e -> m ()
unsafeWrite Table
table Index
i Entry
e
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
numOfEntries (Index -> IO ()) -> Index -> IO ()
forall a b. (a -> b) -> a -> b
$ Index
n Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
1
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
dynamicTableSize Index
dsize'
case CodeInfo
codeInfo of
EncodeInfo RevIndex
rev IORef (Maybe Index)
_ -> Entry -> HIndex -> RevIndex -> IO ()
insertRevIndex Entry
e (Index -> HIndex
DIndex Index
i) RevIndex
rev
CodeInfo
_ -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
removeEnd :: DynamicTable -> IO Entry
removeEnd :: DynamicTable -> IO Entry
removeEnd DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = do
Index
maxN <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxNumOfEntries
Index
off <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
offset
Index
n <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
numOfEntries
Index
i <- Index -> Index -> IO Index
adj Index
maxN (Index
off Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
n)
Table
table <- IORef Table -> IO Table
forall a. IORef a -> IO a
readIORef IORef Table
circularTable
Entry
e <- Table -> Index -> IO Entry
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Index -> m e
unsafeRead Table
table Index
i
Table -> Index -> Entry -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Index -> e -> m ()
unsafeWrite Table
table Index
i Entry
dummyEntry
Index
dsize <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
dynamicTableSize
let dsize' :: Index
dsize' = Index
dsize Index -> Index -> Index
forall a. Num a => a -> a -> a
- Entry -> Index
entrySize Entry
e
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
numOfEntries (Index
n Index -> Index -> Index
forall a. Num a => a -> a -> a
- Index
1)
IORef Index -> Index -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Index
dynamicTableSize Index
dsize'
Entry -> IO Entry
forall (m :: * -> *) a. Monad m => a -> m a
return Entry
e
{-# INLINE toDynamicEntry #-}
toDynamicEntry :: DynamicTable -> Index -> IO Entry
toDynamicEntry :: DynamicTable -> Index -> IO Entry
toDynamicEntry DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} Index
idx = do
Index
maxN <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
maxNumOfEntries
Index
off <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
offset
Index
n <- IORef Index -> IO Index
forall a. IORef a -> IO a
readIORef IORef Index
numOfEntries
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Index
idx Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
> Index
n Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
staticTableSize) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DecodeError -> IO ()
forall e a. Exception e => e -> IO a
throwIO (DecodeError -> IO ()) -> DecodeError -> IO ()
forall a b. (a -> b) -> a -> b
$ Index -> DecodeError
IndexOverrun Index
idx
Index
didx <- Index -> Index -> IO Index
adj Index
maxN (Index
idx Index -> Index -> Index
forall a. Num a => a -> a -> a
+ Index
off Index -> Index -> Index
forall a. Num a => a -> a -> a
- Index
staticTableSize)
Table
table <- IORef Table -> IO Table
forall a. IORef a -> IO a
readIORef IORef Table
circularTable
Table -> Index -> IO Entry
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Index -> m e
unsafeRead Table
table Index
didx
{-# INLINE getRevIndex #-}
getRevIndex :: DynamicTable-> RevIndex
getRevIndex :: DynamicTable -> RevIndex
getRevIndex DynamicTable{IORef Index
IORef Table
CodeInfo
maxDynamicTableSize :: IORef Index
dynamicTableSize :: IORef Index
maxNumOfEntries :: IORef Index
numOfEntries :: IORef Index
offset :: IORef Index
circularTable :: IORef Table
codeInfo :: CodeInfo
maxDynamicTableSize :: DynamicTable -> IORef Index
dynamicTableSize :: DynamicTable -> IORef Index
maxNumOfEntries :: DynamicTable -> IORef Index
numOfEntries :: DynamicTable -> IORef Index
offset :: DynamicTable -> IORef Index
circularTable :: DynamicTable -> IORef Table
codeInfo :: DynamicTable -> CodeInfo
..} = RevIndex
rev
where
EncodeInfo RevIndex
rev IORef (Maybe Index)
_ = CodeInfo
codeInfo