{-# language BangPatterns #-}
{-# language DataKinds #-}
{-# language LambdaCase #-}
{-# language MagicHash #-}
module Socket.Stream.Uninterruptible.Bytes
( send
, receiveExactly
, receiveOnce
, receiveBetween
) where
import Data.Primitive (ByteArray)
import Data.Bytes.Types (MutableBytes(..),Bytes(..))
import GHC.Exts (proxy#)
import Socket.Stream (Connection,ReceiveException,SendException)
import Socket (Interruptibility(Uninterruptible))
import qualified Data.Primitive as PM
import qualified Socket.Stream.Uninterruptible.Bytes.Send as Send
import qualified Socket.Stream.Uninterruptible.MutableBytes.Receive as Receive
send ::
Connection
-> Bytes
-> IO (Either (SendException 'Uninterruptible) ())
{-# inline send #-}
send = Send.send proxy#
receiveExactly ::
Connection
-> Int
-> IO (Either (ReceiveException 'Uninterruptible) ByteArray)
{-# inline receiveExactly #-}
receiveExactly !conn !n = do
!marr <- PM.newByteArray n
Receive.receiveExactly proxy# conn (MutableBytes marr 0 n) >>= \case
Left err -> pure (Left err)
Right _ -> do
!arr <- PM.unsafeFreezeByteArray marr
pure $! Right $! arr
receiveOnce ::
Connection
-> Int
-> IO (Either (ReceiveException 'Uninterruptible) ByteArray)
{-# inline receiveOnce #-}
receiveOnce !conn !n = do
!marr0 <- PM.newByteArray n
Receive.receiveOnce proxy# 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 ::
Connection
-> Int
-> Int
-> IO (Either (ReceiveException 'Uninterruptible) ByteArray)
{-# inline receiveBetween #-}
receiveBetween !conn !minLen !maxLen = do
!marr0 <- PM.newByteArray maxLen
Receive.receiveBetween proxy# 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