1 #![allow(unknown_lints, unexpected_cfgs)]
2 #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
3 #![doc(test(
4     no_crate_inject,
5     attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
6 ))]
7 #![no_std]
8 #![cfg_attr(docsrs, feature(doc_cfg))]
9 
10 //! Provides abstractions for working with bytes.
11 //!
12 //! The `bytes` crate provides an efficient byte buffer structure
13 //! ([`Bytes`]) and traits for working with buffer
14 //! implementations ([`Buf`], [`BufMut`]).
15 //!
16 //! # `Bytes`
17 //!
18 //! `Bytes` is an efficient container for storing and operating on contiguous
19 //! slices of memory. It is intended for use primarily in networking code, but
20 //! could have applications elsewhere as well.
21 //!
22 //! `Bytes` values facilitate zero-copy network programming by allowing multiple
23 //! `Bytes` objects to point to the same underlying memory. This is managed by
24 //! using a reference count to track when the memory is no longer needed and can
25 //! be freed.
26 //!
27 //! A `Bytes` handle can be created directly from an existing byte store (such as `&[u8]`
28 //! or `Vec<u8>`), but usually a `BytesMut` is used first and written to. For
29 //! example:
30 //!
31 //! ```rust
32 //! use bytes::{BytesMut, BufMut};
33 //!
34 //! let mut buf = BytesMut::with_capacity(1024);
35 //! buf.put(&b"hello world"[..]);
36 //! buf.put_u16(1234);
37 //!
38 //! let a = buf.split();
39 //! assert_eq!(a, b"hello world\x04\xD2"[..]);
40 //!
41 //! buf.put(&b"goodbye world"[..]);
42 //!
43 //! let b = buf.split();
44 //! assert_eq!(b, b"goodbye world"[..]);
45 //!
46 //! assert_eq!(buf.capacity(), 998);
47 //! ```
48 //!
49 //! In the above example, only a single buffer of 1024 is allocated. The handles
50 //! `a` and `b` will share the underlying buffer and maintain indices tracking
51 //! the view into the buffer represented by the handle.
52 //!
53 //! See the [struct docs](`Bytes`) for more details.
54 //!
55 //! # `Buf`, `BufMut`
56 //!
57 //! These two traits provide read and write access to buffers. The underlying
58 //! storage may or may not be in contiguous memory. For example, `Bytes` is a
59 //! buffer that guarantees contiguous memory, but a [rope] stores the bytes in
60 //! disjoint chunks. `Buf` and `BufMut` maintain cursors tracking the current
61 //! position in the underlying byte storage. When bytes are read or written, the
62 //! cursor is advanced.
63 //!
64 //! [rope]: https://en.wikipedia.org/wiki/Rope_(data_structure)
65 //!
66 //! ## Relation with `Read` and `Write`
67 //!
68 //! At first glance, it may seem that `Buf` and `BufMut` overlap in
69 //! functionality with [`std::io::Read`] and [`std::io::Write`]. However, they
70 //! serve different purposes. A buffer is the value that is provided as an
71 //! argument to `Read::read` and `Write::write`. `Read` and `Write` may then
72 //! perform a syscall, which has the potential of failing. Operations on `Buf`
73 //! and `BufMut` are infallible.
74 
75 extern crate alloc;
76 
77 #[cfg(feature = "std")]
78 extern crate std;
79 
80 pub mod buf;
81 pub use crate::buf::{Buf, BufMut};
82 
83 mod bytes;
84 mod bytes_mut;
85 mod fmt;
86 mod loom;
87 pub use crate::bytes::Bytes;
88 pub use crate::bytes_mut::BytesMut;
89 
90 // Optional Serde support
91 #[cfg(feature = "serde")]
92 mod serde;
93 
94 #[inline(never)]
95 #[cold]
abort() -> !96 fn abort() -> ! {
97     #[cfg(feature = "std")]
98     {
99         std::process::abort();
100     }
101 
102     #[cfg(not(feature = "std"))]
103     {
104         struct Abort;
105         impl Drop for Abort {
106             fn drop(&mut self) {
107                 panic!();
108             }
109         }
110         let _a = Abort;
111         panic!("abort");
112     }
113 }
114 
115 #[inline(always)]
116 #[cfg(feature = "std")]
saturating_sub_usize_u64(a: usize, b: u64) -> usize117 fn saturating_sub_usize_u64(a: usize, b: u64) -> usize {
118     use core::convert::TryFrom;
119     match usize::try_from(b) {
120         Ok(b) => a.saturating_sub(b),
121         Err(_) => 0,
122     }
123 }
124 
125 #[inline(always)]
126 #[cfg(feature = "std")]
min_u64_usize(a: u64, b: usize) -> usize127 fn min_u64_usize(a: u64, b: usize) -> usize {
128     use core::convert::TryFrom;
129     match usize::try_from(a) {
130         Ok(a) => usize::min(a, b),
131         Err(_) => b,
132     }
133 }
134 
135 /// Panic with a nice error message.
136 #[cold]
panic_advance(idx: usize, len: usize) -> !137 fn panic_advance(idx: usize, len: usize) -> ! {
138     panic!(
139         "advance out of bounds: the len is {} but advancing by {}",
140         len, idx
141     );
142 }
143 
144 #[cold]
panic_does_not_fit(size: usize, nbytes: usize) -> !145 fn panic_does_not_fit(size: usize, nbytes: usize) -> ! {
146     panic!(
147         "size too large: the integer type can fit {} bytes, but nbytes is {}",
148         size, nbytes
149     );
150 }
151 
152 /// Precondition: dst >= original
153 ///
154 /// The following line is equivalent to:
155 ///
156 /// ```rust,ignore
157 /// self.ptr.as_ptr().offset_from(ptr) as usize;
158 /// ```
159 ///
160 /// But due to min rust is 1.39 and it is only stabilized
161 /// in 1.47, we cannot use it.
162 #[inline]
offset_from(dst: *const u8, original: *const u8) -> usize163 fn offset_from(dst: *const u8, original: *const u8) -> usize {
164     dst as usize - original as usize
165 }
166