Add versions of functions that don't close handles

This commit is contained in:
Julian Ospald 2020-01-29 21:26:35 +01:00
parent d30896b4d6
commit 8ef8bda3ce
No known key found for this signature in database
GPG Key ID: 511B62C09D50CD28
1 changed files with 65 additions and 9 deletions

View File

@ -15,16 +15,20 @@ module Streamly.External.FileSystem.Handle.Posix
(
-- * File reading
readFileLBS
, readFileLBS'
, readFileStream
, readFileStream'
-- * File writing
, copyFileHandle
, copyFileHandle'
, copyFileStream
, copyFileStream'
, copyLBS
, copyLBS'
-- * Directory listing
, unfoldDirContents
, dirContentsStream
, dirContents
, DirType
)
where
@ -61,6 +65,14 @@ import qualified Streamly.Internal.Data.Unfold as SIU
import qualified Streamly.Internal.Prelude as S
-- https://github.com/psibi/streamly-bytestring/issues/7
fromChunks :: SerialT IO (Array Word8) -> IO BSLI.ByteString
fromChunks =
S.foldrM (\x b -> unsafeInterleaveIO b >>= pure . BSLI.chunk x)
(pure BSLI.Empty)
. S.map Strict.fromArray
-- |Read the given file lazily as a lazy ByteString.
--
-- The handle is closed automatically, when the stream exits normally,
@ -70,12 +82,16 @@ import qualified Streamly.Internal.Prelude as S
readFileLBS :: Handle -- ^ readable file handle
-> IO L.ByteString
readFileLBS handle' = fromChunks (readFileStream handle')
where
-- https://github.com/psibi/streamly-bytestring/issues/7
fromChunks =
S.foldrM (\x b -> unsafeInterleaveIO b >>= pure . BSLI.chunk x)
(pure BSLI.Empty)
. S.map Strict.fromArray
-- |Read the given file lazily as a lazy ByteString.
--
-- The handle is NOT closed automatically.
--
-- This uses `unsafeInterleaveIO` under the hood.
readFileLBS' :: Handle -- ^ readable file handle
-> IO L.ByteString
readFileLBS' handle' = fromChunks (readFileStream' handle')
-- | Read from the given handle as a streamly filestream.
@ -88,8 +104,19 @@ readFileStream :: (MonadCatch m, MonadAsync m)
-> SerialT m (Array Word8)
readFileStream = S.unfold (SIU.finallyIO (liftIO . hClose) FH.readChunks)
-- | Read from the given handle as a streamly filestream.
--
-- The handle is NOT closed automatically.
-- The stream must not be used after the handle is closed.
readFileStream' :: (MonadCatch m, MonadAsync m)
=> Handle
-> SerialT m (Array Word8)
readFileStream' = S.unfold FH.readChunks
-- | Like 'copyFileStream', except for two file handles.
--
-- Both handles are closed automatically.
copyFileHandle :: (MonadCatch m, MonadAsync m, MonadMask m)
=> Handle -- ^ copy from this handle, must be readable
-> Handle -- ^ copy to this handle, must be writable
@ -97,6 +124,16 @@ copyFileHandle :: (MonadCatch m, MonadAsync m, MonadMask m)
copyFileHandle fromHandle toHandle =
copyFileStream (readFileStream fromHandle) toHandle
-- | Like 'copyFileStream'', except for two file handles.
--
-- Handles are NOT closed automatically.
copyFileHandle' :: (MonadCatch m, MonadAsync m, MonadMask m)
=> Handle -- ^ copy from this handle, must be readable
-> Handle -- ^ copy to this handle, must be writable
-> m ()
copyFileHandle' fromHandle toHandle =
copyFileStream' (readFileStream' fromHandle) toHandle
-- | Copy a stream to a file handle.
--
@ -106,8 +143,17 @@ copyFileStream :: (MonadCatch m, MonadAsync m, MonadMask m)
-> Handle -- ^ file handle to copy to, must be writable
-> m ()
copyFileStream stream handle' =
(flip finally) (liftIO $ hClose handle')
$ S.fold (FH.writeChunks handle') stream
(flip finally) (liftIO $ hClose handle') $ copyFileStream' stream handle'
-- | Copy a stream to a file handle.
--
-- The handle is NOT closed automatically.
copyFileStream' :: (MonadCatch m, MonadAsync m, MonadMask m)
=> SerialT m (Array Word8) -- ^ stream to copy
-> Handle -- ^ file handle to copy to, must be writable
-> m ()
copyFileStream' stream handle' = S.fold (FH.writeChunks handle') stream
-- | Like 'copyFileStream', except with a lazy bytestring.
@ -120,6 +166,16 @@ copyLBS :: (MonadCatch m, MonadAsync m, MonadMask m)
copyLBS lbs = copyFileStream (Lazy.toChunks lbs)
-- | Like 'copyFileStream', except with a lazy bytestring.
--
-- The handle is NOT closed automatically.
copyLBS' :: (MonadCatch m, MonadAsync m, MonadMask m)
=> L.ByteString -- ^ lazy bytestring to copy
-> Handle -- ^ file handle to copy to, must be writable
-> m ()
copyLBS' lbs = copyFileStream' (Lazy.toChunks lbs)
-- | Create an 'Unfold' of directory contents.
unfoldDirContents :: MonadIO m => Unfold m DirStream (DirType, RawFilePath)
unfoldDirContents = Unfold step return