packages feed

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+++