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 |
Safe Haskell | Unsafe |
Language | Haskell2010 |
- 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.
Synopsis
- type Size = Int
- data FixedPrim a
- fixedPrim :: Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a
- size :: FixedPrim a -> Int
- runF :: FixedPrim a -> a -> Ptr Word8 -> IO ()
- emptyF :: FixedPrim a
- contramapF :: (b -> a) -> FixedPrim a -> FixedPrim b
- pairF :: FixedPrim a -> FixedPrim b -> FixedPrim (a, b)
- storableToF :: forall a. Storable a => FixedPrim a
- data BoundedPrim a
- boundedPrim :: Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
- sizeBound :: BoundedPrim a -> Int
- runB :: BoundedPrim a -> a -> Ptr Word8 -> IO (Ptr Word8)
- emptyB :: BoundedPrim a
- contramapB :: (b -> a) -> BoundedPrim a -> BoundedPrim b
- pairB :: BoundedPrim a -> BoundedPrim b -> BoundedPrim (a, b)
- eitherB :: BoundedPrim a -> BoundedPrim b -> BoundedPrim (Either a b)
- condB :: (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a
- toB :: FixedPrim a -> BoundedPrim a
- liftFixedToBounded :: FixedPrim a -> BoundedPrim a
- (>$<) :: Contravariant f => (b -> a) -> f a -> f b
- (>*<) :: Monoidal f => f a -> f b -> f (a, b)
- caseWordSize_32_64 :: a -> a -> a
- boudedPrim :: Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
Fixed-size builder primitives
A builder primitive that always results in a sequence of bytes of a pre-determined, fixed size.
contramapF :: (b -> a) -> FixedPrim a -> FixedPrim b Source #
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)
pairF :: FixedPrim a -> FixedPrim b -> FixedPrim (a, b) Source #
Encode a pair by encoding its first component and then its second component.
storableToF :: forall a. Storable a => FixedPrim a Source #
Deprecated: Deprecated since bytestring-0.12.1.0
.
This function is dangerous in the presence of internal padding
and makes naive assumptions about alignment.
* For a primitive Haskell type like Int64
, use the
corresponding primitive like int64Host
.
* For other types, it is recommended to manually write a small
function that performs the necessary unaligned write
and zeroes or removes any internal padding bits.
Bounded-size builder primitives
data BoundedPrim a Source #
A builder primitive that always results in sequence of bytes that is no longer than a pre-determined bound.
boundedPrim :: Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a Source #
Since: 0.10.12.0
sizeBound :: BoundedPrim a -> Int Source #
The bound on the size of sequences of bytes generated by this BoundedPrim
.
emptyB :: BoundedPrim a Source #
The BoundedPrim
that always results in the zero-length sequence.
contramapB :: (b -> a) -> BoundedPrim a -> BoundedPrim b Source #
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)
pairB :: BoundedPrim a -> BoundedPrim b -> BoundedPrim (a, b) Source #
Encode a pair by encoding its first component and then its second component.
eitherB :: BoundedPrim a -> BoundedPrim b -> BoundedPrim (Either a b) Source #
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
condB :: (a -> Bool) -> BoundedPrim a -> BoundedPrim a -> BoundedPrim a Source #
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
char7
)emptyB
toB :: FixedPrim a -> BoundedPrim a Source #
Convert a FixedPrim
to a BoundedPrim
.
liftFixedToBounded :: FixedPrim a -> BoundedPrim a Source #
Lift a FixedPrim
to a BoundedPrim
.
Shared operators
(>$<) :: Contravariant f => (b -> a) -> f a -> f b infixl 4 Source #
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.
(>*<) :: Monoidal f => f a -> f b -> f (a, b) infixr 5 Source #
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"
Helpers
caseWordSize_32_64 :: a -> a -> a Source #
Select an implementation depending on bitness. Throw a compile time error if bitness is neither 32 nor 64.
Deprecated
boudedPrim :: Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a Source #
Deprecated: Use boundedPrim
instead