{-# LANGUAGE CPP, MagicHash #-} #if __GLASGOW_HASKELL__ >= 701 {-# LANGUAGE Safe #-} #endif ----------------------------------------------------------------------------- -- | -- Module : Data.Binary.Builder -- Copyright : Lennart Kolmodin, Ross Paterson -- License : BSD3-style (see LICENSE) -- -- Maintainer : Lennart Kolmodin <kolmodin@gmail.com> -- Stability : experimental -- Portability : portable to Hugs and GHC -- -- Efficient constructions of lazy bytestrings. -- -- This now re-exports 'Data.ByteString.Lazy.Builder'. -- ----------------------------------------------------------------------------- module Data.Binary.Builder ( -- * The Builder type Builder , toLazyByteString -- * Constructing Builders , empty , singleton , append , fromByteString -- :: S.ByteString -> Builder , fromLazyByteString -- :: L.ByteString -> Builder #if MIN_VERSION_bytestring(0,10,4) , fromShortByteString -- :: T.ByteString -> Builder #endif -- * Flushing the buffer state , flush -- * Derived Builders -- ** Big-endian writes , putWord16be -- :: Word16 -> Builder , putWord32be -- :: Word32 -> Builder , putWord64be -- :: Word64 -> Builder , putInt16be -- :: Int16 -> Builder , putInt32be -- :: Int32 -> Builder , putInt64be -- :: Int64 -> Builder -- ** Little-endian writes , putWord16le -- :: Word16 -> Builder , putWord32le -- :: Word32 -> Builder , putWord64le -- :: Word64 -> Builder , putInt16le -- :: Int16 -> Builder , putInt32le -- :: Int32 -> Builder , putInt64le -- :: Int64 -> Builder -- ** Host-endian, unaligned writes , putWordhost -- :: Word -> Builder , putWord16host -- :: Word16 -> Builder , putWord32host -- :: Word32 -> Builder , putWord64host -- :: Word64 -> Builder , putInthost -- :: Int -> Builder , putInt16host -- :: Int16 -> Builder , putInt32host -- :: Int32 -> Builder , putInt64host -- :: Int64 -> Builder -- ** Unicode , putCharUtf8 , putStringUtf8 ) where import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as L import qualified Data.ByteString.Short as T import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Builder.Prim as Prim import Data.ByteString.Builder ( Builder, toLazyByteString ) import Data.ByteString.Builder.Extra ( flush ) import Data.Monoid import Data.Word import Data.Int import Prelude -- Silence AMP warning. ------------------------------------------------------------------------ -- | /O(1)./ The empty Builder, satisfying -- -- * @'toLazyByteString' 'empty' = 'L.empty'@ -- empty :: Builder empty = mempty {-# INLINE empty #-} -- | /O(1)./ A Builder taking a single byte, satisfying -- -- * @'toLazyByteString' ('singleton' b) = 'L.singleton' b@ -- singleton :: Word8 -> Builder singleton = B.word8 {-# INLINE singleton #-} ------------------------------------------------------------------------ -- | /O(1)./ The concatenation of two Builders, an associative operation -- with identity 'empty', satisfying -- -- * @'toLazyByteString' ('append' x y) = 'L.append' ('toLazyByteString' x) ('toLazyByteString' y)@ -- append :: Builder -> Builder -> Builder append = mappend {-# INLINE append #-} -- | /O(1)./ A Builder taking a 'S.ByteString', satisfying -- -- * @'toLazyByteString' ('fromByteString' bs) = 'L.fromChunks' [bs]@ -- fromByteString :: S.ByteString -> Builder fromByteString = B.byteString {-# INLINE fromByteString #-} -- | /O(1)./ A Builder taking a lazy 'L.ByteString', satisfying -- -- * @'toLazyByteString' ('fromLazyByteString' bs) = bs@ -- fromLazyByteString :: L.ByteString -> Builder fromLazyByteString = B.lazyByteString {-# INLINE fromLazyByteString #-} #if MIN_VERSION_bytestring(0,10,4) -- | /O(n)./ A builder taking 'T.ShortByteString' and copy it to a Builder, -- satisfying -- -- * @'toLazyByteString' ('fromShortByteString' bs) = 'L.fromChunks' ['T.fromShort' bs] fromShortByteString :: T.ShortByteString -> Builder fromShortByteString = B.shortByteString {-# INLINE fromShortByteString #-} #endif ------------------------------------------------------------------------ -- | Write a Word16 in big endian format putWord16be :: Word16 -> Builder putWord16be = B.word16BE {-# INLINE putWord16be #-} -- | Write a Word16 in little endian format putWord16le :: Word16 -> Builder putWord16le = B.word16LE {-# INLINE putWord16le #-} -- | Write a Word32 in big endian format putWord32be :: Word32 -> Builder putWord32be = B.word32BE {-# INLINE putWord32be #-} -- | Write a Word32 in little endian format putWord32le :: Word32 -> Builder putWord32le = B.word32LE {-# INLINE putWord32le #-} -- | Write a Word64 in big endian format putWord64be :: Word64 -> Builder putWord64be = B.word64BE {-# INLINE putWord64be #-} -- | Write a Word64 in little endian format putWord64le :: Word64 -> Builder putWord64le = B.word64LE {-# INLINE putWord64le #-} -- | Write a Int16 in big endian format putInt16be :: Int16 -> Builder putInt16be = B.int16BE {-# INLINE putInt16be #-} -- | Write a Int16 in little endian format putInt16le :: Int16 -> Builder putInt16le = B.int16LE {-# INLINE putInt16le #-} -- | Write a Int32 in big endian format putInt32be :: Int32 -> Builder putInt32be = B.int32BE {-# INLINE putInt32be #-} -- | Write a Int32 in little endian format putInt32le :: Int32 -> Builder putInt32le = B.int32LE {-# INLINE putInt32le #-} -- | Write a Int64 in big endian format putInt64be :: Int64 -> Builder putInt64be = B.int64BE -- | Write a Int64 in little endian format putInt64le :: Int64 -> Builder putInt64le = B.int64LE ------------------------------------------------------------------------ -- Unaligned, word size ops -- | /O(1)./ A Builder taking 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. -- putWordhost :: Word -> Builder putWordhost = Prim.primFixed Prim.wordHost {-# INLINE putWordhost #-} -- | Write a Word16 in native host order and host endianness. -- 2 bytes will be written, unaligned. putWord16host :: Word16 -> Builder putWord16host = Prim.primFixed Prim.word16Host {-# INLINE putWord16host #-} -- | Write a Word32 in native host order and host endianness. -- 4 bytes will be written, unaligned. putWord32host :: Word32 -> Builder putWord32host = Prim.primFixed Prim.word32Host {-# INLINE putWord32host #-} -- | Write a Word64 in native host order. -- On a 32 bit machine we write two host order Word32s, in big endian form. -- 8 bytes will be written, unaligned. putWord64host :: Word64 -> Builder putWord64host = Prim.primFixed Prim.word64Host {-# INLINE putWord64host #-} -- | /O(1)./ A Builder taking 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 Int 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. -- putInthost :: Int -> Builder putInthost = Prim.primFixed Prim.intHost {-# INLINE putInthost #-} -- | Write a Int16 in native host order and host endianness. -- 2 bytes will be written, unaligned. putInt16host :: Int16 -> Builder putInt16host = Prim.primFixed Prim.int16Host {-# INLINE putInt16host #-} -- | Write a Int32 in native host order and host endianness. -- 4 bytes will be written, unaligned. putInt32host :: Int32 -> Builder putInt32host = Prim.primFixed Prim.int32Host {-# INLINE putInt32host #-} -- | Write a Int64 in native host order. -- On a 32 bit machine we write two host order Int32s, in big endian form. -- 8 bytes will be written, unaligned. putInt64host :: Int64 -> Builder putInt64host = Prim.primFixed Prim.int64Host {-# INLINE putInt64host #-} ------------------------------------------------------------------------ -- Unicode -- | Write a character using UTF-8 encoding. putCharUtf8 :: Char -> Builder putCharUtf8 = Prim.primBounded Prim.charUtf8 {-# INLINE putCharUtf8 #-} -- | Write a String using UTF-8 encoding. putStringUtf8 :: String -> Builder putStringUtf8 = Prim.primMapListBounded Prim.charUtf8 {-# INLINE putStringUtf8 #-}