summaryrefslogtreecommitdiff
path: root/vendor/bytes/src/buf/take.rs
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
committermo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
commit8cdfa445d6629ffef4cb84967ff7017654045bc2 (patch)
tree22f0b0907c024c78d26a731e2e1f5219407d8102 /vendor/bytes/src/buf/take.rs
parent4351c74c7c5f97156bc94d3a8549b9940ac80e3f (diff)
chore: add vendor directory
Diffstat (limited to 'vendor/bytes/src/buf/take.rs')
-rw-r--r--vendor/bytes/src/buf/take.rs204
1 files changed, 204 insertions, 0 deletions
diff --git a/vendor/bytes/src/buf/take.rs b/vendor/bytes/src/buf/take.rs
new file mode 100644
index 00000000..acfeef6e
--- /dev/null
+++ b/vendor/bytes/src/buf/take.rs
@@ -0,0 +1,204 @@
+use crate::Buf;
+
+use core::cmp;
+
+#[cfg(feature = "std")]
+use std::io::IoSlice;
+
+/// 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()`](Buf::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, BufMut};
+ ///
+ /// 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;
+ ///
+ /// let 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};
+ ///
+ /// 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;
+ ///
+ /// 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};
+ ///
+ /// 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 chunk(&self) -> &[u8] {
+ let bytes = self.inner.chunk();
+ &bytes[..cmp::min(bytes.len(), self.limit)]
+ }
+
+ fn advance(&mut self, cnt: usize) {
+ assert!(cnt <= self.limit);
+ self.inner.advance(cnt);
+ self.limit -= cnt;
+ }
+
+ fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes {
+ assert!(len <= self.remaining(), "`len` greater than remaining");
+
+ let r = self.inner.copy_to_bytes(len);
+ self.limit -= len;
+ r
+ }
+
+ #[cfg(feature = "std")]
+ fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
+ if self.limit == 0 {
+ return 0;
+ }
+
+ const LEN: usize = 16;
+ let mut slices: [IoSlice<'a>; LEN] = [
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ IoSlice::new(&[]),
+ ];
+
+ let cnt = self
+ .inner
+ .chunks_vectored(&mut slices[..dst.len().min(LEN)]);
+ let mut limit = self.limit;
+ for (i, (dst, slice)) in dst[..cnt].iter_mut().zip(slices.iter()).enumerate() {
+ if let Some(buf) = slice.get(..limit) {
+ // SAFETY: We could do this safely with `IoSlice::advance` if we had a larger MSRV.
+ let buf = unsafe { std::mem::transmute::<&[u8], &'a [u8]>(buf) };
+ *dst = IoSlice::new(buf);
+ return i + 1;
+ } else {
+ // SAFETY: We could do this safely with `IoSlice::advance` if we had a larger MSRV.
+ let buf = unsafe { std::mem::transmute::<&[u8], &'a [u8]>(slice) };
+ *dst = IoSlice::new(buf);
+ limit -= slice.len();
+ }
+ }
+ cnt
+ }
+}