on 2ea9fb0 help sign in
132 lines 4.7 kB history raw
1-- |
2-- Module : Streamly.Internal.System.IOVec
3-- Copyright : (c) 2019 Composewell Technologies
4--
5-- License : BSD3
6-- Maintainer : streamly@composewell.com
7-- Stability : experimental
8-- Portability : GHC
9--
10-- Low level IO routines interfacing the operating system.
11--
13module Streamly.Internal.System.IOVec
14 ( IOVec(..)
15 , c_writev
16 , c_safe_writev
17#if !defined(mingw32_HOST_OS)
18{-
19 , groupIOVecsOf
20 , groupIOVecsOfMut
21-}
22#endif
23 )
24where
26#include "inline.hs"
28#if !defined(mingw32_HOST_OS)
29{-
30import Control.Monad (when)
31import Control.Monad.IO.Class (MonadIO(..))
32import Foreign.Ptr (castPtr)
33import Streamly.Internal.Data.Array.Unboxed.Mut.Type (length)
34import Streamly.Internal.Data.SVar.Type (adaptState)
35import Streamly.Internal.Data.Array.Unboxed.Mut.Type (Array(..))
37import qualified Streamly.Internal.Data.Array.Unboxed.Type as Array
38import qualified Streamly.Internal.Data.Array.Unboxed.Mut.Type as MArray
39import qualified Streamly.Internal.Data.Stream.StreamD as D
40-}
41#endif
43import Streamly.Internal.System.IOVec.Type
45import Prelude hiding (length)
47#if !defined(mingw32_HOST_OS)
48{-
49data GatherState s arr
50 = GatherInitial s
51 | GatherBuffering s arr Int
52 | GatherYielding arr (GatherState s arr)
53 | GatherFinish
55-- | @groupIOVecsOf maxBytes maxEntries@ groups arrays in the incoming stream
56-- to create a stream of 'IOVec' arrays with a maximum of @maxBytes@ bytes in
57-- each array and a maximum of @maxEntries@ entries in each array.
58--
59-- @since 0.7.0
60{-# INLINE_NORMAL groupIOVecsOfMut #-}
61groupIOVecsOfMut :: MonadIO m
62 => Int -> Int -> D.Stream m (Array a) -> D.Stream m (Array IOVec)
63groupIOVecsOfMut n maxIOVLen (D.Stream step state) =
64 D.Stream step' (GatherInitial state)
66 where
68 {-# INLINE_LATE step' #-}
69 step' gst (GatherInitial st) = do
70 when (n <= 0) $
71 -- XXX we can pass the module string from the higher level API
72 error $ "Streamly.Internal.Data.Array.Unboxed.Mut.Type.groupIOVecsOf: the size of "
73 ++ "groups [" ++ show n ++ "] must be a natural number"
74 when (maxIOVLen <= 0) $
75 -- XXX we can pass the module string from the higher level API
76 error $ "Streamly.Internal.Data.Array.Unboxed.Mut.Type.groupIOVecsOf: the number of "
77 ++ "IOVec entries [" ++ show n ++ "] must be a natural number"
78 r <- step (adaptState gst) st
79 case r of
80 D.Yield arr s -> do
81 let p = arrStart arr
82 len = MArray.byteLength arr
83 iov <- liftIO $ MArray.newArray maxIOVLen
84 iov' <- liftIO $ MArray.snocUnsafe iov (IOVec (castPtr p)
85 (fromIntegral len))
86 if len >= n
87 then return $ D.Skip (GatherYielding iov' (GatherInitial s))
88 else return $ D.Skip (GatherBuffering s iov' len)
89 D.Skip s -> return $ D.Skip (GatherInitial s)
90 D.Stop -> return D.Stop
92 step' gst (GatherBuffering st iov len) = do
93 r <- step (adaptState gst) st
94 case r of
95 D.Yield arr s -> do
96 let p = arrStart arr
97 alen = MArray.byteLength arr
98 len' = len + alen
99 if len' > n || length iov >= maxIOVLen
100 then do
101 iov' <- liftIO $ MArray.newArray maxIOVLen
102 iov'' <- liftIO $ MArray.snocUnsafe iov' (IOVec (castPtr p)
103 (fromIntegral alen))
104 return $ D.Skip (GatherYielding iov
105 (GatherBuffering s iov'' alen))
106 else do
107 iov' <- liftIO $ MArray.snocUnsafe iov (IOVec (castPtr p)
108 (fromIntegral alen))
109 return $ D.Skip (GatherBuffering s iov' len')
110 D.Skip s -> return $ D.Skip (GatherBuffering s iov len)
111 D.Stop -> return $ D.Skip (GatherYielding iov GatherFinish)
113 step' _ GatherFinish = return D.Stop
115 step' _ (GatherYielding iov next) = return $ D.Yield iov next
117-- | @groupIOVecsOf maxBytes maxEntries@ groups arrays in the incoming stream
118-- to create a stream of 'IOVec' arrays with a maximum of @maxBytes@ bytes in
119-- each array and a maximum of @maxEntries@ entries in each array.
120--
121-- @since 0.7.0
122{-# INLINE_NORMAL groupIOVecsOf #-}
123groupIOVecsOf :: MonadIO m
124 => Int
125 -> Int
126 -> D.Stream m (Array.Array a) -> D.Stream m (Array.Array IOVec)
127groupIOVecsOf n maxIOVLen str =
128 D.map Array.unsafeFreeze
129 $ groupIOVecsOfMut n maxIOVLen
130 $ D.map Array.unsafeThaw str
131-}
132#endif