• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::iter::FromIterator;
2 use core::ops::{Deref, RangeBounds};
3 use core::{cmp, fmt, hash, mem, ptr, slice, usize};
4 
5 use alloc::{
6     alloc::{dealloc, Layout},
7     borrow::Borrow,
8     boxed::Box,
9     string::String,
10     vec::Vec,
11 };
12 
13 use crate::buf::IntoIter;
14 #[allow(unused)]
15 use crate::loom::sync::atomic::AtomicMut;
16 use crate::loom::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
17 use crate::Buf;
18 
19 /// A cheaply cloneable and sliceable chunk of contiguous memory.
20 ///
21 /// `Bytes` is an efficient container for storing and operating on contiguous
22 /// slices of memory. It is intended for use primarily in networking code, but
23 /// could have applications elsewhere as well.
24 ///
25 /// `Bytes` values facilitate zero-copy network programming by allowing multiple
26 /// `Bytes` objects to point to the same underlying memory.
27 ///
28 /// `Bytes` does not have a single implementation. It is an interface, whose
29 /// exact behavior is implemented through dynamic dispatch in several underlying
30 /// implementations of `Bytes`.
31 ///
32 /// All `Bytes` implementations must fulfill the following requirements:
33 /// - They are cheaply cloneable and thereby shareable between an unlimited amount
34 ///   of components, for example by modifying a reference count.
35 /// - Instances can be sliced to refer to a subset of the original buffer.
36 ///
37 /// ```
38 /// use bytes::Bytes;
39 ///
40 /// let mut mem = Bytes::from("Hello world");
41 /// let a = mem.slice(0..5);
42 ///
43 /// assert_eq!(a, "Hello");
44 ///
45 /// let b = mem.split_to(6);
46 ///
47 /// assert_eq!(mem, "world");
48 /// assert_eq!(b, "Hello ");
49 /// ```
50 ///
51 /// # Memory layout
52 ///
53 /// The `Bytes` struct itself is fairly small, limited to 4 `usize` fields used
54 /// to track information about which segment of the underlying memory the
55 /// `Bytes` handle has access to.
56 ///
57 /// `Bytes` keeps both a pointer to the shared state containing the full memory
58 /// slice and a pointer to the start of the region visible by the handle.
59 /// `Bytes` also tracks the length of its view into the memory.
60 ///
61 /// # Sharing
62 ///
63 /// `Bytes` contains a vtable, which allows implementations of `Bytes` to define
64 /// how sharing/cloning is implemented in detail.
65 /// When `Bytes::clone()` is called, `Bytes` will call the vtable function for
66 /// cloning the backing storage in order to share it behind between multiple
67 /// `Bytes` instances.
68 ///
69 /// For `Bytes` implementations which refer to constant memory (e.g. created
70 /// via `Bytes::from_static()`) the cloning implementation will be a no-op.
71 ///
72 /// For `Bytes` implementations which point to a reference counted shared storage
73 /// (e.g. an `Arc<[u8]>`), sharing will be implemented by increasing the
74 /// reference count.
75 ///
76 /// Due to this mechanism, multiple `Bytes` instances may point to the same
77 /// shared memory region.
78 /// Each `Bytes` instance can point to different sections within that
79 /// memory region, and `Bytes` instances may or may not have overlapping views
80 /// into the memory.
81 ///
82 /// The following diagram visualizes a scenario where 2 `Bytes` instances make
83 /// use of an `Arc`-based backing storage, and provide access to different views:
84 ///
85 /// ```text
86 ///
87 ///    Arc ptrs                   ┌─────────┐
88 ///    ________________________ / │ Bytes 2 │
89 ///   /                           └─────────┘
90 ///  /          ┌───────────┐     |         |
91 /// |_________/ │  Bytes 1  │     |         |
92 /// |           └───────────┘     |         |
93 /// |           |           | ___/ data     | tail
94 /// |      data |      tail |/              |
95 /// v           v           v               v
96 /// ┌─────┬─────┬───────────┬───────────────┬─────┐
97 /// │ Arc │     │           │               │     │
98 /// └─────┴─────┴───────────┴───────────────┴─────┘
99 /// ```
100 pub struct Bytes {
101     ptr: *const u8,
102     len: usize,
103     // inlined "trait object"
104     data: AtomicPtr<()>,
105     vtable: &'static Vtable,
106 }
107 
108 pub(crate) struct Vtable {
109     /// fn(data, ptr, len)
110     pub clone: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Bytes,
111     /// fn(data, ptr, len)
112     ///
113     /// takes `Bytes` to value
114     pub to_vec: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Vec<u8>,
115     /// fn(data, ptr, len)
116     pub drop: unsafe fn(&mut AtomicPtr<()>, *const u8, usize),
117 }
118 
119 impl Bytes {
120     /// Creates a new empty `Bytes`.
121     ///
122     /// This will not allocate and the returned `Bytes` handle will be empty.
123     ///
124     /// # Examples
125     ///
126     /// ```
127     /// use bytes::Bytes;
128     ///
129     /// let b = Bytes::new();
130     /// assert_eq!(&b[..], b"");
131     /// ```
132     #[inline]
133     #[cfg(not(all(loom, test)))]
new() -> Self134     pub const fn new() -> Self {
135         // Make it a named const to work around
136         // "unsizing casts are not allowed in const fn"
137         const EMPTY: &[u8] = &[];
138         Bytes::from_static(EMPTY)
139     }
140 
141     #[cfg(all(loom, test))]
new() -> Self142     pub fn new() -> Self {
143         const EMPTY: &[u8] = &[];
144         Bytes::from_static(EMPTY)
145     }
146 
147     /// Creates a new `Bytes` from a static slice.
148     ///
149     /// The returned `Bytes` will point directly to the static slice. There is
150     /// no allocating or copying.
151     ///
152     /// # Examples
153     ///
154     /// ```
155     /// use bytes::Bytes;
156     ///
157     /// let b = Bytes::from_static(b"hello");
158     /// assert_eq!(&b[..], b"hello");
159     /// ```
160     #[inline]
161     #[cfg(not(all(loom, test)))]
from_static(bytes: &'static [u8]) -> Self162     pub const fn from_static(bytes: &'static [u8]) -> Self {
163         Bytes {
164             ptr: bytes.as_ptr(),
165             len: bytes.len(),
166             data: AtomicPtr::new(ptr::null_mut()),
167             vtable: &STATIC_VTABLE,
168         }
169     }
170 
171     #[cfg(all(loom, test))]
from_static(bytes: &'static [u8]) -> Self172     pub fn from_static(bytes: &'static [u8]) -> Self {
173         Bytes {
174             ptr: bytes.as_ptr(),
175             len: bytes.len(),
176             data: AtomicPtr::new(ptr::null_mut()),
177             vtable: &STATIC_VTABLE,
178         }
179     }
180 
181     /// Returns the number of bytes contained in this `Bytes`.
182     ///
183     /// # Examples
184     ///
185     /// ```
186     /// use bytes::Bytes;
187     ///
188     /// let b = Bytes::from(&b"hello"[..]);
189     /// assert_eq!(b.len(), 5);
190     /// ```
191     #[inline]
len(&self) -> usize192     pub const fn len(&self) -> usize {
193         self.len
194     }
195 
196     /// Returns true if the `Bytes` has a length of 0.
197     ///
198     /// # Examples
199     ///
200     /// ```
201     /// use bytes::Bytes;
202     ///
203     /// let b = Bytes::new();
204     /// assert!(b.is_empty());
205     /// ```
206     #[inline]
is_empty(&self) -> bool207     pub const fn is_empty(&self) -> bool {
208         self.len == 0
209     }
210 
211     /// Creates `Bytes` instance from slice, by copying it.
copy_from_slice(data: &[u8]) -> Self212     pub fn copy_from_slice(data: &[u8]) -> Self {
213         data.to_vec().into()
214     }
215 
216     /// Returns a slice of self for the provided range.
217     ///
218     /// This will increment the reference count for the underlying memory and
219     /// return a new `Bytes` handle set to the slice.
220     ///
221     /// This operation is `O(1)`.
222     ///
223     /// # Examples
224     ///
225     /// ```
226     /// use bytes::Bytes;
227     ///
228     /// let a = Bytes::from(&b"hello world"[..]);
229     /// let b = a.slice(2..5);
230     ///
231     /// assert_eq!(&b[..], b"llo");
232     /// ```
233     ///
234     /// # Panics
235     ///
236     /// Requires that `begin <= end` and `end <= self.len()`, otherwise slicing
237     /// will panic.
slice(&self, range: impl RangeBounds<usize>) -> Self238     pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
239         use core::ops::Bound;
240 
241         let len = self.len();
242 
243         let begin = match range.start_bound() {
244             Bound::Included(&n) => n,
245             Bound::Excluded(&n) => n + 1,
246             Bound::Unbounded => 0,
247         };
248 
249         let end = match range.end_bound() {
250             Bound::Included(&n) => n.checked_add(1).expect("out of range"),
251             Bound::Excluded(&n) => n,
252             Bound::Unbounded => len,
253         };
254 
255         assert!(
256             begin <= end,
257             "range start must not be greater than end: {:?} <= {:?}",
258             begin,
259             end,
260         );
261         assert!(
262             end <= len,
263             "range end out of bounds: {:?} <= {:?}",
264             end,
265             len,
266         );
267 
268         if end == begin {
269             return Bytes::new();
270         }
271 
272         let mut ret = self.clone();
273 
274         ret.len = end - begin;
275         ret.ptr = unsafe { ret.ptr.add(begin) };
276 
277         ret
278     }
279 
280     /// Returns a slice of self that is equivalent to the given `subset`.
281     ///
282     /// When processing a `Bytes` buffer with other tools, one often gets a
283     /// `&[u8]` which is in fact a slice of the `Bytes`, i.e. a subset of it.
284     /// This function turns that `&[u8]` into another `Bytes`, as if one had
285     /// called `self.slice()` with the offsets that correspond to `subset`.
286     ///
287     /// This operation is `O(1)`.
288     ///
289     /// # Examples
290     ///
291     /// ```
292     /// use bytes::Bytes;
293     ///
294     /// let bytes = Bytes::from(&b"012345678"[..]);
295     /// let as_slice = bytes.as_ref();
296     /// let subset = &as_slice[2..6];
297     /// let subslice = bytes.slice_ref(&subset);
298     /// assert_eq!(&subslice[..], b"2345");
299     /// ```
300     ///
301     /// # Panics
302     ///
303     /// Requires that the given `sub` slice is in fact contained within the
304     /// `Bytes` buffer; otherwise this function will panic.
slice_ref(&self, subset: &[u8]) -> Self305     pub fn slice_ref(&self, subset: &[u8]) -> Self {
306         // Empty slice and empty Bytes may have their pointers reset
307         // so explicitly allow empty slice to be a subslice of any slice.
308         if subset.is_empty() {
309             return Bytes::new();
310         }
311 
312         let bytes_p = self.as_ptr() as usize;
313         let bytes_len = self.len();
314 
315         let sub_p = subset.as_ptr() as usize;
316         let sub_len = subset.len();
317 
318         assert!(
319             sub_p >= bytes_p,
320             "subset pointer ({:p}) is smaller than self pointer ({:p})",
321             subset.as_ptr(),
322             self.as_ptr(),
323         );
324         assert!(
325             sub_p + sub_len <= bytes_p + bytes_len,
326             "subset is out of bounds: self = ({:p}, {}), subset = ({:p}, {})",
327             self.as_ptr(),
328             bytes_len,
329             subset.as_ptr(),
330             sub_len,
331         );
332 
333         let sub_offset = sub_p - bytes_p;
334 
335         self.slice(sub_offset..(sub_offset + sub_len))
336     }
337 
338     /// Splits the bytes into two at the given index.
339     ///
340     /// Afterwards `self` contains elements `[0, at)`, and the returned `Bytes`
341     /// contains elements `[at, len)`.
342     ///
343     /// This is an `O(1)` operation that just increases the reference count and
344     /// sets a few indices.
345     ///
346     /// # Examples
347     ///
348     /// ```
349     /// use bytes::Bytes;
350     ///
351     /// let mut a = Bytes::from(&b"hello world"[..]);
352     /// let b = a.split_off(5);
353     ///
354     /// assert_eq!(&a[..], b"hello");
355     /// assert_eq!(&b[..], b" world");
356     /// ```
357     ///
358     /// # Panics
359     ///
360     /// Panics if `at > len`.
361     #[must_use = "consider Bytes::truncate if you don't need the other half"]
split_off(&mut self, at: usize) -> Self362     pub fn split_off(&mut self, at: usize) -> Self {
363         assert!(
364             at <= self.len(),
365             "split_off out of bounds: {:?} <= {:?}",
366             at,
367             self.len(),
368         );
369 
370         if at == self.len() {
371             return Bytes::new();
372         }
373 
374         if at == 0 {
375             return mem::replace(self, Bytes::new());
376         }
377 
378         let mut ret = self.clone();
379 
380         self.len = at;
381 
382         unsafe { ret.inc_start(at) };
383 
384         ret
385     }
386 
387     /// Splits the bytes into two at the given index.
388     ///
389     /// Afterwards `self` contains elements `[at, len)`, and the returned
390     /// `Bytes` contains elements `[0, at)`.
391     ///
392     /// This is an `O(1)` operation that just increases the reference count and
393     /// sets a few indices.
394     ///
395     /// # Examples
396     ///
397     /// ```
398     /// use bytes::Bytes;
399     ///
400     /// let mut a = Bytes::from(&b"hello world"[..]);
401     /// let b = a.split_to(5);
402     ///
403     /// assert_eq!(&a[..], b" world");
404     /// assert_eq!(&b[..], b"hello");
405     /// ```
406     ///
407     /// # Panics
408     ///
409     /// Panics if `at > len`.
410     #[must_use = "consider Bytes::advance if you don't need the other half"]
split_to(&mut self, at: usize) -> Self411     pub fn split_to(&mut self, at: usize) -> Self {
412         assert!(
413             at <= self.len(),
414             "split_to out of bounds: {:?} <= {:?}",
415             at,
416             self.len(),
417         );
418 
419         if at == self.len() {
420             return mem::replace(self, Bytes::new());
421         }
422 
423         if at == 0 {
424             return Bytes::new();
425         }
426 
427         let mut ret = self.clone();
428 
429         unsafe { self.inc_start(at) };
430 
431         ret.len = at;
432         ret
433     }
434 
435     /// Shortens the buffer, keeping the first `len` bytes and dropping the
436     /// rest.
437     ///
438     /// If `len` is greater than the buffer's current length, this has no
439     /// effect.
440     ///
441     /// The [`split_off`] method can emulate `truncate`, but this causes the
442     /// excess bytes to be returned instead of dropped.
443     ///
444     /// # Examples
445     ///
446     /// ```
447     /// use bytes::Bytes;
448     ///
449     /// let mut buf = Bytes::from(&b"hello world"[..]);
450     /// buf.truncate(5);
451     /// assert_eq!(buf, b"hello"[..]);
452     /// ```
453     ///
454     /// [`split_off`]: #method.split_off
455     #[inline]
truncate(&mut self, len: usize)456     pub fn truncate(&mut self, len: usize) {
457         if len < self.len {
458             // The Vec "promotable" vtables do not store the capacity,
459             // so we cannot truncate while using this repr. We *have* to
460             // promote using `split_off` so the capacity can be stored.
461             if self.vtable as *const Vtable == &PROMOTABLE_EVEN_VTABLE
462                 || self.vtable as *const Vtable == &PROMOTABLE_ODD_VTABLE
463             {
464                 drop(self.split_off(len));
465             } else {
466                 self.len = len;
467             }
468         }
469     }
470 
471     /// Clears the buffer, removing all data.
472     ///
473     /// # Examples
474     ///
475     /// ```
476     /// use bytes::Bytes;
477     ///
478     /// let mut buf = Bytes::from(&b"hello world"[..]);
479     /// buf.clear();
480     /// assert!(buf.is_empty());
481     /// ```
482     #[inline]
clear(&mut self)483     pub fn clear(&mut self) {
484         self.truncate(0);
485     }
486 
487     #[inline]
with_vtable( ptr: *const u8, len: usize, data: AtomicPtr<()>, vtable: &'static Vtable, ) -> Bytes488     pub(crate) unsafe fn with_vtable(
489         ptr: *const u8,
490         len: usize,
491         data: AtomicPtr<()>,
492         vtable: &'static Vtable,
493     ) -> Bytes {
494         Bytes {
495             ptr,
496             len,
497             data,
498             vtable,
499         }
500     }
501 
502     // private
503 
504     #[inline]
as_slice(&self) -> &[u8]505     fn as_slice(&self) -> &[u8] {
506         unsafe { slice::from_raw_parts(self.ptr, self.len) }
507     }
508 
509     #[inline]
inc_start(&mut self, by: usize)510     unsafe fn inc_start(&mut self, by: usize) {
511         // should already be asserted, but debug assert for tests
512         debug_assert!(self.len >= by, "internal: inc_start out of bounds");
513         self.len -= by;
514         self.ptr = self.ptr.add(by);
515     }
516 }
517 
518 // Vtable must enforce this behavior
519 unsafe impl Send for Bytes {}
520 unsafe impl Sync for Bytes {}
521 
522 impl Drop for Bytes {
523     #[inline]
drop(&mut self)524     fn drop(&mut self) {
525         unsafe { (self.vtable.drop)(&mut self.data, self.ptr, self.len) }
526     }
527 }
528 
529 impl Clone for Bytes {
530     #[inline]
clone(&self) -> Bytes531     fn clone(&self) -> Bytes {
532         unsafe { (self.vtable.clone)(&self.data, self.ptr, self.len) }
533     }
534 }
535 
536 impl Buf for Bytes {
537     #[inline]
remaining(&self) -> usize538     fn remaining(&self) -> usize {
539         self.len()
540     }
541 
542     #[inline]
chunk(&self) -> &[u8]543     fn chunk(&self) -> &[u8] {
544         self.as_slice()
545     }
546 
547     #[inline]
advance(&mut self, cnt: usize)548     fn advance(&mut self, cnt: usize) {
549         assert!(
550             cnt <= self.len(),
551             "cannot advance past `remaining`: {:?} <= {:?}",
552             cnt,
553             self.len(),
554         );
555 
556         unsafe {
557             self.inc_start(cnt);
558         }
559     }
560 
copy_to_bytes(&mut self, len: usize) -> crate::Bytes561     fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes {
562         if len == self.remaining() {
563             core::mem::replace(self, Bytes::new())
564         } else {
565             let ret = self.slice(..len);
566             self.advance(len);
567             ret
568         }
569     }
570 }
571 
572 impl Deref for Bytes {
573     type Target = [u8];
574 
575     #[inline]
deref(&self) -> &[u8]576     fn deref(&self) -> &[u8] {
577         self.as_slice()
578     }
579 }
580 
581 impl AsRef<[u8]> for Bytes {
582     #[inline]
as_ref(&self) -> &[u8]583     fn as_ref(&self) -> &[u8] {
584         self.as_slice()
585     }
586 }
587 
588 impl hash::Hash for Bytes {
hash<H>(&self, state: &mut H) where H: hash::Hasher,589     fn hash<H>(&self, state: &mut H)
590     where
591         H: hash::Hasher,
592     {
593         self.as_slice().hash(state);
594     }
595 }
596 
597 impl Borrow<[u8]> for Bytes {
borrow(&self) -> &[u8]598     fn borrow(&self) -> &[u8] {
599         self.as_slice()
600     }
601 }
602 
603 impl IntoIterator for Bytes {
604     type Item = u8;
605     type IntoIter = IntoIter<Bytes>;
606 
into_iter(self) -> Self::IntoIter607     fn into_iter(self) -> Self::IntoIter {
608         IntoIter::new(self)
609     }
610 }
611 
612 impl<'a> IntoIterator for &'a Bytes {
613     type Item = &'a u8;
614     type IntoIter = core::slice::Iter<'a, u8>;
615 
into_iter(self) -> Self::IntoIter616     fn into_iter(self) -> Self::IntoIter {
617         self.as_slice().iter()
618     }
619 }
620 
621 impl FromIterator<u8> for Bytes {
from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self622     fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
623         Vec::from_iter(into_iter).into()
624     }
625 }
626 
627 // impl Eq
628 
629 impl PartialEq for Bytes {
eq(&self, other: &Bytes) -> bool630     fn eq(&self, other: &Bytes) -> bool {
631         self.as_slice() == other.as_slice()
632     }
633 }
634 
635 impl PartialOrd for Bytes {
partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering>636     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
637         self.as_slice().partial_cmp(other.as_slice())
638     }
639 }
640 
641 impl Ord for Bytes {
cmp(&self, other: &Bytes) -> cmp::Ordering642     fn cmp(&self, other: &Bytes) -> cmp::Ordering {
643         self.as_slice().cmp(other.as_slice())
644     }
645 }
646 
647 impl Eq for Bytes {}
648 
649 impl PartialEq<[u8]> for Bytes {
eq(&self, other: &[u8]) -> bool650     fn eq(&self, other: &[u8]) -> bool {
651         self.as_slice() == other
652     }
653 }
654 
655 impl PartialOrd<[u8]> for Bytes {
partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering>656     fn partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering> {
657         self.as_slice().partial_cmp(other)
658     }
659 }
660 
661 impl PartialEq<Bytes> for [u8] {
eq(&self, other: &Bytes) -> bool662     fn eq(&self, other: &Bytes) -> bool {
663         *other == *self
664     }
665 }
666 
667 impl PartialOrd<Bytes> for [u8] {
partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering>668     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
669         <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
670     }
671 }
672 
673 impl PartialEq<str> for Bytes {
eq(&self, other: &str) -> bool674     fn eq(&self, other: &str) -> bool {
675         self.as_slice() == other.as_bytes()
676     }
677 }
678 
679 impl PartialOrd<str> for Bytes {
partial_cmp(&self, other: &str) -> Option<cmp::Ordering>680     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
681         self.as_slice().partial_cmp(other.as_bytes())
682     }
683 }
684 
685 impl PartialEq<Bytes> for str {
eq(&self, other: &Bytes) -> bool686     fn eq(&self, other: &Bytes) -> bool {
687         *other == *self
688     }
689 }
690 
691 impl PartialOrd<Bytes> for str {
partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering>692     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
693         <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
694     }
695 }
696 
697 impl PartialEq<Vec<u8>> for Bytes {
eq(&self, other: &Vec<u8>) -> bool698     fn eq(&self, other: &Vec<u8>) -> bool {
699         *self == other[..]
700     }
701 }
702 
703 impl PartialOrd<Vec<u8>> for Bytes {
partial_cmp(&self, other: &Vec<u8>) -> Option<cmp::Ordering>704     fn partial_cmp(&self, other: &Vec<u8>) -> Option<cmp::Ordering> {
705         self.as_slice().partial_cmp(&other[..])
706     }
707 }
708 
709 impl PartialEq<Bytes> for Vec<u8> {
eq(&self, other: &Bytes) -> bool710     fn eq(&self, other: &Bytes) -> bool {
711         *other == *self
712     }
713 }
714 
715 impl PartialOrd<Bytes> for Vec<u8> {
partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering>716     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
717         <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
718     }
719 }
720 
721 impl PartialEq<String> for Bytes {
eq(&self, other: &String) -> bool722     fn eq(&self, other: &String) -> bool {
723         *self == other[..]
724     }
725 }
726 
727 impl PartialOrd<String> for Bytes {
partial_cmp(&self, other: &String) -> Option<cmp::Ordering>728     fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
729         self.as_slice().partial_cmp(other.as_bytes())
730     }
731 }
732 
733 impl PartialEq<Bytes> for String {
eq(&self, other: &Bytes) -> bool734     fn eq(&self, other: &Bytes) -> bool {
735         *other == *self
736     }
737 }
738 
739 impl PartialOrd<Bytes> for String {
partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering>740     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
741         <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
742     }
743 }
744 
745 impl PartialEq<Bytes> for &[u8] {
eq(&self, other: &Bytes) -> bool746     fn eq(&self, other: &Bytes) -> bool {
747         *other == *self
748     }
749 }
750 
751 impl PartialOrd<Bytes> for &[u8] {
partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering>752     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
753         <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
754     }
755 }
756 
757 impl PartialEq<Bytes> for &str {
eq(&self, other: &Bytes) -> bool758     fn eq(&self, other: &Bytes) -> bool {
759         *other == *self
760     }
761 }
762 
763 impl PartialOrd<Bytes> for &str {
partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering>764     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
765         <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
766     }
767 }
768 
769 impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
770 where
771     Bytes: PartialEq<T>,
772 {
eq(&self, other: &&'a T) -> bool773     fn eq(&self, other: &&'a T) -> bool {
774         *self == **other
775     }
776 }
777 
778 impl<'a, T: ?Sized> PartialOrd<&'a T> for Bytes
779 where
780     Bytes: PartialOrd<T>,
781 {
partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering>782     fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
783         self.partial_cmp(&**other)
784     }
785 }
786 
787 // impl From
788 
789 impl Default for Bytes {
790     #[inline]
default() -> Bytes791     fn default() -> Bytes {
792         Bytes::new()
793     }
794 }
795 
796 impl From<&'static [u8]> for Bytes {
from(slice: &'static [u8]) -> Bytes797     fn from(slice: &'static [u8]) -> Bytes {
798         Bytes::from_static(slice)
799     }
800 }
801 
802 impl From<&'static str> for Bytes {
from(slice: &'static str) -> Bytes803     fn from(slice: &'static str) -> Bytes {
804         Bytes::from_static(slice.as_bytes())
805     }
806 }
807 
808 impl From<Vec<u8>> for Bytes {
from(vec: Vec<u8>) -> Bytes809     fn from(vec: Vec<u8>) -> Bytes {
810         let mut vec = vec;
811         let ptr = vec.as_mut_ptr();
812         let len = vec.len();
813         let cap = vec.capacity();
814 
815         // Avoid an extra allocation if possible.
816         if len == cap {
817             return Bytes::from(vec.into_boxed_slice());
818         }
819 
820         let shared = Box::new(Shared {
821             buf: ptr,
822             cap,
823             ref_cnt: AtomicUsize::new(1),
824         });
825         mem::forget(vec);
826 
827         let shared = Box::into_raw(shared);
828         // The pointer should be aligned, so this assert should
829         // always succeed.
830         debug_assert!(
831             0 == (shared as usize & KIND_MASK),
832             "internal: Box<Shared> should have an aligned pointer",
833         );
834         Bytes {
835             ptr,
836             len,
837             data: AtomicPtr::new(shared as _),
838             vtable: &SHARED_VTABLE,
839         }
840     }
841 }
842 
843 impl From<Box<[u8]>> for Bytes {
from(slice: Box<[u8]>) -> Bytes844     fn from(slice: Box<[u8]>) -> Bytes {
845         // Box<[u8]> doesn't contain a heap allocation for empty slices,
846         // so the pointer isn't aligned enough for the KIND_VEC stashing to
847         // work.
848         if slice.is_empty() {
849             return Bytes::new();
850         }
851 
852         let len = slice.len();
853         let ptr = Box::into_raw(slice) as *mut u8;
854 
855         if ptr as usize & 0x1 == 0 {
856             let data = ptr_map(ptr, |addr| addr | KIND_VEC);
857             Bytes {
858                 ptr,
859                 len,
860                 data: AtomicPtr::new(data.cast()),
861                 vtable: &PROMOTABLE_EVEN_VTABLE,
862             }
863         } else {
864             Bytes {
865                 ptr,
866                 len,
867                 data: AtomicPtr::new(ptr.cast()),
868                 vtable: &PROMOTABLE_ODD_VTABLE,
869             }
870         }
871     }
872 }
873 
874 impl From<String> for Bytes {
from(s: String) -> Bytes875     fn from(s: String) -> Bytes {
876         Bytes::from(s.into_bytes())
877     }
878 }
879 
880 impl From<Bytes> for Vec<u8> {
from(bytes: Bytes) -> Vec<u8>881     fn from(bytes: Bytes) -> Vec<u8> {
882         let bytes = mem::ManuallyDrop::new(bytes);
883         unsafe { (bytes.vtable.to_vec)(&bytes.data, bytes.ptr, bytes.len) }
884     }
885 }
886 
887 // ===== impl Vtable =====
888 
889 impl fmt::Debug for Vtable {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result890     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
891         f.debug_struct("Vtable")
892             .field("clone", &(self.clone as *const ()))
893             .field("drop", &(self.drop as *const ()))
894             .finish()
895     }
896 }
897 
898 // ===== impl StaticVtable =====
899 
900 const STATIC_VTABLE: Vtable = Vtable {
901     clone: static_clone,
902     to_vec: static_to_vec,
903     drop: static_drop,
904 };
905 
static_clone(_: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes906 unsafe fn static_clone(_: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
907     let slice = slice::from_raw_parts(ptr, len);
908     Bytes::from_static(slice)
909 }
910 
static_to_vec(_: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8>911 unsafe fn static_to_vec(_: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
912     let slice = slice::from_raw_parts(ptr, len);
913     slice.to_vec()
914 }
915 
static_drop(_: &mut AtomicPtr<()>, _: *const u8, _: usize)916 unsafe fn static_drop(_: &mut AtomicPtr<()>, _: *const u8, _: usize) {
917     // nothing to drop for &'static [u8]
918 }
919 
920 // ===== impl PromotableVtable =====
921 
922 static PROMOTABLE_EVEN_VTABLE: Vtable = Vtable {
923     clone: promotable_even_clone,
924     to_vec: promotable_even_to_vec,
925     drop: promotable_even_drop,
926 };
927 
928 static PROMOTABLE_ODD_VTABLE: Vtable = Vtable {
929     clone: promotable_odd_clone,
930     to_vec: promotable_odd_to_vec,
931     drop: promotable_odd_drop,
932 };
933 
promotable_even_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes934 unsafe fn promotable_even_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
935     let shared = data.load(Ordering::Acquire);
936     let kind = shared as usize & KIND_MASK;
937 
938     if kind == KIND_ARC {
939         shallow_clone_arc(shared.cast(), ptr, len)
940     } else {
941         debug_assert_eq!(kind, KIND_VEC);
942         let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
943         shallow_clone_vec(data, shared, buf, ptr, len)
944     }
945 }
946 
promotable_to_vec( data: &AtomicPtr<()>, ptr: *const u8, len: usize, f: fn(*mut ()) -> *mut u8, ) -> Vec<u8>947 unsafe fn promotable_to_vec(
948     data: &AtomicPtr<()>,
949     ptr: *const u8,
950     len: usize,
951     f: fn(*mut ()) -> *mut u8,
952 ) -> Vec<u8> {
953     let shared = data.load(Ordering::Acquire);
954     let kind = shared as usize & KIND_MASK;
955 
956     if kind == KIND_ARC {
957         shared_to_vec_impl(shared.cast(), ptr, len)
958     } else {
959         // If Bytes holds a Vec, then the offset must be 0.
960         debug_assert_eq!(kind, KIND_VEC);
961 
962         let buf = f(shared);
963 
964         let cap = (ptr as usize - buf as usize) + len;
965 
966         // Copy back buffer
967         ptr::copy(ptr, buf, len);
968 
969         Vec::from_raw_parts(buf, len, cap)
970     }
971 }
972 
promotable_even_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8>973 unsafe fn promotable_even_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
974     promotable_to_vec(data, ptr, len, |shared| {
975         ptr_map(shared.cast(), |addr| addr & !KIND_MASK)
976     })
977 }
978 
promotable_even_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize)979 unsafe fn promotable_even_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
980     data.with_mut(|shared| {
981         let shared = *shared;
982         let kind = shared as usize & KIND_MASK;
983 
984         if kind == KIND_ARC {
985             release_shared(shared.cast());
986         } else {
987             debug_assert_eq!(kind, KIND_VEC);
988             let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
989             free_boxed_slice(buf, ptr, len);
990         }
991     });
992 }
993 
promotable_odd_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes994 unsafe fn promotable_odd_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
995     let shared = data.load(Ordering::Acquire);
996     let kind = shared as usize & KIND_MASK;
997 
998     if kind == KIND_ARC {
999         shallow_clone_arc(shared as _, ptr, len)
1000     } else {
1001         debug_assert_eq!(kind, KIND_VEC);
1002         shallow_clone_vec(data, shared, shared.cast(), ptr, len)
1003     }
1004 }
1005 
promotable_odd_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8>1006 unsafe fn promotable_odd_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
1007     promotable_to_vec(data, ptr, len, |shared| shared.cast())
1008 }
1009 
promotable_odd_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize)1010 unsafe fn promotable_odd_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
1011     data.with_mut(|shared| {
1012         let shared = *shared;
1013         let kind = shared as usize & KIND_MASK;
1014 
1015         if kind == KIND_ARC {
1016             release_shared(shared.cast());
1017         } else {
1018             debug_assert_eq!(kind, KIND_VEC);
1019 
1020             free_boxed_slice(shared.cast(), ptr, len);
1021         }
1022     });
1023 }
1024 
free_boxed_slice(buf: *mut u8, offset: *const u8, len: usize)1025 unsafe fn free_boxed_slice(buf: *mut u8, offset: *const u8, len: usize) {
1026     let cap = (offset as usize - buf as usize) + len;
1027     dealloc(buf, Layout::from_size_align(cap, 1).unwrap())
1028 }
1029 
1030 // ===== impl SharedVtable =====
1031 
1032 struct Shared {
1033     // Holds arguments to dealloc upon Drop, but otherwise doesn't use them
1034     buf: *mut u8,
1035     cap: usize,
1036     ref_cnt: AtomicUsize,
1037 }
1038 
1039 impl Drop for Shared {
drop(&mut self)1040     fn drop(&mut self) {
1041         unsafe { dealloc(self.buf, Layout::from_size_align(self.cap, 1).unwrap()) }
1042     }
1043 }
1044 
1045 // Assert that the alignment of `Shared` is divisible by 2.
1046 // This is a necessary invariant since we depend on allocating `Shared` a
1047 // shared object to implicitly carry the `KIND_ARC` flag in its pointer.
1048 // This flag is set when the LSB is 0.
1049 const _: [(); 0 - mem::align_of::<Shared>() % 2] = []; // Assert that the alignment of `Shared` is divisible by 2.
1050 
1051 static SHARED_VTABLE: Vtable = Vtable {
1052     clone: shared_clone,
1053     to_vec: shared_to_vec,
1054     drop: shared_drop,
1055 };
1056 
1057 const KIND_ARC: usize = 0b0;
1058 const KIND_VEC: usize = 0b1;
1059 const KIND_MASK: usize = 0b1;
1060 
shared_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes1061 unsafe fn shared_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1062     let shared = data.load(Ordering::Relaxed);
1063     shallow_clone_arc(shared as _, ptr, len)
1064 }
1065 
shared_to_vec_impl(shared: *mut Shared, ptr: *const u8, len: usize) -> Vec<u8>1066 unsafe fn shared_to_vec_impl(shared: *mut Shared, ptr: *const u8, len: usize) -> Vec<u8> {
1067     // Check that the ref_cnt is 1 (unique).
1068     //
1069     // If it is unique, then it is set to 0 with AcqRel fence for the same
1070     // reason in release_shared.
1071     //
1072     // Otherwise, we take the other branch and call release_shared.
1073     if (*shared)
1074         .ref_cnt
1075         .compare_exchange(1, 0, Ordering::AcqRel, Ordering::Relaxed)
1076         .is_ok()
1077     {
1078         let buf = (*shared).buf;
1079         let cap = (*shared).cap;
1080 
1081         // Deallocate Shared
1082         drop(Box::from_raw(shared as *mut mem::ManuallyDrop<Shared>));
1083 
1084         // Copy back buffer
1085         ptr::copy(ptr, buf, len);
1086 
1087         Vec::from_raw_parts(buf, len, cap)
1088     } else {
1089         let v = slice::from_raw_parts(ptr, len).to_vec();
1090         release_shared(shared);
1091         v
1092     }
1093 }
1094 
shared_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8>1095 unsafe fn shared_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
1096     shared_to_vec_impl(data.load(Ordering::Relaxed).cast(), ptr, len)
1097 }
1098 
shared_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize)1099 unsafe fn shared_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
1100     data.with_mut(|shared| {
1101         release_shared(shared.cast());
1102     });
1103 }
1104 
shallow_clone_arc(shared: *mut Shared, ptr: *const u8, len: usize) -> Bytes1105 unsafe fn shallow_clone_arc(shared: *mut Shared, ptr: *const u8, len: usize) -> Bytes {
1106     let old_size = (*shared).ref_cnt.fetch_add(1, Ordering::Relaxed);
1107 
1108     if old_size > usize::MAX >> 1 {
1109         crate::abort();
1110     }
1111 
1112     Bytes {
1113         ptr,
1114         len,
1115         data: AtomicPtr::new(shared as _),
1116         vtable: &SHARED_VTABLE,
1117     }
1118 }
1119 
1120 #[cold]
shallow_clone_vec( atom: &AtomicPtr<()>, ptr: *const (), buf: *mut u8, offset: *const u8, len: usize, ) -> Bytes1121 unsafe fn shallow_clone_vec(
1122     atom: &AtomicPtr<()>,
1123     ptr: *const (),
1124     buf: *mut u8,
1125     offset: *const u8,
1126     len: usize,
1127 ) -> Bytes {
1128     // If  the buffer is still tracked in a `Vec<u8>`. It is time to
1129     // promote the vec to an `Arc`. This could potentially be called
1130     // concurrently, so some care must be taken.
1131 
1132     // First, allocate a new `Shared` instance containing the
1133     // `Vec` fields. It's important to note that `ptr`, `len`,
1134     // and `cap` cannot be mutated without having `&mut self`.
1135     // This means that these fields will not be concurrently
1136     // updated and since the buffer hasn't been promoted to an
1137     // `Arc`, those three fields still are the components of the
1138     // vector.
1139     let shared = Box::new(Shared {
1140         buf,
1141         cap: (offset as usize - buf as usize) + len,
1142         // Initialize refcount to 2. One for this reference, and one
1143         // for the new clone that will be returned from
1144         // `shallow_clone`.
1145         ref_cnt: AtomicUsize::new(2),
1146     });
1147 
1148     let shared = Box::into_raw(shared);
1149 
1150     // The pointer should be aligned, so this assert should
1151     // always succeed.
1152     debug_assert!(
1153         0 == (shared as usize & KIND_MASK),
1154         "internal: Box<Shared> should have an aligned pointer",
1155     );
1156 
1157     // Try compare & swapping the pointer into the `arc` field.
1158     // `Release` is used synchronize with other threads that
1159     // will load the `arc` field.
1160     //
1161     // If the `compare_exchange` fails, then the thread lost the
1162     // race to promote the buffer to shared. The `Acquire`
1163     // ordering will synchronize with the `compare_exchange`
1164     // that happened in the other thread and the `Shared`
1165     // pointed to by `actual` will be visible.
1166     match atom.compare_exchange(ptr as _, shared as _, Ordering::AcqRel, Ordering::Acquire) {
1167         Ok(actual) => {
1168             debug_assert!(actual as usize == ptr as usize);
1169             // The upgrade was successful, the new handle can be
1170             // returned.
1171             Bytes {
1172                 ptr: offset,
1173                 len,
1174                 data: AtomicPtr::new(shared as _),
1175                 vtable: &SHARED_VTABLE,
1176             }
1177         }
1178         Err(actual) => {
1179             // The upgrade failed, a concurrent clone happened. Release
1180             // the allocation that was made in this thread, it will not
1181             // be needed.
1182             let shared = Box::from_raw(shared);
1183             mem::forget(*shared);
1184 
1185             // Buffer already promoted to shared storage, so increment ref
1186             // count.
1187             shallow_clone_arc(actual as _, offset, len)
1188         }
1189     }
1190 }
1191 
release_shared(ptr: *mut Shared)1192 unsafe fn release_shared(ptr: *mut Shared) {
1193     // `Shared` storage... follow the drop steps from Arc.
1194     if (*ptr).ref_cnt.fetch_sub(1, Ordering::Release) != 1 {
1195         return;
1196     }
1197 
1198     // This fence is needed to prevent reordering of use of the data and
1199     // deletion of the data.  Because it is marked `Release`, the decreasing
1200     // of the reference count synchronizes with this `Acquire` fence. This
1201     // means that use of the data happens before decreasing the reference
1202     // count, which happens before this fence, which happens before the
1203     // deletion of the data.
1204     //
1205     // As explained in the [Boost documentation][1],
1206     //
1207     // > It is important to enforce any possible access to the object in one
1208     // > thread (through an existing reference) to *happen before* deleting
1209     // > the object in a different thread. This is achieved by a "release"
1210     // > operation after dropping a reference (any access to the object
1211     // > through this reference must obviously happened before), and an
1212     // > "acquire" operation before deleting the object.
1213     //
1214     // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
1215     //
1216     // Thread sanitizer does not support atomic fences. Use an atomic load
1217     // instead.
1218     (*ptr).ref_cnt.load(Ordering::Acquire);
1219 
1220     // Drop the data
1221     drop(Box::from_raw(ptr));
1222 }
1223 
1224 // Ideally we would always use this version of `ptr_map` since it is strict
1225 // provenance compatible, but it results in worse codegen. We will however still
1226 // use it on miri because it gives better diagnostics for people who test bytes
1227 // code with miri.
1228 //
1229 // See https://github.com/tokio-rs/bytes/pull/545 for more info.
1230 #[cfg(miri)]
ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8 where F: FnOnce(usize) -> usize,1231 fn ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8
1232 where
1233     F: FnOnce(usize) -> usize,
1234 {
1235     let old_addr = ptr as usize;
1236     let new_addr = f(old_addr);
1237     let diff = new_addr.wrapping_sub(old_addr);
1238     ptr.wrapping_add(diff)
1239 }
1240 
1241 #[cfg(not(miri))]
ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8 where F: FnOnce(usize) -> usize,1242 fn ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8
1243 where
1244     F: FnOnce(usize) -> usize,
1245 {
1246     let old_addr = ptr as usize;
1247     let new_addr = f(old_addr);
1248     new_addr as *mut u8
1249 }
1250 
1251 // compile-fails
1252 
1253 /// ```compile_fail
1254 /// use bytes::Bytes;
1255 /// #[deny(unused_must_use)]
1256 /// {
1257 ///     let mut b1 = Bytes::from("hello world");
1258 ///     b1.split_to(6);
1259 /// }
1260 /// ```
_split_to_must_use()1261 fn _split_to_must_use() {}
1262 
1263 /// ```compile_fail
1264 /// use bytes::Bytes;
1265 /// #[deny(unused_must_use)]
1266 /// {
1267 ///     let mut b1 = Bytes::from("hello world");
1268 ///     b1.split_off(6);
1269 /// }
1270 /// ```
_split_off_must_use()1271 fn _split_off_must_use() {}
1272 
1273 // fuzz tests
1274 #[cfg(all(test, loom))]
1275 mod fuzz {
1276     use loom::sync::Arc;
1277     use loom::thread;
1278 
1279     use super::Bytes;
1280     #[test]
bytes_cloning_vec()1281     fn bytes_cloning_vec() {
1282         loom::model(|| {
1283             let a = Bytes::from(b"abcdefgh".to_vec());
1284             let addr = a.as_ptr() as usize;
1285 
1286             // test the Bytes::clone is Sync by putting it in an Arc
1287             let a1 = Arc::new(a);
1288             let a2 = a1.clone();
1289 
1290             let t1 = thread::spawn(move || {
1291                 let b: Bytes = (*a1).clone();
1292                 assert_eq!(b.as_ptr() as usize, addr);
1293             });
1294 
1295             let t2 = thread::spawn(move || {
1296                 let b: Bytes = (*a2).clone();
1297                 assert_eq!(b.as_ptr() as usize, addr);
1298             });
1299 
1300             t1.join().unwrap();
1301             t2.join().unwrap();
1302         });
1303     }
1304 }
1305