[−][src]Struct glean_ffi::byte_buffer::ByteBuffer
ByteBuffer is a struct that represents an array of bytes to be sent over the FFI boundaries. There are several cases when you might want to use this, but the primary one for us is for returning protobuf-encoded data to Swift and Java. The type is currently rather limited (implementing almost no functionality), however in the future it may be more expanded.
Caveats
Note that the order of the fields is len
(an i32) then data
(a *mut u8
), getting
this wrong on the other side of the FFI will cause memory corruption and crashes.
i32
is used for the length instead of u64
and usize
because JNA has interop
issues with both these types.
ByteBuffer does not implement Drop. This is intentional. Memory passed into it will
be leaked if it is not explicitly destroyed by calling ByteBuffer::destroy
. This
is because in the future, we may allow it's use for passing data into Rust code.
ByteBuffer assuming ownership of the data would make this a problem.
Note that calling destroy
manually is not typically needed or recommended,
and instead you should use [define_bytebuffer_destructor!
].
Layout/fields
This struct's field are not pub
(mostly so that we can soundly implement Send
, but also so
that we can verify Rust users are constructing them appropriately), the fields, their types, and
their order are very much a part of the public API of this type. Consumers on the other side
of the FFI will need to know its layout.
If this were a C struct, it would look like
struct ByteBuffer {
int64_t len;
uint8_t *data; // note: nullable
};
In Rust, there are two fields, in this order: len: i32
, and data: *mut u8
.
Description of fields
data
is a pointer to an array of len
bytes. Not that data can be a null pointer and therefore
should be checked.
The bytes array is allocated on the heap and must be freed on it as well. Critically, if there are multiple rust packages using being used in the same application, it must be freed on the same heap that allocated it, or you will corrupt both heaps.
Typically, this object is managed on the other side of the FFI (on the "FFI consumer"), which
means you must expose a function to release the resources of data
which can be done easily
using the [define_bytebuffer_destructor!
] macro provided by this crate.
Implementations
impl ByteBuffer
[src]
pub fn new_with_size(size: usize) -> Self
[src]
Creates a ByteBuffer
of the requested size, zero-filled.
The contents of the vector will not be dropped. Instead, destroy
must
be called later to reclaim this memory or it will be leaked.
Caveats
This will panic if the buffer length (usize
) cannot fit into a i32
.
pub fn from_vec(bytes: Vec<u8>) -> Self
[src]
Creates a ByteBuffer
instance from a Vec
instance.
The contents of the vector will not be dropped. Instead, destroy
must
be called later to reclaim this memory or it will be leaked.
Caveats
This will panic if the buffer length (usize
) cannot fit into a i32
.
pub fn into_vec(self) -> Vec<u8>
[src]
Convert this ByteBuffer
into a Vec
pub fn destroy(self)
[src]
Reclaim memory stored in this ByteBuffer.
You typically should not call this manually, and instead expose a
function that does so via [define_bytebuffer_destructor!
].
Caveats
This is safe so long as the buffer is empty, or the data was allocated
by Rust code, e.g. this is a ByteBuffer created by
ByteBuffer::from_vec
or Default::default
.
If the ByteBuffer were passed into Rust (which you shouldn't do, since
theres no way to see the data in Rust currently), then calling destroy
is fundamentally broken.
Trait Implementations
impl Default for ByteBuffer
[src]
impl From<Vec<u8>> for ByteBuffer
[src]
Auto Trait Implementations
impl RefUnwindSafe for ByteBuffer
impl !Send for ByteBuffer
impl !Sync for ByteBuffer
impl Unpin for ByteBuffer
impl UnwindSafe for ByteBuffer
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,