[][src]Struct ffi_support::ByteBuffer

#[repr(C)]
pub struct ByteBuffer { /* fields omitted */ }

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 i64) then data (a *mut u8), getting this wrong on the other side of the FFI will cause memory corruption and crashes. i64 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 alling 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: i64, 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.

Methods

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

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

pub fn into_vec(self) -> Vec<u8>[src]

Convert this ByteBuffer into a Vec. This is the only way to access the data from inside the buffer.

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 IntoFfi for ByteBuffer[src]

type Value = ByteBuffer

This type must be: Read more

impl Default for ByteBuffer[src]

impl From<Vec<u8>> for ByteBuffer[src]

Auto Trait Implementations

impl !Send for ByteBuffer

impl !Sync for ByteBuffer

Blanket Implementations

impl<T> From for T[src]

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]