#[repr(C)]
pub struct RustBuffer { capacity: u64, len: u64, data: *mut u8, }
Expand description

Support for passing an allocated-by-Rust buffer of bytes over the FFI.

We can pass a Vec<u8> to foreign language code by decomposing it into its raw parts (buffer pointer, length, and capacity) and passing those around as a struct. Naturally, this can be tremendously unsafe! So here are the details:

  • RustBuffer structs must only ever be constructed from a Vec<u8>, either explicitly via RustBuffer::from_vec or indirectly by calling one of the RustBuffer::new* constructors.

  • RustBuffer structs do not implement Drop, since they are intended to be passed to foreign-language code outside of the control of Rust’s ownership system. To avoid memory leaks they must passed back into Rust and either explicitly destroyed using RustBuffer::destroy, or converted back to a Vec<u8> using RustBuffer::destroy_into_vec (which will then be dropped via Rust’s usual ownership-tracking system).

Foreign-language code should not construct RustBuffer structs other than by receiving them from a call into the Rust code, and should not modify them apart from the following safe operations:

  • Writing bytes into the buffer pointed to by data, without writing beyond the indicated capacity.

  • Adjusting the len property to indicate the amount of data written, while ensuring that 0 <= len <= capacity.

  • As a special case, constructing a RustBuffer with zero capacity, zero length, and a null data pointer to indicate an empty buffer.

In particular, it is not safe for foreign-language code to construct a RustBuffer that points to its own allocated memory; use the ForeignBytes struct to pass a view of foreign-owned memory in to Rust code.

Implementation note: all the fields of this struct are private, so you can’t manually construct instances that don’t come from a Vec<u8>. If you’ve got a RustBuffer then it either came from a public constructor (all of which are safe) or it came from foreign-language code (which should have in turn received it by calling some Rust function, and should be respecting the invariants listed above).

This struct is based on ByteBuffer from the ffi-support crate, but modified to retain unallocated capacity rather than truncating to the occupied length.

Fields§

§capacity: u64§len: u64§data: *mut u8

Implementations§

§

impl RustBuffer

pub fn new() -> RustBuffer

Creates an empty RustBuffer.

The buffer will not allocate. The resulting vector will not be automatically dropped; you must arrange to call destroy or destroy_into_vec when finished with it.

pub unsafe fn from_raw_parts( data: *mut u8, len: u64, capacity: u64 ) -> RustBuffer

Creates a RustBuffer from its constituent fields.

This is intended mainly as an internal convenience function and should not be used outside of this module.

Safety

You must ensure that the raw parts uphold the documented invariants of this class.

pub fn len(&self) -> usize

Get the current length of the buffer, as a usize.

This is mostly a helper function to convert the i32 length field into a usize, which is what Rust code usually expects.

Panics

Panics if called on an invalid struct obtained from foreign-language code, in which the len field is negative.

pub fn data_pointer(&self) -> *const u8

Get a pointer to the data

pub fn is_empty(&self) -> bool

Returns true if the length of the buffer is 0.

pub fn new_with_size(size: u64) -> RustBuffer

Creates a RustBuffer zero-filed to the requested size.

The resulting vector will not be automatically dropped; you must arrange to call destroy or destroy_into_vec when finished with it.

Panics

Panics if the requested size is too large to fit in an i32, and hence would risk incompatibility with some foreign-language code.

pub fn from_vec(v: Vec<u8, Global>) -> RustBuffer

Consumes a Vec<u8> and returns its raw parts as a RustBuffer.

The resulting vector will not be automatically dropped; you must arrange to call destroy or destroy_into_vec when finished with it.

Panics

Panics if the vector’s length or capacity are too large to fit in an i32, and hence would risk incompatibility with some foreign-language code.

pub fn destroy_into_vec(self) -> Vec<u8, Global>

Converts this RustBuffer back into an owned Vec<u8>.

This restores ownership of the underlying buffer to Rust, meaning it will be dropped when the Vec<u8> is dropped. The RustBuffer must have been previously obtained from a valid Vec<u8> owned by this Rust code.

Panics

Panics if called on an invalid struct obtained from foreign-language code, which does not respect the invairiants on len and capacity.

pub fn destroy(self)

Reclaim memory stored in this RustBuffer.

Panics

Panics if called on an invalid struct obtained from foreign-language code, which does not respect the invairiants on len and capacity.

Trait Implementations§

§

impl Debug for RustBuffer

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for RustBuffer

§

fn default() -> RustBuffer

Returns the “default value” for a type. Read more
§

impl FfiDefault for RustBuffer

§

impl Send for RustBuffer

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.