Trait uninit::read::ReadIntoUninit
source · [−]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>ⓘNotable traits for Chain<R1, R2>impl<R1, R2> Read for Chain<R1, R2> where
R1: ReadIntoUninit,
R2: ReadIntoUninit,
where
Self: Sized,
{ ... }
}
std
only.Expand description
Trait for a Read
able
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
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.
Provided Methods
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.
fn chain<R: ReadIntoUninit>(self, next: R) -> Chain<Self, R>ⓘNotable traits for Chain<R1, R2>impl<R1, R2> Read for Chain<R1, R2> where
R1: ReadIntoUninit,
R2: ReadIntoUninit,
where
Self: Sized,
fn chain<R: ReadIntoUninit>(self, next: R) -> Chain<Self, R>ⓘNotable traits for Chain<R1, R2>impl<R1, R2> Read for Chain<R1, R2> where
R1: ReadIntoUninit,
R2: ReadIntoUninit,
where
Self: Sized,
R1: ReadIntoUninit,
R2: ReadIntoUninit,
chain
only.Chains / concats two ReadIntoUninit
readers into one.
Implementations on Foreign Types
sourceimpl<R: ReadIntoUninit + ?Sized> ReadIntoUninit for &mut R
impl<R: ReadIntoUninit + ?Sized> ReadIntoUninit for &mut R
sourceimpl ReadIntoUninit for &[u8]
impl ReadIntoUninit for &[u8]
sourceimpl<R: Read> ReadIntoUninit for BufReader<R>
impl<R: Read> ReadIntoUninit for BufReader<R>
sourceimpl<T: AsRef<[u8]>> ReadIntoUninit for Cursor<T>
impl<T: AsRef<[u8]>> ReadIntoUninit for Cursor<T>
sourceimpl ReadIntoUninit for Empty
impl ReadIntoUninit for Empty
sourceimpl ReadIntoUninit for StdinLock<'_>
impl ReadIntoUninit for StdinLock<'_>
sourceimpl<T: BufRead> ReadIntoUninit for Take<T>
impl<T: BufRead> ReadIntoUninit for Take<T>
sourceimpl<R: ReadIntoUninit + ?Sized> ReadIntoUninit for Box<R>
impl<R: ReadIntoUninit + ?Sized> ReadIntoUninit for Box<R>
Implementors
impl<R1, R2> ReadIntoUninit for Chain<R1, R2> where
R1: ReadIntoUninit,
R2: ReadIntoUninit,
chain
only.impl<R: Read> ReadIntoUninit for R
specialization
only.