#include "inline.hs"
module Streamly.Internal.FileSystem.Handle
(
getChunk
, getChunkOf
, putChunk
, read
, readWithBufferOf
, toBytes
, toBytesWithBufferOf
, readChunks
, readChunksWithBufferOf
, toChunksWithBufferOf
, toChunks
, write
, consumer
, writeWithBufferOf
, writeMaybesWithBufferOf
, putBytes
, putBytesWithBufferOf
, writeChunks
, writeChunksWithBufferOf
, putChunksWithBufferOf
, putChunks
, readChunksFromToWith
)
where
import Control.Exception (assert)
import Control.Monad.IO.Class (MonadIO(..))
import Data.Function ((&))
import Data.Maybe (isNothing, fromJust)
import Data.Word (Word8)
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (minusPtr, plusPtr)
import Foreign.Storable (Storable(..))
import GHC.ForeignPtr (mallocPlainForeignPtrBytes)
import System.IO (Handle, SeekMode(..), hGetBufSome, hPutBuf, hSeek)
import Prelude hiding (read)
import Streamly.Internal.Data.Array.Foreign.Mut.Type (touch)
import Streamly.Internal.Data.Fold (Fold)
import Streamly.Internal.Data.Refold.Type (Refold(..))
import Streamly.Internal.Data.Unfold.Type (Unfold(..))
import Streamly.Internal.Data.Array.Foreign.Type
(Array(..), writeNUnsafe, unsafeFreezeWithShrink, byteLength)
import Streamly.Internal.Data.Array.Foreign.Mut.Type (fromForeignPtrUnsafe)
import Streamly.Internal.Data.Stream.Serial (SerialT)
import Streamly.Internal.Data.Stream.IsStream.Type
(IsStream, mkStream, fromStreamD)
import Streamly.Internal.Data.Array.Stream.Foreign (lpackArraysChunksOf)
import Streamly.Internal.System.IO (defaultChunkSize)
import qualified Streamly.Internal.Data.Array.Foreign as A
import qualified Streamly.Internal.Data.Array.Stream.Foreign as AS
import qualified Streamly.Internal.Data.Refold.Type as Refold
import qualified Streamly.Internal.Data.Fold as FL
import qualified Streamly.Internal.Data.Fold.Type as FL
import qualified Streamly.Internal.Data.Stream.IsStream as S
import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
import qualified Streamly.Internal.Data.Unfold as UF
{-# INLINABLE getChunk #-}
getChunk :: MonadIO m => Int -> Handle -> m (Array Word8)
getChunk :: Int -> Handle -> m (Array Word8)
getChunk Int
size Handle
h = IO (Array Word8) -> m (Array Word8)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Array Word8) -> m (Array Word8))
-> IO (Array Word8) -> m (Array Word8)
forall a b. (a -> b) -> a -> b
$ do
ForeignPtr Word8
ptr <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
mallocPlainForeignPtrBytes Int
size
ForeignPtr Word8
-> (Ptr Word8 -> IO (Array Word8)) -> IO (Array Word8)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
ptr ((Ptr Word8 -> IO (Array Word8)) -> IO (Array Word8))
-> (Ptr Word8 -> IO (Array Word8)) -> IO (Array Word8)
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> do
Int
n <- Handle -> Ptr Word8 -> Int -> IO Int
forall a. Handle -> Ptr a -> Int -> IO Int
hGetBufSome Handle
h Ptr Word8
p Int
size
Array Word8 -> IO (Array Word8)
forall (m :: * -> *) a. Monad m => a -> m a
return (Array Word8 -> IO (Array Word8))
-> Array Word8 -> IO (Array Word8)
forall a b. (a -> b) -> a -> b
$
Array Word8 -> Array Word8
forall a. Storable a => Array a -> Array a
unsafeFreezeWithShrink (Array Word8 -> Array Word8) -> Array Word8 -> Array Word8
forall a b. (a -> b) -> a -> b
$
ForeignPtr Word8 -> Ptr Word8 -> Ptr Word8 -> Array Word8
forall a. ForeignPtr a -> Ptr a -> Ptr a -> Array a
fromForeignPtrUnsafe ForeignPtr Word8
ptr (Ptr Word8
p Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
n) (Ptr Word8
p Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
size)
{-# INLINABLE getChunkOf #-}
getChunkOf :: Int -> Handle -> IO (Array Word8)
getChunkOf :: Int -> Handle -> IO (Array Word8)
getChunkOf = Int -> Handle -> IO (Array Word8)
forall a. HasCallStack => a
undefined
{-# INLINABLE _toChunksWithBufferOf #-}
_toChunksWithBufferOf :: (IsStream t, MonadIO m)
=> Int -> Handle -> t m (Array Word8)
_toChunksWithBufferOf :: Int -> Handle -> t m (Array Word8)
_toChunksWithBufferOf Int
size Handle
h = t m (Array Word8)
go
where
go :: t m (Array Word8)
go = (forall r.
State Stream m (Array Word8)
-> (Array Word8 -> t m (Array Word8) -> m r)
-> (Array Word8 -> m r)
-> m r
-> m r)
-> t m (Array Word8)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
IsStream t =>
(forall r.
State Stream m a
-> (a -> t m a -> m r) -> (a -> m r) -> m r -> m r)
-> t m a
mkStream ((forall r.
State Stream m (Array Word8)
-> (Array Word8 -> t m (Array Word8) -> m r)
-> (Array Word8 -> m r)
-> m r
-> m r)
-> t m (Array Word8))
-> (forall r.
State Stream m (Array Word8)
-> (Array Word8 -> t m (Array Word8) -> m r)
-> (Array Word8 -> m r)
-> m r
-> m r)
-> t m (Array Word8)
forall a b. (a -> b) -> a -> b
$ \State Stream m (Array Word8)
_ Array Word8 -> t m (Array Word8) -> m r
yld Array Word8 -> m r
_ m r
stp -> do
Array Word8
arr <- Int -> Handle -> m (Array Word8)
forall (m :: * -> *). MonadIO m => Int -> Handle -> m (Array Word8)
getChunk Int
size Handle
h
if Array Word8 -> Int
forall a. Array a -> Int
byteLength Array Word8
arr Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then m r
stp
else Array Word8 -> t m (Array Word8) -> m r
yld Array Word8
arr t m (Array Word8)
go
{-# INLINE_NORMAL toChunksWithBufferOf #-}
toChunksWithBufferOf :: (IsStream t, MonadIO m) =>
Int -> Handle -> t m (Array Word8)
toChunksWithBufferOf :: Int -> Handle -> t m (Array Word8)
toChunksWithBufferOf Int
size Handle
h = Stream m (Array Word8) -> t m (Array Word8)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD ((State Stream m (Array Word8) -> () -> m (Step () (Array Word8)))
-> () -> Stream m (Array Word8)
forall (m :: * -> *) a s.
(State Stream m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State Stream m (Array Word8) -> () -> m (Step () (Array Word8))
forall (m :: * -> *) p p.
MonadIO m =>
p -> p -> m (Step () (Array Word8))
step ())
where
{-# INLINE_LATE step #-}
step :: p -> p -> m (Step () (Array Word8))
step p
_ p
_ = do
Array Word8
arr <- Int -> Handle -> m (Array Word8)
forall (m :: * -> *). MonadIO m => Int -> Handle -> m (Array Word8)
getChunk Int
size Handle
h
Step () (Array Word8) -> m (Step () (Array Word8))
forall (m :: * -> *) a. Monad m => a -> m a
return (Step () (Array Word8) -> m (Step () (Array Word8)))
-> Step () (Array Word8) -> m (Step () (Array Word8))
forall a b. (a -> b) -> a -> b
$
case Array Word8 -> Int
forall a. Array a -> Int
byteLength Array Word8
arr of
Int
0 -> Step () (Array Word8)
forall s a. Step s a
D.Stop
Int
_ -> Array Word8 -> () -> Step () (Array Word8)
forall s a. a -> s -> Step s a
D.Yield Array Word8
arr ()
{-# INLINE_NORMAL readChunksWithBufferOf #-}
readChunksWithBufferOf :: MonadIO m => Unfold m (Int, Handle) (Array Word8)
readChunksWithBufferOf :: Unfold m (Int, Handle) (Array Word8)
readChunksWithBufferOf =
((Int, Handle) -> m (Array Word8))
-> Unfold m (m (Array Word8)) (Array Word8)
-> Unfold m (Int, Handle) (Array Word8)
forall a c (m :: * -> *) b.
(a -> c) -> Unfold m c b -> Unfold m a b
UF.lmap ((Int -> Handle -> m (Array Word8))
-> (Int, Handle) -> m (Array Word8)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> Handle -> m (Array Word8)
forall (m :: * -> *). MonadIO m => Int -> Handle -> m (Array Word8)
getChunk) Unfold m (m (Array Word8)) (Array Word8)
forall (m :: * -> *) a. Monad m => Unfold m (m a) a
UF.repeatM
Unfold m (Int, Handle) (Array Word8)
-> (Unfold m (Int, Handle) (Array Word8)
-> Unfold m (Int, Handle) (Array Word8))
-> Unfold m (Int, Handle) (Array Word8)
forall a b. a -> (a -> b) -> b
& (Array Word8 -> Bool)
-> Unfold m (Int, Handle) (Array Word8)
-> Unfold m (Int, Handle) (Array Word8)
forall (m :: * -> *) b a.
Monad m =>
(b -> Bool) -> Unfold m a b -> Unfold m a b
UF.takeWhile ((Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0) (Int -> Bool) -> (Array Word8 -> Int) -> Array Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array Word8 -> Int
forall a. Array a -> Int
byteLength)
{-# INLINE_NORMAL readChunksFromToWith #-}
readChunksFromToWith :: MonadIO m =>
Unfold m (Int, Int, Int, Handle) (Array Word8)
readChunksFromToWith :: Unfold m (Int, Int, Int, Handle) (Array Word8)
readChunksFromToWith = ((Int, Int, Handle) -> m (Step (Int, Int, Handle) (Array Word8)))
-> ((Int, Int, Int, Handle) -> m (Int, Int, Handle))
-> Unfold m (Int, Int, Int, Handle) (Array Word8)
forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
Unfold (Int, Int, Handle) -> m (Step (Int, Int, Handle) (Array Word8))
forall (m :: * -> *).
MonadIO m =>
(Int, Int, Handle) -> m (Step (Int, Int, Handle) (Array Word8))
step (Int, Int, Int, Handle) -> m (Int, Int, Handle)
forall (m :: * -> *) a b.
(MonadIO m, Integral a) =>
(a, a, b, Handle) -> m (a, b, Handle)
inject
where
inject :: (a, a, b, Handle) -> m (a, b, Handle)
inject (a
from, a
to, b
bufSize, Handle
h) = do
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ Handle -> SeekMode -> Integer -> IO ()
hSeek Handle
h SeekMode
AbsoluteSeek (Integer -> IO ()) -> Integer -> IO ()
forall a b. (a -> b) -> a -> b
$ a -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
from
(a, b, Handle) -> m (a, b, Handle)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
to a -> a -> a
forall a. Num a => a -> a -> a
- a
from a -> a -> a
forall a. Num a => a -> a -> a
+ a
1, b
bufSize, Handle
h)
{-# INLINE_LATE step #-}
step :: (Int, Int, Handle) -> m (Step (Int, Int, Handle) (Array Word8))
step (Int
remaining, Int
bufSize, Handle
h) =
if Int
remaining Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
then Step (Int, Int, Handle) (Array Word8)
-> m (Step (Int, Int, Handle) (Array Word8))
forall (m :: * -> *) a. Monad m => a -> m a
return Step (Int, Int, Handle) (Array Word8)
forall s a. Step s a
D.Stop
else do
Array Word8
arr <- Int -> Handle -> m (Array Word8)
forall (m :: * -> *). MonadIO m => Int -> Handle -> m (Array Word8)
getChunk (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
bufSize Int
remaining) Handle
h
Step (Int, Int, Handle) (Array Word8)
-> m (Step (Int, Int, Handle) (Array Word8))
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Int, Int, Handle) (Array Word8)
-> m (Step (Int, Int, Handle) (Array Word8)))
-> Step (Int, Int, Handle) (Array Word8)
-> m (Step (Int, Int, Handle) (Array Word8))
forall a b. (a -> b) -> a -> b
$
case Array Word8 -> Int
forall a. Array a -> Int
byteLength Array Word8
arr of
Int
0 -> Step (Int, Int, Handle) (Array Word8)
forall s a. Step s a
D.Stop
Int
len ->
Bool
-> Step (Int, Int, Handle) (Array Word8)
-> Step (Int, Int, Handle) (Array Word8)
forall a. HasCallStack => Bool -> a -> a
assert (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
remaining)
(Step (Int, Int, Handle) (Array Word8)
-> Step (Int, Int, Handle) (Array Word8))
-> Step (Int, Int, Handle) (Array Word8)
-> Step (Int, Int, Handle) (Array Word8)
forall a b. (a -> b) -> a -> b
$ Array Word8
-> (Int, Int, Handle) -> Step (Int, Int, Handle) (Array Word8)
forall s a. a -> s -> Step s a
D.Yield Array Word8
arr (Int
remaining Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len, Int
bufSize, Handle
h)
{-# INLINE toChunks #-}
toChunks :: (IsStream t, MonadIO m) => Handle -> t m (Array Word8)
toChunks :: Handle -> t m (Array Word8)
toChunks = Int -> Handle -> t m (Array Word8)
forall (t :: (* -> *) -> * -> *) (m :: * -> *).
(IsStream t, MonadIO m) =>
Int -> Handle -> t m (Array Word8)
toChunksWithBufferOf Int
defaultChunkSize
{-# INLINE readChunks #-}
readChunks :: MonadIO m => Unfold m Handle (Array Word8)
readChunks :: Unfold m Handle (Array Word8)
readChunks = Int
-> Unfold m (Int, Handle) (Array Word8)
-> Unfold m Handle (Array Word8)
forall a (m :: * -> *) b c. a -> Unfold m (a, b) c -> Unfold m b c
UF.supplyFirst Int
defaultChunkSize Unfold m (Int, Handle) (Array Word8)
forall (m :: * -> *).
MonadIO m =>
Unfold m (Int, Handle) (Array Word8)
readChunksWithBufferOf
{-# INLINE readWithBufferOf #-}
readWithBufferOf :: MonadIO m => Unfold m (Int, Handle) Word8
readWithBufferOf :: Unfold m (Int, Handle) Word8
readWithBufferOf = Unfold m (Int, Handle) (Array Word8)
-> Unfold m (Array Word8) Word8 -> Unfold m (Int, Handle) Word8
forall (m :: * -> *) a b c.
Monad m =>
Unfold m a b -> Unfold m b c -> Unfold m a c
UF.many Unfold m (Int, Handle) (Array Word8)
forall (m :: * -> *).
MonadIO m =>
Unfold m (Int, Handle) (Array Word8)
readChunksWithBufferOf Unfold m (Array Word8) Word8
forall (m :: * -> *) a.
(Monad m, Storable a) =>
Unfold m (Array a) a
A.read
{-# INLINE toBytesWithBufferOf #-}
toBytesWithBufferOf :: (IsStream t, MonadIO m) => Int -> Handle -> t m Word8
toBytesWithBufferOf :: Int -> Handle -> t m Word8
toBytesWithBufferOf Int
size Handle
h = t m (Array Word8) -> t m Word8
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, MonadIO m, Storable a) =>
t m (Array a) -> t m a
AS.concat (t m (Array Word8) -> t m Word8) -> t m (Array Word8) -> t m Word8
forall a b. (a -> b) -> a -> b
$ Int -> Handle -> t m (Array Word8)
forall (t :: (* -> *) -> * -> *) (m :: * -> *).
(IsStream t, MonadIO m) =>
Int -> Handle -> t m (Array Word8)
toChunksWithBufferOf Int
size Handle
h
{-# INLINE read #-}
read :: MonadIO m => Unfold m Handle Word8
read :: Unfold m Handle Word8
read = Unfold m Handle (Array Word8)
-> Unfold m (Array Word8) Word8 -> Unfold m Handle Word8
forall (m :: * -> *) a b c.
Monad m =>
Unfold m a b -> Unfold m b c -> Unfold m a c
UF.many Unfold m Handle (Array Word8)
forall (m :: * -> *). MonadIO m => Unfold m Handle (Array Word8)
readChunks Unfold m (Array Word8) Word8
forall (m :: * -> *) a.
(Monad m, Storable a) =>
Unfold m (Array a) a
A.read
{-# INLINE toBytes #-}
toBytes :: (IsStream t, MonadIO m) => Handle -> t m Word8
toBytes :: Handle -> t m Word8
toBytes = t m (Array Word8) -> t m Word8
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, MonadIO m, Storable a) =>
t m (Array a) -> t m a
AS.concat (t m (Array Word8) -> t m Word8)
-> (Handle -> t m (Array Word8)) -> Handle -> t m Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> t m (Array Word8)
forall (t :: (* -> *) -> * -> *) (m :: * -> *).
(IsStream t, MonadIO m) =>
Handle -> t m (Array Word8)
toChunks
{-# INLINABLE putChunk #-}
putChunk :: (MonadIO m, Storable a) => Handle -> Array a -> m ()
putChunk :: Handle -> Array a -> m ()
putChunk Handle
_ Array a
arr | Array a -> Int
forall a. Storable a => Array a -> Int
A.length Array a
arr Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
putChunk Handle
h Array{Ptr a
ArrayContents
aEnd :: forall a. Array a -> Ptr a
arrStart :: forall a. Array a -> Ptr a
arrContents :: forall a. Array a -> ArrayContents
aEnd :: Ptr a
arrStart :: Ptr a
arrContents :: ArrayContents
..} =
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ Handle -> Ptr a -> Int -> IO ()
forall a. Handle -> Ptr a -> Int -> IO ()
hPutBuf Handle
h Ptr a
arrStart Int
aLen IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ArrayContents -> IO ()
touch ArrayContents
arrContents
where
aLen :: Int
aLen = Ptr a
aEnd Ptr a -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr a
arrStart
{-# INLINE putChunks #-}
putChunks :: (MonadIO m, Storable a)
=> Handle -> SerialT m (Array a) -> m ()
putChunks :: Handle -> SerialT m (Array a) -> m ()
putChunks Handle
h = (Array a -> m ()) -> SerialT m (Array a) -> m ()
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SerialT m a -> m ()
S.mapM_ (Handle -> Array a -> m ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Handle -> Array a -> m ()
putChunk Handle
h)
{-# INLINE putChunksWithBufferOf #-}
putChunksWithBufferOf :: (MonadIO m, Storable a)
=> Int -> Handle -> SerialT m (Array a) -> m ()
putChunksWithBufferOf :: Int -> Handle -> SerialT m (Array a) -> m ()
putChunksWithBufferOf Int
n Handle
h SerialT m (Array a)
xs = Handle -> SerialT m (Array a) -> m ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Handle -> SerialT m (Array a) -> m ()
putChunks Handle
h (SerialT m (Array a) -> m ()) -> SerialT m (Array a) -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> SerialT m (Array a) -> SerialT m (Array a)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> SerialT m (Array a) -> SerialT m (Array a)
AS.compact Int
n SerialT m (Array a)
xs
{-# INLINE putBytesWithBufferOf #-}
putBytesWithBufferOf :: MonadIO m => Int -> Handle -> SerialT m Word8 -> m ()
putBytesWithBufferOf :: Int -> Handle -> SerialT m Word8 -> m ()
putBytesWithBufferOf Int
n Handle
h SerialT m Word8
m = Handle -> SerialT m (Array Word8) -> m ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Handle -> SerialT m (Array a) -> m ()
putChunks Handle
h (SerialT m (Array Word8) -> m ())
-> SerialT m (Array Word8) -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> SerialT m Word8 -> SerialT m (Array Word8)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, MonadIO m, Storable a) =>
Int -> t m a -> t m (Array a)
S.arraysOf Int
n SerialT m Word8
m
{-# INLINE putBytes #-}
putBytes :: MonadIO m => Handle -> SerialT m Word8 -> m ()
putBytes :: Handle -> SerialT m Word8 -> m ()
putBytes = Int -> Handle -> SerialT m Word8 -> m ()
forall (m :: * -> *).
MonadIO m =>
Int -> Handle -> SerialT m Word8 -> m ()
putBytesWithBufferOf Int
defaultChunkSize
{-# INLINE writeChunks #-}
writeChunks :: (MonadIO m, Storable a) => Handle -> Fold m (Array a) ()
writeChunks :: Handle -> Fold m (Array a) ()
writeChunks Handle
h = (Array a -> m ()) -> Fold m (Array a) ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Fold m a ()
FL.drainBy (Handle -> Array a -> m ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Handle -> Array a -> m ()
putChunk Handle
h)
{-# INLINE consumeChunks #-}
consumeChunks :: (MonadIO m, Storable a) => Refold m Handle (Array a) ()
consumeChunks :: Refold m Handle (Array a) ()
consumeChunks = (Handle -> Array a -> m ()) -> Refold m Handle (Array a) ()
forall (m :: * -> *) c a b.
Monad m =>
(c -> a -> m b) -> Refold m c a ()
Refold.drainBy Handle -> Array a -> m ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Handle -> Array a -> m ()
putChunk
{-# INLINE writeChunksWithBufferOf #-}
writeChunksWithBufferOf :: (MonadIO m, Storable a)
=> Int -> Handle -> Fold m (Array a) ()
writeChunksWithBufferOf :: Int -> Handle -> Fold m (Array a) ()
writeChunksWithBufferOf Int
n Handle
h = Int -> Fold m (Array a) () -> Fold m (Array a) ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> Fold m (Array a) () -> Fold m (Array a) ()
lpackArraysChunksOf Int
n (Handle -> Fold m (Array a) ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Handle -> Fold m (Array a) ()
writeChunks Handle
h)
{-# INLINE writeWithBufferOf #-}
writeWithBufferOf :: MonadIO m => Int -> Handle -> Fold m Word8 ()
writeWithBufferOf :: Int -> Handle -> Fold m Word8 ()
writeWithBufferOf Int
n Handle
h = Int
-> Fold m Word8 (Array Word8)
-> Fold m (Array Word8) ()
-> Fold m Word8 ()
forall (m :: * -> *) a b c.
Monad m =>
Int -> Fold m a b -> Fold m b c -> Fold m a c
FL.chunksOf Int
n (Int -> Fold m Word8 (Array Word8)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> Fold m a (Array a)
writeNUnsafe Int
n) (Handle -> Fold m (Array Word8) ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Handle -> Fold m (Array a) ()
writeChunks Handle
h)
{-# INLINE writeMaybesWithBufferOf #-}
writeMaybesWithBufferOf :: (MonadIO m )
=> Int -> Handle -> Fold m (Maybe Word8) ()
writeMaybesWithBufferOf :: Int -> Handle -> Fold m (Maybe Word8) ()
writeMaybesWithBufferOf Int
n Handle
h =
let writeNJusts :: Fold m (Maybe Word8) (Array Word8)
writeNJusts = (Maybe Word8 -> Word8)
-> Fold m Word8 (Array Word8) -> Fold m (Maybe Word8) (Array Word8)
forall a b (m :: * -> *) r. (a -> b) -> Fold m b r -> Fold m a r
FL.lmap Maybe Word8 -> Word8
forall a. HasCallStack => Maybe a -> a
fromJust (Fold m Word8 (Array Word8) -> Fold m (Maybe Word8) (Array Word8))
-> Fold m Word8 (Array Word8) -> Fold m (Maybe Word8) (Array Word8)
forall a b. (a -> b) -> a -> b
$ Int -> Fold m Word8 (Array Word8)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> Fold m a (Array a)
A.writeN Int
n
writeOnNothing :: Fold m (Maybe Word8) (Array Word8)
writeOnNothing = (Maybe Word8 -> Bool)
-> Fold m (Maybe Word8) (Array Word8)
-> Fold m (Maybe Word8) (Array Word8)
forall (m :: * -> *) a b.
Monad m =>
(a -> Bool) -> Fold m a b -> Fold m a b
FL.takeEndBy_ Maybe Word8 -> Bool
forall a. Maybe a -> Bool
isNothing Fold m (Maybe Word8) (Array Word8)
writeNJusts
in Fold m (Maybe Word8) (Array Word8)
-> Fold m (Array Word8) () -> Fold m (Maybe Word8) ()
forall (m :: * -> *) a b c.
Monad m =>
Fold m a b -> Fold m b c -> Fold m a c
FL.many Fold m (Maybe Word8) (Array Word8)
writeOnNothing (Handle -> Fold m (Array Word8) ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Handle -> Fold m (Array a) ()
writeChunks Handle
h)
{-# INLINE consumerWithBufferOf #-}
consumerWithBufferOf :: MonadIO m => Int -> Refold m Handle Word8 ()
consumerWithBufferOf :: Int -> Refold m Handle Word8 ()
consumerWithBufferOf Int
n =
Fold m Word8 (Array Word8)
-> Refold m Handle (Array Word8) () -> Refold m Handle Word8 ()
forall (m :: * -> *) a b x c.
Monad m =>
Fold m a b -> Refold m x b c -> Refold m x a c
FL.refoldMany (Int -> Fold m Word8 (Array Word8) -> Fold m Word8 (Array Word8)
forall (m :: * -> *) a b.
Monad m =>
Int -> Fold m a b -> Fold m a b
FL.take Int
n (Fold m Word8 (Array Word8) -> Fold m Word8 (Array Word8))
-> Fold m Word8 (Array Word8) -> Fold m Word8 (Array Word8)
forall a b. (a -> b) -> a -> b
$ Int -> Fold m Word8 (Array Word8)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> Fold m a (Array a)
writeNUnsafe Int
n) Refold m Handle (Array Word8) ()
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Refold m Handle (Array a) ()
consumeChunks
{-# INLINE write #-}
write :: MonadIO m => Handle -> Fold m Word8 ()
write :: Handle -> Fold m Word8 ()
write = Int -> Handle -> Fold m Word8 ()
forall (m :: * -> *). MonadIO m => Int -> Handle -> Fold m Word8 ()
writeWithBufferOf Int
defaultChunkSize
{-# INLINE consumer #-}
consumer :: MonadIO m => Refold m Handle Word8 ()
consumer :: Refold m Handle Word8 ()
consumer = Int -> Refold m Handle Word8 ()
forall (m :: * -> *). MonadIO m => Int -> Refold m Handle Word8 ()
consumerWithBufferOf Int
defaultChunkSize