on bcecc5a help sign in
115 lines 3.8 kB history raw
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE MagicHash #-}
4{-# LANGUAGE RecordWildCards #-}
5{-# LANGUAGE UnboxedTuples #-}
7#include "inline.hs"
9-- |
10-- Module : Streamly.Internal.FileSystem.Handle
11-- Copyright : (c) 2018 Composewell Technologies
12--
13-- License : BSD3
14-- Maintainer : harendra.kumar@gmail.com
15-- Stability : experimental
16-- Portability : GHC
17--
18-- Streaming based IO write rotuines based on file handles.
20module Streamly.Internal.FileSystem.Handle
21 (
22 writeArray
24 -- Byte stream write
25 , writeS
26 , writeSInChunksOf
28 -- -- * Array stream Write
29 , writeSArrays
30 , writeSArraysInChunksOf
31 )
32where
34import Control.Monad.IO.Class (MonadIO(..))
35import Data.Word (Word8)
36import Foreign.ForeignPtr (withForeignPtr)
37import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
38import Foreign.Ptr (minusPtr)
39import Foreign.Storable (Storable(..))
40import System.IO (Handle, hPutBuf)
41import Prelude hiding (read)
43import Streamly.Internal.Memory.Array.Types (Array(..))
44import Streamly.Streams.Serial (SerialT)
45import Streamly.Internal.Memory.Array.Types (defaultChunkSize)
47import qualified Streamly.Memory.Array as A
48import qualified Streamly.Internal.Memory.ArrayStream as AS
49import qualified Streamly.Internal.Prelude as S
51-------------------------------------------------------------------------------
52-- Array IO (output)
53-------------------------------------------------------------------------------
55-- | Write an 'Array' to a file handle.
56--
57-- @since 0.7.0
58{-# INLINABLE writeArray #-}
59writeArray :: Storable a => Handle -> Array a -> IO ()
60writeArray _ arr | A.length arr == 0 = return ()
61writeArray h Array{..} = withForeignPtr aStart $ \p -> hPutBuf h p aLen
62 where
63 aLen =
64 let p = unsafeForeignPtrToPtr aStart
65 in aEnd `minusPtr` p
67-------------------------------------------------------------------------------
68-- Stream of Arrays IO
69-------------------------------------------------------------------------------
71-------------------------------------------------------------------------------
72-- Writing
73-------------------------------------------------------------------------------
75-- | Write a stream of arrays to a handle.
76--
77-- @since 0.7.0
78{-# INLINE writeSArrays #-}
79writeSArrays :: (MonadIO m, Storable a)
80 => Handle -> SerialT m (Array a) -> m ()
81writeSArrays h m = S.mapM_ (liftIO . writeArray h) m
83-- | @writeArraysPackedUpto chunkSize handle stream@ writes a stream of arrays
84-- to @handle@ after coalescing the adjacent arrays in chunks of @chunkSize@.
85-- The chunk size is only a maximum and the actual writes could be smaller as
86-- we do not split the arrays to fit exactly to the specified size.
87--
88-- @since 0.7.0
89{-# INLINE writeSArraysInChunksOf #-}
90writeSArraysInChunksOf :: (MonadIO m, Storable a)
91 => Int -> Handle -> SerialT m (Array a) -> m ()
92writeSArraysInChunksOf n h xs = writeSArrays h $ AS.compact n xs
94-- | @writeSInChunksOf chunkSize handle stream@ writes @stream@ to @handle@ in
95-- chunks of @chunkSize@. A write is performed to the IO device as soon as we
96-- collect the required input size.
97--
98-- @since 0.7.0
99{-# INLINE writeSInChunksOf #-}
100writeSInChunksOf :: MonadIO m => Int -> Handle -> SerialT m Word8 -> m ()
101writeSInChunksOf n h m = writeSArrays h $ S.arraysOf n m
102-- writeSInChunksOf n h m = writeSArrays h $ AS.arraysOf n m
104-- > write = 'writeInChunksOf' A.defaultChunkSize
105--
106-- | Write a byte stream to a file handle. Accumulates the input in chunks of
107-- up to 'A.defaultChunkSize' before writing.
108--
109-- NOTE: This may perform better than the 'write' fold, you can try this if you
110-- need some extra perf boost.
111--
112-- @since 0.7.0
113{-# INLINE writeS #-}
114writeS :: MonadIO m => Handle -> SerialT m Word8 -> m ()
115writeS = writeSInChunksOf defaultChunkSize