{-# language BangPatterns #-}
{-# language LambdaCase #-}
{-# language DataKinds #-}
module Socket.Stream.Interruptible.Bytes
( send
, receiveExactly
, receiveOnce
, receiveBetween
) where
import Data.Primitive (ByteArray)
import Data.Bytes.Types (MutableBytes(..),Bytes(..))
import Control.Concurrent.STM (TVar)
import Socket.Stream (Connection,ReceiveException,SendException)
import Socket (Interruptibility(Interruptible))
import qualified Data.Primitive as PM
import qualified Socket.Stream.Interruptible.Bytes.Send as Send
import qualified Socket.Stream.Interruptible.MutableBytes.Receive as Receive
send ::
TVar Bool
-> Connection
-> Bytes
-> IO (Either (SendException 'Interruptible) ())
{-# inline send #-}
send = Send.send
receiveExactly ::
TVar Bool
-> Connection
-> Int
-> IO (Either (ReceiveException 'Interruptible) ByteArray)
{-# inline receiveExactly #-}
receiveExactly !tv !conn !n = do
!marr <- PM.newByteArray n
Receive.receiveExactly tv conn (MutableBytes marr 0 n) >>= \case
Left err -> pure (Left err)
Right _ -> do
!arr <- PM.unsafeFreezeByteArray marr
pure $! Right $! arr
receiveOnce ::
TVar Bool
-> Connection
-> Int
-> IO (Either (ReceiveException 'Interruptible) ByteArray)
{-# inline receiveOnce #-}
receiveOnce !tv !conn !n = do
!marr0 <- PM.newByteArray n
Receive.receiveOnce tv conn (MutableBytes marr0 0 n) >>= \case
Left err -> pure (Left err)
Right sz -> do
marr1 <- PM.resizeMutableByteArray marr0 sz
!arr <- PM.unsafeFreezeByteArray marr1
pure $! Right $! arr
receiveBetween ::
TVar Bool
-> Connection
-> Int
-> Int
-> IO (Either (ReceiveException 'Interruptible) ByteArray)
{-# inline receiveBetween #-}
receiveBetween !tv !conn !minLen !maxLen = do
!marr0 <- PM.newByteArray maxLen
Receive.receiveBetween tv conn (MutableBytes marr0 0 maxLen) minLen >>= \case
Left err -> pure (Left err)
Right sz -> do
marr1 <- PM.resizeMutableByteArray marr0 sz
!arr <- PM.unsafeFreezeByteArray marr1
pure $! Right $! arr