Safe Haskell | None |
---|---|
Language | GHC2021 |
Synopsis
- type Poke# s = Addr# -> Int# -> State# s -> (# State# s, Int# #)
- newtype Poke s = Poke {}
- unsafeRunPokeBS :: Int -> Poke RealWorld -> ByteString
- unsafeRunPokeBSUptoN :: Int -> Poke RealWorld -> ByteString
- unsafeRunPoke :: MonadPrim s m => Poke s -> Ptr Word8 -> m Int
- prim :: Prim' a => a -> Poke s
- byteString :: ByteString -> Poke RealWorld
- byteArray# :: ByteArray# -> Int# -> Int# -> Poke s
- replicateByte :: Int -> Word8 -> Poke RealWorld
- fromStructPoke :: Int -> Poke s -> Poke s
- toStructPoke :: Poke s -> Poke s
Documentation
= Addr# | buffer pointer |
-> Int# | buffer offset |
-> State# s | state token |
-> (# State# s, Int# #) | (state token, next offset) |
Unboxed buffer write operation.
The next offset must be greater than or equal to the input buffer offset. This is not checked.
Note that the only way to find out the length of a write is to perform it. But
you can't perform a length without providing a correctly-sized buffer. Thus, you
may only use a Poke#
when you have a buffer large enough to fit its maximum
write length-- which in turn means means you must track write lengths
separately. (Write
does this.)
I provide this highly unsafe, seemingly unhelpful type because it's a
requirement for Write
, and here I can guarantee performance
better because I don't need to worry about laziness.
We cannot be polymorphic on the pointer type unless we box the pointer.
We thus limit ourselves to writing to Addr#
s, and not MutableByteArray#
s.
(I figure we're most interested in ByteString
s, which use Addr#
.)
Note that if we did provide write length, then the next offset might appear superfluous. But that next offset is usually already calculated, and may be passed directly to sequenced writes, unlike if we returned a write length which would need to be added to the original offset.
Poke newtype wrapper.
unsafeRunPokeBS :: Int -> Poke RealWorld -> ByteString Source #
Execute a Poke
at a fresh ByteString
of the given length.
unsafeRunPokeBSUptoN :: Int -> Poke RealWorld -> ByteString Source #
Execute a Poke
at a fresh ByteString
of the given maximum length.
Does not reallocate if final size is less than estimated.
unsafeRunPoke :: MonadPrim s m => Poke s -> Ptr Word8 -> m Int Source #
Execute a Poke
at a pointer. Returns the number of bytes written.
The pointer must be a mutable buffer with enough space to hold the poke. Absolutely none of this is checked. Use with caution. Sensible uses:
- implementing pokes to ByteStrings and the like
- executing known-length (!!) pokes to known-length (!!) buffers e.g. together with allocaBytes
byteString :: ByteString -> Poke RealWorld Source #
byteArray# :: ByteArray# -> Int# -> Int# -> Poke s Source #
fromStructPoke :: Int -> Poke s -> Poke s Source #
Use a struct poke as a regular poke.
To do this, we must associate a constant byte length with an existing poker.
Note that pokers don't expose the type of the data they are serializing,
so this is a very clumsy operation by itself. You should only be using this
when you have such types in scope, and the constant length should be obtained
in a sensible manner (e.g. KnownSizeOf
for generic
struct pokers, or your own constant size class if you're doing funky stuff).
toStructPoke :: Poke s -> Poke s Source #
Use a struct poke as a regular poke by throwing away the return offset.