mirror of
https://github.com/openharmony/third_party_rust_bytes.git
synced 2026-07-19 17:05:29 -04:00
Bytes::extend_from_slice (#120)
`extend_with_slice` is super-convenient operation on `Bytes`. While `put_u8` would be expensive on `Bytes`, `extend_from_slice` is OK, because it is batch, and it checks for kind only once. Patch also adds `impl Extend for Bytes`. cc #116
This commit is contained in:
committed by
Carl Lerche
parent
6af66c4f21
commit
07db74b009
@@ -648,6 +648,48 @@ impl Bytes {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Append given bytes to this object.
|
||||
///
|
||||
/// If this `Bytes` object has not enough capacity, it is resized first.
|
||||
/// It `Bytes` is shared (`refcount > 1`), it is copied first.
|
||||
///
|
||||
/// This operation can be less effective than similar operation on `BytesMut`,
|
||||
/// especially on small additions.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::Bytes;
|
||||
///
|
||||
/// let mut buf = Bytes::from("aabb");
|
||||
/// buf.extend_from_slice(b"ccdd");
|
||||
/// buf.extend_from_slice(b"eeff");
|
||||
///
|
||||
/// assert_eq!(b"aabbccddeeff", &buf[..]);
|
||||
/// ```
|
||||
pub fn extend_from_slice(&mut self, extend: &[u8]) {
|
||||
if extend.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let new_cap = self.len().checked_add(extend.len()).expect("capacity overflow");
|
||||
|
||||
let result = match mem::replace(self, Bytes::new()).try_mut() {
|
||||
Ok(mut bytes_mut) => {
|
||||
bytes_mut.extend_from_slice(extend);
|
||||
bytes_mut
|
||||
},
|
||||
Err(bytes) => {
|
||||
let mut bytes_mut = BytesMut::with_capacity(new_cap);
|
||||
bytes_mut.put_slice(&bytes);
|
||||
bytes_mut.put_slice(extend);
|
||||
bytes_mut
|
||||
}
|
||||
};
|
||||
|
||||
mem::replace(self, result.freeze());
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoBuf for Bytes {
|
||||
@@ -786,6 +828,38 @@ impl<'a> IntoIterator for &'a Bytes {
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<u8> for Bytes {
|
||||
fn extend<T>(&mut self, iter: T) where T: IntoIterator<Item = u8> {
|
||||
let iter = iter.into_iter();
|
||||
|
||||
let (lower, upper) = iter.size_hint();
|
||||
|
||||
// Avoid possible conversion into mut if there's nothing to add
|
||||
if let Some(0) = upper {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut bytes_mut = match mem::replace(self, Bytes::new()).try_mut() {
|
||||
Ok(bytes_mut) => bytes_mut,
|
||||
Err(bytes) => {
|
||||
let mut bytes_mut = BytesMut::with_capacity(bytes.len() + lower);
|
||||
bytes_mut.put_slice(&bytes);
|
||||
bytes_mut
|
||||
}
|
||||
};
|
||||
|
||||
bytes_mut.extend(iter);
|
||||
|
||||
mem::replace(self, bytes_mut.freeze());
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Extend<&'a u8> for Bytes {
|
||||
fn extend<T>(&mut self, iter: T) where T: IntoIterator<Item = &'a u8> {
|
||||
self.extend(iter.into_iter().map(|b| *b))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* ===== BytesMut =====
|
||||
|
||||
+28
-1
@@ -357,12 +357,39 @@ fn inline_storage() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend() {
|
||||
fn extend_mut() {
|
||||
let mut bytes = BytesMut::with_capacity(0);
|
||||
bytes.extend(LONG);
|
||||
assert_eq!(*bytes, LONG[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend_shr() {
|
||||
let mut bytes = Bytes::new();
|
||||
bytes.extend(LONG);
|
||||
assert_eq!(*bytes, LONG[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend_from_slice_mut() {
|
||||
for &i in &[3, 34] {
|
||||
let mut bytes = BytesMut::new();
|
||||
bytes.extend_from_slice(&LONG[..i]);
|
||||
bytes.extend_from_slice(&LONG[i..]);
|
||||
assert_eq!(LONG[..], *bytes);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend_from_slice_shr() {
|
||||
for &i in &[3, 34] {
|
||||
let mut bytes = Bytes::new();
|
||||
bytes.extend_from_slice(&LONG[..i]);
|
||||
bytes.extend_from_slice(&LONG[i..]);
|
||||
assert_eq!(LONG[..], *bytes);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_static() {
|
||||
let mut a = Bytes::from_static(b"ab");
|
||||
|
||||
Reference in New Issue
Block a user