------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.ByteString -- Copyright: (c) 2013 Leon P Smith -- License: BSD3 -- Maintainer: https://github.com/blaze-builder -- Stability: stable -- -- 'Write's and 'B.Builder's for strict and lazy bytestrings. -- -- We assume the following qualified imports in order to differentiate between -- strict and lazy bytestrings in the code examples. -- -- > import qualified Data.ByteString as S -- > import qualified Data.ByteString.Lazy as L -- ------------------------------------------------------------------------------ module Blaze.ByteString.Builder.ByteString ( -- * Strict bytestrings writeByteString , fromByteString , fromByteStringWith , copyByteString , insertByteString -- * Lazy bytestrings , fromLazyByteString , fromLazyByteStringWith , copyLazyByteString , insertLazyByteString ) where import Blaze.ByteString.Builder.Internal.Write ( Write, exactWrite ) import Foreign import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Builder.Extra as B import qualified Data.ByteString as S import qualified Data.ByteString.Internal as S import qualified Data.ByteString.Lazy as L -- | Write a strict 'S.ByteString' to a buffer. writeByteString :: S.ByteString -> Write writeByteString :: ByteString -> Write writeByteString ByteString bs = Int -> (Ptr Word8 -> IO ()) -> Write exactWrite Int l forall {a}. Ptr a -> IO () io where (ForeignPtr Word8 fptr, Int o, Int l) = ByteString -> (ForeignPtr Word8, Int, Int) S.toForeignPtr ByteString bs io :: Ptr a -> IO () io Ptr a pf = forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b withForeignPtr ForeignPtr Word8 fptr forall a b. (a -> b) -> a -> b $ \Ptr Word8 p -> forall a. Ptr a -> Ptr a -> Int -> IO () copyBytes Ptr a pf (Ptr Word8 p forall a b. Ptr a -> Int -> Ptr b `plusPtr` Int o) Int l {-# INLINE writeByteString #-} -- | Create a 'B.Builder' denoting the same sequence of bytes as a strict -- 'S.ByteString'. -- The 'B.Builder' inserts large 'S.ByteString's directly, but copies small ones -- to ensure that the generated chunks are large on average. fromByteString :: S.ByteString -> B.Builder fromByteString :: ByteString -> Builder fromByteString = ByteString -> Builder B.byteString {-# INLINE fromByteString #-} -- | Construct a 'B.Builder' that copies the strict 'S.ByteString's, if it is -- smaller than the threshold, and inserts it directly otherwise. -- -- For example, @fromByteStringWith 1024@ copies strict 'S.ByteString's whose size -- is less or equal to 1kb, and inserts them directly otherwise. This implies -- that the average chunk-size of the generated lazy 'L.ByteString' may be as -- low as 513 bytes, as there could always be just a single byte between the -- directly inserted 1025 byte, strict 'S.ByteString's. -- fromByteStringWith :: Int -- ^ Maximal number of bytes to copy. -> S.ByteString -- ^ Strict 'S.ByteString' to serialize. -> B.Builder -- ^ Resulting 'B.Builder'. fromByteStringWith :: Int -> ByteString -> Builder fromByteStringWith = Int -> ByteString -> Builder B.byteStringThreshold {-# INLINE fromByteStringWith #-} -- | Construct a 'B.Builder' that copies the strict 'S.ByteString'. -- -- Use this function to create 'B.Builder's from smallish (@<= 4kb@) -- 'S.ByteString's or if you need to guarantee that the 'S.ByteString' is not -- shared with the chunks generated by the 'B.Builder'. -- copyByteString :: S.ByteString -> B.Builder copyByteString :: ByteString -> Builder copyByteString = ByteString -> Builder B.byteStringCopy {-# INLINE copyByteString #-} -- | Construct a 'B.Builder' that always inserts the strict 'S.ByteString' -- directly as a chunk. -- -- This implies flushing the output buffer, even if it contains just -- a single byte. You should therefore use 'insertByteString' only for large -- (@> 8kb@) 'S.ByteString's. Otherwise, the generated chunks are too -- fragmented to be processed efficiently afterwards. -- insertByteString :: S.ByteString -> B.Builder insertByteString :: ByteString -> Builder insertByteString = ByteString -> Builder B.byteStringInsert {-# INLINE insertByteString #-} -- | Create a 'B.Builder' denoting the same sequence of bytes as a lazy -- 'S.ByteString'. -- The 'B.Builder' inserts large chunks of the lazy 'L.ByteString' directly, -- but copies small ones to ensure that the generated chunks are large on -- average. -- fromLazyByteString :: L.ByteString -> B.Builder fromLazyByteString :: ByteString -> Builder fromLazyByteString = ByteString -> Builder B.lazyByteString {-# INLINE fromLazyByteString #-} -- | Construct a 'B.Builder' that uses the thresholding strategy of 'fromByteStringWith' -- for each chunk of the lazy 'L.ByteString'. -- fromLazyByteStringWith :: Int -> L.ByteString -> B.Builder fromLazyByteStringWith :: Int -> ByteString -> Builder fromLazyByteStringWith = Int -> ByteString -> Builder B.lazyByteStringThreshold {-# INLINE fromLazyByteStringWith #-} -- | Construct a 'B.Builder' that copies the lazy 'L.ByteString'. -- copyLazyByteString :: L.ByteString -> B.Builder copyLazyByteString :: ByteString -> Builder copyLazyByteString = ByteString -> Builder B.lazyByteStringCopy {-# INLINE copyLazyByteString #-} -- | Construct a 'B.Builder' that inserts all chunks of the lazy 'L.ByteString' -- directly. -- insertLazyByteString :: L.ByteString -> B.Builder insertLazyByteString :: ByteString -> Builder insertLazyByteString = ByteString -> Builder B.lazyByteStringInsert {-# INLINE insertLazyByteString #-}