{-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-}
#if __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE Trustworthy #-}
#endif
module Data.ByteString.Builder.Extra
(
toLazyByteStringWith
, AllocationStrategy
, safeStrategy
, untrimmedStrategy
, smallChunkSize
, defaultChunkSize
, byteStringCopy
, byteStringInsert
, byteStringThreshold
, lazyByteStringCopy
, lazyByteStringInsert
, lazyByteStringThreshold
, flush
, BufferWriter
, Next(..)
, runBuilder
, intHost
, int16Host
, int32Host
, int64Host
, wordHost
, word16Host
, word32Host
, word64Host
, floatHost
, doubleHost
) where
import Data.ByteString.Builder.Internal
( Builder, toLazyByteStringWith
, AllocationStrategy, safeStrategy, untrimmedStrategy
, smallChunkSize, defaultChunkSize, flush
, byteStringCopy, byteStringInsert, byteStringThreshold
, lazyByteStringCopy, lazyByteStringInsert, lazyByteStringThreshold )
import qualified Data.ByteString.Builder.Internal as I
import qualified Data.ByteString.Builder.Prim as P
import qualified Data.ByteString.Internal as S
import Foreign
type BufferWriter = Ptr Word8 -> Int -> IO (Int, Next)
data Next =
Done
| More !Int BufferWriter
| Chunk !S.ByteString BufferWriter
runBuilder :: Builder -> BufferWriter
runBuilder = run . I.runBuilder
where
bytesWritten startPtr endPtr = endPtr `minusPtr` startPtr
run :: I.BuildStep () -> BufferWriter
run step = \buf len ->
let doneH endPtr () =
let !wc = bytesWritten buf endPtr
next = Done
in return (wc, next)
bufferFullH endPtr minReq step' =
let !wc = bytesWritten buf endPtr
next = More minReq (run step')
in return (wc, next)
insertChunkH endPtr bs step' =
let !wc = bytesWritten buf endPtr
next = Chunk bs (run step')
in return (wc, next)
br = I.BufferRange buf (buf `plusPtr` len)
in I.fillWithBuildStep step doneH bufferFullH insertChunkH br
{-# INLINE intHost #-}
intHost :: Int -> Builder
intHost = P.primFixed P.intHost
{-# INLINE int16Host #-}
int16Host :: Int16 -> Builder
int16Host = P.primFixed P.int16Host
{-# INLINE int32Host #-}
int32Host :: Int32 -> Builder
int32Host = P.primFixed P.int32Host
{-# INLINE int64Host #-}
int64Host :: Int64 -> Builder
int64Host = P.primFixed P.int64Host
{-# INLINE wordHost #-}
wordHost :: Word -> Builder
wordHost = P.primFixed P.wordHost
{-# INLINE word16Host #-}
word16Host :: Word16 -> Builder
word16Host = P.primFixed P.word16Host
{-# INLINE word32Host #-}
word32Host :: Word32 -> Builder
word32Host = P.primFixed P.word32Host
{-# INLINE word64Host #-}
word64Host :: Word64 -> Builder
word64Host = P.primFixed P.word64Host
{-# INLINE floatHost #-}
floatHost :: Float -> Builder
floatHost = P.primFixed P.floatHost
{-# INLINE doubleHost #-}
doubleHost :: Double -> Builder
doubleHost = P.primFixed P.doubleHost