http2 0.3.0 → 0.4.0
raw patch · 10 files changed
+484/−364 lines, 10 filesdep ~base
Dependency ranges changed: base
Files
- Network/HPACK/Context.hs +10/−5
- Network/HPACK/Context/ReferenceSet.hs +4/−5
- Network/HPACK/HeaderBlock/Integer.hs +36/−3
- Network/HPACK/Huffman/Table.hs +222/−222
- Network/HPACK/Table.hs +128/−48
- Network/HPACK/Table/Static.hs +61/−61
- http2.cabal +2/−2
- test-hpack/HPACKDecode.hs +4/−1
- test/HeaderBlock.hs +5/−5
- test/HuffmanSpec.hs +12/−12
Network/HPACK/Context.hs view
@@ -67,7 +67,12 @@ return $ Context hdrtbl emptyReferenceSet changeContextForDecoding :: Context -> Size -> IO Context-changeContextForDecoding _ctx siz = newContextForDecoding siz -- fixme: copy table+changeContextForDecoding ctx@(Context hdrtbl refs) siz+ | shouldRenew hdrtbl siz = do+ (hdrtbl',n) <- renewHeaderTable siz hdrtbl+ let refs' = restrictIndices n refs+ return $ Context hdrtbl' refs'+ | otherwise = return ctx ---------------------------------------------------------------- @@ -88,9 +93,9 @@ -- A reference to the new entry is added to the reference set. newEntryForEncoding :: Context -> Entry -> IO ([Index],Context) newEntryForEncoding (Context hdrtbl refs) e = do- (hdrtbl', is) <- insertEntry e hdrtbl+ (hdrtbl', i, is) <- insertEntry e hdrtbl let ns = getCommon is refs- refs' = addIndex 1 $ adjustReferenceSet $ removeIndices is refs+ refs' = addIndex 1 $ restrictIndices i $ adjustReferenceSet refs ctx = Context hdrtbl' refs' return (ns, ctx) @@ -98,8 +103,8 @@ -- A reference to the new entry is added to the reference set. newEntryForDecoding :: Context -> Entry -> IO Context newEntryForDecoding (Context hdrtbl refs) e = do- (hdrtbl', is) <- insertEntry e hdrtbl- let refs' = addIndex 1 $ adjustReferenceSet $ removeIndices is refs+ (hdrtbl', i, _) <- insertEntry e hdrtbl+ let refs' = addIndex 1 $ restrictIndices i $ adjustReferenceSet refs return $ Context hdrtbl' refs' -- | The referenced header table entry is added to the reference set.
Network/HPACK/Context/ReferenceSet.hs view
@@ -6,7 +6,7 @@ , isMember , addIndex , removeIndex- , removeIndices+ , restrictIndices -- * Managing reference set , getNotEmittedIndices , adjustReferenceSet@@ -17,7 +17,6 @@ , getCommon ) where -import Data.List (foldl') import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import Network.HPACK.Table@@ -51,9 +50,9 @@ removeIndex :: Index -> ReferenceSet -> ReferenceSet removeIndex idx (ReferenceSet m) = ReferenceSet $ M.delete idx m --- | Removing a set of 'Index' from 'ReferenceSet'.-removeIndices :: [Index] -> ReferenceSet -> ReferenceSet-removeIndices idcs (ReferenceSet m) = ReferenceSet $ foldl' (flip M.delete) m idcs+restrictIndices :: Index -> ReferenceSet -> ReferenceSet+restrictIndices idx (ReferenceSet m) =+ ReferenceSet $ M.filterWithKey (\k _ -> k <= idx) m ----------------------------------------------------------------
Network/HPACK/HeaderBlock/Integer.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE BangPatterns, OverloadedStrings #-}+ module Network.HPACK.HeaderBlock.Integer ( encode , decode@@ -20,6 +22,17 @@ ---------------------------------------------------------------- +{-+if I < 2^N - 1, encode I on N bits+ else+ encode (2^N - 1) on N bits+ I = I - (2^N - 1)+ while I >= 128+ encode (I % 128 + 128) on 8 bits+ I = I / 128+ encode I on 8 bits+-}+ -- | Integer encoding. The first argument is N of prefix. -- -- >>> encode 5 10@@ -46,6 +59,19 @@ ---------------------------------------------------------------- +{-+decode I from the next N bits+ if I < 2^N - 1, return I+ else+ M = 0+ repeat+ B = next octet+ I = I + (B & 127) * 2^M+ M = M + 7+ while B & 128 == 128+ return I+-}+ -- | Integer decoding. The first argument is N of prefix. -- -- >>> decode 5 10 $ BS.empty@@ -58,12 +84,19 @@ decode n w bs | i < p = i | BS.null bs = error $ "decode: n = " ++ show n ++ ", w = " ++ show w ++ ", bs = empty"- | otherwise = BS.foldr' (\x y -> fromIntegral x - 128 + y * 128) i0 bs' + i+ | otherwise = decode' bs 0 i where p = powerArray ! n i = fromIntegral w- i0 = fromIntegral $ BS.last bs- bs' = BS.init bs++decode' :: ByteString -> Int -> Int -> Int+decode' "" _ i = i+decode' bs m i = decode' bs' m' i'+ where+ !b = fromIntegral $ BS.head bs+ !bs' = BS.tail bs+ !i' = i + (b .&. 127) * 2 ^ m+ !m' = m + 7 ----------------------------------------------------------------
Network/HPACK/Huffman/Table.hs view
@@ -4,261 +4,261 @@ huffmanTable :: [Bits] huffmanTable = [- [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,T]- , [F,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,F,F]- , [T,T,T,T,T,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,F,F]- , [F,T,T,T,T,F]- , [T,T,F,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,F,T]+ [T,T,T,T,T,T,T,T,T,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T]+ , [F,T,F,T,F,F]+ , [T,T,T,T,T,T,T,F,F,F]+ , [T,T,T,T,T,T,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,F,F,T]+ , [F,T,F,T,F,T]+ , [T,T,T,T,T,F,F,F]+ , [T,T,T,T,T,T,T,T,F,T,F] , [T,T,T,T,T,T,T,F,T,F]- , [T,T,T,T,T,F,F,F,T] , [T,T,T,T,T,T,T,F,T,T]- , [T,T,T,T,T,T,T,T,F,F]- , [T,T,F,F,T,F,T]- , [T,T,F,F,T,T,F]+ , [T,T,T,T,T,F,F,T]+ , [T,T,T,T,T,T,T,T,F,T,T]+ , [T,T,T,T,T,F,T,F]+ , [F,T,F,T,T,F]+ , [F,T,F,T,T,T]+ , [F,T,T,F,F,F]+ , [F,F,F,F,F]+ , [F,F,F,F,T]+ , [F,F,F,T,F]+ , [F,T,T,F,F,T]+ , [F,T,T,F,T,F]+ , [F,T,T,F,T,T]+ , [F,T,T,T,F,F]+ , [F,T,T,T,F,T]+ , [F,T,T,T,T,F] , [F,T,T,T,T,T]- , [F,F,T,T,T]- , [F,F,F,F]- , [F,F,F,T]- , [F,F,T,F]- , [F,T,F,F,F]+ , [T,F,T,T,T,F,F]+ , [T,T,T,T,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,F,F] , [T,F,F,F,F,F]+ , [T,T,T,T,T,T,T,T,T,F,T,T]+ , [T,T,T,T,T,T,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,F,T,F] , [T,F,F,F,F,T]- , [T,F,F,F,T,F]- , [T,F,F,F,T,T]- , [T,F,F,T,F,F]- , [T,F,F,T,F,T]- , [T,F,F,T,T,F]- , [T,T,T,F,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F]- , [T,F,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,F]+ , [T,F,T,T,T,F,T]+ , [T,F,T,T,T,T,F]+ , [T,F,T,T,T,T,T]+ , [T,T,F,F,F,F,F]+ , [T,T,F,F,F,F,T]+ , [T,T,F,F,F,T,F]+ , [T,T,F,F,F,T,T]+ , [T,T,F,F,T,F,F]+ , [T,T,F,F,T,F,T]+ , [T,T,F,F,T,T,F] , [T,T,F,F,T,T,T]- , [T,T,T,F,T,T,F,T]- , [T,T,T,F,T,T,T,F] , [T,T,F,T,F,F,F]- , [T,T,T,F,T,T,T,T] , [T,T,F,T,F,F,T] , [T,T,F,T,F,T,F]- , [T,T,T,T,T,F,F,T,F]- , [T,T,T,T,F,F,F,F]- , [T,T,T,T,T,F,F,T,T]- , [T,T,T,T,T,F,T,F,F]- , [T,T,T,T,T,F,T,F,T] , [T,T,F,T,F,T,T] , [T,T,F,T,T,F,F]- , [T,T,T,T,F,F,F,T]- , [T,T,T,T,F,F,T,F]- , [T,T,T,T,T,F,T,T,F]- , [T,T,T,T,T,F,T,T,T] , [T,T,F,T,T,F,T]- , [T,F,T,F,F,F]- , [T,T,T,T,F,F,T,T]- , [T,T,T,T,T,T,F,F,F]- , [T,T,T,T,T,T,F,F,T]- , [T,T,T,T,F,T,F,F]- , [T,T,T,T,T,T,F,T,F]- , [T,T,T,T,T,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,F,T] , [T,T,F,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F]- , [F,T,F,F,T] , [T,T,F,T,T,T,T]- , [F,T,F,T,F]- , [T,F,T,F,F,T]- , [F,T,F,T,T] , [T,T,T,F,F,F,F]- , [T,F,T,F,T,F]- , [T,F,T,F,T,T]- , [F,T,T,F,F]- , [T,T,T,T,F,T,F,T]- , [T,T,T,T,F,T,T,F]- , [T,F,T,T,F,F]- , [T,F,T,T,F,T]- , [T,F,T,T,T,F]- , [F,T,T,F,T]- , [T,F,T,T,T,T]- , [T,T,T,T,T,T,T,F,F]- , [T,T,F,F,F,F]- , [T,T,F,F,F,T]- , [F,T,T,T,F] , [T,T,T,F,F,F,T] , [T,T,T,F,F,T,F]+ , [T,T,T,T,T,T,F,F] , [T,T,T,F,F,T,T]+ , [T,T,T,T,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,F,F]+ , [T,F,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,F,T]+ , [F,F,F,T,T]+ , [T,F,F,F,T,T]+ , [F,F,T,F,F]+ , [T,F,F,T,F,F]+ , [F,F,T,F,T]+ , [T,F,F,T,F,T]+ , [T,F,F,T,T,F]+ , [T,F,F,T,T,T]+ , [F,F,T,T,F] , [T,T,T,F,T,F,F] , [T,T,T,F,T,F,T]- , [T,T,T,T,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,T]+ , [T,F,T,F,F,F]+ , [T,F,T,F,F,T]+ , [T,F,T,F,T,F]+ , [F,F,T,T,T]+ , [T,F,T,F,T,T]+ , [T,T,T,F,T,T,F]+ , [T,F,T,T,F,F]+ , [F,T,F,F,F]+ , [F,T,F,F,T]+ , [T,F,T,T,F,T]+ , [T,T,T,F,T,T,T]+ , [T,T,T,T,F,F,F]+ , [T,T,T,T,F,F,T]+ , [T,T,T,T,F,T,F]+ , [T,T,T,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,T] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F] , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,F,T,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F,T,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,F,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,F]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,F,T,T]- , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,T,T,F,F]+ , [T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T] ]
Network/HPACK/Table.hs view
@@ -1,11 +1,13 @@-{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TupleSections, RecordWildCards #-} module Network.HPACK.Table ( -- * Header table HeaderTable , newHeaderTableForEncoding , newHeaderTableForDecoding+ , renewHeaderTable , printHeaderTable+ , shouldRenew -- * Insertion , insertEntry -- * Lookup@@ -26,17 +28,45 @@ import qualified Network.HPACK.Table.HashPSQ as HP import Network.HPACK.Table.Static import Network.HPACK.Types+import Control.Monad (forM) ---------------------------------------------------------------- +type Table = IOArray Index Entry++{-+ offset+ v+ +-+-+-+-+-+-+-+-++ | | | |z|y|x| | |+ +-+-+-+-+-+-+-+-++ 1 2 3 (numOfEntries = 3)++After insertion:++ offset+ v+ +-+-+-+-+-+-+-+-++ | | |w|z|y|x| | |+ +-+-+-+-+-+-+-+-++ 1 2 3 4 (numOfEntries = 4)+-}+ -- | Type for header table. data HeaderTable = HeaderTable {- maxNumOfEntries :: !Int+ -- | An array+ circularTable :: !Table+ -- | Start point , offset :: !Index+ -- | The current number of entries , numOfEntries :: !Int- , circularTable :: !(IOArray Index Entry)+ -- | The size of the array+ , maxNumOfEntries :: !Int+ -- | The current header table size (defined in HPACK) , headerTableSize :: !Size+ -- | The max header table size (defined in HPACK) , maxHeaderTableSize :: !Size+ -- | Header-to-index , reverseIndex :: Maybe (HP.HashPSQ HIndex) } @@ -47,15 +77,15 @@ -- | Printing 'HeaderTable'. printHeaderTable :: HeaderTable -> IO ()-printHeaderTable (HeaderTable maxN off n tbl tblsiz _ rev) = do- es <- mapM (readArray tbl . adj maxN) [beg .. end]+printHeaderTable HeaderTable{..} = do+ es <- mapM (readArray circularTable . adj maxNumOfEntries) [beg .. end] let ts = zip [1..] es mapM_ printEntry ts- putStrLn $ " Table size: " ++ show tblsiz- print rev+ putStrLn $ " Table size: " ++ show headerTableSize+ print reverseIndex where- beg = off + 1- end = off + n+ beg = offset + 1+ end = offset + numOfEntries printEntry :: (Index,Entry) -> IO () printEntry (i,e) = do@@ -84,26 +114,22 @@ ---------------------------------------------------------------- fromHIndexToIndex :: HeaderTable -> HIndex -> Index-fromHIndexToIndex hdrtbl (HIndex hidx) = idx -- fixme :: Checkme+fromHIndexToIndex HeaderTable{..} (HIndex hidx) = idx where- maxN = maxNumOfEntries hdrtbl- off = offset hdrtbl- idx = adj maxN (maxN + hidx - off)+ idx = adj maxNumOfEntries (maxNumOfEntries + hidx - offset) fromIndexToHIndex :: HeaderTable -> Index -> HIndex-fromIndexToHIndex hdrtbl idx = HIndex hidx+fromIndexToHIndex HeaderTable{..} idx = HIndex hidx where- maxN = maxNumOfEntries hdrtbl- off = offset hdrtbl- hidx = adj maxN (off + idx)+ hidx = adj maxNumOfEntries (offset + idx) fromSIndexToIndex :: HeaderTable -> SIndex -> Index-fromSIndexToIndex hdrtbl sidx = fromStaticIndex sidx + numOfEntries hdrtbl+fromSIndexToIndex HeaderTable{..} sidx = fromStaticIndex sidx + numOfEntries fromIndexToSIndex :: HeaderTable -> Index -> SIndex-fromIndexToSIndex hdrtbl idx = toStaticIndex sidx+fromIndexToSIndex HeaderTable{..} idx = toStaticIndex sidx where- sidx = idx - numOfEntries hdrtbl+ sidx = idx - numOfEntries ---------------------------------------------------------------- @@ -135,33 +161,68 @@ maxN = maxNumbers maxsiz end = maxN - 1 +renewHeaderTable :: Size -> HeaderTable -> IO (HeaderTable, Int)+renewHeaderTable maxsiz oldhdrtbl = do+ putStrLn $ "numOfEntries oldhdrtbl: " ++ show (numOfEntries oldhdrtbl)+ hdrtbl <- newHeaderTable maxsiz mhp+ newhdrtbl <- copyTable oldhdrtbl hdrtbl+ putStrLn $ "numOfEntries newhdrtbl: " ++ show (numOfEntries newhdrtbl)+ return (newhdrtbl, numOfEntries newhdrtbl)+ where+ mhp = case reverseIndex oldhdrtbl of+ Nothing -> Nothing+ _ -> Just HP.empty++copyTable :: HeaderTable -> HeaderTable -> IO HeaderTable+copyTable oldhdrtbl newhdrtbl = do+ ents <- getEntries oldhdrtbl+ putStrLn $ "length of entries: " ++ show (length ents)+ copyEntries newhdrtbl ents++getEntries :: HeaderTable -> IO [Entry]+getEntries HeaderTable{..} = forM [1 .. numOfEntries] readTable+ where+ readTable i = readArray circularTable $ adj maxNumOfEntries (offset + i)++copyEntries :: HeaderTable -> [Entry] -> IO HeaderTable+copyEntries hdrtbl [] = return hdrtbl+copyEntries hdrtbl@HeaderTable{..} (e:es)+ | headerTableSize + entrySize e <= maxHeaderTableSize = do+ hdrtbl' <- insertEnd e hdrtbl+ copyEntries hdrtbl' es+ | otherwise = return hdrtbl++shouldRenew :: HeaderTable -> Size -> Bool+shouldRenew HeaderTable{..} maxsiz = maxHeaderTableSize /= maxsiz+ ---------------------------------------------------------------- -- | Inserting 'Entry' to 'HeaderTable'.--- New 'HeaderTable' and a set of dropped OLD 'Index'+-- New 'HeaderTable', the largest new 'Index'+-- and a set of dropped OLD 'Index' -- are returned.-insertEntry :: Entry -> HeaderTable -> IO (HeaderTable,[Index])+insertEntry :: Entry -> HeaderTable -> IO (HeaderTable,Index,[Index]) insertEntry e hdrtbl = do- (hdrtbl', is, hs) <- insertOne e hdrtbl >>= adjustTableSize+ (hdrtbl', is, hs) <- insertFront e hdrtbl >>= adjustTableSize let hdrtbl'' = case reverseIndex hdrtbl' of Nothing -> hdrtbl' Just rev -> hdrtbl' { reverseIndex = Just (HP.deleteList hs rev) }- return (hdrtbl'', is)+ return (hdrtbl'', numOfEntries hdrtbl'', is) -insertOne :: Entry -> HeaderTable -> IO HeaderTable-insertOne e hdrtbl@(HeaderTable maxN off n tbl tsize _ mrev) = do- writeArray tbl i e+insertFront :: Entry -> HeaderTable -> IO HeaderTable+insertFront e hdrtbl@HeaderTable{..} = do+ writeArray circularTable i e return $ hdrtbl {- offset = off'- , numOfEntries = n + 1- , headerTableSize = tsize'- , reverseIndex = mrev'+ offset = offset'+ , numOfEntries = numOfEntries + 1+ , headerTableSize = headerTableSize'+ , reverseIndex = reverseIndex' } where- i = off- tsize' = tsize + entrySize e- off' = adj maxN (off - 1)- mrev' = case mrev of+ i = offset+ headerTableSize' = headerTableSize + entrySize e+ offset' = adj maxNumOfEntries (offset - 1)+ reverseIndex' = case reverseIndex of Nothing -> Nothing Just rev -> Just $ HP.insert (entryHeader e) (HIndex i) rev @@ -172,24 +233,44 @@ adjust hdrtbl is hs | tsize <= maxtsize = return (hdrtbl, is, hs) | otherwise = do- (hdrtbl', i, h) <- removeOne hdrtbl+ (hdrtbl', i, h) <- removeEnd hdrtbl adjust hdrtbl' (i:is) (h:hs) where tsize = headerTableSize hdrtbl maxtsize = maxHeaderTableSize hdrtbl -removeOne :: HeaderTable -> IO (HeaderTable,Index,Header)-removeOne hdrtbl@(HeaderTable maxN off n tbl tsize _ _) = do- let i = adj maxN (off + n)- e <- readArray tbl i- writeArray tbl i dummyEntry -- let the entry GCed- let tsize' = tsize - entrySize e+----------------------------------------------------------------++insertEnd :: Entry -> HeaderTable -> IO HeaderTable+insertEnd e hdrtbl@HeaderTable{..} = do+ writeArray circularTable i e+ return $ hdrtbl {+ numOfEntries = numOfEntries + 1+ , headerTableSize = headerTableSize'+ , reverseIndex = reverseIndex'+ }+ where+ i = adj maxNumOfEntries (offset + numOfEntries + 1)+ hi = numOfEntries + 1+ headerTableSize' = headerTableSize + entrySize e+ reverseIndex' = case reverseIndex of+ Nothing -> Nothing+ Just rev -> Just $ HP.insert (entryHeader e) (HIndex hi) rev++----------------------------------------------------------------++removeEnd :: HeaderTable -> IO (HeaderTable,Index,Header)+removeEnd hdrtbl@HeaderTable{..} = do+ let i = adj maxNumOfEntries (offset + numOfEntries)+ e <- readArray circularTable i+ writeArray circularTable i dummyEntry -- let the entry GCed+ let tsize = headerTableSize - entrySize e h = entryHeader e hdrtbl' = hdrtbl {- numOfEntries = n - 1- , headerTableSize = tsize'+ numOfEntries = numOfEntries - 1+ , headerTableSize = tsize }- return (hdrtbl',n - 1, h)+ return (hdrtbl', numOfEntries - 1, h) ---------------------------------------------------------------- @@ -209,7 +290,7 @@ ---------------------------------------------------------------- isIn :: Int -> HeaderTable -> Bool-isIn idx hdrtbl = idx <= numOfEntries hdrtbl+isIn idx HeaderTable{..} = idx <= numOfEntries -- | Which table does 'Index' belong to? which :: HeaderTable -> Index -> IO (WhichTable, Entry)@@ -222,5 +303,4 @@ sidx = fromIndexToSIndex hdrtbl idx toHeaderEntry :: HeaderTable -> HIndex -> IO Entry-toHeaderEntry hdrtbl (HIndex hidx) = readArray (circularTable hdrtbl) hidx-+toHeaderEntry HeaderTable{..} (HIndex hidx) = readArray circularTable hidx
Network/HPACK/Table/Static.hs view
@@ -55,65 +55,65 @@ staticTableList :: [Header] staticTableList = [- (":authority","")- , (":method","GET")- , (":method","POST")- , (":path","/")- , (":path","/index.html")- , (":scheme","http")- , (":scheme","https")- , (":status","200")- , (":status","204")- , (":status","206")- , (":status","304")- , (":status","400")- , (":status","404")- , (":status","500")- , ("accept-charset","")- , ("accept-encoding","")- , ("accept-language","")- , ("accept-ranges","")- , ("accept","")- , ("access-control-allow-origin","")- , ("age","")- , ("allow","")- , ("authorization","")- , ("cache-control","")- , ("content-disposition","")- , ("content-encoding","")- , ("content-language","")- , ("content-length","")- , ("content-location","")- , ("content-range","")- , ("content-type","")- , ("cookie","")- , ("date","")- , ("etag","")- , ("expect","")- , ("expires","")- , ("from","")- , ("host","")- , ("if-match","")- , ("if-modified-since","")- , ("if-none-match","")- , ("if-range","")- , ("if-unmodified-since","")- , ("last-modified","")- , ("link","")- , ("location","")- , ("max-forwards","")- , ("proxy-authenticate","")- , ("proxy-authorization","")- , ("range","")- , ("referer","")- , ("refresh","")- , ("retry-after","")- , ("server","")- , ("set-cookie","")- , ("strict-transport-security","")- , ("transfer-encoding","")- , ("user-agent","")- , ("vary","")- , ("via","")- , ("www-authenticate","")+ (":authority", "")+ , (":method", "GET")+ , (":method", "POST")+ , (":path", "/")+ , (":path", "/index.html")+ , (":scheme", "http")+ , (":scheme", "https")+ , (":status", "200")+ , (":status", "204")+ , (":status", "206")+ , (":status", "304")+ , (":status", "400")+ , (":status", "404")+ , (":status", "500")+ , ("accept-charset", "")+ , ("accept-encoding", "gzip, deflate")+ , ("accept-language", "")+ , ("accept-ranges", "")+ , ("accept", "")+ , ("access-control-allow-origin", "")+ , ("age", "")+ , ("allow", "")+ , ("authorization", "")+ , ("cache-control", "")+ , ("content-disposition", "")+ , ("content-encoding", "")+ , ("content-language", "")+ , ("content-length", "")+ , ("content-location", "")+ , ("content-range", "")+ , ("content-type", "")+ , ("cookie", "")+ , ("date", "")+ , ("etag", "")+ , ("expect", "")+ , ("expires", "")+ , ("from", "")+ , ("host", "")+ , ("if-match", "")+ , ("if-modified-since", "")+ , ("if-none-match", "")+ , ("if-range", "")+ , ("if-unmodified-since", "")+ , ("last-modified", "")+ , ("link", "")+ , ("location", "")+ , ("max-forwards", "")+ , ("proxy-authenticate", "")+ , ("proxy-authorization", "")+ , ("range", "")+ , ("referer", "")+ , ("refresh", "")+ , ("retry-after", "")+ , ("server", "")+ , ("set-cookie", "")+ , ("strict-transport-security", "")+ , ("transfer-encoding", "")+ , ("user-agent", "")+ , ("vary", "")+ , ("via", "")+ , ("www-authenticate", "") ]
http2.cabal view
@@ -1,12 +1,12 @@ Name: http2-Version: 0.3.0+Version: 0.4.0 Author: Kazu Yamamoto <kazu@iij.ad.jp> Maintainer: Kazu Yamamoto <kazu@iij.ad.jp> License: BSD3 License-File: LICENSE Synopsis: HTTP/2.0 library including HPACK Description: HTTP/2.0 library including HPACK.- Currently only HPACK 07 is supported.+ Currently only HPACK 08 is supported. Category: Network Cabal-Version: >= 1.10 Build-Type: Simple
test-hpack/HPACKDecode.hs view
@@ -61,7 +61,10 @@ B8.putStrLn hex putStrLn "---- Input header block" print hd- x <- try $ decodeHeader dctx inp+ dctx0 <- case size c of+ Nothing -> return dctx+ Just siz -> changeContextForDecoding dctx siz+ x <- try $ decodeHeader dctx0 inp case x of Left e -> return $ Left $ show (e :: DecodeError) Right (dctx',hs') -> do
test/HeaderBlock.hs view
@@ -26,7 +26,7 @@ ] d41b :: ByteStream-d41b = fromHexString "828786448ce7cf9bebe89b6fb16fa9b6ff"+d41b = fromHexString "828786448cf1e3c2e5f23a6ba0ab90f4ff" d42 :: HeaderBlock d42 = [@@ -41,7 +41,7 @@ ,(":authority","www.example.com")] d42b :: ByteStream-d42b = fromHexString "5c86b9b9949556bf"+d42b = fromHexString "5c86a8eb10649cbf" d43 :: HeaderBlock d43 = [@@ -62,7 +62,7 @@ ] d43b :: ByteStream-d43b = fromHexString "30858c8b844088571c5cdb737b2faf89571c5cdb73724d9c57"+d43b = fromHexString "30858c8b84408825a849e95ba97d7f8925a849e95bb8e8b4bf" ---------------------------------------------------------------- @@ -82,7 +82,7 @@ ] d61b :: ByteStream-d61b = fromHexString "488240175985bf06724b976393d6dbb29884de2a718805062098513109b56ba37191adcebf198e7e7cf9bebe89b6fb16fa9b6f"+d61b = fromHexString "488264025985aec3771a4b6396d07abe941054d444a8200595040b8166e082a62d1bff71919d29ad171863c78f0b97c8e9ae82ae43d3" d62 :: HeaderBlock d62 = [@@ -121,4 +121,4 @@ ,("set-cookie","foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1")] d63b :: ByteStream-d63b = fromHexString "84844393d6dbb29884de2a718805062098513111b56ba35e84abdd97ff848483837bb1e0d6cf9f6e8f9fd3e5f6fa76fefd3c7edf9eff1f2f0f3cfe9f6fcf7f8f879f61ad4f4cc9a973a2200ec3725e18b1b74e3f"+d63b = fromHexString "84844396d07abe941054d444a8200595040b8166e084a62d1bff5e839bd9ab848483837bad94e7821dd7f2e6c7b335dfdfcd5b3960d5af27087f3672c1ab270fb5291f9587316065c003ed4ee5b1063d5007"
test/HuffmanSpec.hs view
@@ -14,16 +14,16 @@ testData :: [(ByteString, ByteString)] testData = [ ("", "")- , ("www.example.com", "e7cf9bebe89b6fb16fa9b6ff")- , ("no-cache", "b9b9949556bf")- , ("custom-key", "571c5cdb737b2faf")- , ("custom-value", "571c5cdb73724d9c57")- , ("private", "bf06724b97")- , ("Mon, 21 Oct 2013 20:13:21 GMT", "d6dbb29884de2a718805062098513109b56ba3")- , ("https://www.example.com", "adcebf198e7e7cf9bebe89b6fb16fa9b6f")- , ("Mon, 21 Oct 2013 20:13:22 GMT", "d6dbb29884de2a718805062098513111b56ba3")- , ("gzip", "abdd97ff")- , ("foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", "e0d6cf9f6e8f9fd3e5f6fa76fefd3c7edf9eff1f2f0f3cfe9f6fcf7f8f879f61ad4f4cc9a973a2200ec3725e18b1b74e3f")+ , ("www.example.com", "f1e3c2e5f23a6ba0ab90f4ff")+ , ("no-cache", "a8eb10649cbf")+ , ("custom-key", "25a849e95ba97d7f")+ , ("custom-value", "25a849e95bb8e8b4bf")+ , ("private", "aec3771a4b")+ , ("Mon, 21 Oct 2013 20:13:21 GMT", "d07abe941054d444a8200595040b8166e082a62d1bff")+ , ("https://www.example.com", "9d29ad171863c78f0b97c8e9ae82ae43d3")+ , ("Mon, 21 Oct 2013 20:13:22 GMT", "d07abe941054d444a8200595040b8166e084a62d1bff")+ , ("gzip", "9bd9ab")+ , ("foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", "94e7821dd7f2e6c7b335dfdfcd5b3960d5af27087f3672c1ab270fb5291f9587316065c003ed4ee5b1063d5007") ] shouldBeEncoded :: ByteString -> ByteString -> Expectation@@ -48,6 +48,6 @@ describe "decode" $ do it "decodes" $ do "ff" `shouldBeDecoded` Left TooLongEos- "ffffeeff" `shouldBeDecoded` Right "\1"- "ffffeeffff" `shouldBeDecoded` Left TooLongEos+ "ffffea" `shouldBeDecoded` Right "\9"+ "ffffeaff" `shouldBeDecoded` Left TooLongEos mapM_ (\(x,y) -> y `shouldBeDecoded` Right x) testData