------------------------------------------------------------------------------ -- | -- Module: Blaze.ByteString.Builder.ByteString -- Copyright: (c) 2013 Leon P Smith -- License: BSD3 -- Maintainer: Leon P Smith -- Stability: experimental -- -- '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 bs = exactWrite l io where (fptr, o, l) = S.toForeignPtr bs io pf = withForeignPtr fptr $ \p -> copyBytes pf (p `plusPtr` o) 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 = B.byteString {-# INLINE fromByteString #-} -- | Construct a 'B.Builder' that copies the strict 'S.ByteString's, if it is -- smaller than the treshold, 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 = 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 = 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 = 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 = 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 = B.lazyByteStringThreshold {-# INLINE fromLazyByteStringWith #-} -- | Construct a 'B.Builder' that copies the lazy 'L.ByteString'. -- copyLazyByteString :: L.ByteString -> B.Builder copyLazyByteString = B.lazyByteStringCopy {-# INLINE copyLazyByteString #-} -- | Construct a 'B.Builder' that inserts all chunks of the lazy 'L.ByteString' -- directly. -- insertLazyByteString :: L.ByteString -> B.Builder insertLazyByteString = B.lazyByteStringInsert {-# INLINE insertLazyByteString #-}