diff options
Diffstat (limited to 'vendor/rustix/src/buffer.rs')
| -rw-r--r-- | vendor/rustix/src/buffer.rs | 448 |
1 files changed, 0 insertions, 448 deletions
diff --git a/vendor/rustix/src/buffer.rs b/vendor/rustix/src/buffer.rs deleted file mode 100644 index 6c86826f..00000000 --- a/vendor/rustix/src/buffer.rs +++ /dev/null @@ -1,448 +0,0 @@ -//! Utilities for functions that return data via buffers. - -#![allow(unsafe_code)] - -#[cfg(feature = "alloc")] -use alloc::vec::Vec; -use core::mem::MaybeUninit; -use core::slice; - -/// A memory buffer that may be uninitialized. -/// -/// There are three types that implement the `Buffer` trait, and the type you -/// use determines the return type of the functions that use it: -/// -/// | If you pass a… | You get back a… | -/// | ------------------------ | --------------- | -/// | `&mut [u8]` | `usize`, indicating the number of elements initialized. | -/// | `&mut [MaybeUninit<u8>]` | `(&mut [u8], &mut [MaybeUninit<u8>])`, holding the initialized and uninitialized subslices. | -/// | [`SpareCapacity`] | `usize`, indicating the number of elements initialized. And the `Vec` is extended. | -/// -/// # Examples -/// -/// Passing a `&mut [u8]`: -/// -/// ``` -/// # use rustix::io::read; -/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> { -/// let mut buf = [0_u8; 64]; -/// let nread = read(fd, &mut buf)?; -/// // `nread` is the number of bytes read. -/// # Ok(()) -/// # } -/// ``` -/// -/// Passing a `&mut [MaybeUninit<u8>]`: -/// -/// ``` -/// # use rustix::io::read; -/// # use std::mem::MaybeUninit; -/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> { -/// let mut buf = [MaybeUninit::<u8>::uninit(); 64]; -/// let (init, uninit) = read(fd, &mut buf)?; -/// // `init` is a `&mut [u8]` with the initialized bytes. -/// // `uninit` is a `&mut [MaybeUninit<u8>]` with the remaining bytes. -/// # Ok(()) -/// # } -/// ``` -/// -/// Passing a [`SpareCapacity`], via the [`spare_capacity`] helper function: -/// -/// ``` -/// # use rustix::io::read; -/// # use rustix::buffer::spare_capacity; -/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> { -/// let mut buf = Vec::with_capacity(64); -/// let nread = read(fd, spare_capacity(&mut buf))?; -/// // `nread` is the number of bytes read. -/// // Also, `buf.len()` is now `nread` elements longer than it was before. -/// # Ok(()) -/// # } -/// ``` -/// -/// # Guide to error messages -/// -/// Sometimes code using `Buffer` can encounter non-obvious error messages. -/// Here are some we've encountered, along with ways to fix them. -/// -/// If you see errors like -/// "cannot move out of `self` which is behind a mutable reference" -/// and -/// "move occurs because `x` has type `&mut [u8]`, which does not implement the `Copy` trait", -/// replace `x` with `&mut *x`. See `error_buffer_wrapper` in -/// examples/buffer_errors.rs. -/// -/// If you see errors like -/// "type annotations needed" -/// and -/// "cannot infer type of the type parameter `Buf` declared on the function `read`", -/// you may need to change a `&mut []` to `&mut [0_u8; 0]`. See -/// `error_empty_slice` in examples/buffer_errors.rs. -/// -/// If you see errors like -/// "the trait bound `[MaybeUninit<u8>; 1]: Buffer<u8>` is not satisfied", -/// add a `&mut` to pass the array by reference instead of by value. See -/// `error_array_by_value` in examples/buffer_errors.rs. -/// -/// If you see errors like -/// "cannot move out of `x`, a captured variable in an `FnMut` closure", -/// try replacing `x` with `&mut *x`, or, if that doesn't work, try moving a -/// `let` into the closure body. See `error_retry_closure` and -/// `error_retry_indirect_closure` in examples/buffer_errors.rs. -/// -/// If you see errors like -/// "captured variable cannot escape `FnMut` closure body", -/// use an explicit loop instead of `retry_on_intr`, assuming you're using -/// that. See `error_retry_closure_uninit` in examples/buffer_errors.rs. -pub trait Buffer<T>: private::Sealed<T> {} - -// Implement `Buffer` for all the types that implement `Sealed`. -impl<T> Buffer<T> for &mut [T] {} -impl<T, const N: usize> Buffer<T> for &mut [T; N] {} -#[cfg(feature = "alloc")] -impl<T> Buffer<T> for &mut Vec<T> {} -impl<T> Buffer<T> for &mut [MaybeUninit<T>] {} -impl<T, const N: usize> Buffer<T> for &mut [MaybeUninit<T>; N] {} -#[cfg(feature = "alloc")] -impl<T> Buffer<T> for &mut Vec<MaybeUninit<T>> {} -#[cfg(feature = "alloc")] -impl<'a, T> Buffer<T> for SpareCapacity<'a, T> {} - -impl<T> private::Sealed<T> for &mut [T] { - type Output = usize; - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - len - } -} - -impl<T, const N: usize> private::Sealed<T> for &mut [T; N] { - type Output = usize; - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr(), N) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - len - } -} - -// `Vec` implements `DerefMut` to `&mut [T]`, however it doesn't get -// auto-derefed in a `impl Buffer<u8>`, so we add this `impl` so that our users -// don't have to add an extra `*` in these situations. -#[cfg(feature = "alloc")] -impl<T> private::Sealed<T> for &mut Vec<T> { - type Output = usize; - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - len - } -} - -impl<'a, T> private::Sealed<T> for &'a mut [MaybeUninit<T>] { - type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]); - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr().cast(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - let (init, uninit) = self.split_at_mut(len); - - // SAFETY: The user asserts that the slice is now initialized. - let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len()); - - (init, uninit) - } -} - -impl<'a, T, const N: usize> private::Sealed<T> for &'a mut [MaybeUninit<T>; N] { - type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]); - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr().cast(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - let (init, uninit) = self.split_at_mut(len); - - // SAFETY: The user asserts that the slice is now initialized. - let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len()); - - (init, uninit) - } -} - -#[cfg(feature = "alloc")] -impl<'a, T> private::Sealed<T> for &'a mut Vec<MaybeUninit<T>> { - type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]); - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr().cast(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - let (init, uninit) = self.split_at_mut(len); - - // SAFETY: The user asserts that the slice is now initialized. - let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len()); - - (init, uninit) - } -} - -/// A type that implements [`Buffer`] by appending to a `Vec`, up to its -/// capacity. -/// -/// To use this, use the [`spare_capacity`] function. -/// -/// Because this uses the capacity, and never reallocates, the `Vec` should -/// have some non-empty spare capacity. -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub struct SpareCapacity<'a, T>(&'a mut Vec<T>); - -/// Construct an [`SpareCapacity`], which implements [`Buffer`]. -/// -/// This wraps a `Vec` and uses the spare capacity of the `Vec` as the buffer -/// to receive data in, automatically calling `set_len` on the `Vec` to set the -/// length to include the received elements. -/// -/// This uses the existing capacity, and never allocates, so the `Vec` should -/// have some non-empty spare capacity! -/// -/// # Examples -/// -/// ``` -/// # fn test(input: rustix::fd::BorrowedFd) -> rustix::io::Result<()> { -/// use rustix::buffer::spare_capacity; -/// use rustix::io::{read, Errno}; -/// -/// let mut buf = Vec::with_capacity(1024); -/// match read(input, spare_capacity(&mut buf)) { -/// Ok(0) => { /* end of stream */ } -/// Ok(n) => { /* `buf` is now `n` bytes longer */ } -/// Err(Errno::INTR) => { /* `buf` is unmodified */ } -/// Err(e) => { -/// return Err(e); -/// } -/// } -/// -/// # Ok(()) -/// # } -/// ``` -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn spare_capacity<'a, T>(v: &'a mut Vec<T>) -> SpareCapacity<'a, T> { - debug_assert_ne!( - v.capacity(), - 0, - "`extend` uses spare capacity, and never allocates new memory, so the `Vec` passed to it \ - should have some spare capacity." - ); - - SpareCapacity(v) -} - -#[cfg(feature = "alloc")] -impl<'a, T> private::Sealed<T> for SpareCapacity<'a, T> { - /// The mutated `Vec` reflects the number of bytes read. We also return - /// this number, and a value of 0 indicates the end of the stream has - /// been reached. - type Output = usize; - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - let spare = self.0.spare_capacity_mut(); - (spare.as_mut_ptr().cast(), spare.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - // We initialized `len` elements; extend the `Vec` to include them. - self.0.set_len(self.0.len() + len); - len - } -} - -mod private { - pub trait Sealed<T> { - /// The result of the process operation. - type Output; - - /// Return a pointer and length for this buffer. - /// - /// The length is the number of elements of type `T`, not a number of - /// bytes. - /// - /// It's tempting to have this return `&mut [MaybeUninit<T>]` instead, - /// however that would require this function to be `unsafe`, because - /// callers could use the `&mut [MaybeUninit<T>]` slice to set elements - /// to `MaybeUninit::<T>::uninit()`, which would be a problem if `Self` - /// is `&mut [T]` or similar. - fn parts_mut(&mut self) -> (*mut T, usize); - - /// Convert a finished buffer pointer into its result. - /// - /// # Safety - /// - /// At least `len` elements of the buffer must now be initialized. - #[must_use] - unsafe fn assume_init(self, len: usize) -> Self::Output; - } -} - -#[cfg(test)] -mod tests { - #[allow(unused_imports)] - use super::*; - - #[cfg(not(windows))] - #[test] - fn test_compilation() { - use crate::io::read; - use core::mem::MaybeUninit; - - // We need to obtain input stream, so open our own source file. - let input = std::fs::File::open("src/buffer.rs").unwrap(); - - let mut buf = vec![0_u8; 3]; - buf.reserve(32); - let _x: usize = read(&input, spare_capacity(&mut buf)).unwrap(); - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = - read(&input, buf.spare_capacity_mut()).unwrap(); - let _x: usize = read(&input, &mut buf).unwrap(); - let _x: usize = read(&input, &mut *buf).unwrap(); - let _x: usize = read(&input, &mut buf[..]).unwrap(); - let _x: usize = read(&input, &mut (*buf)[..]).unwrap(); - - let mut buf = [0, 0, 0]; - let _x: usize = read(&input, &mut buf).unwrap(); - let _x: usize = read(&input, &mut buf[..]).unwrap(); - - let mut buf = [ - MaybeUninit::uninit(), - MaybeUninit::uninit(), - MaybeUninit::uninit(), - ]; - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf).unwrap(); - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf[..]).unwrap(); - - let mut buf = vec![ - MaybeUninit::uninit(), - MaybeUninit::uninit(), - MaybeUninit::uninit(), - ]; - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf).unwrap(); - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf[..]).unwrap(); - } - - #[cfg(not(windows))] - #[test] - fn test_slice() { - use crate::io::read; - use std::io::{Seek, SeekFrom}; - - // We need to obtain input stream with contents that we can compare - // against, so open our own source file. - let mut input = std::fs::File::open("src/buffer.rs").unwrap(); - - let mut buf = [0_u8; 64]; - let nread = read(&input, &mut buf).unwrap(); - assert_eq!(nread, buf.len()); - assert_eq!( - &buf[..58], - b"//! Utilities for functions that return data via buffers.\n" - ); - input.seek(SeekFrom::End(-1)).unwrap(); - let nread = read(&input, &mut buf).unwrap(); - assert_eq!(nread, 1); - input.seek(SeekFrom::End(0)).unwrap(); - let nread = read(&input, &mut buf).unwrap(); - assert_eq!(nread, 0); - } - - #[cfg(not(windows))] - #[test] - fn test_slice_uninit() { - use crate::io::read; - use core::mem::MaybeUninit; - use std::io::{Seek, SeekFrom}; - - // We need to obtain input stream with contents that we can compare - // against, so open our own source file. - let mut input = std::fs::File::open("src/buffer.rs").unwrap(); - - let mut buf = [MaybeUninit::<u8>::uninit(); 64]; - let (init, uninit) = read(&input, &mut buf).unwrap(); - assert_eq!(uninit.len(), 0); - assert_eq!( - &init[..58], - b"//! Utilities for functions that return data via buffers.\n" - ); - assert_eq!(init.len(), buf.len()); - assert_eq!( - unsafe { core::mem::transmute::<&mut [MaybeUninit<u8>], &mut [u8]>(&mut buf[..58]) }, - b"//! Utilities for functions that return data via buffers.\n" - ); - input.seek(SeekFrom::End(-1)).unwrap(); - let (init, uninit) = read(&input, &mut buf).unwrap(); - assert_eq!(init.len(), 1); - assert_eq!(uninit.len(), buf.len() - 1); - input.seek(SeekFrom::End(0)).unwrap(); - let (init, uninit) = read(&input, &mut buf).unwrap(); - assert_eq!(init.len(), 0); - assert_eq!(uninit.len(), buf.len()); - } - - #[cfg(not(windows))] - #[test] - fn test_spare_capacity() { - use crate::io::read; - use std::io::{Seek, SeekFrom}; - - // We need to obtain input stream with contents that we can compare - // against, so open our own source file. - let mut input = std::fs::File::open("src/buffer.rs").unwrap(); - - let mut buf = Vec::with_capacity(64); - let nread = read(&input, spare_capacity(&mut buf)).unwrap(); - assert_eq!(nread, buf.capacity()); - assert_eq!(nread, buf.len()); - assert_eq!( - &buf[..58], - b"//! Utilities for functions that return data via buffers.\n" - ); - buf.clear(); - input.seek(SeekFrom::End(-1)).unwrap(); - let nread = read(&input, spare_capacity(&mut buf)).unwrap(); - assert_eq!(nread, 1); - assert_eq!(buf.len(), 1); - buf.clear(); - input.seek(SeekFrom::End(0)).unwrap(); - let nread = read(&input, spare_capacity(&mut buf)).unwrap(); - assert_eq!(nread, 0); - assert!(buf.is_empty()); - } -} |
