bsb-http-chunked 0.0.0.1 → 0.0.0.2
raw patch · 12 files changed
+14/−1268 lines, 12 filesdep −HUnitdep −QuickCheckdep −blaze-builderdep ~basedep ~bytestringPVP ok
version bump matches the API change (PVP)
Dependencies removed: HUnit, QuickCheck, blaze-builder, test-framework, test-framework-hunit, test-framework-quickcheck2, text, utf8-string
Dependency ranges changed: base, bytestring
API changes (from Hackage documentation)
Files
- Blaze/ByteString/Builder.hs +0/−258
- Blaze/ByteString/Builder/ByteString.hs +0/−128
- Blaze/ByteString/Builder/Char8.hs +0/−23
- Blaze/ByteString/Builder/Compat/Write.hs +2/−9
- Blaze/ByteString/Builder/Int.hs +0/−258
- Blaze/ByteString/Builder/Internal/Write.hs +1/−144
- Blaze/ByteString/Builder/Word.hs +0/−268
- CHANGELOG.md +6/−1
- Data/ByteString/Builder/HTTP/Chunked.hs +2/−3
- bsb-http-chunked.cabal +3/−29
- tests/LlvmSegfault.hs +0/−35
- tests/Tests.hs +0/−112
− Blaze/ByteString/Builder.hs
@@ -1,258 +0,0 @@-{-# LANGUAGE CPP, BangPatterns #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}----------------------------------------------------------------------------------- |--- Module: Blaze.ByteString.Builder--- Copyright: (c) 2013 Leon P Smith--- License: BSD3--- Maintainer: Leon P Smith <leon@melding-monads.com>--- Stability: experimental------ "Blaze.ByteString.Builder" is the main module, which you should import as a user--- of the @blaze-builder@ library.------ > import Blaze.ByteString.Builder------ It provides you with a type 'Builder' that allows to efficiently construct--- lazy bytestrings with a large average chunk size.------ Intuitively, a 'Builder' denotes the construction of a part of a lazy--- bytestring. Builders can either be created using one of the primitive--- combinators in "Blaze.ByteString.Builder.Write" or by using one of the predefined--- combinators for standard Haskell values (see the exposed modules of this--- package). Concatenation of builders is done using 'mappend' from the--- 'Monoid' typeclass.------ Here is a small example that serializes a list of strings using the UTF-8--- encoding.------ @ import "Blaze.ByteString.Builder.Char.Utf8"@------ > strings :: [String]--- > strings = replicate 10000 "Hello there!"------ The function @'fromString'@ creates a 'Builder' denoting the UTF-8 encoded--- argument. Hence, UTF-8 encoding and concatenating all @strings@ can be done--- follows.------ > concatenation :: Builder--- > concatenation = mconcat $ map fromString strings------ The function 'toLazyByteString' can be used to execute a 'Builder' and--- obtain the resulting lazy bytestring.------ > result :: L.ByteString--- > result = toLazyByteString concatenation------ The @result@ is a lazy bytestring containing 10000 repetitions of the string--- @\"Hello there!\"@ encoded using UTF-8. The corresponding 120000 bytes are--- distributed among three chunks of 32kb and a last chunk of 6kb.------ /A note on history./ This serialization library was inspired by the--- @Data.Binary.Builder@ module provided by the @binary@ package. It was--- originally developed with the specific needs of the @blaze-html@ package in--- mind. Since then it has been restructured to serve as a drop-in replacement--- for @Data.Binary.Builder@, which it improves upon both in speed as well as--- expressivity.------------------------------------------------------------------------------------module Blaze.ByteString.Builder- (- -- * The 'Builder' type- B.Builder-- -- * Creating builders- , module Blaze.ByteString.Builder.Int- , module Blaze.ByteString.Builder.Word- , module Blaze.ByteString.Builder.ByteString- , B.flush-- -- * Executing builders- , B.toLazyByteString- , toLazyByteStringWith- , toByteString- , toByteStringIO- , toByteStringIOWith-- -- * 'Write's- , W.Write- , W.fromWrite- , W.fromWriteSingleton- , W.fromWriteList- , writeToByteString-- -- ** Writing 'Storable's- , W.writeStorable- , W.fromStorable- , W.fromStorables-- ) where--import Control.Monad(unless)--#if __GLASGOW_HASKELL__ >= 702-import Foreign-import qualified Foreign.ForeignPtr.Unsafe as Unsafe-#else-import Foreign as Unsafe-#endif--import qualified Blaze.ByteString.Builder.Internal.Write as W-import Blaze.ByteString.Builder.ByteString-import Blaze.ByteString.Builder.Word-import Blaze.ByteString.Builder.Int--import Data.ByteString.Builder ( Builder )-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-import qualified Data.ByteString.Lazy.Internal as L--#if __GLASGOW_HASKELL__ >= 702-import System.IO.Unsafe (unsafeDupablePerformIO)-#else-unsafeDupablePerformIO :: IO a -> a-unsafeDupablePerformIO = unsafePerformIO-#endif------ | Pack the chunks of a lazy bytestring into a single strict bytestring.-packChunks :: L.ByteString -> S.ByteString-packChunks lbs = do- S.unsafeCreate (fromIntegral $ L.length lbs) (copyChunks lbs)- where- copyChunks !L.Empty !_pf = return ()- copyChunks !(L.Chunk (S.PS fpbuf o l) lbs') !pf = do- withForeignPtr fpbuf $ \pbuf ->- copyBytes pf (pbuf `plusPtr` o) l- copyChunks lbs' (pf `plusPtr` l)---- | Run the builder to construct a strict bytestring containing the sequence--- of bytes denoted by the builder. This is done by first serializing to a lazy bytestring and then packing its--- chunks to a appropriately sized strict bytestring.------ > toByteString = packChunks . toLazyByteString------ Note that @'toByteString'@ is a 'Monoid' homomorphism.------ > toByteString mempty == mempty--- > toByteString (x `mappend` y) == toByteString x `mappend` toByteString y------ However, in the second equation, the left-hand-side is generally faster to--- execute.----toByteString :: Builder -> S.ByteString-toByteString = packChunks . B.toLazyByteString---- | Default size (~32kb) for the buffer that becomes a chunk of the output--- stream once it is filled.----defaultBufferSize :: Int-defaultBufferSize = 32 * 1024 - overhead -- Copied from Data.ByteString.Lazy.- where overhead = 2 * sizeOf (undefined :: Int)----- | @toByteStringIOWith bufSize io b@ runs the builder @b@ with a buffer of--- at least the size @bufSize@ and executes the 'IO' action @io@ whenever the--- buffer is full.------ Compared to 'toLazyByteStringWith' this function requires less allocation,--- as the output buffer is only allocated once at the start of the--- serialization and whenever something bigger than the current buffer size has--- to be copied into the buffer, which should happen very seldomly for the--- default buffer size of 32kb. Hence, the pressure on the garbage collector is--- reduced, which can be an advantage when building long sequences of bytes.----toByteStringIO :: (S.ByteString -> IO ()) -> Builder -> IO ()-toByteStringIO = toByteStringIOWith defaultBufferSize--toByteStringIOWith :: Int -- ^ Buffer size (upper bounds- -- the number of bytes forced- -- per call to the 'IO' action).- -> (S.ByteString -> IO ()) -- ^ 'IO' action to execute per- -- full buffer, which is- -- referenced by a strict- -- 'S.ByteString'.- -> Builder -- ^ 'Builder' to run.- -> IO () -- ^ Resulting 'IO' action.-toByteStringIOWith !bufSize io builder = do- S.mallocByteString bufSize >>= getBuffer (B.runBuilder builder) bufSize- where- getBuffer writer !size fp = do- let !ptr = Unsafe.unsafeForeignPtrToPtr fp- (bytes, next) <- writer ptr size- case next of- B.Done -> io $! S.PS fp 0 bytes- B.More req writer' -> do- io $! S.PS fp 0 bytes- let !size' = max bufSize req- S.mallocByteString size' >>= getBuffer writer' size'- B.Chunk bs' writer' -> do- if bytes > 0- then do- io $! S.PS fp 0 bytes- unless (S.null bs') (io bs')- S.mallocByteString bufSize >>= getBuffer writer' bufSize- else do- unless (S.null bs') (io bs')- getBuffer writer' size fp----- | Run a 'Builder' with the given buffer sizes.------ Use this function for integrating the 'Builder' type with other libraries--- that generate lazy bytestrings.------ Note that the builders should guarantee that on average the desired chunk--- size is attained. Builders may decide to start a new buffer and not--- completely fill the existing buffer, if this is faster. However, they should--- not spill too much of the buffer, if they cannot compensate for it.------ FIXME: Note that the following paragraphs are not entirely correct as of--- blaze-builder-0.4:------ A call @toLazyByteStringWith bufSize minBufSize firstBufSize@ will generate--- a lazy bytestring according to the following strategy. First, we allocate--- a buffer of size @firstBufSize@ and start filling it. If it overflows, we--- allocate a buffer of size @minBufSize@ and copy the first buffer to it in--- order to avoid generating a too small chunk. Finally, every next buffer will--- be of size @bufSize@. This, slow startup strategy is required to achieve--- good speed for short (<200 bytes) resulting bytestrings, as for them the--- allocation cost is of a large buffer cannot be compensated. Moreover, this--- strategy also allows us to avoid spilling too much memory for short--- resulting bytestrings.------ Note that setting @firstBufSize >= minBufSize@ implies that the first buffer--- is no longer copied but allocated and filled directly. Hence, setting--- @firstBufSize = bufSize@ means that all chunks will use an underlying buffer--- of size @bufSize@. This is recommended, if you know that you always output--- more than @minBufSize@ bytes.-toLazyByteStringWith- :: Int -- ^ Buffer size (upper-bounds the resulting chunk size).- -> Int -- ^ This parameter is ignored as of blaze-builder-0.4- -> Int -- ^ Size of the first buffer to be used and copied for- -- larger resulting sequences- -> Builder -- ^ Builder to run.- -> L.ByteString -- ^ Lazy bytestring to output after the builder is- -- finished.- -> L.ByteString -- ^ Resulting lazy bytestring-toLazyByteStringWith bufSize _minBufSize firstBufSize builder k =- B.toLazyByteStringWith (B.safeStrategy firstBufSize bufSize) k builder---- | Run a 'Write' to produce a strict 'S.ByteString'.--- This is equivalent to @('toByteString' . 'fromWrite')@, but is more--- efficient because it uses just one appropriately-sized buffer.-writeToByteString :: W.Write -> S.ByteString-writeToByteString !w = unsafeDupablePerformIO $ do- fptr <- S.mallocByteString (W.getBound w)- len <- withForeignPtr fptr $ \ptr -> do- end <- W.runWrite w ptr- return $! end `minusPtr` ptr- return $! S.fromForeignPtr fptr 0 len-{-# INLINE writeToByteString #-}
− Blaze/ByteString/Builder/ByteString.hs
@@ -1,128 +0,0 @@---------------------------------------------------------------------------------- |--- Module: Blaze.ByteString.Builder.ByteString--- Copyright: (c) 2013 Leon P Smith--- License: BSD3--- Maintainer: Leon P Smith <leon@melding-monads.com>--- 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 #-}
Blaze/ByteString/Builder/Char8.hs view
@@ -21,35 +21,12 @@ ( -- * Writing Latin-1 (ISO 8859-1) encodable characters to a buffer writeChar-- -- * Creating Builders from Latin-1 (ISO 8859-1) encodable characters- , fromChar- , fromString- , fromShow ) where import Blaze.ByteString.Builder.Compat.Write ( Write, writePrimFixed )-import Data.ByteString.Builder ( Builder )-import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Builder.Prim as P -- | Write the lower 8-bits of a character to a buffer. writeChar :: Char -> Write writeChar = writePrimFixed P.char8 {-# INLINE writeChar #-}---- | /O(1)/. Serialize the lower 8-bits of a character.-fromChar :: Char -> Builder-fromChar = B.char8-{-# INLINE fromChar #-}---- | /O(n)/. Serialize the lower 8-bits of all characters of a string-fromString :: String -> Builder-fromString = P.primMapListFixed P.char8-{-# INLINE fromString #-}---- | /O(n)/. Serialize a value by 'Show'ing it and serializing the lower 8-bits--- of the resulting string.-fromShow :: Show a => a -> Builder-fromShow = fromString . show-{-# INLINE fromShow #-}
Blaze/ByteString/Builder/Compat/Write.hs view
@@ -13,18 +13,11 @@ module Blaze.ByteString.Builder.Compat.Write ( Write , writePrimFixed- , writePrimBounded ) where -import Data.ByteString.Builder.Prim.Internal (BoundedPrim, FixedPrim- , runB, runF, size, sizeBound)-import Blaze.ByteString.Builder.Internal.Write (Poke(..), Write- , boundedWrite, exactWrite)+import Data.ByteString.Builder.Prim.Internal (FixedPrim, runF, size)+import Blaze.ByteString.Builder.Internal.Write (Write, exactWrite) writePrimFixed :: FixedPrim a -> a -> Write writePrimFixed fe a = exactWrite (size fe) (runF fe a) {-# INLINE writePrimFixed #-}--writePrimBounded :: BoundedPrim a -> a -> Write-writePrimBounded be a = boundedWrite (sizeBound be) (Poke (runB be a))-{-# INLINE writePrimBounded #-}
− Blaze/ByteString/Builder/Int.hs
@@ -1,258 +0,0 @@---------------------------------------------------------------------------------- |--- Module: Blaze.ByteString.Builder.Int--- Copyright: (c) 2013 Leon P Smith--- License: BSD3--- Maintainer: Leon P Smith <leon@melding-monads.com>--- Stability: experimental------ 'Write's and 'Builder's for serializing integers.------ See "Blaze.ByteString.Builder.Word" for information about how to best write several--- integers at once.------------------------------------------------------------------------------------module Blaze.ByteString.Builder.Int- (- -- * Writing integers to a buffer-- writeInt8-- -- ** Big-endian writes- , writeInt16be -- :: Int16 -> Write- , writeInt32be -- :: Int32 -> Write- , writeInt64be -- :: Int64 -> Write-- -- ** Little-endian writes- , writeInt16le -- :: Int16 -> Write- , writeInt32le -- :: Int32 -> Write- , writeInt64le -- :: Int64 -> Write-- -- ** Host-endian writes- , writeInthost -- :: Int -> Write- , writeInt16host -- :: Int16 -> Write- , writeInt32host -- :: Int32 -> Write- , writeInt64host -- :: Int64 -> Write-- -- * Creating builders from integers-- -- | We provide serialization functions both for singleton integers as well as- -- for lists of integers. Using these list serialization functions is /much/ faster- -- than using @mconcat . map fromInt/<n/>@, as the list serialization- -- functions use a tighter inner loop.-- , fromInt8- , fromInt8s-- -- ** Big-endian serialization- , fromInt16be -- :: Int16 -> Builder- , fromInt32be -- :: Int32 -> Builder- , fromInt64be -- :: Int64 -> Builder- , fromInt32sbe -- :: [Int32] -> Builder- , fromInt16sbe -- :: [Int16] -> Builder- , fromInt64sbe -- :: [Int64] -> Builder-- -- ** Little-endian serialization- , fromInt16le -- :: Int16 -> Builder- , fromInt32le -- :: Int32 -> Builder- , fromInt64le -- :: Int64 -> Builder- , fromInt16sle -- :: [Int16] -> Builder- , fromInt32sle -- :: [Int32] -> Builder- , fromInt64sle -- :: [Int64] -> Builder-- -- ** Host-endian serialization- , fromInthost -- :: Int -> Builder- , fromInt16host -- :: Int16 -> Builder- , fromInt32host -- :: Int32 -> Builder- , fromInt64host -- :: Int64 -> Builder- , fromIntshost -- :: [Int] -> Builder- , fromInt16shost -- :: [Int16] -> Builder- , fromInt32shost -- :: [Int32] -> Builder- , fromInt64shost -- :: [Int64] -> Builder-- ) where--import Data.Int-import Blaze.ByteString.Builder.Compat.Write ( Write, writePrimFixed )-import Data.ByteString.Builder ( Builder )-import qualified Data.ByteString.Builder as B-import qualified Data.ByteString.Builder.Extra as B-import qualified Data.ByteString.Builder.Prim as P---- | Write a single signed byte.----writeInt8 :: Int8 -> Write-writeInt8 = writePrimFixed P.int8-{-# INLINE writeInt8 #-}---- | Write an 'Int16' in big endian format.-writeInt16be :: Int16 -> Write-writeInt16be = writePrimFixed P.int16BE-{-# INLINE writeInt16be #-}---- | Write an 'Int32' in big endian format.-writeInt32be :: Int32 -> Write-writeInt32be = writePrimFixed P.int32BE-{-# INLINE writeInt32be #-}---- | Write an 'Int64' in big endian format.-writeInt64be :: Int64 -> Write-writeInt64be = writePrimFixed P.int64BE-{-# INLINE writeInt64be #-}---- | Write an 'Int16' in little endian format.-writeInt16le :: Int16 -> Write-writeInt16le = writePrimFixed P.int16LE-{-# INLINE writeInt16le #-}---- | Write an 'Int32' in little endian format.-writeInt32le :: Int32 -> Write-writeInt32le = writePrimFixed P.int32LE-{-# INLINE writeInt32le #-}---- | Write an 'Int64' in little endian format.-writeInt64le :: Int64 -> Write-writeInt64le = writePrimFixed P.int64LE-{-# INLINE writeInt64le #-}---- | Write a single native machine 'Int'. The 'Int' is written in host order,--- host endian form, for the machine you're on. On a 64 bit machine the 'Int'--- is an 8 byte value, on a 32 bit machine, 4 bytes. Values written this way--- are not portable to different endian or integer sized machines, without--- conversion.----writeInthost :: Int -> Write-writeInthost = writePrimFixed P.intHost-{-# INLINE writeInthost #-}---- | Write an 'Int16' in native host order and host endianness.-writeInt16host :: Int16 -> Write-writeInt16host = writePrimFixed P.int16Host-{-# INLINE writeInt16host #-}---- | Write an 'Int32' in native host order and host endianness.-writeInt32host :: Int32 -> Write-writeInt32host = writePrimFixed P.int32Host-{-# INLINE writeInt32host #-}---- | Write an 'Int64' in native host order and host endianness.-writeInt64host :: Int64 -> Write-writeInt64host = writePrimFixed P.int64Host-{-# INLINE writeInt64host #-}---- | Serialize a single byte.-fromInt8 :: Int8 -> Builder-fromInt8 = B.int8-{-# INLINE fromInt8 #-}---- | Serialize a list of bytes.-fromInt8s :: [Int8] -> Builder-fromInt8s = P.primMapListFixed P.int8-{-# INLINE fromInt8s #-}---- | Serialize an 'Int16' in big endian format.-fromInt16be :: Int16 -> Builder-fromInt16be = B.int16BE-{-# INLINE fromInt16be #-}---- | Serialize an 'Int32' in big endian format.-fromInt32be :: Int32 -> Builder-fromInt32be = B.int32BE-{-# INLINE fromInt32be #-}---- | Serialize an 'Int64' in big endian format.-fromInt64be :: Int64 -> Builder-fromInt64be = B.int64BE-{-# INLINE fromInt64be #-}---- | Serialize a list of 'Int32's in big endian format.-fromInt32sbe :: [Int32] -> Builder-fromInt32sbe = P.primMapListFixed P.int32BE-{-# INLINE fromInt32sbe #-}---- | Serialize a list of 'Int16's in big endian format.-fromInt16sbe :: [Int16] -> Builder-fromInt16sbe = P.primMapListFixed P.int16BE-{-# INLINE fromInt16sbe #-}---- | Serialize a list of 'Int64's in big endian format.-fromInt64sbe :: [Int64] -> Builder-fromInt64sbe = P.primMapListFixed P.int64BE-{-# INLINE fromInt64sbe #-}---- | Serialize an 'Int16' in little endian format.-fromInt16le :: Int16 -> Builder-fromInt16le = B.int16LE-{-# INLINE fromInt16le #-}---- | Serialize an 'Int32' in little endian format.-fromInt32le :: Int32 -> Builder-fromInt32le = B.int32LE-{-# INLINE fromInt32le #-}---- | Serialize an 'Int64' in little endian format.-fromInt64le :: Int64 -> Builder-fromInt64le = B.int64LE-{-# INLINE fromInt64le #-}---- | Serialize a list of 'Int16's in little endian format.-fromInt16sle :: [Int16] -> Builder-fromInt16sle = P.primMapListFixed P.int16LE-{-# INLINE fromInt16sle #-}---- | Serialize a list of 'Int32's in little endian format.-fromInt32sle :: [Int32] -> Builder-fromInt32sle = P.primMapListFixed P.int32LE-{-# INLINE fromInt32sle #-}---- | Serialize a list of 'Int64's in little endian format.-fromInt64sle :: [Int64] -> Builder-fromInt64sle = P.primMapListFixed P.int64LE-{-# INLINE fromInt64sle #-}---- | Serialize a single native machine 'Int'. The 'Int' is serialized in host--- order, host endian form, for the machine you're on. On a 64 bit machine the--- 'Int' is an 8 byte value, on a 32 bit machine, 4 bytes. Values written this--- way are not portable to different endian or integer sized machines, without--- conversion.----fromInthost :: Int -> Builder-fromInthost = B.intHost-{-# INLINE fromInthost #-}---- | Write an 'Int16' in native host order and host endianness.-fromInt16host :: Int16 -> Builder-fromInt16host = B.int16Host-{-# INLINE fromInt16host #-}---- | Write an 'Int32' in native host order and host endianness.-fromInt32host :: Int32 -> Builder-fromInt32host = B.int32Host-{-# INLINE fromInt32host #-}---- | Write an 'Int64' in native host order and host endianness.-fromInt64host :: Int64 -> Builder-fromInt64host = B.int64Host-{-# INLINE fromInt64host #-}---- | Serialize a list of 'Int's.--- See 'fromInthost' for usage considerations.-fromIntshost :: [Int] -> Builder-fromIntshost = P.primMapListFixed P.intHost-{-# INLINE fromIntshost #-}---- | Write a list of 'Int16's in native host order and host endianness.-fromInt16shost :: [Int16] -> Builder-fromInt16shost = P.primMapListFixed P.int16Host-{-# INLINE fromInt16shost #-}---- | Write a list of 'Int32's in native host order and host endianness.-fromInt32shost :: [Int32] -> Builder-fromInt32shost = P.primMapListFixed P.int32Host-{-# INLINE fromInt32shost #-}---- | Write a list of 'Int64's in native host order and host endianness.-fromInt64shost :: [Int64] -> Builder-fromInt64shost = P.primMapListFixed P.int64Host-{-# INLINE fromInt64shost #-}
Blaze/ByteString/Builder/Internal/Write.hs view
@@ -22,29 +22,15 @@ -- * Writing to abuffer , Write(..)- , runWrite- , getBound- , getBound' , getPoke , exactWrite , boundedWrite- , writeLiftIO- , writeIf- , writeEq- , writeOrdering- , writeOrd -- * Constructing builders from writes , fromWrite- , fromWriteSingleton- , fromWriteList -- * Writing 'Storable's- , writeStorable- , fromStorable- , fromStorables- ) where import Foreign@@ -100,26 +86,6 @@ getPoke :: Write -> Poke getPoke (Write _ wio) = wio --- | Run the 'Poke' action of a write.-{-# INLINE runWrite #-}-runWrite :: Write -> Ptr Word8 -> IO (Ptr Word8)-runWrite = runPoke . getPoke---- | Extract the maximal number of bytes that this write could write.-{-# INLINE getBound #-}-getBound :: Write -> Int-getBound (Write bound _) = bound---- | Extract the maximal number of bytes that this write could write in any--- case. Assumes that the bound of the write is data-independent.-{-# INLINE getBound' #-}-getBound' :: String -- ^ Name of caller: for debugging purposes.- -> (a -> Write)- -> Int-getBound' msg write =- getBound $ write $ error $- "getBound' called from " ++ msg ++ ": write bound is not data-independent."- #if MIN_VERSION_base(4,9,0) instance Semigroup Poke where {-# INLINE (<>) #-}@@ -131,7 +97,7 @@ instance Monoid Poke where {-# INLINE mempty #-}- mempty = Poke $ return+ mempty = Poke return #if !(MIN_VERSION_base(4,11,0)) {-# INLINE mappend #-}@@ -188,53 +154,6 @@ boundedWrite :: Int -> Poke -> Write boundedWrite = Write --- | @writeLiftIO io write@ creates a write executes the @io@ action to compute--- the value that is then written.-{-# INLINE writeLiftIO #-}-writeLiftIO :: (a -> Write) -> IO a -> Write-writeLiftIO write io =- Write (getBound' "writeLiftIO" write)- (Poke $ \pf -> do x <- io; runWrite (write x) pf)---- | @writeIf p wTrue wFalse x@ creates a 'Write' with a 'Poke' equal to @wTrue--- x@, if @p x@ and equal to @wFalse x@ otherwise. The bound of this new--- 'Write' is the maximum of the bounds for either 'Write'. This yields a data--- independent bound, if the bound for @wTrue@ and @wFalse@ is already data--- independent.-{-# INLINE writeIf #-}-writeIf :: (a -> Bool) -> (a -> Write) -> (a -> Write) -> (a -> Write)-writeIf p wTrue wFalse x =- boundedWrite (max (getBound $ wTrue x) (getBound $ wFalse x))- (if p x then getPoke $ wTrue x else getPoke $ wFalse x)---- | Compare the value to a test value and use the first write action for the--- equal case and the second write action for the non-equal case.-{-# INLINE writeEq #-}-writeEq :: Eq a => a -> (a -> Write) -> (a -> Write) -> (a -> Write)-writeEq test = writeIf (test ==)---- | TODO: Test this. It might well be too difficult to use.--- FIXME: Better name required!-{-# INLINE writeOrdering #-}-writeOrdering :: (a -> Ordering)- -> (a -> Write) -> (a -> Write) -> (a -> Write)- -> (a -> Write)-writeOrdering ord wLT wEQ wGT x =- boundedWrite bound (case ord x of LT -> getPoke $ wLT x;- EQ -> getPoke $ wEQ x;- GT -> getPoke $ wGT x)- where- bound = max (getBound $ wLT x) (max (getBound $ wEQ x) (getBound $ wGT x))---- | A write combinator useful to build decision trees for deciding what value--- to write with a constant bound on the maximal number of bytes written.-{-# INLINE writeOrd #-}-writeOrd :: Ord a- => a- -> (a -> Write) -> (a -> Write) -> (a -> Write)- -> (a -> Write)-writeOrd test = writeOrdering (`compare` test)- -- | Create a builder that execute a single 'Write'. {-# INLINE fromWrite #-} fromWrite :: Write -> Builder@@ -247,65 +166,3 @@ let !br' = BufferRange op' ope k br' | otherwise = return $ bufferFull maxSize op (step k)--{-# INLINE fromWriteSingleton #-}-fromWriteSingleton :: (a -> Write) -> (a -> Builder)-fromWriteSingleton write =- mkBuilder- where- mkBuilder x = builder step- where- step k (BufferRange op ope)- | op `plusPtr` maxSize <= ope = do- op' <- runPoke wio op- let !br' = BufferRange op' ope- k br'- | otherwise = return $ bufferFull maxSize op (step k)- where- Write maxSize wio = write x----- | Construct a 'Builder' writing a list of data one element at a time.-fromWriteList :: (a -> Write) -> [a] -> Builder-fromWriteList write =- makeBuilder- where- makeBuilder xs0 = builder $ step xs0- where- step xs1 k !(BufferRange op0 ope0) = go xs1 op0- where- go [] !op = do- let !br' = BufferRange op ope0- k br'-- go xs@(x':xs') !op- | op `plusPtr` maxSize <= ope0 = do- !op' <- runPoke wio op- go xs' op'- | otherwise = return $ bufferFull maxSize op (step xs k)- where- Write maxSize wio = write x'-{-# INLINE fromWriteList #-}------------------------------------------------------------------------------------- Writing storables------------------------------------------------------------------------------------ | Write a storable value.-{-# INLINE writeStorable #-}-writeStorable :: Storable a => a -> Write-writeStorable x = exactWrite (sizeOf x) (\op -> poke (castPtr op) x)---- | A builder that serializes a storable value. No alignment is done.-{-# INLINE fromStorable #-}-fromStorable :: Storable a => a -> Builder-fromStorable = fromWriteSingleton writeStorable---- | A builder that serializes a list of storable values by writing them--- consecutively. No alignment is done. Parsing information needs to be--- provided externally.-fromStorables :: Storable a => [a] -> Builder-fromStorables = fromWriteList writeStorable
− Blaze/ByteString/Builder/Word.hs
@@ -1,268 +0,0 @@---------------------------------------------------------------------------------- |--- Module: Blaze.ByteString.Builder.Word--- Copyright: (c) 2013 Leon P Smith--- License: BSD3--- Maintainer: Leon P Smith <leon@melding-monads.com>--- Stability: experimental------ 'Write's and 'Builder's for serializing words.------ Note that for serializing a three tuple @(x,y,z)@ of bytes (or other word--- values) you should use the expression------ > fromWrite $ writeWord8 x `mappend` writeWord8 y `mappend` writeWord z------ instead of------ > fromWord8 x `mappend` fromWord8 y `mappend` fromWord z------ The first expression will result in a single atomic write of three bytes,--- while the second expression will check for each byte, if there is free space--- left in the output buffer. Coalescing these checks can improve performance--- quite a bit, as long as you use it sensibly.------------------------------------------------------------------------------------module Blaze.ByteString.Builder.Word- (- -- * Writing words to a buffer-- writeWord8-- -- ** Big-endian writes- , writeWord16be -- :: Word16 -> Write- , writeWord32be -- :: Word32 -> Write- , writeWord64be -- :: Word64 -> Write-- -- ** Little-endian writes- , writeWord16le -- :: Word16 -> Write- , writeWord32le -- :: Word32 -> Write- , writeWord64le -- :: Word64 -> Write-- -- ** Host-endian writes- , writeWordhost -- :: Word -> Write- , writeWord16host -- :: Word16 -> Write- , writeWord32host -- :: Word32 -> Write- , writeWord64host -- :: Word64 -> Write-- -- * Creating builders from words-- -- | We provide serialization functions both for singleton words as well as- -- for lists of words. Using these list serialization functions is /much/ faster- -- than using @mconcat . map fromWord/<n/>@, as the list serialization- -- functions use a tighter inner loop.-- , fromWord8- , fromWord8s-- -- ** Big-endian serialization- , fromWord16be -- :: Word16 -> Builder- , fromWord32be -- :: Word32 -> Builder- , fromWord64be -- :: Word64 -> Builder- , fromWord32sbe -- :: [Word32] -> Builder- , fromWord16sbe -- :: [Word16] -> Builder- , fromWord64sbe -- :: [Word64] -> Builder-- -- ** Little-endian serialization- , fromWord16le -- :: Word16 -> Builder- , fromWord32le -- :: Word32 -> Builder- , fromWord64le -- :: Word64 -> Builder- , fromWord16sle -- :: [Word16] -> Builder- , fromWord32sle -- :: [Word32] -> Builder- , fromWord64sle -- :: [Word64] -> Builder-- -- ** Host-endian serialization- , fromWordhost -- :: Word -> Builder- , fromWord16host -- :: Word16 -> Builder- , fromWord32host -- :: Word32 -> Builder- , fromWord64host -- :: Word64 -> Builder- , fromWordshost -- :: [Word] -> Builder- , fromWord16shost -- :: [Word16] -> Builder- , fromWord32shost -- :: [Word32] -> Builder- , fromWord64shost -- :: [Word64] -> Builder-- ) where--import Data.Word-import Blaze.ByteString.Builder.Compat.Write ( Write, writePrimFixed )-import Data.ByteString.Builder ( Builder )-import qualified Data.ByteString.Builder as B-import qualified Data.ByteString.Builder.Extra as B-import qualified Data.ByteString.Builder.Prim as P---- | Write a single byte.----writeWord8 :: Word8 -> Write-writeWord8 = writePrimFixed P.word8-{-# INLINE writeWord8 #-}---- | Write a 'Word16' in big endian format.-writeWord16be :: Word16 -> Write-writeWord16be = writePrimFixed P.word16BE-{-# INLINE writeWord16be #-}---- | Write a 'Word32' in big endian format.-writeWord32be :: Word32 -> Write-writeWord32be = writePrimFixed P.word32BE-{-# INLINE writeWord32be #-}---- | Write a 'Word64' in big endian format.-writeWord64be :: Word64 -> Write-writeWord64be = writePrimFixed P.word64BE-{-# INLINE writeWord64be #-}---- | Write a 'Word16' in little endian format.-writeWord16le :: Word16 -> Write-writeWord16le = writePrimFixed P.word16LE-{-# INLINE writeWord16le #-}---- | Write a 'Word32' in big endian format.-writeWord32le :: Word32 -> Write-writeWord32le = writePrimFixed P.word32LE-{-# INLINE writeWord32le #-}---- | Write a 'Word64' in little endian format.-writeWord64le :: Word64 -> Write-writeWord64le = writePrimFixed P.word64LE-{-# INLINE writeWord64le #-}---- | Write a single native machine 'Word'. The 'Word' is written in host order,--- host endian form, for the machine you're on. On a 64 bit machine the 'Word'--- is an 8 byte value, on a 32 bit machine, 4 bytes. Values written this way--- are not portable to different endian or word sized machines, without--- conversion.----writeWordhost :: Word -> Write-writeWordhost = writePrimFixed P.wordHost-{-# INLINE writeWordhost #-}---- | Write a 'Word16' in native host order and host endianness.-writeWord16host :: Word16 -> Write-writeWord16host = writePrimFixed P.word16Host-{-# INLINE writeWord16host #-}---- | Write a 'Word32' in native host order and host endianness.-writeWord32host :: Word32 -> Write-writeWord32host = writePrimFixed P.word32Host-{-# INLINE writeWord32host #-}---- | Write a 'Word64' in native host order and host endianness.-writeWord64host :: Word64 -> Write-writeWord64host = writePrimFixed P.word64Host-{-# INLINE writeWord64host #-}---- | Serialize a single byte.-fromWord8 :: Word8 -> Builder-fromWord8 = B.word8-{-# INLINE fromWord8 #-}---- | Serialize a list of bytes.-fromWord8s :: [Word8] -> Builder-fromWord8s = P.primMapListFixed P.word8-{-# INLINE fromWord8s #-}---- | Serialize a 'Word16' in big endian format.-fromWord16be :: Word16 -> Builder-fromWord16be = B.word16BE-{-# INLINE fromWord16be #-}---- | Serialize a 'Word32' in big endian format.-fromWord32be :: Word32 -> Builder-fromWord32be = B.word32BE-{-# INLINE fromWord32be #-}---- | Serialize a 'Word64' in big endian format.-fromWord64be :: Word64 -> Builder-fromWord64be = B.word64BE-{-# INLINE fromWord64be #-}---- | Serialize a list of 'Word32's in big endian format.-fromWord32sbe :: [Word32] -> Builder-fromWord32sbe = P.primMapListFixed P.word32BE-{-# INLINE fromWord32sbe #-}---- | Serialize a list of 'Word16's in big endian format.-fromWord16sbe :: [Word16] -> Builder-fromWord16sbe = P.primMapListFixed P.word16BE-{-# INLINE fromWord16sbe #-}---- | Serialize a list of 'Word64's in big endian format.-fromWord64sbe :: [Word64] -> Builder-fromWord64sbe = P.primMapListFixed P.word64BE-{-# INLINE fromWord64sbe #-}---- | Serialize a 'Word16' in little endian format.-fromWord16le :: Word16 -> Builder-fromWord16le = B.word16LE-{-# INLINE fromWord16le #-}---- | Serialize a list of 'Word32's in little endian format.-fromWord32le :: Word32 -> Builder-fromWord32le = B.word32LE-{-# INLINE fromWord32le #-}---- | Serialize a 'Word64' in little endian format.-fromWord64le :: Word64 -> Builder-fromWord64le = B.word64LE-{-# INLINE fromWord64le #-}---- | Serialize a list of 'Word16's in little endian format.-fromWord16sle :: [Word16] -> Builder-fromWord16sle = P.primMapListFixed P.word16LE-{-# INLINE fromWord16sle #-}---- | Serialize a list of 'Word32's in little endian format.-fromWord32sle :: [Word32] -> Builder-fromWord32sle = P.primMapListFixed P.word32LE-{-# INLINE fromWord32sle #-}---- | Serialize a list of 'Word64's in little endian format.-fromWord64sle :: [Word64] -> Builder-fromWord64sle = P.primMapListFixed P.word64LE-{-# INLINE fromWord64sle #-}---- | Serialize a single native machine 'Word'. The 'Word' is serialized in host--- order, host endian form, for the machine you're on. On a 64 bit machine the--- 'Word' is an 8 byte value, on a 32 bit machine, 4 bytes. Values written this--- way are not portable to different endian or word sized machines, without--- conversion.-fromWordhost :: Word -> Builder-fromWordhost = B.wordHost-{-# INLINE fromWordhost #-}---- | Write a 'Word16' in native host order and host endianness.-fromWord16host :: Word16 -> Builder-fromWord16host = B.word16Host-{-# INLINE fromWord16host #-}---- | Write a 'Word32' in native host order and host endianness.-fromWord32host :: Word32 -> Builder-fromWord32host = B.word32Host-{-# INLINE fromWord32host #-}---- | Write a 'Word64' in native host order and host endianness.-fromWord64host :: Word64 -> Builder-fromWord64host = B.word64Host-{-# INLINE fromWord64host #-}---- | Serialize a list of 'Word's.--- See 'fromWordhost' for usage considerations.-fromWordshost :: [Word] -> Builder-fromWordshost = P.primMapListFixed P.wordHost-{-# INLINE fromWordshost #-}---- | Write a list of 'Word16's in native host order and host endianness.-fromWord16shost :: [Word16] -> Builder-fromWord16shost = P.primMapListFixed P.word16Host-{-# INLINE fromWord16shost #-}---- | Write a list of 'Word32's in native host order and host endianness.-fromWord32shost :: [Word32] -> Builder-fromWord32shost = P.primMapListFixed P.word32Host-{-# INLINE fromWord32shost #-}---- | Write a 'Word64' in native host order and host endianness.-fromWord64shost :: [Word64] -> Builder-fromWord64shost = P.primMapListFixed P.word64Host-{-# INLINE fromWord64shost #-}
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog for the `bsb-http-chunked` package +## [0.0.0.2] – 2018-03-13++- A lot of unused code was removed+ ## [0.0.0.1] – 2018-03-13 - Documentation improvements@@ -14,5 +18,6 @@ The format of this changelog is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -[Unreleased]: https://github.com/sjakobi/bsb-http-chunked/compare/v0.0.0.1...HEAD+[Unreleased]: https://github.com/sjakobi/bsb-http-chunked/compare/v0.0.0.2...HEAD+[0.0.0.2]: https://github.com/sjakobi/bsb-http-chunked/compare/v0.0.0.1...v0.0.0.2 [0.0.0.1]: https://github.com/sjakobi/bsb-http-chunked/compare/v0...v0.0.0.1
Data/ByteString/Builder/HTTP/Chunked.hs view
@@ -25,7 +25,6 @@ import Blaze.ByteString.Builder.Internal.Write import Data.ByteString.Builder import Data.ByteString.Builder.Internal-import Blaze.ByteString.Builder.ByteString (copyByteString) import qualified Blaze.ByteString.Builder.Char8 as Char8 @@ -108,7 +107,7 @@ transferEncodingStep k = go (runBuilder innerBuilder) where- go innerStep !(BufferRange op ope)+ go innerStep (BufferRange op ope) -- FIXME: Assert that outRemaining < maxBound :: Word32 | outRemaining < minimalBufferSize = return $ bufferFull minimalBufferSize op (go innerStep)@@ -188,4 +187,4 @@ -- | The zero-length chunk '0\r\n\r\n' signaling the termination of the data transfer. chunkedTransferTerminator :: Builder-chunkedTransferTerminator = copyByteString "0\r\n\r\n"+chunkedTransferTerminator = byteStringCopy "0\r\n\r\n"
bsb-http-chunked.cabal view
@@ -1,5 +1,5 @@ Name: bsb-http-chunked-Version: 0.0.0.1+Version: 0.0.0.2 Synopsis: Chunked HTTP transfer encoding for bytestring builders Description: This library contains functions for encoding [bytestring@@ -27,8 +27,7 @@ Build-type: Simple Cabal-version: >= 1.8 -Extra-source-files: CHANGELOG.md,- tests/*.hs+Extra-source-files: CHANGELOG.md Source-repository head Type: git@@ -39,35 +38,10 @@ exposed-modules: Data.ByteString.Builder.HTTP.Chunked - other-modules: Blaze.ByteString.Builder- Blaze.ByteString.Builder.ByteString- Blaze.ByteString.Builder.Char8+ other-modules: Blaze.ByteString.Builder.Char8 Blaze.ByteString.Builder.Compat.Write- Blaze.ByteString.Builder.Int Blaze.ByteString.Builder.Internal.Write- Blaze.ByteString.Builder.Word build-depends: base >= 4.3 && < 4.12, bytestring >= 0.9 && < 0.11, bytestring-builder < 0.11--test-suite test- -- Turn off until the package is cleaned up- buildable: False- type: exitcode-stdio-1.0-- hs-source-dirs: tests- main-is: Tests.hs-- ghc-options: -Wall -fno-warn-orphans-- build-depends: base- , blaze-builder- , bytestring- , HUnit- , QuickCheck- , test-framework- , test-framework-hunit- , test-framework-quickcheck2- , text- , utf8-string
− tests/LlvmSegfault.hs
@@ -1,35 +0,0 @@--- Author: Simon Meier <iridcode@gmail.com>, 10/06/2010------ Attempt to find a small test-case for the segfaults that happen when--- compiling the benchmarks with LLVM and GHC-7.0.1----module LlvmSegfault where--import Data.Word-import Data.Monoid-import qualified Data.ByteString.Lazy as L--import Foreign--import Blaze.ByteString.Builder.Internal----fromWord8 :: Word8 -> Builder-fromWord8 w =- Builder step- where- step k pf pe- | pf < pe = do- poke pf w- let pf' = pf `plusPtr` 1- pf' `seq` k pf' pe- | otherwise = return $ BufferFull 1 pf (step k)---word8s :: Builder-word8s = map (fromWord8 . fromIntegral) $ [(1::Int)..1000]--main :: IO ()-main =- print $ toLazyByteStringWith 10 10 (mconcat word8s) L.empty
− tests/Tests.hs
@@ -1,112 +0,0 @@-{-# LANGUAGE CPP, OverloadedStrings #-}-#if __GLASGOW_HASKELL__ >= 704-{-# OPTIONS_GHC -fsimpl-tick-factor=40000 #-}-#endif--- | Tests for the Blaze builder----module Main where--import Control.Applicative ((<$>))-import Data.Monoid (mempty, mappend, mconcat)--import qualified Data.Text as T-import qualified Data.ByteString.Lazy as LB-import Test.Framework-import Test.Framework.Providers.QuickCheck2-import Test.Framework.Providers.HUnit-import Test.QuickCheck-import Test.HUnit hiding (Test)-import Codec.Binary.UTF8.String (decode)--import Blaze.ByteString.Builder-import Blaze.ByteString.Builder.Char.Utf8-import Blaze.ByteString.Builder.Html.Utf8--main :: IO ()-main = defaultMain $ return $ testGroup "Tests" tests--tests :: [Test]-tests =- [ testProperty "left identity Monoid law" monoidLeftIdentity- , testProperty "right identity Monoid law" monoidRightIdentity- , testProperty "associativity Monoid law" monoidAssociativity- , testProperty "mconcat Monoid law" monoidConcat- , testProperty "string → builder → string" fromStringToString- , testProperty "string and text" stringAndText- , testProperty "lazy bytestring identity" identityLazyByteString- , testProperty "flushing identity" identityFlushing- , testProperty "writeToByteString" writeToByteStringProp- , testCase "escaping case 1" escaping1- , testCase "escaping case 2" escaping2- , testCase "escaping case 3" escaping3- ]--monoidLeftIdentity :: Builder -> Bool-monoidLeftIdentity b = mappend mempty b == b--monoidRightIdentity :: Builder -> Bool-monoidRightIdentity b = mappend b mempty == b--monoidAssociativity :: Builder -> Builder -> Builder -> Bool-monoidAssociativity x y z = mappend x (mappend y z) == mappend (mappend x y) z--monoidConcat :: [Builder] -> Bool-monoidConcat xs = mconcat xs == foldr mappend mempty xs--fromStringToString :: String -> Bool-fromStringToString string = string == convert string- where- convert = decode . LB.unpack . toLazyByteString . fromString--stringAndText :: String -> Bool-stringAndText string = fromString string == fromText (T.pack string)--identityLazyByteString :: LB.ByteString -> Bool-identityLazyByteString lbs = lbs == toLazyByteString (fromLazyByteString lbs)--identityFlushing :: String -> String -> Bool-identityFlushing s1 s2 =- let b1 = fromString s1- b2 = fromString s2- in b1 `mappend` b2 == b1 `mappend` flush `mappend` b2--writeToByteStringProp :: Write -> Bool-writeToByteStringProp w = toByteString (fromWrite w) == writeToByteString w--escaping1 :: Assertion-escaping1 = fromString "<hello>" @?= fromHtmlEscapedString "<hello>"--escaping2 :: Assertion-escaping2 = fromString "f &&& g" @?= fromHtmlEscapedString "f &&& g"--escaping3 :: Assertion-escaping3 = fromString ""'" @?= fromHtmlEscapedString "\"'"--instance Show Builder where- show = show . toLazyByteString--instance Show Write where- show = show . fromWrite--instance Eq Builder where- b1 == b2 =- -- different and small buffer sizses for testing wrapping behaviour- toLazyByteStringWith 1024 1024 256 b1 mempty ==- toLazyByteStringWith 2001 511 256 b2 mempty---- | Artificially scale up size to ensures that buffer wrapping behaviour is--- also tested.-numRepetitions :: Int-numRepetitions = 250--instance Arbitrary Builder where- arbitrary = (mconcat . replicate numRepetitions . fromString) <$> arbitrary--instance Arbitrary Write where- arbitrary = mconcat . map singleWrite <$> arbitrary- where- singleWrite (Left bs) = writeByteString (mconcat (LB.toChunks bs))- singleWrite (Right w) = writeWord8 w--instance Arbitrary LB.ByteString where- arbitrary = (LB.concat . replicate numRepetitions . LB.pack) <$> arbitrary