Copyright | 2010-2011 Simon Meier 2010 Jasper van der Jeugt |
---|---|

License | BSD3-style (see LICENSE) |

Maintainer | Simon Meier <[email protected]> |

Stability | unstable, private |

Portability | GHC |

Safe Haskell | Unsafe |

Language | Haskell98 |

- 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 saftey 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.

The type used for sizes and sizeBounds of sizes.

A builder primitive that always results in a sequence of bytes of a pre-determined, fixed size.

fixedPrim :: Int -> (a -> Ptr Word8 -> IO ()) -> FixedPrim a Source

size :: FixedPrim a -> Int Source

The size of the sequences of bytes generated by this `FixedPrim`

.

runF :: FixedPrim a -> a -> Ptr Word8 -> IO () Source

The `FixedPrim`

that always results in the zero-length sequence.

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 `Contrafunctors`

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

data BoundedPrim a Source

A builder primitive that always results in sequence of bytes that is no longer than a pre-determined bound.

boudedPrim :: Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a Source

sizeBound :: BoundedPrim a -> Int Source

The bound on the size of sequences of bytes generated by this `BoundedPrim`

.

runB :: BoundedPrim a -> a -> Ptr Word8 -> IO (Ptr Word8) Source

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 `Contrafunctors`

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') (fromF 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`

.

(>$<) :: 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.

showEncoding ((\x -> ('\'', (x, '\''))) >$< fixed3) 'x' = "'x'" where fixed3 = char7 >*< char7 >*< 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"

© The University of Glasgow and others

Licensed under a BSD-style license (see top of the page).

https://downloads.haskell.org/~ghc/8.8.3/docs/html/libraries/bytestring-0.10.10.0/Data-ByteString-Builder-Prim-Internal.html