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