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}