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