flaw-base/Flaw/ByteStream.hs
{-|
Module: Flaw.ByteStream
Description: Helper structure for organizing async byte streams.
License: MIT
-}
module Flaw.ByteStream
( ByteStream(..)
, newByteStream
, byteStreamLength
, pushByteStream
, pullByteStream
, isByteStreamFinished
, finishByteStream
) where
import Control.Concurrent.STM
import qualified Data.ByteString.Lazy as BL
import Data.Int
data ByteStream = ByteStream
{ byteStreamBytesVar :: {-# UNPACK #-} !(TVar BL.ByteString)
, byteStreamFinishedVar :: {-# UNPACK #-} !(TVar Bool)
}
newByteStream :: STM ByteStream
newByteStream = ByteStream
<$> newTVar BL.empty
<*> newTVar False
byteStreamLength :: ByteStream -> STM Int64
byteStreamLength = (BL.length <$>) . readTVar . byteStreamBytesVar
pushByteStream :: ByteStream -> BL.ByteString -> STM ()
pushByteStream ByteStream
{ byteStreamBytesVar = bytesVar
} bytes = modifyTVar' bytesVar (<> bytes)
pullByteStream :: ByteStream -> Int64 -> STM BL.ByteString
pullByteStream ByteStream
{ byteStreamBytesVar = bytesVar
} size = do
bytes <- readTVar bytesVar
let (pulledBytes, restBytes) = BL.splitAt size bytes
writeTVar bytesVar restBytes
return pulledBytes
isByteStreamFinished :: ByteStream -> STM Bool
isByteStreamFinished = readTVar . byteStreamFinishedVar
finishByteStream :: ByteStream -> STM ()
finishByteStream = flip writeTVar True . byteStreamFinishedVar