{-# 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 :: Builder -> BufferWriter
runBuilder = BuildStep () -> BufferWriter
run (BuildStep () -> BufferWriter)
-> (Builder -> BuildStep ()) -> Builder -> BufferWriter
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> BuildStep ()
I.runBuilder
where
bytesWritten :: Ptr b -> Ptr a -> Int
bytesWritten Ptr b
startPtr Ptr a
endPtr = Ptr a
endPtr Ptr a -> Ptr b -> Int
forall a b. Ptr a -> Ptr b -> Int
`minusPtr` Ptr b
startPtr
run :: I.BuildStep () -> BufferWriter
run :: BuildStep () -> BufferWriter
run BuildStep ()
step = \Ptr Word8
buf Int
len ->
let doneH :: Ptr a -> () -> m (Int, Next)
doneH Ptr a
endPtr () =
let !wc :: Int
wc = Ptr Word8 -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
bytesWritten Ptr Word8
buf Ptr a
endPtr
next :: Next
next = Next
Done
in (Int, Next) -> m (Int, Next)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
wc, Next
next)
bufferFullH :: Ptr a -> Int -> BuildStep () -> m (Int, Next)
bufferFullH Ptr a
endPtr Int
minReq BuildStep ()
step' =
let !wc :: Int
wc = Ptr Word8 -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
bytesWritten Ptr Word8
buf Ptr a
endPtr
next :: Next
next = Int -> BufferWriter -> Next
More Int
minReq (BuildStep () -> BufferWriter
run BuildStep ()
step')
in (Int, Next) -> m (Int, Next)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
wc, Next
next)
insertChunkH :: Ptr a -> ByteString -> BuildStep () -> m (Int, Next)
insertChunkH Ptr a
endPtr ByteString
bs BuildStep ()
step' =
let !wc :: Int
wc = Ptr Word8 -> Ptr a -> Int
forall a b. Ptr a -> Ptr b -> Int
bytesWritten Ptr Word8
buf Ptr a
endPtr
next :: Next
next = ByteString -> BufferWriter -> Next
Chunk ByteString
bs (BuildStep () -> BufferWriter
run BuildStep ()
step')
in (Int, Next) -> m (Int, Next)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
wc, Next
next)
br :: BufferRange
br = Ptr Word8 -> Ptr Word8 -> BufferRange
I.BufferRange Ptr Word8
buf (Ptr Word8
buf Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len)
in BuildStep ()
-> (Ptr Word8 -> () -> IO (Int, Next))
-> (Ptr Word8 -> Int -> BuildStep () -> IO (Int, Next))
-> (Ptr Word8 -> ByteString -> BuildStep () -> IO (Int, Next))
-> BufferRange
-> IO (Int, Next)
forall a b.
BuildStep a
-> (Ptr Word8 -> a -> IO b)
-> (Ptr Word8 -> Int -> BuildStep a -> IO b)
-> (Ptr Word8 -> ByteString -> BuildStep a -> IO b)
-> BufferRange
-> IO b
I.fillWithBuildStep BuildStep ()
step Ptr Word8 -> () -> IO (Int, Next)
forall (m :: * -> *) a. Monad m => Ptr a -> () -> m (Int, Next)
doneH Ptr Word8 -> Int -> BuildStep () -> IO (Int, Next)
forall (m :: * -> *) a.
Monad m =>
Ptr a -> Int -> BuildStep () -> m (Int, Next)
bufferFullH Ptr Word8 -> ByteString -> BuildStep () -> IO (Int, Next)
forall (m :: * -> *) a.
Monad m =>
Ptr a -> ByteString -> BuildStep () -> m (Int, Next)
insertChunkH BufferRange
br
{-# INLINE intHost #-}
intHost :: Int -> Builder
intHost :: Int -> Builder
intHost = FixedPrim Int -> Int -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Int
P.intHost
{-# INLINE int16Host #-}
int16Host :: Int16 -> Builder
int16Host :: Int16 -> Builder
int16Host = FixedPrim Int16 -> Int16 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Int16
P.int16Host
{-# INLINE int32Host #-}
int32Host :: Int32 -> Builder
int32Host :: Int32 -> Builder
int32Host = FixedPrim Int32 -> Int32 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Int32
P.int32Host
{-# INLINE int64Host #-}
int64Host :: Int64 -> Builder
int64Host :: Int64 -> Builder
int64Host = FixedPrim Int64 -> Int64 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Int64
P.int64Host
{-# INLINE wordHost #-}
wordHost :: Word -> Builder
wordHost :: Word -> Builder
wordHost = FixedPrim Word -> Word -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Word
P.wordHost
{-# INLINE word16Host #-}
word16Host :: Word16 -> Builder
word16Host :: Word16 -> Builder
word16Host = FixedPrim Word16 -> Word16 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Word16
P.word16Host
{-# INLINE word32Host #-}
word32Host :: Word32 -> Builder
word32Host :: Word32 -> Builder
word32Host = FixedPrim Word32 -> Word32 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Word32
P.word32Host
{-# INLINE word64Host #-}
word64Host :: Word64 -> Builder
word64Host :: Word64 -> Builder
word64Host = FixedPrim Word64 -> Word64 -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Word64
P.word64Host
{-# INLINE floatHost #-}
floatHost :: Float -> Builder
floatHost :: Float -> Builder
floatHost = FixedPrim Float -> Float -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Float
P.floatHost
{-# INLINE doubleHost #-}
doubleHost :: Double -> Builder
doubleHost :: Double -> Builder
doubleHost = FixedPrim Double -> Double -> Builder
forall a. FixedPrim a -> a -> Builder
P.primFixed FixedPrim Double
P.doubleHost