Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- data PinnedSizedBytes (n :: Nat )
- psbZero :: KnownNat n => PinnedSizedBytes n
- psbFromBytes :: forall n. KnownNat n => [ Word8 ] -> PinnedSizedBytes n
- psbToBytes :: PinnedSizedBytes n -> [ Word8 ]
- psbFromByteString :: KnownNat n => ByteString -> PinnedSizedBytes n
- psbFromByteStringCheck :: forall n. KnownNat n => ByteString -> Maybe ( PinnedSizedBytes n)
- psbToByteString :: PinnedSizedBytes n -> ByteString
- psbUseAsCPtr :: forall (n :: Nat ) (r :: Type ). PinnedSizedBytes n -> ( Ptr Word8 -> IO r) -> IO r
- psbUseAsCPtrLen :: forall (n :: Nat ) (r :: Type ). KnownNat n => PinnedSizedBytes n -> ( Ptr Word8 -> CSize -> IO r) -> IO r
- psbUseAsSizedPtr :: forall (n :: Nat ) (r :: Type ). PinnedSizedBytes n -> ( SizedPtr n -> IO r) -> IO r
- psbCreate :: forall (n :: Nat ). KnownNat n => ( Ptr Word8 -> IO ()) -> IO ( PinnedSizedBytes n)
- psbCreateLen :: forall (n :: Nat ). KnownNat n => ( Ptr Word8 -> CSize -> IO ()) -> IO ( PinnedSizedBytes n)
- psbCreateSized :: forall (n :: Nat ). KnownNat n => ( SizedPtr n -> IO ()) -> IO ( PinnedSizedBytes n)
- psbCreateResult :: forall (n :: Nat ) (r :: Type ). KnownNat n => ( Ptr Word8 -> IO r) -> IO ( PinnedSizedBytes n, r)
- psbCreateResultLen :: forall (n :: Nat ) (r :: Type ). KnownNat n => ( Ptr Word8 -> CSize -> IO r) -> IO ( PinnedSizedBytes n, r)
- psbCreateSizedResult :: forall (n :: Nat ) (r :: Type ). KnownNat n => ( SizedPtr n -> IO r) -> IO ( PinnedSizedBytes n, r)
- ptrPsbToSizedPtr :: Ptr ( PinnedSizedBytes n) -> SizedPtr n
Documentation
data PinnedSizedBytes (n :: Nat ) Source #
n
bytes.
Storable
.
We have two
*Bytes
types:
-
PinnedSizedBytes
is backed by pinned ByteArray. -
MLockedSizedBytes
is backed by ForeignPtr tomlock
-ed memory region.
The
ByteString
is pinned datatype, but it's represented by
ForeignPtr
+ offset (and size).
I'm sorry for adding more types for bytes. :(
Instances
Initialization
psbZero :: KnownNat n => PinnedSizedBytes n Source #
Deprecated: This is not referentially transparent
Conversions
psbFromBytes :: forall n. KnownNat n => [ Word8 ] -> PinnedSizedBytes n Source #
Deprecated: This is not referentially transparent
See
instance.
IsString
(
PinnedSizedBytes
n)
>>>
psbToBytes . (id @(PinnedSizedBytes 4)) . psbFromBytes $ [1,2,3,4]
[1,2,3,4]
>>>
psbToBytes . (id @(PinnedSizedBytes 4)) . psbFromBytes $ [1,2]
[0,0,1,2]
>>>
psbToBytes . (id @(PinnedSizedBytes 4)) . psbFromBytes $ [1,2,3,4,5,6]
[3,4,5,6]
psbToBytes :: PinnedSizedBytes n -> [ Word8 ] Source #
See
psbFromBytes
.
psbFromByteString :: KnownNat n => ByteString -> PinnedSizedBytes n Source #
psbFromByteStringCheck :: forall n. KnownNat n => ByteString -> Maybe ( PinnedSizedBytes n) Source #
psbToByteString :: PinnedSizedBytes n -> ByteString Source #
C usage
psbUseAsCPtr :: forall (n :: Nat ) (r :: Type ). PinnedSizedBytes n -> ( Ptr Word8 -> IO r) -> IO r Source #
Use a
PinnedSizedBytes
in a setting where its size is 'forgotten'
temporarily.
Note
The
Ptr
given to the function argument
must not
be used as the result of
type
r
.
psbUseAsCPtrLen :: forall (n :: Nat ) (r :: Type ). KnownNat n => PinnedSizedBytes n -> ( Ptr Word8 -> CSize -> IO r) -> IO r Source #
As
psbUseAsCPtr
, but also gives the function argument the size we are
allowed to use as a
CSize
.
This is mostly boilerplate removal, as it is quite common for C APIs to take
a combination of a pointer to some data and its length. A possible use case
(and one we run into) is where we know that we can expect a certain data
length (using
PinnedSizedBytes
as its representation), but the C API allows
any length we like, provided we give the right argument to indicate this.
Therefore, having a helper like this one allows us to avoid having to
manually
natVal
a
Proxy
, as well as ensuring we don't get mismatches
accidentally.
The same caveats apply to the use of this function as to the use of
psbUseAsCPtr
.
psbUseAsSizedPtr :: forall (n :: Nat ) (r :: Type ). PinnedSizedBytes n -> ( SizedPtr n -> IO r) -> IO r Source #
As
psbUseAsCPtr
, but does not 'forget' the size.
The same caveats apply to this use of this function as to the use of
psbUseAsCPtr
.
psbCreate :: forall (n :: Nat ). KnownNat n => ( Ptr Word8 -> IO ()) -> IO ( PinnedSizedBytes n) Source #
As
psbCreateResult
, but presumes that no useful value is produced: that
is, the function argument is run only for its side effects.
psbCreateLen :: forall (n :: Nat ). KnownNat n => ( Ptr Word8 -> CSize -> IO ()) -> IO ( PinnedSizedBytes n) Source #
As
psbCreateResultLen
, but presumes that no useful value is produced:
that is, the function argument is run only for its side effects.
psbCreateSized :: forall (n :: Nat ). KnownNat n => ( SizedPtr n -> IO ()) -> IO ( PinnedSizedBytes n) Source #
As
psbCreateSizedResult
, but presumes that no useful value is produced:
that is, the function argument is run only for its side effects.
psbCreateResult :: forall (n :: Nat ) (r :: Type ). KnownNat n => ( Ptr Word8 -> IO r) -> IO ( PinnedSizedBytes n, r) Source #
Given an 'initialization action', which also produces some result, allocate
new pinned memory of the specified size, perform the action, then return the
result together with the initialized pinned memory (as a
PinnedSizedBytes
).
Note
It is essential that
r
is not the
Ptr
given to the function argument.
Returning this
Ptr
is
extremely
unsafe:
- It breaks referential transparency guarantees by aliasing supposedly immutable memory; and
-
This
Ptr
could refer to memory which has already been garbage collected, which can lead to segfaults or out-of-bounds reads.
This poses both correctness and security risks, so please don't do it.
psbCreateResultLen :: forall (n :: Nat ) (r :: Type ). KnownNat n => ( Ptr Word8 -> CSize -> IO r) -> IO ( PinnedSizedBytes n, r) Source #
As
psbCreateResult
, but also gives the number of bytes we are allowed to
operate on as a
CSize
.
This function is provided for two reasons:
- It is a common practice in C libraries to pass a pointer to data plus a length. While our use case might know the size we expect, the C function we are calling might be more general. This simplifies calling such functions.
-
We avoid
natVal
ing aProxy
twice , since we have to do it anyway.
The same caveats apply to this function as to
psbCreateResult
: the
Ptr
given to the function argument
must not
be returned as
r
.
psbCreateSizedResult :: forall (n :: Nat ) (r :: Type ). KnownNat n => ( SizedPtr n -> IO r) -> IO ( PinnedSizedBytes n, r) Source #
As
psbCreateResult
, but gives a
SizedPtr
to the function argument. The
same caveats apply to this function as to
psbCreateResult
: the
SizedPtr
given to the function argument
must not
be resulted as
r
.
ptrPsbToSizedPtr :: Ptr ( PinnedSizedBytes n) -> SizedPtr n Source #