module Data.Streaming.ByteString.Builder
( toByteStringIO
, toByteStringIOWith
, toByteStringIOWithBuffer )
where
import Control.Monad (when)
import Data.ByteString.Builder (Builder)
import Data.ByteString.Builder.Extra (runBuilder, BufferWriter, Next(Done, More, Chunk))
import Data.ByteString.Internal (mallocByteString, ByteString(PS))
import Data.ByteString.Lazy.Internal (defaultChunkSize)
import Data.Word (Word8)
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)
toByteStringIOWithBuffer :: Int
-> (ByteString -> IO ())
-> Builder
-> ForeignPtr Word8
-> IO ()
toByteStringIOWithBuffer initBufSize io b initBuf = do
go initBufSize initBuf (runBuilder b)
where
go bufSize buf = loop
where
loop :: BufferWriter -> IO ()
loop wr = do
(len, next) <- withForeignPtr buf (flip wr bufSize)
when (len > 0) (io (PS buf 0 len))
case next of
Done -> return ()
More newBufSize nextWr
| newBufSize > bufSize -> do
newBuf <- mallocByteString newBufSize
go newBufSize newBuf nextWr
| otherwise -> loop nextWr
Chunk s nextWr -> do
io s
loop nextWr
toByteStringIOWith :: Int
-> (ByteString -> IO ())
-> Builder
-> IO ()
toByteStringIOWith bufSize io b =
toByteStringIOWithBuffer bufSize io b =<< mallocByteString bufSize
toByteStringIO :: (ByteString -> IO ())
-> Builder
-> IO ()
toByteStringIO = toByteStringIOWith defaultChunkSize