Skip to main content

IoBufMut

Trait IoBufMut 

pub unsafe trait IoBufMut: IoBuf + SetLen {
    // Required methods
    fn as_mut_slice(&mut self) -> &mut [u8] ⓘ;
    fn spare_mut(&mut self) -> &mut [MaybeUninit<u8>];

    // Provided methods
    fn buf_capacity(&mut self) -> usize { ... }
    fn uninit(self) -> Uninit<Self>
       where Self: Sized { ... }
}
Available on crate feature std only.
Expand description

An IoBuf that can also be written into (i.e. used as a read destination).

The backing storage S is the initialized prefix S[..buf_len] followed by the writable, possibly uninitialized spare S[buf_len..]. Safe access is split along that line, so safe code cannot write uninitialized bytes over the prefix: as_mut_slice for the prefix, spare_mut for the spare.

A backend that reads from offset 0 first calls set_len(0), which makes the spare all of S; a kernel read target uses spare_mut()’s pointer and length.

ⓘ
use core::mem::MaybeUninit;
use rama_core::io::IoBufMut;

// There is no safe whole-storage view to de-initialize the prefix through.
fn deinit(b: &mut impl IoBufMut) {
    b.as_uninit()[0] = MaybeUninit::uninit();
}

§Safety

Implementors must ensure that the value has one backing storage S, with the address stability contract of IoBuf, such that while the value is used only through this trait and its supertraits:

  1. S[..buf_len()] is initialized; as_init and as_mut_slice return that range of S, and spare_mut returns S[buf_len()..] (views of S, not copies).
  2. set_len(n), called within its contract, makes buf_len() return n and leaves the bytes of S unchanged.
  3. No other method changes buf_len(), the address of S, or its length.

Required Methods§

fn as_mut_slice(&mut self) -> &mut [u8] ⓘ

The initialized region [0, buf_len) as a mutable slice, for an in-place transform (e.g. decrypting a TLS record inside the very buffer it arrived in, no copy).

fn spare_mut(&mut self) -> &mut [MaybeUninit<u8>]

The writable spare tail [buf_len, capacity): the read destination.

Provided Methods§

fn buf_capacity(&mut self) -> usize

Total capacity (buf_len() + spare_mut().len()).

fn uninit(self) -> Uninit<Self>
where Self: Sized,

A read-target view of just the writable spare [buf_len, capacity).

Reading into it appends to self (the view’s offset 0 is self’s buf_len), so it’s how you accumulate on top of the overwrite-from-0 read primitive, e.g. read_exact loops read_owned(buf.uninit()). The owned analogue of compio’s Uninit.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

§

impl IoBufMut for BytesMut

§

impl IoBufMut for Vec<u8>

§

impl<B> IoBufMut for Uninit<B>
where B: IoBufMut,

§

impl<const N: usize> IoBufMut for ArrayBuf<N>