{-# LANGUAGE RecordWildCards #-}

module Network.QUIC.Stream.Misc (
    getTxStreamOffset
  , isTxStreamClosed
  , setTxStreamClosed
  , getRxStreamOffset
  , isRxStreamClosed
  , setRxStreamClosed
  --
  , readStreamFlowTx
  , addTxStreamData
  , setTxMaxStreamData
  , readStreamFlowRx
  , addRxStreamData
  , setRxMaxStreamData
  , addRxMaxStreamData
  , getRxMaxStreamData
  , getRxStreamWindow
  ) where

import Control.Concurrent.STM

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

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

getTxStreamOffset :: Stream -> Int -> IO Offset
getTxStreamOffset :: Stream -> Int -> IO Int
getTxStreamOffset Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
..} Int
len = IORef StreamState -> (StreamState -> (StreamState, Int)) -> IO Int
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef StreamState
streamStateTx StreamState -> (StreamState, Int)
get
  where
    get :: StreamState -> (StreamState, Int)
get (StreamState Int
off Fin
fin) = (Int -> Fin -> StreamState
StreamState (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len) Fin
fin, Int
off)

isTxStreamClosed :: Stream -> IO Bool
isTxStreamClosed :: Stream -> IO Fin
isTxStreamClosed Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} = do
    StreamState Int
_ Fin
fin <- IORef StreamState -> IO StreamState
forall a. IORef a -> IO a
readIORef IORef StreamState
streamStateTx
    Fin -> IO Fin
forall (m :: * -> *) a. Monad m => a -> m a
return Fin
fin

setTxStreamClosed :: Stream -> IO ()
setTxStreamClosed :: Stream -> IO ()
setTxStreamClosed Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} = IORef StreamState -> (StreamState -> StreamState) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
atomicModifyIORef'' IORef StreamState
streamStateTx StreamState -> StreamState
set
  where
    set :: StreamState -> StreamState
set (StreamState Int
off Fin
_) = Int -> Fin -> StreamState
StreamState Int
off Fin
True

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

getRxStreamOffset :: Stream -> Int -> IO Offset
getRxStreamOffset :: Stream -> Int -> IO Int
getRxStreamOffset Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} Int
len = IORef StreamState -> (StreamState -> (StreamState, Int)) -> IO Int
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef StreamState
streamStateRx StreamState -> (StreamState, Int)
get
  where
    get :: StreamState -> (StreamState, Int)
get (StreamState Int
off Fin
fin) = (Int -> Fin -> StreamState
StreamState (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len) Fin
fin, Int
off)

isRxStreamClosed :: Stream -> IO Bool
isRxStreamClosed :: Stream -> IO Fin
isRxStreamClosed Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} = do
    StreamState Int
_ Fin
fin <- IORef StreamState -> IO StreamState
forall a. IORef a -> IO a
readIORef IORef StreamState
streamStateRx
    Fin -> IO Fin
forall (m :: * -> *) a. Monad m => a -> m a
return Fin
fin

setRxStreamClosed :: Stream -> IO ()
setRxStreamClosed :: Stream -> IO ()
setRxStreamClosed Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} = IORef StreamState -> (StreamState -> StreamState) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
atomicModifyIORef'' IORef StreamState
streamStateRx StreamState -> StreamState
set
  where
    set :: StreamState -> StreamState
set (StreamState Int
off Fin
_) = Int -> Fin -> StreamState
StreamState Int
off Fin
True

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

readStreamFlowTx :: Stream -> STM Flow
readStreamFlowTx :: Stream -> STM Flow
readStreamFlowTx Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} = TVar Flow -> STM Flow
forall a. TVar a -> STM a
readTVar TVar Flow
streamFlowTx

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

addTxStreamData :: Stream -> Int -> STM ()
addTxStreamData :: Stream -> Int -> STM ()
addTxStreamData Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} Int
n = TVar Flow -> (Flow -> Flow) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
modifyTVar' TVar Flow
streamFlowTx Flow -> Flow
add
  where
    add :: Flow -> Flow
add Flow
flow = Flow
flow { flowData :: Int
flowData = Flow -> Int
flowData Flow
flow Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n }

setTxMaxStreamData :: Stream -> Int -> IO ()
setTxMaxStreamData :: Stream -> Int -> IO ()
setTxMaxStreamData Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} Int
n = STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TVar Flow -> (Flow -> Flow) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
modifyTVar' TVar Flow
streamFlowTx Flow -> Flow
set
  where
    set :: Flow -> Flow
set Flow
flow
     | Flow -> Int
flowMaxData Flow
flow Int -> Int -> Fin
forall a. Ord a => a -> a -> Fin
< Int
n = Flow
flow { flowMaxData :: Int
flowMaxData = Int
n }
     | Fin
otherwise            = Flow
flow

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

addRxStreamData :: Stream -> Int -> IO ()
addRxStreamData :: Stream -> Int -> IO ()
addRxStreamData Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} Int
n = IORef Flow -> (Flow -> Flow) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
atomicModifyIORef'' IORef Flow
streamFlowRx Flow -> Flow
add
  where
    add :: Flow -> Flow
add Flow
flow = Flow
flow { flowData :: Int
flowData = Flow -> Int
flowData Flow
flow Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n }

setRxMaxStreamData :: Stream -> Int -> IO ()
setRxMaxStreamData :: Stream -> Int -> IO ()
setRxMaxStreamData Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} Int
n = IORef Flow -> (Flow -> Flow) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
atomicModifyIORef'' IORef Flow
streamFlowRx
    ((Flow -> Flow) -> IO ()) -> (Flow -> Flow) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Flow
flow -> Flow
flow { flowMaxData :: Int
flowMaxData = Int
n }

addRxMaxStreamData :: Stream -> Int -> IO Int
addRxMaxStreamData :: Stream -> Int -> IO Int
addRxMaxStreamData Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} Int
n = IORef Flow -> (Flow -> (Flow, Int)) -> IO Int
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef Flow
streamFlowRx Flow -> (Flow, Int)
add
  where
    add :: Flow -> (Flow, Int)
add Flow
flow = (Flow
flow { flowMaxData :: Int
flowMaxData = Int
m }, Int
m)
      where
        m :: Int
m = Flow -> Int
flowMaxData Flow
flow Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n

getRxMaxStreamData :: Stream -> IO Int
getRxMaxStreamData :: Stream -> IO Int
getRxMaxStreamData Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} = Flow -> Int
flowMaxData (Flow -> Int) -> IO Flow -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef Flow -> IO Flow
forall a. IORef a -> IO a
readIORef IORef Flow
streamFlowRx

getRxStreamWindow :: Stream -> IO Int
getRxStreamWindow :: Stream -> IO Int
getRxStreamWindow Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} = Flow -> Int
flowWindow (Flow -> Int) -> IO Flow -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef Flow -> IO Flow
forall a. IORef a -> IO a
readIORef IORef Flow
streamFlowRx

readStreamFlowRx :: Stream -> IO Flow
readStreamFlowRx :: Stream -> IO Flow
readStreamFlowRx Stream{Int
TVar Flow
IORef (Skew RxStreamData)
IORef StreamState
IORef Flow
Connection
RecvStreamQ
streamReass :: IORef (Skew RxStreamData)
streamRecvQ :: RecvStreamQ
streamStateRx :: IORef StreamState
streamStateTx :: IORef StreamState
streamFlowRx :: IORef Flow
streamFlowTx :: TVar Flow
streamConnection :: Connection
streamId :: Int
streamReass :: Stream -> IORef (Skew RxStreamData)
streamRecvQ :: Stream -> RecvStreamQ
streamStateRx :: Stream -> IORef StreamState
streamStateTx :: Stream -> IORef StreamState
streamFlowRx :: Stream -> IORef Flow
streamFlowTx :: Stream -> TVar Flow
streamConnection :: Stream -> Connection
streamId :: Stream -> Int
..} = IORef Flow -> IO Flow
forall a. IORef a -> IO a
readIORef IORef Flow
streamFlowRx