[][src]Trait uninit::read::ReadIntoUninit

pub unsafe trait ReadIntoUninit: Read {
    fn read_into_uninit<'buf>(
        &mut self,
        buf: Out<'buf, [u8]>
    ) -> Result<&'buf mut [u8]>; fn read_into_uninit_exact<'buf>(
        &mut self,
        buf: Out<'buf, [u8]>
    ) -> Result<&'buf mut [u8]> { ... }
fn chain<R: ReadIntoUninit>(self, next: R) -> Chain<Self, R>
    where
        Self: Sized
, { ... } }
This is supported on feature="std" only.

Trait for a Readable type that can output the bytes read into uninitialised memory.

Safety (to implement) / Guarantees (for users of impl ReadIntoUninit types)

The trait is unsafe (to implement) because it needs to guarantee to users of generic R : ReadIntoUninit code (that may use unsafe code relying on it!) that:

  • if let Ok(init_buf) = self.read_into_uninit(buf), then it must be sound to:

    unsafe {
        buf.get_out_unchecked(.. init_buf.len()).assume_init()
    }
  • if self.read_into_uninit_exact(buf).is_ok(), then it must be sound to: buf.assume_init().

Counterexample

use ::uninit::{prelude::*,
    read::{auto_impl, ReadIntoUninit},
};

pub
struct Evil;

auto_impl! { #[derived_from(ReadIntoUninit)] impl Read for Evil }
unsafe // unsound!
impl ReadIntoUninit for Evil {
    fn read_into_uninit<'buf> (
        self: &'_ mut Self,
        buf: Out<'buf, [u8]>,
    ) -> ::std::io::Result<&'buf mut [u8]>
    {
        Ok(Box::leak(vec![0; buf.len()].into_boxed_slice()))
    }
}

Indeed, with such an impl, the following function could cause UB, when instanced with R = Evil:

use ::uninit::{prelude::*, read::ReadIntoUninit};

fn read_byte<R> (reader: &'_ mut R)
  -> ::std::io::Result<u8>
where
    R : ReadIntoUninit,
{
    let mut byte = MaybeUninit::uninit();
    reader.read_into_uninit_exact(::std::slice::from_mut(&mut byte).as_out())?;
    Ok(unsafe {
        // Safety: Guaranteed by `ReadIntoUninit` contract
        byte.assume_init()
    })
}

Required methods

fn read_into_uninit<'buf>(
    &mut self,
    buf: Out<'buf, [u8]>
) -> Result<&'buf mut [u8]>

This is supported on feature="std" only.

Single attempt to read bytes from Self into buf.

On success, it returns the bytes having been read.

Guarantees (that unsafe code may rely on)

  • if let Ok(init_buf) = self.read_into_uninit(buf), then it is sound to:

    unsafe {
        buf.get_out_unchecked(.. init_buf.len()).assume_init()
    }

This is not guaranteed to read buf.len() bytes, see the docs of .read() for more information.

Loading content...

Provided methods

fn read_into_uninit_exact<'buf>(
    &mut self,
    buf: Out<'buf, [u8]>
) -> Result<&'buf mut [u8]>

This is supported on feature="std" only.

Attempts to fill buf through multiple .read() calls if necessary.

On success, it returns the bytes having been read.

Guarantees (that unsafe code may rely on)

  • if self.read_into_uninit_exact(buf).is_ok(), then it is sound to: buf.assume_init().

See the docs of .read_exact() for more information.

Important traits for Chain<R1, R2>
fn chain<R: ReadIntoUninit>(self, next: R) -> Chain<Self, R> where
    Self: Sized

This is supported on feature="std" and feature="chain" only.

Chains / concats two ReadIntoUninit readers into one.

Loading content...

Implementations on Foreign Types

impl<'_, R: ReadIntoUninit + ?Sized> ReadIntoUninit for &'_ mut R[src]

impl<'_> ReadIntoUninit for &'_ [u8][src]

impl<R: Read> ReadIntoUninit for BufReader<R>[src]

impl<T: AsRef<[u8]>> ReadIntoUninit for Cursor<T>[src]

impl ReadIntoUninit for Empty[src]

impl<'_> ReadIntoUninit for StdinLock<'_>[src]

impl<T: BufRead> ReadIntoUninit for Take<T>[src]

impl<R: ReadIntoUninit + ?Sized> ReadIntoUninit for Box<R>[src]

Loading content...

Implementors

impl<R1, R2> ReadIntoUninit for Chain<R1, R2> where
    R1: ReadIntoUninit,
    R2: ReadIntoUninit
[src]

impl<R: Read> ReadIntoUninit for R[src]

Loading content...