{-# LANGUAGE CPP #-}{-# LANGUAGE Unsafe #-}{-# OPTIONS_HADDOCK not-home #-}-- |-- Copyright : 2010-2011 Simon Meier, 2010 Jasper van der Jeugt-- License : BSD3-style (see LICENSE)---- Maintainer : Simon Meier <iridcode@gmail.com>-- Stability : unstable, private-- Portability : GHC---- *Warning:* this module is internal. If you find that you need it please-- contact the maintainers and explain what you are trying to do and discuss-- what you would need in the public API. It is important that you do this as-- the module may not be exposed at all in future releases.---- The maintainers are glad to accept patches for further-- standard encodings of standard Haskell values.---- If you need to write your own builder primitives, then be aware that you are-- writing code with /all safety belts off/; i.e.,-- *this is the code that might make your application vulnerable to buffer-overflow attacks!*-- The "Data.ByteString.Builder.Prim.Tests" module provides you with-- utilities for testing your encodings thoroughly.--moduleData.ByteString.Builder.Prim.Internal(-- * Fixed-size builder primitivesSize ,FixedPrim ,fixedPrim ,size ,runF ,emptyF ,contramapF ,pairF -- , liftIOF,storableToF -- * Bounded-size builder primitives,BoundedPrim ,boundedPrim ,sizeBound ,runB ,emptyB ,contramapB ,pairB ,eitherB ,condB -- , liftIOB,toB ,liftFixedToBounded -- , withSizeFB-- , withSizeBB-- * Shared operators,(>$<) ,(>*<) -- * Helpers,caseWordSize_32_64 -- * Deprecated,boudedPrim )whereimportForeignimportPreludehiding(maxBound)
#include "MachDeps.h"
#include "bytestring-cpp-macros.h"
-------------------------------------------------------------------------------- Supporting infrastructure-------------------------------------------------------------------------------- | Contravariant functors as in the @contravariant@ package.classContravariant f wherecontramap ::(b ->a )->f a ->f b infixl4>$< -- | A fmap-like operator for builder primitives, both bounded and fixed size.---- Builder primitives are contravariant so it's like the normal fmap, but-- backwards (look at the type). (If it helps to remember, the operator symbol-- is like (<$>) but backwards.)---- We can use it for example to prepend and/or append fixed values to an-- primitive.---- > import Data.ByteString.Builder.Prim as P-- >showEncoding ((\x -> ('\'', (x, '\''))) >$< fixed3) 'x' = "'x'"-- > where-- > fixed3 = P.char7 >*< P.char7 >*< P.char7---- Note that the rather verbose syntax for composition stems from the-- requirement to be able to compute the size / size bound at compile time.--(>$<) ::Contravariant f =>(b ->a )->f a ->f b >$< :: forall (f :: * -> *) b a. Contravariant f => (b -> a) -> f a -> f b
(>$<) =(b -> a) -> f a -> f b
forall b a. (b -> a) -> f a -> f b
forall (f :: * -> *) b a. Contravariant f => (b -> a) -> f a -> f b
contramap instanceContravariant FixedPrim wherecontramap :: forall b a. (b -> a) -> FixedPrim a -> FixedPrim b
contramap =(b -> a) -> FixedPrim a -> FixedPrim b
forall b a. (b -> a) -> FixedPrim a -> FixedPrim b
contramapF instanceContravariant BoundedPrim wherecontramap :: forall b a. (b -> a) -> BoundedPrim a -> BoundedPrim b
contramap =(b -> a) -> BoundedPrim a -> BoundedPrim b
forall b a. (b -> a) -> BoundedPrim a -> BoundedPrim b
contramapB -- | Type-constructors supporting lifting of type-products.classMonoidal f wherepair ::f a ->f b ->f (a ,b )instanceMonoidal FixedPrim wherepair :: forall a b. FixedPrim a -> FixedPrim b -> FixedPrim (a, b)
pair =FixedPrim a -> FixedPrim b -> FixedPrim (a, b)
forall a b. FixedPrim a -> FixedPrim b -> FixedPrim (a, b)
pairF instanceMonoidal BoundedPrim wherepair :: forall a b. BoundedPrim a -> BoundedPrim b -> BoundedPrim (a, b)
pair =BoundedPrim a -> BoundedPrim b -> BoundedPrim (a, b)
forall a b. BoundedPrim a -> BoundedPrim b -> BoundedPrim (a, b)
pairB infixr5>*< -- | A pairing/concatenation operator for builder primitives, both bounded and-- fixed size.---- For example,---- > toLazyByteString (primFixed (char7 >*< char7) ('x','y')) = "xy"---- We can combine multiple primitives using '>*<' multiple times.---- > toLazyByteString (primFixed (char7 >*< char7 >*< char7) ('x',('y','z'))) = "xyz"--(>*<) ::Monoidal f =>f a ->f b ->f (a ,b )>*< :: forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
(>*<) =f a -> f b -> f (a, b)
forall a b. f a -> f b -> f (a, b)
forall (f :: * -> *) a b. Monoidal f => f a -> f b -> f (a, b)
pair -- | The type used for sizes and sizeBounds of sizes.typeSize =Int-------------------------------------------------------------------------------- Fixed-size builder primitives-------------------------------------------------------------------------------- | A builder primitive that always results in a sequence of bytes of a-- pre-determined, fixed size.dataFixedPrim a =FP {-# UNPACK#-}!Int(a ->PtrWord8->IO())fixedPrim ::Int->(a ->PtrWord8->IO())->FixedPrim a fixedPrim :: forall a. Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
fixedPrim =Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
forall a. Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
FP -- | The size of the sequences of bytes generated by this 'FixedPrim'.{-# INLINE CONLIKEsize #-}size ::FixedPrim a ->Intsize :: forall a. FixedPrim a -> Int
size (FP Int
l a -> Ptr Word8 -> IO ()
_)=Int
l {-# INLINE CONLIKErunF #-}runF ::FixedPrim a ->a ->PtrWord8->IO()runF :: forall a. FixedPrim a -> a -> Ptr Word8 -> IO ()
runF (FP Int
_a -> Ptr Word8 -> IO ()
io )=a -> Ptr Word8 -> IO ()
io -- | The 'FixedPrim' that always results in the zero-length sequence.{-# INLINE CONLIKEemptyF #-}emptyF ::FixedPrim a emptyF :: forall a. FixedPrim a
emptyF =Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
forall a. Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
FP Int
0(\a
_Ptr Word8
_->() -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return())-- | Encode a pair by encoding its first component and then its second component.{-# INLINE CONLIKEpairF #-}pairF ::FixedPrim a ->FixedPrim b ->FixedPrim (a ,b )pairF :: forall a b. FixedPrim a -> FixedPrim b -> FixedPrim (a, b)
pairF (FP Int
l1 a -> Ptr Word8 -> IO ()
io1 )(FP Int
l2 b -> Ptr Word8 -> IO ()
io2 )=Int -> ((a, b) -> Ptr Word8 -> IO ()) -> FixedPrim (a, b)
forall a. Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
FP (Int
l1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
l2 )(\(a
x1 ,b
x2 )Ptr Word8
op ->a -> Ptr Word8 -> IO ()
io1 a
x1 Ptr Word8
op IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>b -> Ptr Word8 -> IO ()
io2 b
x2 (Ptr Word8
op Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr`Int
l1 ))-- | Change a primitives such that it first applies a function to the value-- to be encoded.---- Note that primitives are 'Contravariant'-- <http://hackage.haskell.org/package/contravariant>. Hence, the following-- laws hold.---- >contramapF id = id-- >contramapF f . contramapF g = contramapF (g . f){-# INLINE CONLIKEcontramapF #-}contramapF ::(b ->a )->FixedPrim a ->FixedPrim b contramapF :: forall b a. (b -> a) -> FixedPrim a -> FixedPrim b
contramapF b -> a
f (FP Int
l a -> Ptr Word8 -> IO ()
io )=Int -> (b -> Ptr Word8 -> IO ()) -> FixedPrim b
forall a. Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
FP Int
l (a -> Ptr Word8 -> IO ()
io (a -> Ptr Word8 -> IO ()) -> (b -> a) -> b -> Ptr Word8 -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.b -> a
f )-- | Convert a 'FixedPrim' to a 'BoundedPrim'.{-# INLINE CONLIKEtoB #-}toB ::FixedPrim a ->BoundedPrim a toB :: forall a. FixedPrim a -> BoundedPrim a
toB (FP Int
l a -> Ptr Word8 -> IO ()
io )=Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
BP Int
l (\a
x Ptr Word8
op ->a -> Ptr Word8 -> IO ()
io a
x Ptr Word8
op IO () -> IO (Ptr Word8) -> IO (Ptr Word8)
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>(Ptr Word8 -> IO (Ptr Word8)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return(Ptr Word8 -> IO (Ptr Word8)) -> Ptr Word8 -> IO (Ptr Word8)
forall a b. (a -> b) -> a -> b
$!Ptr Word8
op Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr`Int
l ))-- | Lift a 'FixedPrim' to a 'BoundedPrim'.{-# INLINE CONLIKEliftFixedToBounded #-}liftFixedToBounded ::FixedPrim a ->BoundedPrim a liftFixedToBounded :: forall a. FixedPrim a -> BoundedPrim a
liftFixedToBounded =FixedPrim a -> BoundedPrim a
forall a. FixedPrim a -> BoundedPrim a
toB {-# INLINE CONLIKEstorableToF #-}{-# DEPRECATEDstorableToF"Deprecated since @bytestring-0.12.1.0@.\n\nThis function is dangerous in the presence of internal padding\nand makes naive assumptions about alignment.\n\n * For a primitive Haskell type like 'Int64', use the\n corresponding primitive like 'Data.ByteString.Builder.Prim.int64Host'.\n * For other types, it is recommended to manually write a small\n function that performs the necessary unaligned write\n and zeroes or removes any internal padding bits."#-}storableToF ::foralla .Storablea =>FixedPrim a 
#if HS_UNALIGNED_POKES_OK
storableToF :: forall a. Storable a => FixedPrim a
storableToF =Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
forall a. Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
FP (a -> Int
forall a. Storable a => a -> Int
sizeOf(a
forall a. HasCallStack => a
undefined::a ))(\a
x Ptr Word8
op ->Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke(Ptr Word8 -> Ptr a
forall a b. Ptr a -> Ptr b
castPtrPtr Word8
op )a
x )
#else
storableToF=FP(sizeOf(undefined::a))$\xop->ifptrToWordPtrop`mod`fromIntegral(alignment(undefined::a))==0thenpoke(castPtrop)xelsewithx$\tp->copyBytesop(castPtrtp)(sizeOf(undefined::a))
#endif
{-
{-# INLINE CONLIKE liftIOF #-}
liftIOF :: FixedPrim a -> FixedPrim (IO a)
liftIOF (FP l io) = FP l (\xWrapped op -> do x <- xWrapped; io x op)
-}-------------------------------------------------------------------------------- Bounded-size builder primitives-------------------------------------------------------------------------------- | A builder primitive that always results in sequence of bytes that is no longer-- than a pre-determined bound.dataBoundedPrim a =BP {-# UNPACK#-}!Int(a ->PtrWord8->IO(PtrWord8))-- | The bound on the size of sequences of bytes generated by this 'BoundedPrim'.{-# INLINE CONLIKEsizeBound #-}sizeBound ::BoundedPrim a ->IntsizeBound :: forall a. BoundedPrim a -> Int
sizeBound (BP Int
b a -> Ptr Word8 -> IO (Ptr Word8)
_)=Int
b -- | @since 0.10.12.0boundedPrim ::Int->(a ->PtrWord8->IO(PtrWord8))->BoundedPrim a boundedPrim :: forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
boundedPrim =Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
BP {-# DEPRECATEDboudedPrim"Use 'boundedPrim' instead"#-}boudedPrim ::Int->(a ->PtrWord8->IO(PtrWord8))->BoundedPrim a boudedPrim :: forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
boudedPrim =Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
BP {-# INLINE CONLIKErunB #-}runB ::BoundedPrim a ->a ->PtrWord8->IO(PtrWord8)runB :: forall a. BoundedPrim a -> a -> Ptr Word8 -> IO (Ptr Word8)
runB (BP Int
_a -> Ptr Word8 -> IO (Ptr Word8)
io )=a -> Ptr Word8 -> IO (Ptr Word8)
io -- | Change a 'BoundedPrim' such that it first applies a function to the-- value to be encoded.---- Note that 'BoundedPrim's are 'Contravariant'-- <http://hackage.haskell.org/package/contravariant>. Hence, the following-- laws hold.---- >contramapB id = id-- >contramapB f . contramapB g = contramapB (g . f){-# INLINE CONLIKEcontramapB #-}contramapB ::(b ->a )->BoundedPrim a ->BoundedPrim b contramapB :: forall b a. (b -> a) -> BoundedPrim a -> BoundedPrim b
contramapB b -> a
f (BP Int
b a -> Ptr Word8 -> IO (Ptr Word8)
io )=Int -> (b -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim b
forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
BP Int
b (a -> Ptr Word8 -> IO (Ptr Word8)
io (a -> Ptr Word8 -> IO (Ptr Word8))
-> (b -> a) -> b -> Ptr Word8 -> IO (Ptr Word8)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.b -> a
f )-- | The 'BoundedPrim' that always results in the zero-length sequence.{-# INLINE CONLIKEemptyB #-}emptyB ::BoundedPrim a emptyB :: forall a. BoundedPrim a
emptyB =Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
BP Int
0(\a
_Ptr Word8
op ->Ptr Word8 -> IO (Ptr Word8)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
returnPtr Word8
op )-- | Encode a pair by encoding its first component and then its second component.{-# INLINE CONLIKEpairB #-}pairB ::BoundedPrim a ->BoundedPrim b ->BoundedPrim (a ,b )pairB :: forall a b. BoundedPrim a -> BoundedPrim b -> BoundedPrim (a, b)
pairB (BP Int
b1 a -> Ptr Word8 -> IO (Ptr Word8)
io1 )(BP Int
b2 b -> Ptr Word8 -> IO (Ptr Word8)
io2 )=Int
-> ((a, b) -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim (a, b)
forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
BP (Int
b1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
b2 )(\(a
x1 ,b
x2 )Ptr Word8
op ->a -> Ptr Word8 -> IO (Ptr Word8)
io1 a
x1 Ptr Word8
op IO (Ptr Word8) -> (Ptr Word8 -> IO (Ptr Word8)) -> IO (Ptr Word8)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=b -> Ptr Word8 -> IO (Ptr Word8)
io2 b
x2 )-- | Encode an 'Either' value using the first 'BoundedPrim' for 'Left'-- values and the second 'BoundedPrim' for 'Right' values.---- Note that the functions 'eitherB', 'pairB', and 'contramapB' (written below-- using '>$<') suffice to construct 'BoundedPrim's for all non-recursive-- algebraic datatypes. For example,---- @--maybeB :: BoundedPrim () -> BoundedPrim a -> BoundedPrim (Maybe a)--maybeB nothing just = 'maybe' (Left ()) Right '>$<' eitherB nothing just-- @{-# INLINE CONLIKEeitherB #-}eitherB ::BoundedPrim a ->BoundedPrim b ->BoundedPrim (Eithera b )eitherB :: forall a b.
BoundedPrim a -> BoundedPrim b -> BoundedPrim (Either a b)
eitherB (BP Int
b1 a -> Ptr Word8 -> IO (Ptr Word8)
io1 )(BP Int
b2 b -> Ptr Word8 -> IO (Ptr Word8)
io2 )=Int
-> (Either a b -> Ptr Word8 -> IO (Ptr Word8))
-> BoundedPrim (Either a b)
forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
BP (Int -> Int -> Int
forall a. Ord a => a -> a -> a
maxInt
b1 Int
b2 )(\Either a b
x Ptr Word8
op ->caseEither a b
x ofLefta
x1 ->a -> Ptr Word8 -> IO (Ptr Word8)
io1 a
x1 Ptr Word8
op ;Rightb
x2 ->b -> Ptr Word8 -> IO (Ptr Word8)
io2 b
x2 Ptr Word8
op )-- | Conditionally select a 'BoundedPrim'.-- For example, we can implement the ASCII primitive that drops characters with-- Unicode codepoints above 127 as follows.---- @--charASCIIDrop = 'condB' (< \'\128円\') ('liftFixedToBounded' 'Data.ByteString.Builder.Prim.char7') 'emptyB'-- @{-# INLINE CONLIKEcondB #-}condB ::(a ->Bool)->BoundedPrim a ->BoundedPrim a ->BoundedPrim a condB :: forall a.
(a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
condB a -> Bool
p BoundedPrim a
be1 BoundedPrim a
be2 =(a -> Either a a) -> BoundedPrim (Either a a) -> BoundedPrim a
forall b a. (b -> a) -> BoundedPrim a -> BoundedPrim b
contramapB (\a
x ->ifa -> Bool
p a
x thena -> Either a a
forall a b. a -> Either a b
Lefta
x elsea -> Either a a
forall a b. b -> Either a b
Righta
x )(BoundedPrim a -> BoundedPrim a -> BoundedPrim (Either a a)
forall a b.
BoundedPrim a -> BoundedPrim b -> BoundedPrim (Either a b)
eitherB BoundedPrim a
be1 BoundedPrim a
be2 )-- | Select an implementation depending on bitness.-- Throw a compile time error if bitness is neither 32 nor 64.{-# INLINEcaseWordSize_32_64 #-}caseWordSize_32_64 ::a -- Value for 32-bit architecture->a -- Value for 64-bit architecture->a 
#if WORD_SIZE_IN_BITS == 32
caseWordSize_32_64=const
#endif
#if WORD_SIZE_IN_BITS == 64
caseWordSize_32_64 :: forall a. a -> a -> a
caseWordSize_32_64 =(a -> a) -> a -> a -> a
forall a b. a -> b -> a
consta -> a
forall a. a -> a
id
#endif

AltStyle によって変換されたページ (->オリジナル) /