uninit/read/mod.rs
1//! Read into uninitialized bytes logic.
2
3use_prelude!();
4
5use ::std::io::Read;
6
7/// Trait for a [`Read`](https://doc.rust-lang.org/std/io/trait.Read.html)able
8/// type that can output the bytes read into
9/// [uninitialised memory][`MaybeUninit`].
10///
11/// # Safety (to implement) / Guarantees (for users of `impl ReadIntoUninit` types)
12///
13/// The trait is `unsafe` (to implement) because it **needs to guarantee** to
14/// users of generic `R : ReadIntoUninit` code (that may use `unsafe` code
15/// relying on it!) that:
16///
17/// - `if let Ok(init_buf) = self.read_into_uninit(buf)`, then it must be
18/// sound to:
19///
20/// ```rust
21/// # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
22/// unsafe {
23/// buf.get_out_unchecked(.. init_buf.len()).assume_init()
24/// }
25/// # }
26/// ```
27///
28/// - `if self.read_into_uninit_exact(buf).is_ok()`, then it must be
29/// sound to: `buf.assume_init()`.
30///
31/// # Counterexample
32///
33/// ```rust,no_run
34/// #![feature(specialization)]
35/// use ::uninit::{prelude::*,
36/// read::{auto_impl, ReadIntoUninit},
37/// };
38///
39/// pub
40/// struct Evil;
41///
42/// auto_impl! { #[derived_from(ReadIntoUninit)] impl Read for Evil }
43/// unsafe // unsound!
44/// impl ReadIntoUninit for Evil {
45/// fn read_into_uninit<'buf> (
46/// self: &'_ mut Self,
47/// buf: Out<'buf, [u8]>,
48/// ) -> ::std::io::Result<&'buf mut [u8]>
49/// {
50/// Ok(Box::leak(vec![0; buf.len()].into_boxed_slice()))
51/// }
52/// }
53/// ```
54///
55/// Indeed, with such an impl, the following function could cause UB, when
56/// instanced with `R = Evil`:
57///
58/// ```rust
59/// use ::uninit::{prelude::*, read::ReadIntoUninit};
60///
61/// fn read_byte<R> (reader: &'_ mut R)
62/// -> ::std::io::Result<u8>
63/// where
64/// R : ReadIntoUninit,
65/// {
66/// let mut byte = MaybeUninit::uninit();
67/// reader.read_into_uninit_exact(::std::slice::from_mut(&mut byte).as_out())?;
68/// Ok(unsafe {
69/// // Safety: Guaranteed by `ReadIntoUninit` contract
70/// byte.assume_init()
71/// })
72/// }
73/// ```
74pub unsafe trait ReadIntoUninit: Read
75// Safety: `.read_into_uninit_exact()` delegates to `.read_into_uninit()`.
76{
77 /// Single attempt to read bytes from `Self` into `buf`.
78 ///
79 /// On success, it returns the bytes having been read.
80 ///
81 /// # Guarantees (that `unsafe` code may rely on)
82 ///
83 /// - `if let Ok(init_buf) = self.read_into_uninit(buf)`, then it is
84 /// sound to:
85 ///
86 /// ```rust
87 /// # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
88 /// unsafe {
89 /// buf.get_out_unchecked(.. init_buf.len()).assume_init()
90 /// }
91 /// # }
92 /// ```
93 ///
94 /// This is not guaranteed to read `buf.len()` bytes, see the docs of
95 /// [`.read()`][`Read::read`] for more information.
96 fn read_into_uninit<'buf>(
97 self: &'_ mut Self,
98 buf: Out<'buf, [u8]>,
99 ) -> io::Result<&'buf mut [u8]>;
100
101 /// Attempts to _fill_ `buf` through multiple `.read()` calls if necessary.
102 ///
103 /// On success, it returns the bytes having been read.
104 ///
105 /// # Guarantees (that `unsafe` code may rely on)
106 ///
107 /// - `if self.read_into_uninit_exact(buf).is_ok()`, then it is
108 /// sound to: `buf.assume_init()`.
109 ///
110 /// See the docs of [`.read_exact()`][`Read::read_exact`] for more
111 /// information.
112 fn read_into_uninit_exact<'buf>(
113 self: &'_ mut Self,
114 mut buf: Out<'buf, [u8]>,
115 ) -> io::Result<&'buf mut [u8]> {
116 {
117 let mut buf = buf.reborrow();
118 while buf.is_empty().not() {
119 match self.read_into_uninit(buf.r()).map(|it| it.len()) {
120 Ok(0) => {
121 return Err(io::Error::new(
122 io::ErrorKind::UnexpectedEof,
123 "failed to fill whole buffer",
124 ));
125 }
126 Ok(n) => {
127 // buf = &mut buf[n ..];
128 buf = buf.get_out(n..).unwrap();
129 }
130 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
131 Err(e) => {
132 return Err(e);
133 }
134 }
135 }
136 }
137 Ok(unsafe {
138 // # Safety
139 //
140 // - this is the "concatenation" of all the "buf[.. n]"
141 // initialisation witnesses.
142 buf.assume_init()
143 })
144 }
145
146 /// Chains / concats two `ReadIntoUninit` readers into one.
147 #[cfg(feature = "chain")]
148 #[cfg_attr(feature = "nightly", doc(cfg(feature = "chain")))]
149 fn chain<R: ReadIntoUninit>(self: Self, next: R) -> chain::Chain<Self, R>
150 where
151 Self: Sized,
152 {
153 chain::Chain {
154 first: self,
155 second: next,
156 first_done: false,
157 }
158 }
159}
160
161/// Helper macro to alleviate the code duplication from implementing both
162/// `Read` and `ReadIntoUninit`.
163///
164/// Once some type `T` implements `ReadIntoUninit`, you can derive `Read` by
165/// doing:
166///
167/// ```rust
168/// # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
169/// ::uninit::read::auto_impl! {
170/// #[derived_from(ReadIntoUninit)]
171/// impl Read for X
172/// }
173/// // and if X is generic, over, for instance, `Generics`
174/// ::uninit::read::auto_impl! {
175/// #[derived_from(ReadIntoUninit)]
176/// impl[Generics] Read for X<Generics>
177/// }
178/// # }
179/// ```
180#[doc(hidden)]
181#[macro_export]
182macro_rules! _private_auto_impl {(
183 #[derived_from(ReadIntoUninit)]
184 impl $( [$($generics:tt)*] )? Read for $T:ty
185 $(
186 where
187 $($where_clause:tt)*
188 )?
189) => (
190 impl$(<$($generics)*>)? $crate::std::io::Read for $T
191 where
192 $( $($where_clause)* )?
193 {
194 #[inline]
195 fn read (self: &'_ mut Self, buf: &'_ mut [u8])
196 -> $crate::std::io::Result<usize>
197 {
198 <Self as $crate::read::ReadIntoUninit>::read_into_uninit(
199 self,
200 buf.as_out(),
201 ).map(|x| x.len())
202 }
203
204 #[inline]
205 fn read_exact (self: &'_ mut Self, buf: &'_ mut [u8])
206 -> $crate::std::io::Result<()>
207 {
208 <Self as $crate::read::ReadIntoUninit>::read_into_uninit_exact(
209 self,
210 buf.as_out(),
211 ).map(drop)
212 }
213 }
214)}
215#[doc(inline)]
216pub use _private_auto_impl as auto_impl;
217
218pub use crate::extension_traits::VecExtendFromReader;
219
220mod impls;
221
222#[cfg(feature = "chain")]
223#[cfg_attr(feature = "nightly", doc(cfg(feature = "chain")))]
224pub mod chain {
225 #![allow(missing_docs)]
226 use super::*;
227
228 #[cfg_attr(feature = "nightly", doc(cfg(feature = "chain")))]
229 #[derive(Debug)]
230 pub struct Chain<R1, R2>
231 where
232 R1: ReadIntoUninit,
233 R2: ReadIntoUninit,
234 {
235 pub(super) first: R1,
236
237 pub(super) second: R2,
238
239 pub(super) first_done: bool,
240 }
241
242 impl<R1, R2> Chain<R1, R2>
243 where
244 R1: ReadIntoUninit,
245 R2: ReadIntoUninit,
246 {
247 pub fn into_inner(self: Self) -> (R1, R2) {
248 let Self { first, second, .. } = self;
249 (first, second)
250 }
251
252 pub fn get_ref(self: &'_ Self) -> (&'_ R1, &'_ R2) {
253 let Self { first, second, .. } = self;
254 (first, second)
255 }
256 }
257
258 unsafe impl<R1, R2> ReadIntoUninit for Chain<R1, R2>
259 where
260 R1: ReadIntoUninit,
261 R2: ReadIntoUninit,
262 {
263 fn read_into_uninit<'buf>(
264 self: &'_ mut Self,
265 mut buf: Out<'buf, [u8]>,
266 ) -> io::Result<&'buf mut [u8]> {
267 let len = buf.len();
268 if len == 0 {
269 return Ok(buf.copy_from_slice(&[]));
270 }
271 if self.first_done.not() {
272 let buf_ = self.first.read_into_uninit(buf.r())?;
273 if buf_.is_empty() {
274 self.first_done = true;
275 } else {
276 return unsafe {
277 // Safety: `buf_` has been a witness of the
278 // initialization of these bytes.
279 let len = buf_.len();
280 let buf = buf.get_out(..len).unwrap();
281 Ok(buf.assume_init())
282 };
283 }
284 }
285 self.second.read_into_uninit(buf)
286 }
287 }
288
289 super::auto_impl! {
290 #[derived_from(ReadIntoUninit)]
291 impl[R1, R2] Read for Chain<R1, R2>
292 where
293 R1 : ReadIntoUninit,
294 R2 : ReadIntoUninit,
295 }
296}