Crate uninit_tools[−][src]
Examples
A Read
-like trait implemented to better support uninitialized memory.
use std::mem::MaybeUninit; use uninit_tools::buffer::{Buffer, BufferRef}; use uninit_tools::traits::Initialize; pub trait MyRead { // NOTE: The function does not return any count, since the buffer keeps track of that. // // Rather than using `&mut Buffer<T>` directly, we use `BufferRef<'_, T>` to prevent the // caller from replacing the buffer that is being filled with something different. It also // gives the `Read` implementor a reduced subset of the functionality, to that it cannot // for example read the bytes that are already written into the buffer. fn read<'buffer, T>(&mut self, buffer: BufferRef<'buffer, T>) -> io::Result<()> where T: Initialize<Item = u8>, ; } impl MyRead for &[u8] { fn read<'buffer, T>(&mut self, mut buffer: BufferRef<'buffer, T>) -> io::Result<()> where T: Initialize<Item = u8>, { // Get the minimum number of bytes to copy. Note that it will panic if the source slice // were to overflow, as with the regular `copy_from_slice` function for regular slices. let min = std::cmp::min(self.len(), buffer.remaining()); // Advance the buffer by simply copying the source slice. buffer.append(&self[..min]); Ok(()) } } // NOTE: The `Initialize` trait is implemented for arrays of all sizes, thanks to const // generics. let array = [MaybeUninit::uninit(); 32]; let len = array.len(); let mut buf = Buffer::uninit(array); let original_stupid_text: &[u8] = b"copying is expensive!"; let mut stupid_text = original_stupid_text; // Read as many bytes as possible. stupid_text.read(buf.by_ref())?; // Note that while we cannot do anything useful with the rest of the buffer, we can still use // it as the destination of even more I/O, or simply check its length like we do here. assert_eq!(buf.remaining(), len - original_stupid_text.len());
Note that this may not be the best implementation of the Read
trait, but it does show that
uninitialized memory handling can be done entirely in safe code, being moderately ergonomic.
(If this would be incorporated into std::io::Read
, there would probably be a simpler unsafe
function, that defaults to the safer wrapper.)
Modules
buffer | Buffers for single-buffer and vectored I/O which tracking initializedness and how much has been
filled. Container types pointing to possibly-uninitialized memory such as
|
buffers | |
initializer | |
traits | |
wrappers |
Functions
cast_init_to_uninit_slice | Cast a slice of bytes into a slice of uninitialized bytes, pretending that it is uninitialized.
This is completely safe, since |
cast_init_to_uninit_slice_mut⚠ | Cast a mutable slice of bytes into a slice of uninitialized bytes, pretending that it is uninitialized. This is completely safe since they always have the same memory layout; however, the layout of the slices themselves must not be relied upon. The initializedness information is lost as part of this cast, but can be recovered when initializing again or by using unsafe code. |
cast_uninit_to_init_slice⚠ | Cast a possibly uninitialized slice of bytes, into an initializied slice, assuming that it is initialized. |
cast_uninit_to_init_slice_mut⚠ | Cast a mutable slice of possibly initialized bytes into a slice of initialized bytes, assuming it is initialized. |
fill_uninit_slice | Fill a possibly uninitialized mutable slice of bytes, with the same |