Skip to content

Commit d6013bb

Browse files
committed
Add TryFromBytes::try_read_from_io
Makes progress on #158 gherrit-pr-id: Ia15467145b06dd57e4dfd9e127fdd6d7a313ecba
1 parent da442b4 commit d6013bb

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/lib.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2821,6 +2821,40 @@ pub unsafe trait TryFromBytes {
28212821
// its bytes are initialized.
28222822
unsafe { try_read_from(source, candidate).map(|slf| (prefix, slf)) }
28232823
}
2824+
2825+
// TODO: Write tests for this method
2826+
#[cfg(feature = "std")]
2827+
#[inline(always)]
2828+
fn try_read_from_io<R>(mut src: R) -> io::Result<Self>
2829+
where
2830+
Self: Sized,
2831+
R: io::Read,
2832+
{
2833+
// NOTE(#2319, #2320): We do `buf.zero()` separately rather than
2834+
// constructing `let buf = CoreMaybeUninit::zeroed()` because, if `Self`
2835+
// contains padding bytes, then a typed copy of `CoreMaybeUninit<Self>`
2836+
// will not necessarily preserve zeros written to those padding byte
2837+
// locations, and so `buf` could contain uninitialized bytes.
2838+
let mut buf = CoreMaybeUninit::<Self>::uninit();
2839+
buf.zero();
2840+
2841+
let ptr = Ptr::from_mut(&mut buf);
2842+
// SAFETY: After `buf.zero()`, `buf` consists entirely of initialized,
2843+
// zeroed bytes. Since `MaybeUninit` has no validity requirements, `ptr`
2844+
// cannot be used to write values which will violate `buf`'s bit
2845+
// validity. Since `ptr` has `Exclusive` aliasing, nothing other than
2846+
// `ptr` may be used to mutate `ptr`'s referent, and so its bit validity
2847+
// cannot be violated even though `buf` may have more permissive bit
2848+
// validity than `ptr`.
2849+
let ptr = unsafe { ptr.assume_validity::<invariant::Initialized>() };
2850+
let ptr = ptr.as_bytes::<BecauseExclusive>();
2851+
src.read_exact(ptr.as_mut())?;
2852+
2853+
// SAFETY: `buf` entirely consists of initialized bytes.
2854+
//
2855+
// TODO: What error type should we return from this method?
2856+
unsafe { try_read_from((), buf).map_err(|err| todo!()) }
2857+
}
28242858
}
28252859

28262860
#[inline(always)]

0 commit comments

Comments
 (0)