@@ -13,6 +13,11 @@
1313-- fundamental stream IO APIs built on top of those are
1414-- 'readChunksWithBufferOf' and 'writeChunks'. Rest of this module is just
1515-- combinatorial programming using these.
16+--
17+-- We can achieve line buffering by folding lines in the input stream into a
18+-- stream of arrays using Stream.splitOn or Fold.takeEndBy_ and similar
19+-- operations. One can wrap the input stream in 'Maybe' type and then use
20+-- 'writeMaybesWithBufferOf' to achieve user controlled buffering.
1621
1722-- TODO: Need a separate module for pread/pwrite based reading writing for
1823-- seekable devices. Stateless read/write can be helpful in multithreaded
@@ -51,6 +56,7 @@ module Streamly.Internal.FileSystem.Handle
5156 -- , writeByFrames
5257 -- , writeLines
5358 , writeWithBufferOf
59+ , writeMaybesWithBufferOf
5460
5561 , putBytes
5662 , putBytesWithBufferOf
@@ -101,6 +107,7 @@ where
101107import Control.Exception (assert)
102108import Control.Monad.IO.Class (MonadIO(..))
103109import Data.Function ((&))
110+import Data.Maybe (isNothing, fromJust)
104111import Data.Word (Word8)
105112import Foreign.ForeignPtr (withForeignPtr)
106113import Foreign.Ptr (minusPtr, plusPtr)
@@ -509,6 +516,19 @@ writeChunksWithBufferOf n h = lpackArraysChunksOf n (writeChunks h)
509516writeWithBufferOf :: MonadIO m => Int -> Handle -> Fold m Word8 ()
510517writeWithBufferOf n h = FL.chunksOf n (writeNUnsafe n) (writeChunks h)
511518
519+-- | Write a stream of 'Maybe' values. Keep buffering the just values in an
520+-- array until a 'Nothing' is encountered or the buffer size exceeds the
521+-- specified limit, at that point flush the buffer to the handle.
522+--
523+-- /Pre-release/
524+{-# INLINE writeMaybesWithBufferOf #-}
525+writeMaybesWithBufferOf :: (MonadIO m )
526+ => Int -> Handle -> Fold m (Maybe Word8) ()
527+writeMaybesWithBufferOf n h =
528+ let writeNJusts = FL.lmap fromJust $ A.writeN n
529+ writeOnNothing = FL.takeEndBy_ isNothing writeNJusts
530+ in FL.many writeOnNothing (writeChunks h)
531+
512532-- | Like 'writeWithBufferOf' but uses the experimental 'Refold' API.
513533--
514534-- /Internal/