diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/bytes/src/buf/ext | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/bytes/src/buf/ext')
-rw-r--r-- | third_party/rust/bytes/src/buf/ext/chain.rs | 234 | ||||
-rw-r--r-- | third_party/rust/bytes/src/buf/ext/limit.rs | 77 | ||||
-rw-r--r-- | third_party/rust/bytes/src/buf/ext/mod.rs | 176 | ||||
-rw-r--r-- | third_party/rust/bytes/src/buf/ext/reader.rs | 81 | ||||
-rw-r--r-- | third_party/rust/bytes/src/buf/ext/take.rs | 150 | ||||
-rw-r--r-- | third_party/rust/bytes/src/buf/ext/writer.rs | 88 |
6 files changed, 806 insertions, 0 deletions
diff --git a/third_party/rust/bytes/src/buf/ext/chain.rs b/third_party/rust/bytes/src/buf/ext/chain.rs new file mode 100644 index 0000000000..a1ec597df6 --- /dev/null +++ b/third_party/rust/bytes/src/buf/ext/chain.rs @@ -0,0 +1,234 @@ +use crate::{Buf, BufMut}; +use crate::buf::IntoIter; + +use core::mem::MaybeUninit; + +#[cfg(feature = "std")] +use std::io::{IoSlice}; +#[cfg(feature = "std")] +use crate::buf::IoSliceMut; + +/// A `Chain` sequences two buffers. +/// +/// `Chain` is an adapter that links two underlying buffers and provides a +/// continuous view across both buffers. It is able to sequence either immutable +/// buffers ([`Buf`] values) or mutable buffers ([`BufMut`] values). +/// +/// This struct is generally created by calling [`Buf::chain`]. Please see that +/// function's documentation for more detail. +/// +/// # Examples +/// +/// ``` +/// use bytes::{Bytes, Buf, buf::BufExt}; +/// +/// let mut buf = (&b"hello "[..]) +/// .chain(&b"world"[..]); +/// +/// let full: Bytes = buf.to_bytes(); +/// assert_eq!(full[..], b"hello world"[..]); +/// ``` +/// +/// [`Buf::chain`]: trait.Buf.html#method.chain +/// [`Buf`]: trait.Buf.html +/// [`BufMut`]: trait.BufMut.html +#[derive(Debug)] +pub struct Chain<T, U> { + a: T, + b: U, +} + +impl<T, U> Chain<T, U> { + /// Creates a new `Chain` sequencing the provided values. + pub fn new(a: T, b: U) -> Chain<T, U> { + Chain { + a, + b, + } + } + + /// Gets a reference to the first underlying `Buf`. + /// + /// # Examples + /// + /// ``` + /// use bytes::buf::BufExt; + /// + /// let buf = (&b"hello"[..]) + /// .chain(&b"world"[..]); + /// + /// assert_eq!(buf.first_ref()[..], b"hello"[..]); + /// ``` + pub fn first_ref(&self) -> &T { + &self.a + } + + /// Gets a mutable reference to the first underlying `Buf`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, buf::BufExt}; + /// + /// let mut buf = (&b"hello"[..]) + /// .chain(&b"world"[..]); + /// + /// buf.first_mut().advance(1); + /// + /// let full = buf.to_bytes(); + /// assert_eq!(full, b"elloworld"[..]); + /// ``` + pub fn first_mut(&mut self) -> &mut T { + &mut self.a + } + + /// Gets a reference to the last underlying `Buf`. + /// + /// # Examples + /// + /// ``` + /// use bytes::buf::BufExt; + /// + /// let buf = (&b"hello"[..]) + /// .chain(&b"world"[..]); + /// + /// assert_eq!(buf.last_ref()[..], b"world"[..]); + /// ``` + pub fn last_ref(&self) -> &U { + &self.b + } + + /// Gets a mutable reference to the last underlying `Buf`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, buf::BufExt}; + /// + /// let mut buf = (&b"hello "[..]) + /// .chain(&b"world"[..]); + /// + /// buf.last_mut().advance(1); + /// + /// let full = buf.to_bytes(); + /// assert_eq!(full, b"hello orld"[..]); + /// ``` + pub fn last_mut(&mut self) -> &mut U { + &mut self.b + } + + /// Consumes this `Chain`, returning the underlying values. + /// + /// # Examples + /// + /// ``` + /// use bytes::buf::BufExt; + /// + /// let chain = (&b"hello"[..]) + /// .chain(&b"world"[..]); + /// + /// let (first, last) = chain.into_inner(); + /// assert_eq!(first[..], b"hello"[..]); + /// assert_eq!(last[..], b"world"[..]); + /// ``` + pub fn into_inner(self) -> (T, U) { + (self.a, self.b) + } +} + +impl<T, U> Buf for Chain<T, U> + where T: Buf, + U: Buf, +{ + fn remaining(&self) -> usize { + self.a.remaining() + self.b.remaining() + } + + fn bytes(&self) -> &[u8] { + if self.a.has_remaining() { + self.a.bytes() + } else { + self.b.bytes() + } + } + + fn advance(&mut self, mut cnt: usize) { + let a_rem = self.a.remaining(); + + if a_rem != 0 { + if a_rem >= cnt { + self.a.advance(cnt); + return; + } + + // Consume what is left of a + self.a.advance(a_rem); + + cnt -= a_rem; + } + + self.b.advance(cnt); + } + + #[cfg(feature = "std")] + fn bytes_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize { + let mut n = self.a.bytes_vectored(dst); + n += self.b.bytes_vectored(&mut dst[n..]); + n + } +} + +impl<T, U> BufMut for Chain<T, U> + where T: BufMut, + U: BufMut, +{ + fn remaining_mut(&self) -> usize { + self.a.remaining_mut() + self.b.remaining_mut() + } + + fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] { + if self.a.has_remaining_mut() { + self.a.bytes_mut() + } else { + self.b.bytes_mut() + } + } + + unsafe fn advance_mut(&mut self, mut cnt: usize) { + let a_rem = self.a.remaining_mut(); + + if a_rem != 0 { + if a_rem >= cnt { + self.a.advance_mut(cnt); + return; + } + + // Consume what is left of a + self.a.advance_mut(a_rem); + + cnt -= a_rem; + } + + self.b.advance_mut(cnt); + } + + #[cfg(feature = "std")] + fn bytes_vectored_mut<'a>(&'a mut self, dst: &mut [IoSliceMut<'a>]) -> usize { + let mut n = self.a.bytes_vectored_mut(dst); + n += self.b.bytes_vectored_mut(&mut dst[n..]); + n + } +} + +impl<T, U> IntoIterator for Chain<T, U> +where + T: Buf, + U: Buf, +{ + type Item = u8; + type IntoIter = IntoIter<Chain<T, U>>; + + fn into_iter(self) -> Self::IntoIter { + IntoIter::new(self) + } +} diff --git a/third_party/rust/bytes/src/buf/ext/limit.rs b/third_party/rust/bytes/src/buf/ext/limit.rs new file mode 100644 index 0000000000..f86e01151c --- /dev/null +++ b/third_party/rust/bytes/src/buf/ext/limit.rs @@ -0,0 +1,77 @@ +use crate::BufMut; + +use core::{cmp, mem::MaybeUninit}; + +/// A `BufMut` adapter which limits the amount of bytes that can be written +/// to an underlying buffer. +#[derive(Debug)] +pub struct Limit<T> { + inner: T, + limit: usize, +} + +pub(super) fn new<T>(inner: T, limit: usize) -> Limit<T> { + Limit { + inner, + limit, + } +} + +impl<T> Limit<T> { + /// Consumes this `Limit`, returning the underlying value. + pub fn into_inner(self) -> T { + self.inner + } + + /// Gets a reference to the underlying `BufMut`. + /// + /// It is inadvisable to directly write to the underlying `BufMut`. + pub fn get_ref(&self) -> &T { + &self.inner + } + + /// Gets a mutable reference to the underlying `BufMut`. + /// + /// It is inadvisable to directly write to the underlying `BufMut`. + pub fn get_mut(&mut self) -> &mut T { + &mut self.inner + } + + /// Returns the maximum number of bytes that can be written + /// + /// # Note + /// + /// If the inner `BufMut` has fewer bytes than indicated by this method then + /// that is the actual number of available bytes. + pub fn limit(&self) -> usize { + self.limit + } + + /// Sets the maximum number of bytes that can be written. + /// + /// # Note + /// + /// If the inner `BufMut` has fewer bytes than `lim` then that is the actual + /// number of available bytes. + pub fn set_limit(&mut self, lim: usize) { + self.limit = lim + } +} + +impl<T: BufMut> BufMut for Limit<T> { + fn remaining_mut(&self) -> usize { + cmp::min(self.inner.remaining_mut(), self.limit) + } + + fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] { + let bytes = self.inner.bytes_mut(); + let end = cmp::min(bytes.len(), self.limit); + &mut bytes[..end] + } + + unsafe fn advance_mut(&mut self, cnt: usize) { + assert!(cnt <= self.limit); + self.inner.advance_mut(cnt); + self.limit -= cnt; + } +} diff --git a/third_party/rust/bytes/src/buf/ext/mod.rs b/third_party/rust/bytes/src/buf/ext/mod.rs new file mode 100644 index 0000000000..7b0bdab200 --- /dev/null +++ b/third_party/rust/bytes/src/buf/ext/mod.rs @@ -0,0 +1,176 @@ +//! Extra utilities for `Buf` and `BufMut` types. + +use super::{Buf, BufMut}; + +mod chain; +mod limit; +#[cfg(feature = "std")] +mod reader; +mod take; +#[cfg(feature = "std")] +mod writer; + +pub use self::limit::Limit; +pub use self::take::Take; +pub use self::chain::Chain; + +#[cfg(feature = "std")] +pub use self::{reader::Reader, writer::Writer}; + +/// Extra methods for implementations of `Buf`. +pub trait BufExt: Buf { + /// Creates an adaptor which will read at most `limit` bytes from `self`. + /// + /// This function returns a new instance of `Buf` which will read at most + /// `limit` bytes. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, BufMut, buf::BufExt}; + /// + /// let mut buf = b"hello world"[..].take(5); + /// let mut dst = vec![]; + /// + /// dst.put(&mut buf); + /// assert_eq!(dst, b"hello"); + /// + /// let mut buf = buf.into_inner(); + /// dst.clear(); + /// dst.put(&mut buf); + /// assert_eq!(dst, b" world"); + /// ``` + fn take(self, limit: usize) -> Take<Self> + where Self: Sized + { + take::new(self, limit) + } + + /// Creates an adaptor which will chain this buffer with another. + /// + /// The returned `Buf` instance will first consume all bytes from `self`. + /// Afterwards the output is equivalent to the output of next. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, buf::BufExt}; + /// + /// let mut chain = b"hello "[..].chain(&b"world"[..]); + /// + /// let full = chain.to_bytes(); + /// assert_eq!(full.bytes(), b"hello world"); + /// ``` + fn chain<U: Buf>(self, next: U) -> Chain<Self, U> + where Self: Sized + { + Chain::new(self, next) + } + + /// Creates an adaptor which implements the `Read` trait for `self`. + /// + /// This function returns a new value which implements `Read` by adapting + /// the `Read` trait functions to the `Buf` trait functions. Given that + /// `Buf` operations are infallible, none of the `Read` functions will + /// return with `Err`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, Bytes, buf::BufExt}; + /// use std::io::Read; + /// + /// let buf = Bytes::from("hello world"); + /// + /// let mut reader = buf.reader(); + /// let mut dst = [0; 1024]; + /// + /// let num = reader.read(&mut dst).unwrap(); + /// + /// assert_eq!(11, num); + /// assert_eq!(&dst[..11], &b"hello world"[..]); + /// ``` + #[cfg(feature = "std")] + fn reader(self) -> Reader<Self> where Self: Sized { + reader::new(self) + } +} + +impl<B: Buf + ?Sized> BufExt for B {} + +/// Extra methods for implementations of `BufMut`. +pub trait BufMutExt: BufMut { + /// Creates an adaptor which can write at most `limit` bytes to `self`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, buf::BufMutExt}; + /// + /// let arr = &mut [0u8; 128][..]; + /// assert_eq!(arr.remaining_mut(), 128); + /// + /// let dst = arr.limit(10); + /// assert_eq!(dst.remaining_mut(), 10); + /// ``` + fn limit(self, limit: usize) -> Limit<Self> + where Self: Sized + { + limit::new(self, limit) + } + + /// Creates an adaptor which implements the `Write` trait for `self`. + /// + /// This function returns a new value which implements `Write` by adapting + /// the `Write` trait functions to the `BufMut` trait functions. Given that + /// `BufMut` operations are infallible, none of the `Write` functions will + /// return with `Err`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, buf::BufMutExt}; + /// use std::io::Write; + /// + /// let mut buf = vec![].writer(); + /// + /// let num = buf.write(&b"hello world"[..]).unwrap(); + /// assert_eq!(11, num); + /// + /// let buf = buf.into_inner(); + /// + /// assert_eq!(*buf, b"hello world"[..]); + /// ``` + #[cfg(feature = "std")] + fn writer(self) -> Writer<Self> where Self: Sized { + writer::new(self) + } + + /// Creates an adapter which will chain this buffer with another. + /// + /// The returned `BufMut` instance will first write to all bytes from + /// `self`. Afterwards, it will write to `next`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, buf::BufMutExt}; + /// + /// let mut a = [0u8; 5]; + /// let mut b = [0u8; 6]; + /// + /// let mut chain = (&mut a[..]).chain_mut(&mut b[..]); + /// + /// chain.put_slice(b"hello world"); + /// + /// assert_eq!(&a[..], b"hello"); + /// assert_eq!(&b[..], b" world"); + /// ``` + fn chain_mut<U: BufMut>(self, next: U) -> Chain<Self, U> + where Self: Sized + { + Chain::new(self, next) + } +} + +impl<B: BufMut + ?Sized> BufMutExt for B {} diff --git a/third_party/rust/bytes/src/buf/ext/reader.rs b/third_party/rust/bytes/src/buf/ext/reader.rs new file mode 100644 index 0000000000..e38103b1de --- /dev/null +++ b/third_party/rust/bytes/src/buf/ext/reader.rs @@ -0,0 +1,81 @@ +use crate::{Buf}; + +use std::{cmp, io}; + +/// A `Buf` adapter which implements `io::Read` for the inner value. +/// +/// This struct is generally created by calling `reader()` on `Buf`. See +/// documentation of [`reader()`](trait.Buf.html#method.reader) for more +/// details. +#[derive(Debug)] +pub struct Reader<B> { + buf: B, +} + +pub fn new<B>(buf: B) -> Reader<B> { + Reader { buf } +} + +impl<B: Buf> Reader<B> { + /// Gets a reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::buf::BufExt; + /// + /// let mut buf = b"hello world".reader(); + /// + /// assert_eq!(b"hello world", buf.get_ref()); + /// ``` + pub fn get_ref(&self) -> &B { + &self.buf + } + + /// Gets a mutable reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + pub fn get_mut(&mut self) -> &mut B { + &mut self.buf + } + + /// Consumes this `Reader`, returning the underlying value. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, buf::BufExt}; + /// use std::io; + /// + /// let mut buf = b"hello world".reader(); + /// let mut dst = vec![]; + /// + /// io::copy(&mut buf, &mut dst).unwrap(); + /// + /// let buf = buf.into_inner(); + /// assert_eq!(0, buf.remaining()); + /// ``` + pub fn into_inner(self) -> B { + self.buf + } +} + +impl<B: Buf + Sized> io::Read for Reader<B> { + fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> { + let len = cmp::min(self.buf.remaining(), dst.len()); + + Buf::copy_to_slice(&mut self.buf, &mut dst[0..len]); + Ok(len) + } +} + +impl<B: Buf + Sized> io::BufRead for Reader<B> { + fn fill_buf(&mut self) -> io::Result<&[u8]> { + Ok(self.buf.bytes()) + } + fn consume(&mut self, amt: usize) { + self.buf.advance(amt) + } +} diff --git a/third_party/rust/bytes/src/buf/ext/take.rs b/third_party/rust/bytes/src/buf/ext/take.rs new file mode 100644 index 0000000000..6fc4ffc72c --- /dev/null +++ b/third_party/rust/bytes/src/buf/ext/take.rs @@ -0,0 +1,150 @@ +use crate::Buf; + +use core::cmp; + +/// A `Buf` adapter which limits the bytes read from an underlying buffer. +/// +/// This struct is generally created by calling `take()` on `Buf`. See +/// documentation of [`take()`](trait.Buf.html#method.take) for more details. +#[derive(Debug)] +pub struct Take<T> { + inner: T, + limit: usize, +} + +pub fn new<T>(inner: T, limit: usize) -> Take<T> { + Take { + inner, + limit, + } +} + +impl<T> Take<T> { + /// Consumes this `Take`, returning the underlying value. + /// + /// # Examples + /// + /// ```rust + /// use bytes::buf::{Buf, BufMut, BufExt}; + /// + /// let mut buf = b"hello world".take(2); + /// let mut dst = vec![]; + /// + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"he"[..]); + /// + /// let mut buf = buf.into_inner(); + /// + /// dst.clear(); + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"llo world"[..]); + /// ``` + pub fn into_inner(self) -> T { + self.inner + } + + /// Gets a reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, buf::BufExt}; + /// + /// let mut buf = b"hello world".take(2); + /// + /// assert_eq!(11, buf.get_ref().remaining()); + /// ``` + pub fn get_ref(&self) -> &T { + &self.inner + } + + /// Gets a mutable reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut, buf::BufExt}; + /// + /// let mut buf = b"hello world".take(2); + /// let mut dst = vec![]; + /// + /// buf.get_mut().advance(2); + /// + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"ll"[..]); + /// ``` + pub fn get_mut(&mut self) -> &mut T { + &mut self.inner + } + + /// Returns the maximum number of bytes that can be read. + /// + /// # Note + /// + /// If the inner `Buf` has fewer bytes than indicated by this method then + /// that is the actual number of available bytes. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, buf::BufExt}; + /// + /// let mut buf = b"hello world".take(2); + /// + /// assert_eq!(2, buf.limit()); + /// assert_eq!(b'h', buf.get_u8()); + /// assert_eq!(1, buf.limit()); + /// ``` + pub fn limit(&self) -> usize { + self.limit + } + + /// Sets the maximum number of bytes that can be read. + /// + /// # Note + /// + /// If the inner `Buf` has fewer bytes than `lim` then that is the actual + /// number of available bytes. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut, buf::BufExt}; + /// + /// let mut buf = b"hello world".take(2); + /// let mut dst = vec![]; + /// + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"he"[..]); + /// + /// dst.clear(); + /// + /// buf.set_limit(3); + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"llo"[..]); + /// ``` + pub fn set_limit(&mut self, lim: usize) { + self.limit = lim + } +} + +impl<T: Buf> Buf for Take<T> { + fn remaining(&self) -> usize { + cmp::min(self.inner.remaining(), self.limit) + } + + fn bytes(&self) -> &[u8] { + let bytes = self.inner.bytes(); + &bytes[..cmp::min(bytes.len(), self.limit)] + } + + fn advance(&mut self, cnt: usize) { + assert!(cnt <= self.limit); + self.inner.advance(cnt); + self.limit -= cnt; + } +} diff --git a/third_party/rust/bytes/src/buf/ext/writer.rs b/third_party/rust/bytes/src/buf/ext/writer.rs new file mode 100644 index 0000000000..1418418e81 --- /dev/null +++ b/third_party/rust/bytes/src/buf/ext/writer.rs @@ -0,0 +1,88 @@ +use crate::BufMut; + +use std::{cmp, io}; + +/// A `BufMut` adapter which implements `io::Write` for the inner value. +/// +/// This struct is generally created by calling `writer()` on `BufMut`. See +/// documentation of [`writer()`](trait.BufMut.html#method.writer) for more +/// details. +#[derive(Debug)] +pub struct Writer<B> { + buf: B, +} + +pub fn new<B>(buf: B) -> Writer<B> { + Writer { buf } +} + +impl<B: BufMut> Writer<B> { + /// Gets a reference to the underlying `BufMut`. + /// + /// It is inadvisable to directly write to the underlying `BufMut`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::buf::BufMutExt; + /// + /// let mut buf = Vec::with_capacity(1024).writer(); + /// + /// assert_eq!(1024, buf.get_ref().capacity()); + /// ``` + pub fn get_ref(&self) -> &B { + &self.buf + } + + /// Gets a mutable reference to the underlying `BufMut`. + /// + /// It is inadvisable to directly write to the underlying `BufMut`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::buf::BufMutExt; + /// + /// let mut buf = vec![].writer(); + /// + /// buf.get_mut().reserve(1024); + /// + /// assert_eq!(1024, buf.get_ref().capacity()); + /// ``` + pub fn get_mut(&mut self) -> &mut B { + &mut self.buf + } + + /// Consumes this `Writer`, returning the underlying value. + /// + /// # Examples + /// + /// ```rust + /// use bytes::buf::BufMutExt; + /// use std::io; + /// + /// let mut buf = vec![].writer(); + /// let mut src = &b"hello world"[..]; + /// + /// io::copy(&mut src, &mut buf).unwrap(); + /// + /// let buf = buf.into_inner(); + /// assert_eq!(*buf, b"hello world"[..]); + /// ``` + pub fn into_inner(self) -> B { + self.buf + } +} + +impl<B: BufMut + Sized> io::Write for Writer<B> { + fn write(&mut self, src: &[u8]) -> io::Result<usize> { + let n = cmp::min(self.buf.remaining_mut(), src.len()); + + self.buf.put(&src[0..n]); + Ok(n) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} |