aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2021-09-22 10:51:41 -0700
committerJoel Galenson <jgalenson@google.com>2021-09-22 10:51:41 -0700
commit12f62b94d6ccdca90dcd0edfbff82031fec3912f (patch)
tree8e48eb122f9388d510dacf7066a11e16c9b411d3 /src
parent199730d90816980d7cac4cb1dabcce07bc548a38 (diff)
downloadbytes-12f62b94d6ccdca90dcd0edfbff82031fec3912f.tar.gz
Upgrade rust/crates/bytes to 1.1.0
Test: make Change-Id: I62c795247b1a9f37ec66c3ef6b1add6b78530482
Diffstat (limited to 'src')
-rw-r--r--src/buf/buf_impl.rs3
-rw-r--r--src/buf/buf_mut.rs77
-rw-r--r--src/buf/chain.rs27
-rw-r--r--src/buf/take.rs12
-rw-r--r--src/buf/uninit_slice.rs7
-rw-r--r--src/bytes.rs12
-rw-r--r--src/bytes_mut.rs21
-rw-r--r--src/lib.rs1
8 files changed, 142 insertions, 18 deletions
diff --git a/src/buf/buf_impl.rs b/src/buf/buf_impl.rs
index 16ad8a7..a33c8a4 100644
--- a/src/buf/buf_impl.rs
+++ b/src/buf/buf_impl.rs
@@ -127,6 +127,9 @@ pub trait Buf {
/// This function should never panic. Once the end of the buffer is reached,
/// i.e., `Buf::remaining` returns 0, calls to `chunk()` should return an
/// empty slice.
+ // The `chunk` method was previously called `bytes`. This alias makes the rename
+ // more easily discoverable.
+ #[cfg_attr(docsrs, doc(alias = "bytes"))]
fn chunk(&self) -> &[u8];
/// Fills `dst` with potentially multiple slices starting at `self`'s
diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs
index f736727..4c2bd2c 100644
--- a/src/buf/buf_mut.rs
+++ b/src/buf/buf_mut.rs
@@ -33,6 +33,10 @@ pub unsafe trait BufMut {
/// This value is greater than or equal to the length of the slice returned
/// by `chunk_mut()`.
///
+ /// Writing to a `BufMut` may involve allocating more memory on the fly.
+ /// Implementations may fail before reaching the number of bytes indicated
+ /// by this method if they encounter an allocation failure.
+ ///
/// # Examples
///
/// ```
@@ -158,6 +162,12 @@ pub unsafe trait BufMut {
/// `chunk_mut()` returning an empty slice implies that `remaining_mut()` will
/// return 0 and `remaining_mut()` returning 0 implies that `chunk_mut()` will
/// return an empty slice.
+ ///
+ /// This function may trigger an out-of-memory abort if it tries to allocate
+ /// memory and fails to do so.
+ // The `chunk_mut` method was previously called `bytes_mut`. This alias makes the
+ // rename more easily discoverable.
+ #[cfg_attr(docsrs, doc(alias = "bytes_mut"))]
fn chunk_mut(&mut self) -> &mut UninitSlice;
/// Transfer bytes into `self` from `src` and advance the cursor by the
@@ -251,6 +261,37 @@ pub unsafe trait BufMut {
}
}
+ /// Put `cnt` bytes `val` into `self`.
+ ///
+ /// Logically equivalent to calling `self.put_u8(val)` `cnt` times, but may work faster.
+ ///
+ /// `self` must have at least `cnt` remaining capacity.
+ ///
+ /// ```
+ /// use bytes::BufMut;
+ ///
+ /// let mut dst = [0; 6];
+ ///
+ /// {
+ /// let mut buf = &mut dst[..];
+ /// buf.put_bytes(b'a', 4);
+ ///
+ /// assert_eq!(2, buf.remaining_mut());
+ /// }
+ ///
+ /// assert_eq!(b"aaaa\0\0", &dst);
+ /// ```
+ ///
+ /// # Panics
+ ///
+ /// This function panics if there is not enough remaining capacity in
+ /// `self`.
+ fn put_bytes(&mut self, val: u8, cnt: usize) {
+ for _ in 0..cnt {
+ self.put_u8(val);
+ }
+ }
+
/// Writes an unsigned 8 bit integer to `self`.
///
/// The current position is advanced by 1.
@@ -693,7 +734,7 @@ pub unsafe trait BufMut {
self.put_slice(&n.to_le_bytes()[0..nbytes]);
}
- /// Writes a signed n-byte integer to `self` in big-endian byte order.
+ /// Writes low `nbytes` of a signed integer to `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
@@ -703,19 +744,19 @@ pub unsafe trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_int(0x010203, 3);
+ /// buf.put_int(0x0504010203, 3);
/// assert_eq!(buf, b"\x01\x02\x03");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
- /// `self`.
+ /// `self` or if `nbytes` is greater than 8.
fn put_int(&mut self, n: i64, nbytes: usize) {
self.put_slice(&n.to_be_bytes()[mem::size_of_val(&n) - nbytes..]);
}
- /// Writes a signed n-byte integer to `self` in little-endian byte order.
+ /// Writes low `nbytes` of a signed integer to `self` in little-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
@@ -725,14 +766,14 @@ pub unsafe trait BufMut {
/// use bytes::BufMut;
///
/// let mut buf = vec![];
- /// buf.put_int_le(0x010203, 3);
+ /// buf.put_int_le(0x0504010203, 3);
/// assert_eq!(buf, b"\x03\x02\x01");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
- /// `self`.
+ /// `self` or if `nbytes` is greater than 8.
fn put_int_le(&mut self, n: i64, nbytes: usize) {
self.put_slice(&n.to_le_bytes()[0..nbytes]);
}
@@ -1009,12 +1050,29 @@ unsafe impl BufMut for &mut [u8] {
let (_, b) = core::mem::replace(self, &mut []).split_at_mut(cnt);
*self = b;
}
+
+ #[inline]
+ fn put_slice(&mut self, src: &[u8]) {
+ self[..src.len()].copy_from_slice(src);
+ unsafe {
+ self.advance_mut(src.len());
+ }
+ }
+
+ fn put_bytes(&mut self, val: u8, cnt: usize) {
+ assert!(self.remaining_mut() >= cnt);
+ unsafe {
+ ptr::write_bytes(self.as_mut_ptr(), val, cnt);
+ self.advance_mut(cnt);
+ }
+ }
}
unsafe impl BufMut for Vec<u8> {
#[inline]
fn remaining_mut(&self) -> usize {
- usize::MAX - self.len()
+ // A vector can never have more than isize::MAX bytes
+ core::isize::MAX as usize - self.len()
}
#[inline]
@@ -1072,6 +1130,11 @@ unsafe impl BufMut for Vec<u8> {
fn put_slice(&mut self, src: &[u8]) {
self.extend_from_slice(src);
}
+
+ fn put_bytes(&mut self, val: u8, cnt: usize) {
+ let new_len = self.len().checked_add(cnt).unwrap();
+ self.resize(new_len, val);
+ }
}
// The existence of this function makes the compiler catch if the BufMut
diff --git a/src/buf/chain.rs b/src/buf/chain.rs
index d68bc2d..9ce5f23 100644
--- a/src/buf/chain.rs
+++ b/src/buf/chain.rs
@@ -1,5 +1,5 @@
use crate::buf::{IntoIter, UninitSlice};
-use crate::{Buf, BufMut};
+use crate::{Buf, BufMut, Bytes};
#[cfg(feature = "std")]
use std::io::IoSlice;
@@ -135,7 +135,7 @@ where
U: Buf,
{
fn remaining(&self) -> usize {
- self.a.remaining() + self.b.remaining()
+ self.a.remaining().checked_add(self.b.remaining()).unwrap()
}
fn chunk(&self) -> &[u8] {
@@ -170,6 +170,24 @@ where
n += self.b.chunks_vectored(&mut dst[n..]);
n
}
+
+ fn copy_to_bytes(&mut self, len: usize) -> Bytes {
+ let a_rem = self.a.remaining();
+ if a_rem >= len {
+ self.a.copy_to_bytes(len)
+ } else if a_rem == 0 {
+ self.b.copy_to_bytes(len)
+ } else {
+ assert!(
+ len - a_rem <= self.b.remaining(),
+ "`len` greater than remaining"
+ );
+ let mut ret = crate::BytesMut::with_capacity(len);
+ ret.put(&mut self.a);
+ ret.put((&mut self.b).take(len - a_rem));
+ ret.freeze()
+ }
+ }
}
unsafe impl<T, U> BufMut for Chain<T, U>
@@ -178,7 +196,10 @@ where
U: BufMut,
{
fn remaining_mut(&self) -> usize {
- self.a.remaining_mut() + self.b.remaining_mut()
+ self.a
+ .remaining_mut()
+ .checked_add(self.b.remaining_mut())
+ .unwrap()
}
fn chunk_mut(&mut self) -> &mut UninitSlice {
diff --git a/src/buf/take.rs b/src/buf/take.rs
index 1747f6e..d3cb10a 100644
--- a/src/buf/take.rs
+++ b/src/buf/take.rs
@@ -1,11 +1,11 @@
-use crate::Buf;
+use crate::{Buf, Bytes};
use core::cmp;
/// A `Buf` adapter which limits the bytes read from an underlying buffer.
///
/// This struct is generally created by calling `take()` on `Buf`. See
-/// documentation of [`take()`](trait.BufExt.html#method.take) for more details.
+/// documentation of [`take()`](trait.Buf.html#method.take) for more details.
#[derive(Debug)]
pub struct Take<T> {
inner: T,
@@ -144,4 +144,12 @@ impl<T: Buf> Buf for Take<T> {
self.inner.advance(cnt);
self.limit -= cnt;
}
+
+ fn copy_to_bytes(&mut self, len: usize) -> Bytes {
+ assert!(len <= self.remaining(), "`len` greater than remaining");
+
+ let r = self.inner.copy_to_bytes(len);
+ self.limit -= len;
+ r
+ }
}
diff --git a/src/buf/uninit_slice.rs b/src/buf/uninit_slice.rs
index 73f4e89..fb67c0a 100644
--- a/src/buf/uninit_slice.rs
+++ b/src/buf/uninit_slice.rs
@@ -40,6 +40,7 @@ impl UninitSlice {
///
/// let slice = unsafe { UninitSlice::from_raw_parts_mut(ptr, len) };
/// ```
+ #[inline]
pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut UninitSlice {
let maybe_init: &mut [MaybeUninit<u8>] =
core::slice::from_raw_parts_mut(ptr as *mut _, len);
@@ -64,6 +65,7 @@ impl UninitSlice {
///
/// assert_eq!(b"boo", &data[..]);
/// ```
+ #[inline]
pub fn write_byte(&mut self, index: usize, byte: u8) {
assert!(index < self.len());
@@ -90,6 +92,7 @@ impl UninitSlice {
///
/// assert_eq!(b"bar", &data[..]);
/// ```
+ #[inline]
pub fn copy_from_slice(&mut self, src: &[u8]) {
use core::ptr;
@@ -116,6 +119,7 @@ impl UninitSlice {
/// let mut slice = &mut data[..];
/// let ptr = BufMut::chunk_mut(&mut slice).as_mut_ptr();
/// ```
+ #[inline]
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self.0.as_mut_ptr() as *mut _
}
@@ -133,6 +137,7 @@ impl UninitSlice {
///
/// assert_eq!(len, 3);
/// ```
+ #[inline]
pub fn len(&self) -> usize {
self.0.len()
}
@@ -150,6 +155,7 @@ macro_rules! impl_index {
impl Index<$t> for UninitSlice {
type Output = UninitSlice;
+ #[inline]
fn index(&self, index: $t) -> &UninitSlice {
let maybe_uninit: &[MaybeUninit<u8>] = &self.0[index];
unsafe { &*(maybe_uninit as *const [MaybeUninit<u8>] as *const UninitSlice) }
@@ -157,6 +163,7 @@ macro_rules! impl_index {
}
impl IndexMut<$t> for UninitSlice {
+ #[inline]
fn index_mut(&mut self, index: $t) -> &mut UninitSlice {
let maybe_uninit: &mut [MaybeUninit<u8>] = &mut self.0[index];
unsafe { &mut *(maybe_uninit as *mut [MaybeUninit<u8>] as *mut UninitSlice) }
diff --git a/src/bytes.rs b/src/bytes.rs
index b1b35ea..d0be0d2 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -797,14 +797,20 @@ impl From<&'static str> for Bytes {
impl From<Vec<u8>> for Bytes {
fn from(vec: Vec<u8>) -> Bytes {
- // into_boxed_slice doesn't return a heap allocation for empty vectors,
+ let slice = vec.into_boxed_slice();
+ slice.into()
+ }
+}
+
+impl From<Box<[u8]>> for Bytes {
+ fn from(slice: Box<[u8]>) -> Bytes {
+ // Box<[u8]> doesn't contain a heap allocation for empty slices,
// so the pointer isn't aligned enough for the KIND_VEC stashing to
// work.
- if vec.is_empty() {
+ if slice.is_empty() {
return Bytes::new();
}
- let slice = vec.into_boxed_slice();
let len = slice.len();
let ptr = Box::into_raw(slice) as *mut u8;
diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs
index 61c0460..147484d 100644
--- a/src/bytes_mut.rs
+++ b/src/bytes_mut.rs
@@ -380,6 +380,8 @@ impl BytesMut {
/// If `len` is greater than the buffer's current length, this has no
/// effect.
///
+ /// Existing underlying capacity is preserved.
+ ///
/// The [`split_off`] method can emulate `truncate`, but this causes the
/// excess bytes to be returned instead of dropped.
///
@@ -402,7 +404,7 @@ impl BytesMut {
}
}
- /// Clears the buffer, removing all data.
+ /// Clears the buffer, removing all data. Existing capacity is preserved.
///
/// # Examples
///
@@ -819,7 +821,7 @@ impl BytesMut {
}
fn try_unsplit(&mut self, other: BytesMut) -> Result<(), BytesMut> {
- if other.is_empty() {
+ if other.capacity() == 0 {
return Ok(());
}
@@ -1010,6 +1012,19 @@ unsafe impl BufMut for BytesMut {
fn put_slice(&mut self, src: &[u8]) {
self.extend_from_slice(src);
}
+
+ fn put_bytes(&mut self, val: u8, cnt: usize) {
+ self.reserve(cnt);
+ unsafe {
+ let dst = self.uninit_slice();
+ // Reserved above
+ debug_assert!(dst.len() >= cnt);
+
+ ptr::write_bytes(dst.as_mut_ptr(), val, cnt);
+
+ self.advance_mut(cnt);
+ }
+ }
}
impl AsRef<[u8]> for BytesMut {
@@ -1250,6 +1265,7 @@ impl Shared {
}
}
+#[inline]
fn original_capacity_to_repr(cap: usize) -> usize {
let width = PTR_WIDTH - ((cap >> MIN_ORIGINAL_CAPACITY_WIDTH).leading_zeros() as usize);
cmp::min(
@@ -1476,6 +1492,7 @@ impl PartialEq<Bytes> for BytesMut {
}
}
+#[inline]
fn vptr(ptr: *mut u8) -> NonNull<u8> {
if cfg!(debug_assertions) {
NonNull::new(ptr).expect("Vec pointer should be non-null")
diff --git a/src/lib.rs b/src/lib.rs
index dd8cc96..706735e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,7 +3,6 @@
no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
))]
-#![doc(html_root_url = "https://docs.rs/bytes/1.0.1")]
#![no_std]
//! Provides abstractions for working with bytes.