Trait uninit::read::ReadIntoUninit [−][src]
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
fn read_into_uninit<'buf>(
&mut self,
buf: Out<'buf, [u8]>
) -> Result<&'buf mut [u8]>
fn read_into_uninit<'buf>(
&mut self,
buf: Out<'buf, [u8]>
) -> Result<&'buf mut [u8]>
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
fn read_into_uninit_exact<'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]>
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,
impl<R1, R2> Read for Chain<R1, R2> where
R1: ReadIntoUninit,
R2: ReadIntoUninit,
chain
only.Chains / concats two ReadIntoUninit
readers into one.
Implementations on Foreign Types
Implementors
impl<R1, R2> ReadIntoUninit for Chain<R1, R2> where
R1: ReadIntoUninit,
R2: ReadIntoUninit,
chain
only.