network-unexceptional 0.1.1.0 → 0.1.2.0
raw patch · 2 files changed
+52/−3 lines, 2 files
Files
network-unexceptional.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: network-unexceptional-version: 0.1.1.0+version: 0.1.2.0 synopsis: Network functions that do not throw exceptions description: Functions compatible with the Socket type from the network library that@@ -19,13 +19,14 @@ ghc-options: -O2 -Wall exposed-modules: Network.Unexceptional- Network.Unexceptional.Bytes+ Network.Unexceptional.ByteArray Network.Unexceptional.ByteString+ Network.Unexceptional.Bytes Network.Unexceptional.Chunks Network.Unexceptional.MutableBytes Network.Unexceptional.Types build-depends:- , base >=4.17 && <5+ , base >=4.16.3 && <5 , posix-api >=0.6.1 , error-codes >=0.1.1 , byteslice >=0.2.8
+ src/Network/Unexceptional/ByteArray.hs view
@@ -0,0 +1,48 @@+{-# language BangPatterns #-}+{-# language DuplicateRecordFields #-}+{-# language PatternSynonyms #-}+{-# language LambdaCase #-}+{-# language NamedFieldPuns #-}++module Network.Unexceptional.ByteArray+ ( receiveExactly+ ) where++import Control.Exception (throwIO)+import Control.Monad (when)+import Data.Array.Byte (ByteArray)+import Data.Bytes.Types (Bytes(Bytes),MutableBytes(MutableBytes))+import Foreign.C.Error (Errno)+import Foreign.C.Error.Pattern (pattern EWOULDBLOCK,pattern EAGAIN)+import GHC.Conc (threadWaitWrite)+import Network.Socket (Socket)+import System.Posix.Types (Fd(Fd))++import qualified Network.Unexceptional.Types as Types+import qualified Posix.Socket as X+import qualified Linux.Socket as X+import qualified Data.Bytes.Types+import qualified Network.Socket as S+import qualified Data.Primitive as PM+import qualified Network.Unexceptional.MutableBytes as MB++-- | Blocks until an exact number of bytes has been received.+receiveExactly :: + Socket+ -> Int -- ^ Exact number of bytes to receive, must be greater than zero+ -> IO (Either Errno ByteArray)+receiveExactly s n = if n > 0+ then do+ dst <- PM.newByteArray n+ let loop !ix !remaining = case remaining of+ 0 -> do+ dst' <- PM.unsafeFreezeByteArray dst + pure (Right dst')+ _ -> MB.receive s (MutableBytes dst ix remaining) >>= \case+ Left e -> pure (Left e)+ Right k -> loop (ix + k) (remaining - k)+ loop 0 n+ else throwIO Types.NonpositiveReceptionSize+++