diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/iovec/src/lib.rs | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/iovec/src/lib.rs')
-rw-r--r-- | third_party/rust/iovec/src/lib.rs | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/third_party/rust/iovec/src/lib.rs b/third_party/rust/iovec/src/lib.rs new file mode 100644 index 0000000000..1e091a46c9 --- /dev/null +++ b/third_party/rust/iovec/src/lib.rs @@ -0,0 +1,161 @@ +//! A specialized byte slice type for performing vectored I/O operations. +//! +//! For more detail, see [`IoVec`] documentation. +//! +//! [`IoVec`]: struct.IoVec.html + +#[cfg(unix)] +extern crate libc; + +mod sys; + +use std::{ops, mem}; + +#[cfg(unix)] +pub mod unix; + +/// Max length of an `IoVec` slice. +/// +/// Attempts to convert slices longer than this value will result in a panic. +pub const MAX_LENGTH: usize = sys::MAX_LENGTH; + +/// A specialized byte slice type for performing vectored I/O operations. +/// +/// On all systems, the types needed to perform vectored I/O systems have the +/// same size as Rust's [`slice`]. However, the layout is not necessarily the +/// same. `IoVec` provides a portable compatibility layer. +/// +/// The `IoVec` behaves like a Rust [`slice`], providing the same functions. +/// It also provides conversion functions to and from the OS specific vectored +/// types. +/// +/// [`slice`]: https://doc.rust-lang.org/std/primitive.slice.html +/// +/// # Examples +/// +/// ``` +/// use iovec::IoVec; +/// +/// let mut data = vec![]; +/// data.extend_from_slice(b"hello"); +/// +/// let iovec: &IoVec = data.as_slice().into(); +/// +/// assert_eq!(&iovec[..], &b"hello"[..]); +/// ``` +/// +/// # Panics +/// +/// Attempting to convert a zero-length slice or a slice longer than +/// [`MAX_LENGTH`] to an `IoVec` will result in a panic. +/// +/// [`MAX_LENGTH`]: constant.MAX_LENGTH.html +pub struct IoVec { + sys: sys::IoVec, +} + +impl IoVec { + pub fn from_bytes(slice: &[u8]) -> Option<&IoVec> { + if slice.len() == 0 { + return None + } + unsafe { + let iovec: &sys::IoVec = slice.into(); + Some(mem::transmute(iovec)) + } + } + + pub fn from_bytes_mut(slice: &mut [u8]) -> Option<&mut IoVec> { + if slice.len() == 0 { + return None + } + unsafe { + let iovec: &mut sys::IoVec = slice.into(); + Some(mem::transmute(iovec)) + } + } + + #[deprecated(since = "0.1.0", note = "deref instead")] + #[doc(hidden)] + pub fn as_bytes(&self) -> &[u8] { + &**self + } + + #[deprecated(since = "0.1.0", note = "deref instead")] + #[doc(hidden)] + pub fn as_mut_bytes(&mut self) -> &mut [u8] { + &mut **self + } +} + +impl ops::Deref for IoVec { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &self.sys.as_ref() + } +} + +impl ops::DerefMut for IoVec { + fn deref_mut(&mut self) -> &mut [u8] { + self.sys.as_mut() + } +} + +#[doc(hidden)] +impl<'a> From<&'a [u8]> for &'a IoVec { + fn from(bytes: &'a [u8]) -> &'a IoVec { + IoVec::from_bytes(bytes) + .expect("this crate accidentally accepted 0-sized slices \ + originally but this was since discovered as a soundness \ + hole, it's recommended to use the `from_bytes` \ + function instead") + } +} + +#[doc(hidden)] +impl<'a> From<&'a mut [u8]> for &'a mut IoVec { + fn from(bytes: &'a mut [u8]) -> &'a mut IoVec { + IoVec::from_bytes_mut(bytes) + .expect("this crate accidentally accepted 0-sized slices \ + originally but this was since discovered as a soundness \ + hole, it's recommended to use the `from_bytes_mut` \ + function instead") + } +} + +#[doc(hidden)] +impl<'a> Default for &'a IoVec { + fn default() -> Self { + panic!("this implementation was accidentally provided but is \ + unfortunately unsound, it's recommended to stop using \ + `IoVec::default` or construct a vector with a nonzero length"); + } +} + +#[doc(hidden)] +impl<'a> Default for &'a mut IoVec { + fn default() -> Self { + panic!("this implementation was accidentally provided but is \ + unfortunately unsound, it's recommended to stop using \ + `IoVec::default` or construct a vector with a nonzero length"); + } +} + +#[cfg(test)] +mod test { + use super::IoVec; + + #[test] + fn convert_ref() { + let buf: &IoVec = (&b"hello world"[..]).into(); + assert_eq!(buf[..], b"hello world"[..]); + } + + #[test] + fn convert_mut() { + let mut buf: Vec<u8> = b"hello world".to_vec(); + let buf: &mut IoVec = (&mut buf[..]).into(); + assert_eq!(buf[..], b"hello world"[..]); + } +} |