Skip to main content

ntex_bytes/
bvec.rs

1use std::{borrow, fmt, io, ops::DerefMut, ptr};
2
3use crate::{Buf, BufMut, BytePageSize, Bytes, buf::UninitSlice, stvec::StorageVec};
4
5/// A unique reference to a contiguous slice of memory.
6///
7/// `BytesMut` represents a unique view into a potentially shared memory region.
8/// Given the uniqueness guarantee, owners of `BytesMut` handles are able to
9/// mutate the memory. It is similar to a `Vec<u8>` but with fewer copies and
10/// allocations. It also always allocates.
11///
12/// For more detail, see [`Bytes`].
13///
14/// # Growth
15///
16/// Safe write operations such as [`BufMut::put_slice`], [`BufMut::put_u8`], and
17/// [`extend_from_slice`](Self::extend_from_slice) reserve additional capacity
18/// when needed. Use [`reserve`](Self::reserve) when the required capacity is
19/// known in advance to avoid repeated allocation.
20///
21/// # Examples
22///
23/// ```
24/// use ntex_bytes::{BytesMut, BufMut};
25///
26/// let mut buf = BytesMut::with_capacity(64);
27///
28/// buf.put_u8(b'h');
29/// buf.put_u8(b'e');
30/// buf.put_slice(b"llo");
31///
32/// assert_eq!(&buf[..], b"hello");
33///
34/// // Freeze the buffer so that it can be shared
35/// let a = buf.freeze();
36///
37/// // This does not allocate, instead `b` points to the same memory.
38/// let b = a.clone();
39///
40/// assert_eq!(a, b"hello");
41/// assert_eq!(b, b"hello");
42/// ```
43pub struct BytesMut {
44    pub(crate) storage: StorageVec,
45}
46
47impl BytesMut {
48    /// Creates a new `BytesMut` with the specified capacity.
49    ///
50    /// The returned `BytesMut` will be able to hold `capacity` bytes
51    /// without reallocating.
52    ///
53    /// It is important to note that this function does not specify the length
54    /// of the returned `BytesMut`, but only the capacity.
55    ///
56    /// # Panics
57    ///
58    /// Panics if `capacity` exceeds `u32::MAX` minus the buffer
59    /// header size, just under 4 GiB.
60    ///
61    /// # Examples
62    ///
63    /// ```
64    /// use ntex_bytes::{BytesMut, BufMut};
65    ///
66    /// let mut bytes = BytesMut::with_capacity(64);
67    ///
68    /// // `bytes` contains no data, even though there is capacity
69    /// assert_eq!(bytes.len(), 0);
70    ///
71    /// bytes.put(&b"hello world"[..]);
72    ///
73    /// assert_eq!(&bytes[..], b"hello world");
74    /// ```
75    #[inline]
76    #[must_use]
77    pub fn with_capacity(capacity: usize) -> BytesMut {
78        BytesMut {
79            storage: StorageVec::with_capacity(capacity),
80        }
81    }
82
83    /// Creates a new empty `BytesMut` backed by a page of the specified size.
84    ///
85    /// The buffer has the [`capacity`](BytePageSize::capacity) of the page
86    /// size. Pages are taken from the current thread's page cache, and the
87    /// page returns to the cache of the thread that drops the last reference
88    /// to it, including [`Bytes`] split off the buffer. If the cache has no
89    /// page of the requested size but has one of the next smaller size, see
90    /// [`BytePageSize::prev`], that page is used instead, the buffer then has
91    /// the smaller capacity and page size.
92    ///
93    /// When the buffer grows, it moves to a page of the size that fits the
94    /// new capacity, see [`reserve`](Self::reserve). Growth always uses a
95    /// page of exactly that size. Above the largest page size the buffer is
96    /// a regular allocation without a page size, it is freed when dropped.
97    ///
98    /// [`BytePageSize::Unset`] has the allocation size of
99    /// [`BytePageSize::Size64`], it creates a `Size64` page.
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use ntex_bytes::{BytePageSize, BytesMut};
105    ///
106    /// let mut buf = BytesMut::with_page_size(BytePageSize::Size4);
107    /// assert_eq!(buf.capacity(), BytePageSize::Size4.capacity());
108    /// assert_eq!(buf.page_size(), BytePageSize::Size4);
109    ///
110    /// buf.extend_from_slice(&[0; 5000]);
111    /// assert_eq!(buf.page_size(), BytePageSize::Size8);
112    /// ```
113    #[inline]
114    #[must_use]
115    pub fn with_page_size(size: BytePageSize) -> BytesMut {
116        let size = if size == BytePageSize::Unset {
117            BytePageSize::Size64
118        } else {
119            size
120        };
121        BytesMut {
122            storage: StorageVec::sized(size),
123        }
124    }
125
126    /// Creates a new `BytesMut` from the page cache, like
127    /// [`with_page_size`](Self::with_page_size), with the allocation charged
128    /// to `tracker`.
129    ///
130    /// The allocation stays charged while any `BytesMut` or [`Bytes`]
131    /// handle refers to it. A buffer that grows into a new allocation
132    /// charges it to the same tracker, the old allocation is uncharged when
133    /// its last handle is dropped. Copies made by [`Clone`], conversions or
134    /// [`Bytes::trimdown`] are not charged.
135    ///
136    /// # Examples
137    ///
138    /// ```
139    /// use ntex_bytes::{BytePageSize, BytesMut, BytesTracker};
140    ///
141    /// let tracker = BytesTracker::new();
142    /// let buf = BytesMut::with_page_size_in(BytePageSize::Size4, &tracker);
143    /// assert_eq!(tracker.snapshot().live_bytes, 4096);
144    /// assert_eq!(tracker.snapshot().live_allocations, 1);
145    ///
146    /// drop(buf);
147    /// assert_eq!(tracker.snapshot().live_bytes, 0);
148    /// ```
149    #[cfg(feature = "tracker")]
150    #[cfg_attr(docsrs, doc(cfg(feature = "tracker")))]
151    #[inline]
152    #[must_use]
153    pub fn with_page_size_in(size: BytePageSize, tracker: &crate::BytesTracker) -> BytesMut {
154        let size = if size == BytePageSize::Unset {
155            BytePageSize::Size64
156        } else {
157            size
158        };
159        BytesMut {
160            storage: StorageVec::sized_in(size, tracker),
161        }
162    }
163
164    /// Charges the allocation of the buffer to `tracker`.
165    ///
166    /// The allocation stays charged as described in
167    /// [`with_page_size_in`](Self::with_page_size_in). If the allocation is
168    /// charged to a different tracker, the charge moves to `tracker`, also
169    /// while it is shared with [`Bytes`] handles. Setting the tracker the
170    /// buffer is already charged to does nothing.
171    ///
172    /// # Examples
173    ///
174    /// ```
175    /// use ntex_bytes::{BytesMut, BytesTracker};
176    ///
177    /// let tracker = BytesTracker::new();
178    /// let mut buf = BytesMut::with_capacity(256);
179    /// buf.extend_from_slice(&[0; 128]);
180    ///
181    /// let head = buf.split_to(64);
182    /// buf.set_tracker(&tracker);
183    /// assert!(buf.tracker().unwrap().ptr_eq(&tracker));
184    /// assert_eq!(tracker.snapshot().live_allocations, 1);
185    ///
186    /// let other = BytesTracker::new();
187    /// buf.set_tracker(&other);
188    /// assert_eq!(tracker.snapshot().live_allocations, 0);
189    /// assert_eq!(other.snapshot().live_allocations, 1);
190    ///
191    /// drop((buf, head));
192    /// assert_eq!(other.snapshot().live_allocations, 0);
193    /// ```
194    #[cfg(feature = "tracker")]
195    #[cfg_attr(docsrs, doc(cfg(feature = "tracker")))]
196    #[inline]
197    pub fn set_tracker(&mut self, tracker: &crate::BytesTracker) {
198        self.storage.set_tracker(tracker);
199    }
200
201    /// Returns the tracker charged with the allocation of the buffer.
202    #[cfg(feature = "tracker")]
203    #[cfg_attr(docsrs, doc(cfg(feature = "tracker")))]
204    #[inline]
205    #[must_use]
206    pub fn tracker(&self) -> Option<&crate::BytesTracker> {
207        self.storage.tracker()
208    }
209
210    /// Returns the page size of the buffer.
211    ///
212    /// The page size is derived from the allocation size, a buffer whose
213    /// allocation, header included, is exactly a page size belongs to that
214    /// page size. This covers buffers created by
215    /// [`with_page_size`](Self::with_page_size), converted from a pooled
216    /// [`BytePage`](crate::BytePage), or created with a page
217    /// [`capacity`](BytePageSize::capacity). They return to the page cache
218    /// when the last reference is dropped. Other buffers return
219    /// [`BytePageSize::Unset`], they are freed when dropped.
220    #[inline]
221    pub fn page_size(&self) -> BytePageSize {
222        self.storage.page_size()
223    }
224
225    /// Creates a `BytesMut` by copying a byte slice.
226    #[inline]
227    #[must_use]
228    pub fn copy_from_slice<T: AsRef<[u8]>>(src: T) -> Self {
229        let slice = src.as_ref();
230        BytesMut {
231            storage: StorageVec::from_slice(slice.len(), slice),
232        }
233    }
234
235    /// Creates a new `BytesMut` with default capacity.
236    ///
237    /// Resulting object has length 0 and unspecified capacity.
238    ///
239    /// # Examples
240    ///
241    /// ```
242    /// use ntex_bytes::{BytesMut, BufMut};
243    ///
244    /// let mut bytes = BytesMut::new();
245    ///
246    /// assert_eq!(0, bytes.len());
247    ///
248    /// bytes.reserve(2);
249    /// bytes.put_slice(b"xy");
250    ///
251    /// assert_eq!(&b"xy"[..], &bytes[..]);
252    /// ```
253    #[inline]
254    #[must_use]
255    pub fn new() -> BytesMut {
256        BytesMut {
257            storage: StorageVec::with_capacity(crate::storage::MIN_CAPACITY),
258        }
259    }
260
261    /// Returns the number of bytes contained in this `BytesMut`.
262    ///
263    /// # Examples
264    ///
265    /// ```
266    /// use ntex_bytes::BytesMut;
267    ///
268    /// let b = BytesMut::copy_from_slice(&b"hello"[..]);
269    /// assert_eq!(b.len(), 5);
270    /// ```
271    #[inline]
272    pub fn len(&self) -> usize {
273        self.storage.len()
274    }
275
276    /// Returns `true` if the buffer is empty.
277    ///
278    /// # Examples
279    ///
280    /// ```
281    /// use ntex_bytes::BytesMut;
282    ///
283    /// let b = BytesMut::with_capacity(64);
284    /// assert!(b.is_empty());
285    /// ```
286    #[inline]
287    pub fn is_empty(&self) -> bool {
288        self.storage.len() == 0
289    }
290
291    /// Returns the number of bytes the `BytesMut` can hold without reallocating.
292    ///
293    /// # Examples
294    ///
295    /// ```
296    /// use ntex_bytes::BytesMut;
297    ///
298    /// let b = BytesMut::with_capacity(64);
299    /// assert_eq!(b.capacity(), 64);
300    /// ```
301    #[inline]
302    pub fn capacity(&self) -> usize {
303        self.storage.capacity()
304    }
305
306    /// Returns `true` if no other handle refers to the underlying buffer.
307    ///
308    /// Values split off with [`split_to`](Self::split_to) or frozen into
309    /// [`Bytes`] share the buffer with `self`. While they exist, clearing
310    /// `self` does not reclaim the capacity in front of it, and the whole
311    /// allocation stays alive as long as any of them does.
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// use ntex_bytes::BytesMut;
317    ///
318    /// let mut buf = BytesMut::with_capacity(64);
319    /// buf.extend_from_slice(&[0; 32]);
320    /// assert!(buf.is_unique());
321    ///
322    /// let head = buf.split_to(30);
323    /// assert!(!buf.is_unique());
324    ///
325    /// drop(head);
326    /// assert!(buf.is_unique());
327    /// ```
328    #[inline]
329    pub fn is_unique(&self) -> bool {
330        self.storage.is_unique()
331    }
332
333    /// Converts `self` into an immutable `Bytes`.
334    ///
335    /// The conversion is zero cost and is used to indicate that the slice
336    /// referenced by the handle will no longer be mutated. Once the conversion
337    /// is done, the handle can be cloned and shared across threads.
338    ///
339    /// # Examples
340    ///
341    /// ```
342    /// use ntex_bytes::{BytesMut, BufMut};
343    /// use std::thread;
344    ///
345    /// let mut b = BytesMut::with_capacity(64);
346    /// b.put_slice(b"hello world");
347    /// let b1 = b.freeze();
348    /// let b2 = b1.clone();
349    ///
350    /// let th = thread::spawn(move || {
351    ///     assert_eq!(b1, b"hello world");
352    /// });
353    ///
354    /// assert_eq!(b2, b"hello world");
355    /// th.join().unwrap();
356    /// ```
357    #[inline]
358    #[must_use]
359    pub fn freeze(self) -> Bytes {
360        Bytes {
361            storage: self.storage.freeze(),
362        }
363    }
364
365    /// Removes the bytes from the current view, returning them in a
366    /// `Bytes` instance.
367    ///
368    /// Afterwards, `self` will be empty, but will retain any additional
369    /// capacity that it had before the operation. This is identical to
370    /// `self.split_to(self.len())`.
371    ///
372    /// This is an `O(1)` operation that just increases the reference count and
373    /// sets a few indices.
374    ///
375    /// # Examples
376    ///
377    /// ```
378    /// use ntex_bytes::{BytesMut, BufMut};
379    ///
380    /// let mut buf = BytesMut::with_capacity(1024);
381    /// buf.put(&b"hello world"[..]);
382    ///
383    /// let other = buf.take();
384    ///
385    /// assert!(buf.is_empty());
386    /// assert_eq!(1013, buf.capacity());
387    ///
388    /// assert_eq!(other, b"hello world"[..]);
389    /// ```
390    #[inline]
391    #[must_use]
392    pub fn take(&mut self) -> Bytes {
393        Bytes {
394            storage: self.storage.split_to(self.len()),
395        }
396    }
397
398    /// Splits the buffer into two at the given index.
399    ///
400    /// Afterwards `self` contains elements `[at, len)`, and the returned `Bytes`
401    /// contains elements `[0, at)`.
402    ///
403    /// This is an `O(1)` operation that just increases the reference count and
404    /// sets a few indices.
405    ///
406    /// # Examples
407    ///
408    /// ```
409    /// use ntex_bytes::BytesMut;
410    ///
411    /// let mut a = BytesMut::copy_from_slice(&b"hello world"[..]);
412    /// let mut b = a.split_to(5);
413    ///
414    /// a[0] = b'!';
415    ///
416    /// assert_eq!(&a[..], b"!world");
417    /// assert_eq!(&b[..], b"hello");
418    /// ```
419    ///
420    /// # Panics
421    ///
422    /// Panics if `at > len`.
423    #[inline]
424    #[must_use]
425    pub fn split_to(&mut self, at: usize) -> Bytes {
426        self.split_to_checked(at)
427            .expect("at value must be <= self.len()`")
428    }
429
430    /// Advance the internal cursor.
431    ///
432    /// Afterwards `self` contains elements `[cnt, len)`.
433    /// This is an `O(1)` operation.
434    ///
435    /// # Examples
436    ///
437    /// ```
438    /// use ntex_bytes::BytesMut;
439    ///
440    /// let mut a = BytesMut::copy_from_slice(&b"hello world"[..]);
441    /// a.advance_to(5);
442    ///
443    /// a[0] = b'!';
444    ///
445    /// assert_eq!(&a[..], b"!world");
446    /// ```
447    ///
448    /// # Panics
449    ///
450    /// Panics if `cnt > len`.
451    #[inline]
452    pub fn advance_to(&mut self, cnt: usize) {
453        // SAFETY: `set_start` checks `cnt <= len` before advancing within this live, exclusively
454        // owned view.
455        unsafe {
456            self.storage.set_start(cnt);
457        }
458    }
459
460    /// Splits the bytes into two at the given index.
461    ///
462    /// Returns `None` if `at > len`.
463    #[inline]
464    #[must_use]
465    pub fn split_to_checked(&mut self, at: usize) -> Option<Bytes> {
466        if at <= self.len() {
467            Some(Bytes {
468                storage: self.storage.split_to(at),
469            })
470        } else {
471            None
472        }
473    }
474
475    /// Shortens the buffer, keeping the first `len` bytes and dropping the
476    /// rest.
477    ///
478    /// If `len` is greater than the buffer's current length, this has no
479    /// effect.
480    ///
481    /// `truncate(0)` on a buffer that is not shared with any other handle
482    /// also reclaims the capacity in front of the current view, see
483    /// [`clear`](Self::clear).
484    ///
485    /// # Examples
486    ///
487    /// ```
488    /// use ntex_bytes::BytesMut;
489    ///
490    /// let mut buf = BytesMut::copy_from_slice(&b"hello world"[..]);
491    /// buf.truncate(5);
492    /// assert_eq!(buf, b"hello"[..]);
493    /// ```
494    #[inline]
495    pub fn truncate(&mut self, len: usize) {
496        self.storage.truncate(len);
497    }
498
499    /// Clears the buffer, removing all data.
500    ///
501    /// If no other handle refers to the underlying buffer (see
502    /// [`is_unique`](Self::is_unique)), the view is reset to the start of the
503    /// allocation, so the full capacity becomes available again.
504    ///
505    /// # Examples
506    ///
507    /// ```
508    /// use ntex_bytes::BytesMut;
509    ///
510    /// let mut buf = BytesMut::copy_from_slice(&b"hello world"[..]);
511    /// buf.clear();
512    /// assert!(buf.is_empty());
513    /// ```
514    #[inline]
515    pub fn clear(&mut self) {
516        self.truncate(0);
517    }
518
519    /// Resizes the buffer so that `len` is equal to `new_len`.
520    ///
521    /// If `new_len` is greater than `len`, the buffer is extended by the
522    /// difference with each additional byte set to `value`. If `new_len` is
523    /// less than `len`, the buffer is simply truncated.
524    ///
525    /// # Panics
526    ///
527    /// Panics if `new_len` exceeds `u32::MAX` minus the buffer
528    /// header size, just under 4 GiB.
529    ///
530    /// # Examples
531    ///
532    /// ```
533    /// use ntex_bytes::BytesMut;
534    ///
535    /// let mut buf = BytesMut::new();
536    ///
537    /// buf.resize(3, 0x1);
538    /// assert_eq!(&buf[..], &[0x1, 0x1, 0x1]);
539    ///
540    /// buf.resize(2, 0x2);
541    /// assert_eq!(&buf[..], &[0x1, 0x1]);
542    ///
543    /// buf.resize(4, 0x3);
544    /// assert_eq!(&buf[..], &[0x1, 0x1, 0x3, 0x3]);
545    /// ```
546    #[inline]
547    pub fn resize(&mut self, new_len: usize, value: u8) {
548        self.storage.resize(new_len, value);
549    }
550
551    /// Sets the length of the buffer.
552    ///
553    /// This will explicitly set the size of the buffer without actually
554    /// modifying the data, so it is up to the caller to ensure that the data
555    /// has been initialized.
556    ///
557    /// # Examples
558    ///
559    /// ```
560    /// use ntex_bytes::BytesMut;
561    ///
562    /// let mut b = BytesMut::copy_from_slice(&b"hello world"[..]);
563    ///
564    /// unsafe {
565    ///     b.set_len(5);
566    /// }
567    ///
568    /// assert_eq!(&b[..], b"hello");
569    ///
570    /// unsafe {
571    ///     b.set_len(11);
572    /// }
573    ///
574    /// assert_eq!(&b[..], b"hello world");
575    /// ```
576    ///
577    /// # Safety
578    ///
579    /// Caller must ensure that data has been initialized.
580    ///
581    /// # Panics
582    ///
583    /// Panics if `len > self.capacity()`.
584    #[inline]
585    pub unsafe fn set_len(&mut self, len: usize) {
586        self.storage.set_len(len);
587    }
588
589    /// Reserves capacity for at least `additional` more bytes to be inserted
590    /// into the given `BytesMut`.
591    ///
592    /// Before allocating new buffer space, the function will attempt to reclaim
593    /// space in the existing buffer. If the current handle references a small
594    /// view in the original buffer and all other handles have been dropped,
595    /// and the requested capacity is less than or equal to the existing
596    /// buffer's capacity, then the current view will be copied to the front of
597    /// the buffer and the handle will take ownership of the full buffer.
598    ///
599    /// Otherwise a unique buffer that is not a pooled page is reallocated,
600    /// often in place, and a new buffer is allocated in all other cases. The
601    /// new capacity is at least twice the current length, so appending in
602    /// small steps reallocates a logarithmic number of times. Use
603    /// [`reserve_exact`](Self::reserve_exact) to avoid the doubling.
604    ///
605    /// A buffer with a [`page_size`](Self::page_size) moves to a page of the
606    /// smallest size that fits the new capacity, but not smaller than its
607    /// current page size, the old page returns to the page cache. Above the
608    /// largest page size, a regular buffer without a page size is allocated.
609    ///
610    /// # Panics
611    ///
612    /// Panics if the new capacity exceeds `u32::MAX` minus the buffer
613    /// header size, just under 4 GiB.
614    ///
615    /// # Examples
616    ///
617    /// In the following example, a new buffer is allocated.
618    ///
619    /// ```
620    /// use ntex_bytes::BytesMut;
621    ///
622    /// let mut buf = BytesMut::copy_from_slice(&b"hello"[..]);
623    /// buf.reserve(64);
624    /// assert!(buf.capacity() >= 69);
625    /// ```
626    ///
627    /// In the following example, the existing buffer is reclaimed.
628    ///
629    /// ```
630    /// use ntex_bytes::{BytesMut, BufMut};
631    ///
632    /// let mut buf = BytesMut::with_capacity(128);
633    /// buf.put(&[0; 64][..]);
634    ///
635    /// let ptr = buf.as_ptr();
636    /// let other = buf.take();
637    ///
638    /// assert!(buf.is_empty());
639    /// assert_eq!(buf.capacity(), 64);
640    ///
641    /// drop(other);
642    /// buf.reserve(128);
643    ///
644    /// assert_eq!(buf.capacity(), 128);
645    /// assert_eq!(buf.as_ptr(), ptr);
646    /// ```
647    #[inline]
648    pub fn reserve(&mut self, additional: usize) {
649        self.storage.reserve(additional);
650    }
651
652    /// Reserves capacity for exactly `additional` more bytes to be inserted
653    /// into the given `BytesMut`.
654    ///
655    /// Behaves like [`reserve`](Self::reserve), it reclaims the existing buffer
656    /// when possible and reallocates a unique buffer, but a new allocation is
657    /// sized to hold exactly `additional` more bytes instead of growing to at
658    /// least twice the current length. The allocation size is the new capacity
659    /// plus the buffer header, [`METADATA_SIZE`](crate::METADATA_SIZE) bytes.
660    /// The contents are not moved when the buffer already has enough remaining
661    /// capacity.
662    ///
663    /// The capacity is not rounded up to a page size, a buffer with a
664    /// [`page_size`](Self::page_size) loses it unless the new capacity is a page
665    /// capacity.
666    ///
667    /// # Panics
668    ///
669    /// Panics if the new capacity exceeds `u32::MAX` minus the buffer
670    /// header size, just under 4 GiB.
671    ///
672    /// # Examples
673    ///
674    /// ```
675    /// use ntex_bytes::BytesMut;
676    ///
677    /// let mut buf = BytesMut::copy_from_slice(&[0; 1000][..]);
678    /// buf.reserve_exact(24);
679    /// assert_eq!(buf.capacity(), 1024);
680    ///
681    /// // enough remaining capacity keeps the current buffer
682    /// let ptr = buf.as_ptr();
683    /// buf.reserve_exact(24);
684    /// assert_eq!(buf.as_ptr(), ptr);
685    /// ```
686    #[inline]
687    pub fn reserve_exact(&mut self, additional: usize) {
688        self.storage.reserve_exact(additional);
689    }
690
691    /// Grows the buffer by one step if its remaining capacity is less than
692    /// the low threshold of its page size.
693    ///
694    /// Nothing happens when the remaining capacity is at least
695    /// [`BytePageSize::low`](crate::BytePageSize::low) of the buffer's
696    /// [`page_size`](Self::page_size), 1 KiB for a 16 KiB page and 4 KiB
697    /// for a buffer without a page size.
698    ///
699    /// If the allocation holds the data and
700    /// [`BytePageSize::half_capacity`](crate::BytePageSize::half_capacity)
701    /// more bytes, it is reused: a unique buffer moves its data to the start
702    /// of the allocation, a shared buffer with a page size moves to a page of
703    /// the same size. Otherwise a buffer with a page size moves to a page of
704    /// the next larger page size, the old page returns to the page cache. A
705    /// buffer without a page size, or with the largest page size, grows its
706    /// capacity by its current capacity, by at least 112 bytes (104 with the
707    /// `tracker` feature) and by at most 64 KiB, like [`reserve_exact`](Self::reserve_exact) does: a unique
708    /// buffer is reallocated, often in place, otherwise the data is copied
709    /// into a new buffer.
710    ///
711    /// # Panics
712    ///
713    /// Panics if the new capacity exceeds `u32::MAX` minus the buffer
714    /// header size, just under 4 GiB.
715    ///
716    /// # Examples
717    ///
718    /// ```
719    /// use ntex_bytes::{BytePageSize, BytesMut};
720    ///
721    /// let mut buf = BytesMut::with_page_size(BytePageSize::Size4);
722    /// buf.extend_from_slice(b"hello");
723    ///
724    /// // the remaining capacity is above the low threshold, the buffer is kept
725    /// buf.reserve_more();
726    /// assert_eq!(buf.page_size(), BytePageSize::Size4);
727    ///
728    /// buf.extend_from_slice(&[0; 4000]);
729    /// buf.reserve_more();
730    /// assert_eq!(buf.page_size(), BytePageSize::Size8);
731    /// assert_eq!(buf.capacity(), BytePageSize::Size8.capacity());
732    /// assert_eq!(&buf[..5], b"hello");
733    ///
734    /// // consumed data makes room, the page is compacted in place
735    /// let mut buf = BytesMut::with_page_size(BytePageSize::Size4);
736    /// buf.extend_from_slice(&[0; 4000]);
737    /// buf.advance_to(3990);
738    /// buf.reserve_more();
739    /// assert_eq!(buf.page_size(), BytePageSize::Size4);
740    /// assert_eq!(buf.capacity(), BytePageSize::Size4.capacity());
741    ///
742    /// let mut buf = BytesMut::with_capacity(1000);
743    /// buf.reserve_more();
744    /// assert_eq!(buf.capacity(), 2000);
745    ///
746    /// let mut buf = BytesMut::with_capacity(1024 * 1024);
747    /// buf.extend_from_slice(&vec![0; 1024 * 1024]);
748    /// buf.reserve_more();
749    /// assert_eq!(buf.capacity(), 1024 * 1024 + 64 * 1024);
750    /// ```
751    #[inline]
752    pub fn reserve_more(&mut self) {
753        self.storage.reserve_more();
754    }
755
756    /// Appends a byte slice to the buffer.
757    ///
758    /// Additional capacity is reserved automatically when needed.
759    ///
760    /// # Examples
761    ///
762    /// ```
763    /// use ntex_bytes::BytesMut;
764    ///
765    /// let mut buf = BytesMut::with_capacity(0);
766    /// buf.extend_from_slice(b"aaabbb");
767    /// buf.extend_from_slice(b"cccddd");
768    ///
769    /// assert_eq!(b"aaabbbcccddd", &buf[..]);
770    /// ```
771    #[inline]
772    pub fn extend_from_slice(&mut self, extend: &[u8]) {
773        self.put_slice(extend);
774    }
775
776    /// Returns an iterator over the bytes contained by the buffer.
777    ///
778    /// # Examples
779    ///
780    /// ```
781    /// use ntex_bytes::{Buf, BytesMut};
782    ///
783    /// let buf = BytesMut::copy_from_slice(&b"abc"[..]);
784    /// let mut iter = buf.iter();
785    ///
786    /// assert_eq!(iter.next().map(|b| *b), Some(b'a'));
787    /// assert_eq!(iter.next().map(|b| *b), Some(b'b'));
788    /// assert_eq!(iter.next().map(|b| *b), Some(b'c'));
789    /// assert_eq!(iter.next(), None);
790    /// ```
791    #[inline]
792    pub fn iter(&'_ self) -> std::slice::Iter<'_, u8> {
793        self.chunk().iter()
794    }
795}
796
797impl_buf!(BytesMut {});
798
799impl_slice_traits!(BytesMut);
800
801impl_partial_eq!(BytesMut);
802
803impl BufMut for BytesMut {
804    #[inline]
805    fn remaining_mut(&self) -> usize {
806        self.storage.remaining()
807    }
808
809    #[inline]
810    unsafe fn advance_mut(&mut self, cnt: usize) {
811        // This call will panic if `cnt` is too big
812        self.storage.set_len(self.len() + cnt);
813    }
814
815    #[inline]
816    fn chunk_mut(&mut self) -> &mut UninitSlice {
817        self.storage.spare_mut()
818    }
819
820    #[inline]
821    fn put<T: Buf>(&mut self, mut src: T)
822    where
823        Self: Sized,
824    {
825        self.reserve(src.remaining());
826        while src.has_remaining() {
827            let chunk = src.chunk();
828            let len = chunk.len();
829            self.put_slice(chunk);
830            src.advance(len);
831        }
832    }
833
834    #[inline]
835    fn put_slice(&mut self, src: &[u8]) {
836        self.reserve(src.len());
837        self.storage.put_slice_partial(src);
838    }
839
840    #[inline]
841    fn put_u8(&mut self, n: u8) {
842        self.reserve(1);
843        self.storage.put_u8(n);
844    }
845
846    #[inline]
847    fn put_i8(&mut self, n: i8) {
848        self.put_u8(n as u8);
849    }
850}
851
852/// Interop with the `bytes` crate: like `bytes::BytesMut`, the buffer grows on
853/// demand, so `remaining_mut()` reports `usize::MAX - len` and `chunk_mut()`
854/// is never empty. The native [`BufMut`] impl reports spare capacity instead.
855// SAFETY: Chunks expose only allocated spare bytes, and advancement checks capacity before exposing
856// caller-initialized data.
857unsafe impl bytes::buf::BufMut for BytesMut {
858    #[inline]
859    fn remaining_mut(&self) -> usize {
860        usize::MAX - self.len()
861    }
862
863    #[inline]
864    unsafe fn advance_mut(&mut self, cnt: usize) {
865        let remaining = BufMut::remaining_mut(self);
866        assert!(
867            cnt <= remaining,
868            "cannot advance past `remaining_mut`: {cnt:?} <= {remaining:?}"
869        );
870        BufMut::advance_mut(self, cnt);
871    }
872
873    #[inline]
874    fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
875        if BufMut::remaining_mut(self) == 0 {
876            self.reserve(64);
877        }
878        // SAFETY: The live buffer exclusively owns its spare capacity, which is exactly the
879        // returned range.
880        unsafe {
881            let ptr = self.storage.as_ptr();
882            bytes::buf::UninitSlice::from_raw_parts_mut(
883                ptr.add(self.len()),
884                BufMut::remaining_mut(self),
885            )
886        }
887    }
888
889    #[inline]
890    fn put<T: bytes::buf::Buf>(&mut self, mut src: T)
891    where
892        Self: Sized,
893    {
894        self.reserve(src.remaining());
895        while src.has_remaining() {
896            let chunk = src.chunk();
897            let len = chunk.len();
898            BufMut::put_slice(self, chunk);
899            src.advance(len);
900        }
901    }
902
903    #[inline]
904    fn put_slice(&mut self, src: &[u8]) {
905        BufMut::put_slice(self, src);
906    }
907
908    #[inline]
909    fn put_bytes(&mut self, val: u8, cnt: usize) {
910        self.reserve(cnt);
911        // SAFETY: `reserve(cnt)` provides writable space, and all `cnt` bytes are initialized
912        // before advancing.
913        unsafe {
914            ptr::write_bytes(self.storage.as_ptr().add(self.len()), val, cnt);
915            BufMut::advance_mut(self, cnt);
916        }
917    }
918
919    #[inline]
920    fn put_u8(&mut self, n: u8) {
921        BufMut::put_u8(self, n);
922    }
923
924    #[inline]
925    fn put_i8(&mut self, n: i8) {
926        BufMut::put_i8(self, n);
927    }
928}
929
930impl AsMut<[u8]> for BytesMut {
931    #[inline]
932    fn as_mut(&mut self) -> &mut [u8] {
933        self.storage.as_mut()
934    }
935}
936
937impl DerefMut for BytesMut {
938    #[inline]
939    fn deref_mut(&mut self) -> &mut [u8] {
940        self.storage.as_mut()
941    }
942}
943
944impl Eq for BytesMut {}
945
946impl PartialEq for BytesMut {
947    #[inline]
948    fn eq(&self, other: &BytesMut) -> bool {
949        self.storage.as_ref() == other.storage.as_ref()
950    }
951}
952
953impl borrow::BorrowMut<[u8]> for BytesMut {
954    #[inline]
955    fn borrow_mut(&mut self) -> &mut [u8] {
956        self.as_mut()
957    }
958}
959
960impl PartialEq<Bytes> for BytesMut {
961    fn eq(&self, other: &Bytes) -> bool {
962        other[..] == self[..]
963    }
964}
965
966impl PartialEq<BytesMut> for Bytes {
967    fn eq(&self, other: &BytesMut) -> bool {
968        *other == *self
969    }
970}
971
972impl_read!(BytesMut);
973
974impl io::Write for BytesMut {
975    fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
976        self.extend_from_slice(src);
977        Ok(src.len())
978    }
979
980    fn flush(&mut self) -> Result<(), io::Error> {
981        Ok(())
982    }
983}
984
985impl fmt::Write for BytesMut {
986    #[inline]
987    fn write_str(&mut self, s: &str) -> fmt::Result {
988        self.extend_from_slice(s.as_bytes());
989        Ok(())
990    }
991}
992
993impl Clone for BytesMut {
994    #[inline]
995    fn clone(&self) -> BytesMut {
996        BytesMut::from(&self[..])
997    }
998}
999
1000impl FromIterator<u8> for BytesMut {
1001    fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
1002        let iter = into_iter.into_iter();
1003        let (min, maybe_max) = iter.size_hint();
1004
1005        let mut out = BytesMut::with_capacity(maybe_max.unwrap_or(min));
1006        out.extend(iter);
1007        out
1008    }
1009}
1010
1011impl<'a> FromIterator<&'a u8> for BytesMut {
1012    fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
1013        into_iter.into_iter().copied().collect::<BytesMut>()
1014    }
1015}
1016
1017impl Extend<u8> for BytesMut {
1018    fn extend<T>(&mut self, iter: T)
1019    where
1020        T: IntoIterator<Item = u8>,
1021    {
1022        let iter = iter.into_iter();
1023        self.reserve(iter.size_hint().0);
1024        for b in iter {
1025            self.put_u8(b);
1026        }
1027    }
1028}
1029
1030impl<'a> Extend<&'a u8> for BytesMut {
1031    fn extend<T>(&mut self, iter: T)
1032    where
1033        T: IntoIterator<Item = &'a u8>,
1034    {
1035        self.extend(iter.into_iter().copied());
1036    }
1037}
1038
1039impl From<BytesMut> for Bytes {
1040    #[inline]
1041    fn from(b: BytesMut) -> Self {
1042        b.freeze()
1043    }
1044}
1045
1046impl<'a> From<&'a [u8]> for BytesMut {
1047    #[inline]
1048    fn from(src: &'a [u8]) -> BytesMut {
1049        BytesMut::copy_from_slice(src)
1050    }
1051}
1052
1053impl<const N: usize> From<[u8; N]> for BytesMut {
1054    #[inline]
1055    fn from(src: [u8; N]) -> BytesMut {
1056        BytesMut::copy_from_slice(src)
1057    }
1058}
1059
1060impl<'a, const N: usize> From<&'a [u8; N]> for BytesMut {
1061    #[inline]
1062    fn from(src: &'a [u8; N]) -> BytesMut {
1063        BytesMut::copy_from_slice(src)
1064    }
1065}
1066
1067impl<'a> From<&'a str> for BytesMut {
1068    #[inline]
1069    fn from(src: &'a str) -> BytesMut {
1070        BytesMut::from(src.as_bytes())
1071    }
1072}
1073
1074impl From<Bytes> for BytesMut {
1075    #[inline]
1076    fn from(src: Bytes) -> BytesMut {
1077        match src.storage.try_into_vec() {
1078            Ok(storage) => BytesMut { storage },
1079            Err(storage) => BytesMut::copy_from_slice(storage.as_ref()),
1080        }
1081    }
1082}
1083
1084impl From<&Bytes> for BytesMut {
1085    #[inline]
1086    fn from(src: &Bytes) -> BytesMut {
1087        BytesMut::copy_from_slice(&src[..])
1088    }
1089}
1090
1091#[cfg(test)]
1092mod tests {
1093    use super::*;
1094
1095    /// STATEMENT: Repeated small writes grow `BytesMut` amortized rather than reallocating for every write.
1096    ///
1097    /// HOW:
1098    /// - Append eight bytes 10,000 times and check length and at most 16 capacity changes.
1099    /// - Format 1,000 eight-digit numbers into another buffer and verify length and bounded capacity.
1100    #[test]
1101    fn growth_is_amortized() {
1102        let mut buf = BytesMut::with_capacity(0);
1103        let mut cap = buf.capacity();
1104        let mut reallocs = 0;
1105        for _ in 0..10_000 {
1106            buf.put_slice(b"abcdefgh");
1107            if buf.capacity() != cap {
1108                reallocs += 1;
1109                cap = buf.capacity();
1110            }
1111        }
1112        assert_eq!(buf.len(), 80_000);
1113        assert!(reallocs <= 16, "reallocs: {reallocs}");
1114
1115        // writes through `io::Write` and `fmt::Write` grow the same way
1116        let mut buf = BytesMut::with_capacity(0);
1117        for i in 0..1000 {
1118            std::fmt::Write::write_fmt(&mut buf, format_args!("{i:08}")).unwrap();
1119        }
1120        assert_eq!(buf.len(), 8000);
1121        assert!(buf.capacity() < 16_000);
1122    }
1123
1124    /// STATEMENT: Large reservations for small live data allocate only the requested additional capacity.
1125    ///
1126    /// HOW:
1127    /// - Reserve 64 KiB after `hello` and check capacity equals live length plus the request.
1128    /// - Split 1,000 bytes from a shared 1,024-byte buffer, reserve 4,096 for the tail, and check capacity and head data.
1129    #[test]
1130    fn growth_of_little_data_is_exact() {
1131        let mut buf = BytesMut::copy_from_slice(b"hello");
1132        buf.reserve(64 * 1024);
1133        assert_eq!(buf.capacity(), 5 + 64 * 1024);
1134
1135        // a buffer shared with split off `Bytes`
1136        let mut buf = BytesMut::with_capacity(1024);
1137        buf.extend_from_slice(&[1; 1024]);
1138        let head = buf.split_to(1000);
1139        buf.reserve(4096);
1140        assert_eq!(buf.capacity(), 24 + 4096);
1141        assert_eq!(&head[..], &[1; 1000][..]);
1142    }
1143
1144    /// STATEMENT: Converting uniquely owned vector-backed `Bytes` to `BytesMut` reuses spare capacity.
1145    ///
1146    /// HOW:
1147    /// - Freeze 64 bytes in a 256-byte buffer, convert back, and check pointer, contents, and capacity.
1148    /// - Fill the spare capacity and verify the pointer and appended bytes.
1149    #[test]
1150    fn from_unique_bytes_reuses_buffer() {
1151        let mut buf = BytesMut::with_capacity(256);
1152        buf.extend_from_slice(&[1; 64]);
1153        let b = buf.freeze();
1154        let ptr = b.as_ptr();
1155
1156        let mut m = BytesMut::from(b);
1157        assert_eq!(m.as_ptr(), ptr);
1158        assert_eq!(&m[..], &[1; 64][..]);
1159        assert_eq!(m.capacity(), 256);
1160
1161        // spare capacity past the view is writable
1162        m.extend_from_slice(&[2; 192]);
1163        assert_eq!(m.as_ptr(), ptr);
1164        assert_eq!(&m[64..], &[2; 192][..]);
1165    }
1166
1167    /// STATEMENT: A unique `Bytes` subview regains writable capacity after its visible end when made mutable.
1168    ///
1169    /// HOW:
1170    /// - Drop a split 32-byte head, truncate the tail, convert to `BytesMut`, and check pointer and tail capacity.
1171    /// - Append 160 bytes and verify old and new content without relocation.
1172    #[test]
1173    fn from_unique_bytes_subview() {
1174        let mut buf = BytesMut::with_capacity(256);
1175        buf.extend_from_slice(&[1; 128]);
1176        let mut b = buf.freeze();
1177        let head = b.split_to(32);
1178        drop(head);
1179        b.truncate(64);
1180        let ptr = b.as_ptr();
1181
1182        let mut m = BytesMut::from(b);
1183        assert_eq!(m.as_ptr(), ptr);
1184        assert_eq!(m.len(), 64);
1185        assert_eq!(m.capacity(), 256 - 32);
1186
1187        // the dropped tail of the view is spare capacity again
1188        m.extend_from_slice(&[3; 160]);
1189        assert_eq!(m.as_ptr(), ptr);
1190        assert_eq!(&m[..64], &[1; 64][..]);
1191        assert_eq!(&m[64..], &[3; 160][..]);
1192    }
1193
1194    /// STATEMENT: Converting shared `Bytes` to `BytesMut` copies rather than exposing shared mutable storage.
1195    ///
1196    /// HOW:
1197    /// - Keep a clone, convert its sibling, mutate it, and check distinct pointers and unchanged clone data.
1198    /// - Convert bytes taken from a live `BytesMut` and verify later writes to the original do not alter the copy.
1199    #[test]
1200    fn from_shared_bytes_copies() {
1201        let b = BytesMut::copy_from_slice([1; 64]).freeze();
1202        let b2 = b.clone();
1203
1204        let mut m = BytesMut::from(b);
1205        assert_ne!(m.as_ptr(), b2.as_ptr());
1206        m[0] = 2;
1207        assert_eq!(&b2[..], &[1; 64][..]);
1208
1209        // the buffer is still referenced by a `BytesMut`
1210        let mut buf = BytesMut::with_capacity(256);
1211        buf.extend_from_slice(&[1; 64]);
1212        let b = buf.take();
1213        let m = BytesMut::from(b);
1214        assert_ne!(m.as_ptr(), buf.as_ptr());
1215        buf.extend_from_slice(&[2; 64]);
1216        assert_eq!(&m[..], &[1; 64][..]);
1217    }
1218
1219    // Run under miri: without `Acquire`, the header update races with the
1220    // read made by the other thread before it released its handle.
1221    /// STATEMENT: Reclaiming unique `Bytes` storage synchronizes with a different thread releasing its view.
1222    ///
1223    /// HOW:
1224    /// - Read a cloned view on another thread while retrying `try_into_vec` until unique ownership is available.
1225    /// - Check pointer reuse, mutate the reclaimed buffer, and verify the joined thread read the original byte.
1226    #[test]
1227    fn from_bytes_synchronizes_with_release() {
1228        let b = BytesMut::copy_from_slice([1; 64]).freeze();
1229        let other = b.clone();
1230        let handle = std::thread::spawn(move || {
1231            let val = other[0];
1232            drop(other);
1233            val
1234        });
1235
1236        let ptr = b.as_ptr();
1237        let mut storage = b.storage;
1238        let mut m = loop {
1239            match storage.try_into_vec() {
1240                Ok(storage) => break BytesMut { storage },
1241                Err(st) => {
1242                    storage = st;
1243                    std::thread::yield_now();
1244                }
1245            }
1246        };
1247        assert_eq!(m.as_ptr(), ptr);
1248        m[0] = 2;
1249        assert_eq!(handle.join().unwrap(), 1);
1250    }
1251
1252    /// STATEMENT: Inline and static `Bytes` convert to mutable buffers with unchanged contents.
1253    ///
1254    /// HOW:
1255    /// - Convert inline `inline` bytes and a static 64-byte array with `BytesMut::from` and compare their contents.
1256    #[test]
1257    fn from_inline_and_static_bytes() {
1258        let m = BytesMut::from(Bytes::copy_from_slice(b"inline"));
1259        assert_eq!(&m[..], b"inline");
1260
1261        let m = BytesMut::from(Bytes::from_static(&[1; 64]));
1262        assert_eq!(&m[..], &[1; 64][..]);
1263    }
1264
1265    /// STATEMENT: Reading `BytesMut` consumes its contents without touching unused destination bytes.
1266    ///
1267    /// HOW:
1268    /// - Read `123` into a ten-byte zeroed array and verify a three-byte read, an empty buffer, and seven untouched zeros.
1269    #[test]
1270    fn bvec_read() {
1271        use std::io::Read;
1272
1273        let mut b = BytesMut::copy_from_slice(b"123");
1274
1275        let mut buf = [0; 10];
1276        assert_eq!(b.read(&mut buf).unwrap(), 3);
1277        assert_eq!(b.len(), 0);
1278        assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
1279    }
1280
1281    /// STATEMENT: Converting borrowed `Bytes` yields independently extensible mutable contents.
1282    ///
1283    /// HOW:
1284    /// - Convert borrowed static `hello`, append `!`, and verify `hello!` while the source remains `hello`.
1285    #[test]
1286    fn from_bytes_ref() {
1287        let b = Bytes::from_static(b"hello");
1288        let mut m = BytesMut::from(&b);
1289        m.extend_from_slice(b"!");
1290        assert_eq!(m, "hello!");
1291        assert_eq!(b, "hello");
1292    }
1293}