{-# LANGUAGE OverloadedStrings #-}

module Network.QUIC.Packet.Frame (
    encodeFrames
  , encodeFramesWithPadding
  , decodeFrames
  , countZero -- testing
  ) where

import qualified Data.ByteString as BS
import qualified Data.ByteString.Short as Short
import Foreign.Ptr (Ptr, plusPtr, minusPtr, alignPtr, castPtr)
import Foreign.Storable (peek, alignment)
import Network.Socket.Internal (zeroMemory)

import Network.QUIC.Imports
import Network.QUIC.Types

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

encodeFrames :: [Frame] -> IO ByteString
encodeFrames :: [Frame] -> IO ByteString
encodeFrames [Frame]
frames = BufferSize -> (WriteBuffer -> IO ()) -> IO ByteString
withWriteBuffer BufferSize
2048 ((WriteBuffer -> IO ()) -> IO ByteString)
-> (WriteBuffer -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \WriteBuffer
wbuf ->
  (Frame -> IO ()) -> [Frame] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (WriteBuffer -> Frame -> IO ()
encodeFrame WriteBuffer
wbuf) [Frame]
frames

encodeFramesWithPadding :: Buffer
                        -> BufferSize
                        -> [Frame]
                        -> IO Int   -- ^ payload size without paddings
encodeFramesWithPadding :: Buffer -> BufferSize -> [Frame] -> IO BufferSize
encodeFramesWithPadding Buffer
buf BufferSize
siz [Frame]
frames = do
    Buffer -> CSize -> IO ()
forall a. Ptr a -> CSize -> IO ()
zeroMemory Buffer
buf (CSize -> IO ()) -> CSize -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
siz -- padding
    WriteBuffer
wbuf <- Buffer -> BufferSize -> IO WriteBuffer
newWriteBuffer Buffer
buf BufferSize
siz
    WriteBuffer -> IO ()
forall a. Readable a => a -> IO ()
save WriteBuffer
wbuf
    (Frame -> IO ()) -> [Frame] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (WriteBuffer -> Frame -> IO ()
encodeFrame WriteBuffer
wbuf) [Frame]
frames
    WriteBuffer -> IO BufferSize
forall a. Readable a => a -> IO BufferSize
savingSize WriteBuffer
wbuf

encodeFrame :: WriteBuffer -> Frame -> IO ()
encodeFrame :: WriteBuffer -> Frame -> IO ()
encodeFrame WriteBuffer
wbuf (Padding BufferSize
n) = BufferSize -> IO () -> IO ()
forall (m :: * -> *) a. Applicative m => BufferSize -> m a -> m ()
replicateM_ BufferSize
n (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x00
encodeFrame WriteBuffer
wbuf Frame
Ping = WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x01
encodeFrame WriteBuffer
wbuf (Ack (AckInfo BufferSize
largest BufferSize
range1 [(BufferSize, BufferSize)]
ranges) (Milliseconds Int64
delay)) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x02
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
largest
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ Int64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
delay
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (BufferSize -> Int64) -> BufferSize -> Int64
forall a b. (a -> b) -> a -> b
$ [(BufferSize, BufferSize)] -> BufferSize
forall (t :: * -> *) a. Foldable t => t a -> BufferSize
length [(BufferSize, BufferSize)]
ranges
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
range1
    ((BufferSize, BufferSize) -> IO ())
-> [(BufferSize, BufferSize)] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (BufferSize, BufferSize) -> IO ()
forall a a. (Integral a, Integral a) => (a, a) -> IO ()
putRanges [(BufferSize, BufferSize)]
ranges
  where
    putRanges :: (a, a) -> IO ()
putRanges (a
gap,a
rng) = do
        WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ a -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
gap
        WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ a -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
rng
encodeFrame WriteBuffer
wbuf (ResetStream BufferSize
sid (ApplicationProtocolError BufferSize
err) BufferSize
finalLen) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x04
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
sid
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
err
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
finalLen
encodeFrame WriteBuffer
wbuf (StopSending BufferSize
sid (ApplicationProtocolError BufferSize
err)) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x05
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
sid
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
err
encodeFrame WriteBuffer
wbuf (CryptoF BufferSize
off ByteString
cdata) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x06
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
off
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (BufferSize -> Int64) -> BufferSize -> Int64
forall a b. (a -> b) -> a -> b
$ ByteString -> BufferSize
BS.length ByteString
cdata
    WriteBuffer -> ByteString -> IO ()
copyByteString WriteBuffer
wbuf ByteString
cdata
encodeFrame WriteBuffer
wbuf (NewToken ByteString
token) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x07
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (BufferSize -> Int64) -> BufferSize -> Int64
forall a b. (a -> b) -> a -> b
$ ByteString -> BufferSize
BS.length ByteString
token
    WriteBuffer -> ByteString -> IO ()
copyByteString WriteBuffer
wbuf ByteString
token
encodeFrame WriteBuffer
wbuf (StreamF BufferSize
sid BufferSize
off [ByteString]
dats Fin
fin) = do
    let flag0 :: Word8
flag0 = Word8
0x08 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8
0x02 -- len
        flag1 :: Word8
flag1 | BufferSize
off BufferSize -> BufferSize -> Fin
forall a. Eq a => a -> a -> Fin
/= BufferSize
0  = Word8
flag0 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8
0x04 -- off
              | Fin
otherwise = Word8
flag0
        flag2 :: Word8
flag2 | Fin
fin       = Word8
flag1 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8
0x01 -- fin
              | Fin
otherwise = Word8
flag1
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
flag2
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
sid
    Fin -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Fin -> f () -> f ()
when (BufferSize
off BufferSize -> BufferSize -> Fin
forall a. Eq a => a -> a -> Fin
/= BufferSize
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
off
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (BufferSize -> Int64) -> BufferSize -> Int64
forall a b. (a -> b) -> a -> b
$ [ByteString] -> BufferSize
totalLen [ByteString]
dats
    (ByteString -> IO ()) -> [ByteString] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (WriteBuffer -> ByteString -> IO ()
copyByteString WriteBuffer
wbuf) [ByteString]
dats
encodeFrame WriteBuffer
wbuf (MaxData BufferSize
n) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x10
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
n
encodeFrame WriteBuffer
wbuf (MaxStreamData BufferSize
sid BufferSize
n) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x11
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
sid
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
n
encodeFrame WriteBuffer
wbuf (MaxStreams Direction
dir BufferSize
ms) = do
    case Direction
dir of
      Direction
Bidirectional  -> WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x12
      Direction
Unidirectional -> WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x13
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
ms
encodeFrame WriteBuffer
wbuf (DataBlocked BufferSize
n) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x14
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
n
encodeFrame WriteBuffer
wbuf (StreamDataBlocked BufferSize
sid BufferSize
n) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x15
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
sid
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
n
encodeFrame WriteBuffer
wbuf (StreamsBlocked Direction
dir BufferSize
ms) = do
    case Direction
dir of
      Direction
Bidirectional  -> WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x16
      Direction
Unidirectional -> WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x17
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
ms
encodeFrame WriteBuffer
wbuf (NewConnectionID CIDInfo
cidInfo BufferSize
rpt) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x18
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (BufferSize -> Int64) -> BufferSize -> Int64
forall a b. (a -> b) -> a -> b
$ CIDInfo -> BufferSize
cidInfoSeq CIDInfo
cidInfo
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
rpt
    let (ShortByteString
cid, Word8
len) = CID -> (ShortByteString, Word8)
unpackCID (CID -> (ShortByteString, Word8))
-> CID -> (ShortByteString, Word8)
forall a b. (a -> b) -> a -> b
$ CIDInfo -> CID
cidInfoCID CIDInfo
cidInfo
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
len
    WriteBuffer -> ShortByteString -> IO ()
copyShortByteString WriteBuffer
wbuf ShortByteString
cid
    let StatelessResetToken ShortByteString
token = CIDInfo -> StatelessResetToken
cidInfoSRT CIDInfo
cidInfo
    WriteBuffer -> ShortByteString -> IO ()
copyShortByteString WriteBuffer
wbuf ShortByteString
token
encodeFrame WriteBuffer
wbuf (RetireConnectionID BufferSize
seqNum) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x19
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
seqNum
encodeFrame WriteBuffer
wbuf (PathChallenge (PathData ShortByteString
pdata)) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x1a
    WriteBuffer -> ByteString -> IO ()
copyByteString WriteBuffer
wbuf (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ ShortByteString -> ByteString
Short.fromShort ShortByteString
pdata
encodeFrame WriteBuffer
wbuf (PathResponse (PathData ShortByteString
pdata)) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x1b
    WriteBuffer -> ByteString -> IO ()
copyByteString WriteBuffer
wbuf (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ ShortByteString -> ByteString
Short.fromShort ShortByteString
pdata
encodeFrame WriteBuffer
wbuf (ConnectionClose (TransportError BufferSize
err) BufferSize
ftyp ShortByteString
reason) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x1c
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
err
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
ftyp
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (BufferSize -> Int64) -> BufferSize -> Int64
forall a b. (a -> b) -> a -> b
$ ShortByteString -> BufferSize
Short.length ShortByteString
reason
    WriteBuffer -> ShortByteString -> IO ()
copyShortByteString WriteBuffer
wbuf ShortByteString
reason
encodeFrame WriteBuffer
wbuf (ConnectionCloseApp (ApplicationProtocolError BufferSize
err) ShortByteString
reason) = do
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x1d
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
err
    WriteBuffer -> Int64 -> IO ()
encodeInt' WriteBuffer
wbuf (Int64 -> IO ()) -> Int64 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (BufferSize -> Int64) -> BufferSize -> Int64
forall a b. (a -> b) -> a -> b
$ ShortByteString -> BufferSize
Short.length ShortByteString
reason
    WriteBuffer -> ShortByteString -> IO ()
copyShortByteString WriteBuffer
wbuf ShortByteString
reason
encodeFrame WriteBuffer
wbuf Frame
HandshakeDone =
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf Word8
0x1e
encodeFrame WriteBuffer
wbuf (UnknownFrame BufferSize
typ) =
    WriteBuffer -> Word8 -> IO ()
write8 WriteBuffer
wbuf (Word8 -> IO ()) -> Word8 -> IO ()
forall a b. (a -> b) -> a -> b
$ BufferSize -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral BufferSize
typ

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

decodeFrames :: Buffer -> BufferSize -> IO (Maybe [Frame])
decodeFrames :: Buffer -> BufferSize -> IO (Maybe [Frame])
decodeFrames Buffer
buf BufferSize
bufsiz = do
    ReadBuffer
rbuf <- Buffer -> BufferSize -> IO ReadBuffer
newReadBuffer Buffer
buf BufferSize
bufsiz
    ([Frame] -> [Frame]) -> ReadBuffer -> IO (Maybe [Frame])
forall a. ([Frame] -> a) -> ReadBuffer -> IO (Maybe a)
loop [Frame] -> [Frame]
forall a. a -> a
id ReadBuffer
rbuf
  where
    loop :: ([Frame] -> a) -> ReadBuffer -> IO (Maybe a)
loop [Frame] -> a
frames ReadBuffer
rbuf = do
        Fin
ok <- (BufferSize -> BufferSize -> Fin
forall a. Ord a => a -> a -> Fin
>= BufferSize
1) (BufferSize -> Fin) -> IO BufferSize -> IO Fin
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO BufferSize
forall a. Readable a => a -> IO BufferSize
remainingSize ReadBuffer
rbuf
        if Fin
ok then do
            Frame
frame <- ReadBuffer -> IO Frame
decodeFrame ReadBuffer
rbuf
            case Frame
frame of
              UnknownFrame BufferSize
_ -> Maybe a -> IO (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
              Frame
_              -> ([Frame] -> a) -> ReadBuffer -> IO (Maybe a)
loop ([Frame] -> a
frames ([Frame] -> a) -> ([Frame] -> [Frame]) -> [Frame] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Frame
frameFrame -> [Frame] -> [Frame]
forall a. a -> [a] -> [a]
:)) ReadBuffer
rbuf
          else
            Maybe a -> IO (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> IO (Maybe a)) -> Maybe a -> IO (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ [Frame] -> a
frames []

decodeFrame :: ReadBuffer -> IO Frame
decodeFrame :: ReadBuffer -> IO Frame
decodeFrame ReadBuffer
rbuf = do
    BufferSize
ftyp <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    case BufferSize
ftyp :: FrameType of
      BufferSize
0x00 -> ReadBuffer -> IO Frame
decodePadding ReadBuffer
rbuf
      BufferSize
0x01 -> Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return Frame
Ping
      BufferSize
0x02 -> ReadBuffer -> IO Frame
decodeAck ReadBuffer
rbuf
   -- 0x03 -> Ack with ECN Counts
      BufferSize
0x04 -> ReadBuffer -> IO Frame
decodeResetStream ReadBuffer
rbuf
      BufferSize
0x05 -> ReadBuffer -> IO Frame
decodeStopSending ReadBuffer
rbuf
      BufferSize
0x06 -> ReadBuffer -> IO Frame
decodeCrypto ReadBuffer
rbuf
      BufferSize
0x07 -> ReadBuffer -> IO Frame
decodeNewToken ReadBuffer
rbuf
      BufferSize
x | BufferSize
0x08 BufferSize -> BufferSize -> Fin
forall a. Ord a => a -> a -> Fin
<= BufferSize
x Fin -> Fin -> Fin
&& BufferSize
x BufferSize -> BufferSize -> Fin
forall a. Ord a => a -> a -> Fin
<= BufferSize
0x0f -> do
              let off :: Fin
off = BufferSize -> BufferSize -> Fin
forall a. Bits a => a -> BufferSize -> Fin
testBit BufferSize
x BufferSize
2
                  len :: Fin
len = BufferSize -> BufferSize -> Fin
forall a. Bits a => a -> BufferSize -> Fin
testBit BufferSize
x BufferSize
1
                  fin :: Fin
fin = BufferSize -> BufferSize -> Fin
forall a. Bits a => a -> BufferSize -> Fin
testBit BufferSize
x BufferSize
0
              ReadBuffer -> Fin -> Fin -> Fin -> IO Frame
decodeStream ReadBuffer
rbuf Fin
off Fin
len Fin
fin
      BufferSize
0x10 -> ReadBuffer -> IO Frame
decodeMaxData ReadBuffer
rbuf
      BufferSize
0x11 -> ReadBuffer -> IO Frame
decodeMaxStreamData ReadBuffer
rbuf
      BufferSize
0x12 -> ReadBuffer -> Direction -> IO Frame
decodeMaxStreams ReadBuffer
rbuf Direction
Bidirectional
      BufferSize
0x13 -> ReadBuffer -> Direction -> IO Frame
decodeMaxStreams ReadBuffer
rbuf Direction
Unidirectional
      BufferSize
0x14 -> ReadBuffer -> IO Frame
decodeDataBlocked ReadBuffer
rbuf
      BufferSize
0x15 -> ReadBuffer -> IO Frame
decodeStreamDataBlocked ReadBuffer
rbuf
      BufferSize
0x16 -> ReadBuffer -> Direction -> IO Frame
decodeStreamsBlocked ReadBuffer
rbuf Direction
Bidirectional
      BufferSize
0x17 -> ReadBuffer -> Direction -> IO Frame
decodeStreamsBlocked ReadBuffer
rbuf Direction
Unidirectional
      BufferSize
0x18 -> ReadBuffer -> IO Frame
decodeNewConnectionID ReadBuffer
rbuf
      BufferSize
0x19 -> ReadBuffer -> IO Frame
decodeRetireConnectionID ReadBuffer
rbuf
      BufferSize
0x1a -> ReadBuffer -> IO Frame
decodePathChallenge ReadBuffer
rbuf
      BufferSize
0x1b -> ReadBuffer -> IO Frame
decodePathResponse ReadBuffer
rbuf
      BufferSize
0x1c -> ReadBuffer -> IO Frame
decodeConnectionClose ReadBuffer
rbuf
      BufferSize
0x1d -> ReadBuffer -> IO Frame
decodeConnectionCloseApp ReadBuffer
rbuf
      BufferSize
0x1e -> Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return Frame
HandshakeDone
      BufferSize
x    -> Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ BufferSize -> Frame
UnknownFrame BufferSize
x

decodePadding :: ReadBuffer -> IO Frame
decodePadding :: ReadBuffer -> IO Frame
decodePadding ReadBuffer
rbuf = do
    BufferSize
n <- ReadBuffer -> (Buffer -> IO BufferSize) -> IO BufferSize
forall a b. Readable a => a -> (Buffer -> IO b) -> IO b
withCurrentOffSet ReadBuffer
rbuf ((Buffer -> IO BufferSize) -> IO BufferSize)
-> (Buffer -> IO BufferSize) -> IO BufferSize
forall a b. (a -> b) -> a -> b
$ \Buffer
beg -> do
        BufferSize
rest <- ReadBuffer -> IO BufferSize
forall a. Readable a => a -> IO BufferSize
remainingSize ReadBuffer
rbuf
        let end :: Ptr b
end = Buffer
beg Buffer -> BufferSize -> Ptr b
forall a b. Ptr a -> BufferSize -> Ptr b
`plusPtr` BufferSize
rest
        Buffer -> Buffer -> IO BufferSize
countZero Buffer
beg Buffer
forall b. Ptr b
end
    ReadBuffer -> BufferSize -> IO ()
forall a. Readable a => a -> BufferSize -> IO ()
ff ReadBuffer
rbuf BufferSize
n
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ BufferSize -> Frame
Padding (BufferSize
n BufferSize -> BufferSize -> BufferSize
forall a. Num a => a -> a -> a
+ BufferSize
1)

countZero :: Ptr Word8 -> Ptr Word8 -> IO Int
countZero :: Buffer -> Buffer -> IO BufferSize
countZero Buffer
beg0 Buffer
end0
  | (Buffer
end0 Buffer -> Buffer -> BufferSize
forall a b. Ptr a -> Ptr b -> BufferSize
`minusPtr` Buffer
beg0) BufferSize -> BufferSize -> Fin
forall a. Ord a => a -> a -> Fin
<= BufferSize
ali = (BufferSize, Fin) -> BufferSize
forall a b. (a, b) -> a
fst ((BufferSize, Fin) -> BufferSize)
-> IO (BufferSize, Fin) -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Buffer -> Buffer -> BufferSize -> IO (BufferSize, Fin)
countBy1 Buffer
beg0 Buffer
end0 BufferSize
0
  | Fin
otherwise = do
    let beg1 :: Buffer
beg1 = Buffer -> BufferSize -> Buffer
forall a. Ptr a -> BufferSize -> Ptr a
alignPtr Buffer
beg0 BufferSize
ali
        end1' :: Buffer
end1' = Buffer -> BufferSize -> Buffer
forall a. Ptr a -> BufferSize -> Ptr a
alignPtr Buffer
end0 BufferSize
ali
        end1 :: Buffer
end1 | Buffer
end0 Buffer -> Buffer -> Fin
forall a. Eq a => a -> a -> Fin
== Buffer
end1' = Buffer
end1'
             | Fin
otherwise     = Buffer
end1' Buffer -> BufferSize -> Buffer
forall a b. Ptr a -> BufferSize -> Ptr b
`plusPtr` BufferSize -> BufferSize
forall a. Num a => a -> a
negate BufferSize
ali
    (BufferSize
n1,Fin
cont1) <- Buffer -> Buffer -> BufferSize -> IO (BufferSize, Fin)
countBy1 Buffer
beg0 Buffer
beg1 BufferSize
0
    if Fin -> Fin
not Fin
cont1 then
        BufferSize -> IO BufferSize
forall (m :: * -> *) a. Monad m => a -> m a
return BufferSize
n1
      else do
        (BufferSize
n2,Ptr Word64
beg2) <- Ptr Word64
-> Ptr Word64 -> BufferSize -> IO (BufferSize, Ptr Word64)
countBy8 (Buffer -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Buffer
beg1) (Buffer -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Buffer
end1) BufferSize
0
        (BufferSize
n3,Fin
_) <- Buffer -> Buffer -> BufferSize -> IO (BufferSize, Fin)
countBy1 (Ptr Word64 -> Buffer
forall a b. Ptr a -> Ptr b
castPtr Ptr Word64
beg2) Buffer
end0 BufferSize
0
        BufferSize -> IO BufferSize
forall (m :: * -> *) a. Monad m => a -> m a
return (BufferSize
n1 BufferSize -> BufferSize -> BufferSize
forall a. Num a => a -> a -> a
+ BufferSize
n2 BufferSize -> BufferSize -> BufferSize
forall a. Num a => a -> a -> a
+ BufferSize
n3)
  where
    ali :: BufferSize
ali = Word64 -> BufferSize
forall a. Storable a => a -> BufferSize
alignment (Word64
0 :: Word64)
    countBy1 :: Ptr Word8 -> Ptr Word8 -> Int -> IO (Int,Bool)
    countBy1 :: Buffer -> Buffer -> BufferSize -> IO (BufferSize, Fin)
countBy1 Buffer
beg Buffer
end BufferSize
n
      | Buffer
beg Buffer -> Buffer -> Fin
forall a. Ord a => a -> a -> Fin
< Buffer
end = do
            Word8
ftyp <- Buffer -> IO Word8
forall a. Storable a => Ptr a -> IO a
peek Buffer
beg
            if Word8
ftyp Word8 -> Word8 -> Fin
forall a. Eq a => a -> a -> Fin
== Word8
0 then
                Buffer -> Buffer -> BufferSize -> IO (BufferSize, Fin)
countBy1 (Buffer
beg Buffer -> BufferSize -> Buffer
forall a b. Ptr a -> BufferSize -> Ptr b
`plusPtr` BufferSize
1) Buffer
end (BufferSize
n BufferSize -> BufferSize -> BufferSize
forall a. Num a => a -> a -> a
+ BufferSize
1)
              else
                (BufferSize, Fin) -> IO (BufferSize, Fin)
forall (m :: * -> *) a. Monad m => a -> m a
return (BufferSize
n, Fin
False)
      | Fin
otherwise = (BufferSize, Fin) -> IO (BufferSize, Fin)
forall (m :: * -> *) a. Monad m => a -> m a
return (BufferSize
n, Fin
True)
    countBy8 :: Ptr Word64 -> Ptr Word64 -> Int -> IO (Int, Ptr Word64)
    countBy8 :: Ptr Word64
-> Ptr Word64 -> BufferSize -> IO (BufferSize, Ptr Word64)
countBy8 Ptr Word64
beg Ptr Word64
end BufferSize
n
      | Ptr Word64
beg Ptr Word64 -> Ptr Word64 -> Fin
forall a. Ord a => a -> a -> Fin
< Ptr Word64
end = do
            Word64
ftyp <- Ptr Word64 -> IO Word64
forall a. Storable a => Ptr a -> IO a
peek Ptr Word64
beg
            if Word64
ftyp Word64 -> Word64 -> Fin
forall a. Eq a => a -> a -> Fin
== Word64
0 then
                Ptr Word64
-> Ptr Word64 -> BufferSize -> IO (BufferSize, Ptr Word64)
countBy8 (Ptr Word64
beg Ptr Word64 -> BufferSize -> Ptr Word64
forall a b. Ptr a -> BufferSize -> Ptr b
`plusPtr` BufferSize
ali) Ptr Word64
end (BufferSize
n BufferSize -> BufferSize -> BufferSize
forall a. Num a => a -> a -> a
+ BufferSize
ali)
              else
                (BufferSize, Ptr Word64) -> IO (BufferSize, Ptr Word64)
forall (m :: * -> *) a. Monad m => a -> m a
return (BufferSize
n, Ptr Word64
beg)
      | Fin
otherwise = (BufferSize, Ptr Word64) -> IO (BufferSize, Ptr Word64)
forall (m :: * -> *) a. Monad m => a -> m a
return (BufferSize
n, Ptr Word64
beg)

decodeCrypto :: ReadBuffer -> IO Frame
decodeCrypto :: ReadBuffer -> IO Frame
decodeCrypto ReadBuffer
rbuf = do
    BufferSize
off <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
len <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    ByteString
cdata <- ReadBuffer -> BufferSize -> IO ByteString
forall a. Readable a => a -> BufferSize -> IO ByteString
extractByteString ReadBuffer
rbuf BufferSize
len
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ BufferSize -> ByteString -> Frame
CryptoF BufferSize
off ByteString
cdata

decodeAck :: ReadBuffer -> IO Frame
decodeAck :: ReadBuffer -> IO Frame
decodeAck ReadBuffer
rbuf = do
    BufferSize
largest <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    Int64
delay   <- Int64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Int64) -> IO Int64 -> IO Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
count   <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
range1  <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    [(BufferSize, BufferSize)]
ranges  <- BufferSize
-> ([(BufferSize, BufferSize)] -> [(BufferSize, BufferSize)])
-> IO [(BufferSize, BufferSize)]
forall a b c.
(Num a, Num b) =>
BufferSize -> ([(a, b)] -> c) -> IO c
getRanges BufferSize
count [(BufferSize, BufferSize)] -> [(BufferSize, BufferSize)]
forall a. a -> a
id
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ AckInfo -> Milliseconds -> Frame
Ack (BufferSize -> BufferSize -> [(BufferSize, BufferSize)] -> AckInfo
AckInfo BufferSize
largest BufferSize
range1 [(BufferSize, BufferSize)]
ranges) (Milliseconds -> Frame) -> Milliseconds -> Frame
forall a b. (a -> b) -> a -> b
$ Int64 -> Milliseconds
Milliseconds Int64
delay
  where
    getRanges :: BufferSize -> ([(a, b)] -> c) -> IO c
getRanges BufferSize
0 [(a, b)] -> c
build = c -> IO c
forall (m :: * -> *) a. Monad m => a -> m a
return (c -> IO c) -> c -> IO c
forall a b. (a -> b) -> a -> b
$ [(a, b)] -> c
build []
    getRanges BufferSize
n [(a, b)] -> c
build = do
        a
gap <- Int64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> a) -> IO Int64 -> IO a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
        b
rng <- Int64 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> b) -> IO Int64 -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
        let n' :: BufferSize
n' = BufferSize
n BufferSize -> BufferSize -> BufferSize
forall a. Num a => a -> a -> a
- BufferSize
1 :: Int
        BufferSize -> ([(a, b)] -> c) -> IO c
getRanges BufferSize
n' ([(a, b)] -> c
build ([(a, b)] -> c) -> ([(a, b)] -> [(a, b)]) -> [(a, b)] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a
gap, b
rng) (a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
:))

decodeResetStream :: ReadBuffer -> IO Frame
decodeResetStream :: ReadBuffer -> IO Frame
decodeResetStream ReadBuffer
rbuf = do
    BufferSize
sID <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    ApplicationProtocolError
err <- BufferSize -> ApplicationProtocolError
ApplicationProtocolError (BufferSize -> ApplicationProtocolError)
-> (Int64 -> BufferSize) -> Int64 -> ApplicationProtocolError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> ApplicationProtocolError)
-> IO Int64 -> IO ApplicationProtocolError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
finalLen <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ BufferSize -> ApplicationProtocolError -> BufferSize -> Frame
ResetStream BufferSize
sID ApplicationProtocolError
err BufferSize
finalLen

decodeStopSending :: ReadBuffer -> IO Frame
decodeStopSending :: ReadBuffer -> IO Frame
decodeStopSending ReadBuffer
rbuf = do
    BufferSize
sID <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    ApplicationProtocolError
err <- BufferSize -> ApplicationProtocolError
ApplicationProtocolError (BufferSize -> ApplicationProtocolError)
-> (Int64 -> BufferSize) -> Int64 -> ApplicationProtocolError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> ApplicationProtocolError)
-> IO Int64 -> IO ApplicationProtocolError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ BufferSize -> ApplicationProtocolError -> Frame
StopSending BufferSize
sID ApplicationProtocolError
err

decodeNewToken :: ReadBuffer -> IO Frame
decodeNewToken :: ReadBuffer -> IO Frame
decodeNewToken ReadBuffer
rbuf = do
    BufferSize
len <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    ByteString -> Frame
NewToken (ByteString -> Frame) -> IO ByteString -> IO Frame
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> BufferSize -> IO ByteString
forall a. Readable a => a -> BufferSize -> IO ByteString
extractByteString ReadBuffer
rbuf BufferSize
len

decodeStream :: ReadBuffer -> Bool -> Bool -> Bool -> IO Frame
decodeStream :: ReadBuffer -> Fin -> Fin -> Fin -> IO Frame
decodeStream ReadBuffer
rbuf Fin
hasOff Fin
hasLen Fin
fin = do
    BufferSize
sID <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
off <- if Fin
hasOff then
             Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
           else
             BufferSize -> IO BufferSize
forall (m :: * -> *) a. Monad m => a -> m a
return BufferSize
0
    ByteString
dat <- if Fin
hasLen then do
             BufferSize
len <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
             ReadBuffer -> BufferSize -> IO ByteString
forall a. Readable a => a -> BufferSize -> IO ByteString
extractByteString ReadBuffer
rbuf BufferSize
len
           else do
             BufferSize
len <- ReadBuffer -> IO BufferSize
forall a. Readable a => a -> IO BufferSize
remainingSize ReadBuffer
rbuf
             ReadBuffer -> BufferSize -> IO ByteString
forall a. Readable a => a -> BufferSize -> IO ByteString
extractByteString ReadBuffer
rbuf BufferSize
len
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ BufferSize -> BufferSize -> [ByteString] -> Fin -> Frame
StreamF BufferSize
sID BufferSize
off [ByteString
dat] Fin
fin

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

decodeMaxData :: ReadBuffer -> IO Frame
decodeMaxData :: ReadBuffer -> IO Frame
decodeMaxData ReadBuffer
rbuf = BufferSize -> Frame
MaxData (BufferSize -> Frame) -> (Int64 -> BufferSize) -> Int64 -> Frame
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Frame) -> IO Int64 -> IO Frame
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf

decodeMaxStreamData :: ReadBuffer -> IO Frame
decodeMaxStreamData :: ReadBuffer -> IO Frame
decodeMaxStreamData ReadBuffer
rbuf = do
    BufferSize
sID <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
maxstrdata <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ BufferSize -> BufferSize -> Frame
MaxStreamData BufferSize
sID BufferSize
maxstrdata

decodeMaxStreams :: ReadBuffer -> Direction -> IO Frame
decodeMaxStreams :: ReadBuffer -> Direction -> IO Frame
decodeMaxStreams ReadBuffer
rbuf Direction
dir = Direction -> BufferSize -> Frame
MaxStreams Direction
dir (BufferSize -> Frame) -> (Int64 -> BufferSize) -> Int64 -> Frame
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Frame) -> IO Int64 -> IO Frame
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf

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

decodeDataBlocked :: ReadBuffer -> IO Frame
decodeDataBlocked :: ReadBuffer -> IO Frame
decodeDataBlocked ReadBuffer
rbuf = BufferSize -> Frame
DataBlocked (BufferSize -> Frame) -> (Int64 -> BufferSize) -> Int64 -> Frame
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Frame) -> IO Int64 -> IO Frame
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf

decodeStreamDataBlocked :: ReadBuffer -> IO Frame
decodeStreamDataBlocked :: ReadBuffer -> IO Frame
decodeStreamDataBlocked ReadBuffer
rbuf = do
    BufferSize
sID <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
msd <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ BufferSize -> BufferSize -> Frame
StreamDataBlocked BufferSize
sID BufferSize
msd

decodeStreamsBlocked :: ReadBuffer -> Direction -> IO Frame
decodeStreamsBlocked :: ReadBuffer -> Direction -> IO Frame
decodeStreamsBlocked ReadBuffer
rbuf Direction
dir = Direction -> BufferSize -> Frame
StreamsBlocked Direction
dir (BufferSize -> Frame) -> (Int64 -> BufferSize) -> Int64 -> Frame
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Frame) -> IO Int64 -> IO Frame
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf

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

decodeConnectionClose :: ReadBuffer -> IO Frame
decodeConnectionClose :: ReadBuffer -> IO Frame
decodeConnectionClose ReadBuffer
rbuf = do
    TransportError
err    <- BufferSize -> TransportError
TransportError (BufferSize -> TransportError)
-> (Int64 -> BufferSize) -> Int64 -> TransportError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> TransportError) -> IO Int64 -> IO TransportError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
ftyp   <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
len    <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    ShortByteString
reason <- ReadBuffer -> BufferSize -> IO ShortByteString
forall a. Readable a => a -> BufferSize -> IO ShortByteString
extractShortByteString ReadBuffer
rbuf BufferSize
len
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ TransportError -> BufferSize -> ShortByteString -> Frame
ConnectionClose TransportError
err BufferSize
ftyp ShortByteString
reason

decodeConnectionCloseApp  :: ReadBuffer -> IO Frame
decodeConnectionCloseApp :: ReadBuffer -> IO Frame
decodeConnectionCloseApp ReadBuffer
rbuf = do
    ApplicationProtocolError
err    <- BufferSize -> ApplicationProtocolError
ApplicationProtocolError (BufferSize -> ApplicationProtocolError)
-> (Int64 -> BufferSize) -> Int64 -> ApplicationProtocolError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> ApplicationProtocolError)
-> IO Int64 -> IO ApplicationProtocolError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
len    <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    ShortByteString
reason <- ReadBuffer -> BufferSize -> IO ShortByteString
forall a. Readable a => a -> BufferSize -> IO ShortByteString
extractShortByteString ReadBuffer
rbuf BufferSize
len
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ ApplicationProtocolError -> ShortByteString -> Frame
ConnectionCloseApp ApplicationProtocolError
err ShortByteString
reason

decodeNewConnectionID :: ReadBuffer -> IO Frame
decodeNewConnectionID :: ReadBuffer -> IO Frame
decodeNewConnectionID ReadBuffer
rbuf = do
    BufferSize
seqNum <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
rpt <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    BufferSize
cidLen <- Word8 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> BufferSize) -> IO Word8 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Word8
forall a. Readable a => a -> IO Word8
read8 ReadBuffer
rbuf
    CID
cID <- ShortByteString -> CID
makeCID (ShortByteString -> CID) -> IO ShortByteString -> IO CID
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> BufferSize -> IO ShortByteString
forall a. Readable a => a -> BufferSize -> IO ShortByteString
extractShortByteString ReadBuffer
rbuf BufferSize
cidLen
    StatelessResetToken
token <- ShortByteString -> StatelessResetToken
StatelessResetToken (ShortByteString -> StatelessResetToken)
-> IO ShortByteString -> IO StatelessResetToken
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> BufferSize -> IO ShortByteString
forall a. Readable a => a -> BufferSize -> IO ShortByteString
extractShortByteString ReadBuffer
rbuf BufferSize
16
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ CIDInfo -> BufferSize -> Frame
NewConnectionID (BufferSize -> CID -> StatelessResetToken -> CIDInfo
CIDInfo BufferSize
seqNum CID
cID StatelessResetToken
token) BufferSize
rpt

decodeRetireConnectionID :: ReadBuffer -> IO Frame
decodeRetireConnectionID :: ReadBuffer -> IO Frame
decodeRetireConnectionID ReadBuffer
rbuf = do
    BufferSize
seqNum <- Int64 -> BufferSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> BufferSize) -> IO Int64 -> IO BufferSize
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> IO Int64
decodeInt' ReadBuffer
rbuf
    Frame -> IO Frame
forall (m :: * -> *) a. Monad m => a -> m a
return (Frame -> IO Frame) -> Frame -> IO Frame
forall a b. (a -> b) -> a -> b
$ BufferSize -> Frame
RetireConnectionID BufferSize
seqNum

decodePathChallenge :: ReadBuffer -> IO Frame
decodePathChallenge :: ReadBuffer -> IO Frame
decodePathChallenge ReadBuffer
rbuf =
    PathData -> Frame
PathChallenge (PathData -> Frame)
-> (ShortByteString -> PathData) -> ShortByteString -> Frame
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> PathData
PathData (ShortByteString -> Frame) -> IO ShortByteString -> IO Frame
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> BufferSize -> IO ShortByteString
forall a. Readable a => a -> BufferSize -> IO ShortByteString
extractShortByteString ReadBuffer
rbuf BufferSize
8

decodePathResponse :: ReadBuffer -> IO Frame
decodePathResponse :: ReadBuffer -> IO Frame
decodePathResponse ReadBuffer
rbuf =
    PathData -> Frame
PathResponse (PathData -> Frame)
-> (ShortByteString -> PathData) -> ShortByteString -> Frame
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> PathData
PathData (ShortByteString -> Frame) -> IO ShortByteString -> IO Frame
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBuffer -> BufferSize -> IO ShortByteString
forall a. Readable a => a -> BufferSize -> IO ShortByteString
extractShortByteString ReadBuffer
rbuf BufferSize
8