From 59606a030839fe44d2d99a3aaa057c437098edf1 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Wed, 31 Jan 2024 20:36:25 +0100 Subject: Upgrade bytes to 1.5.0 This project was upgraded with external_updater. Usage: tools/external_updater/updater.sh update external/rust/crates/bytes For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md Test: TreeHugger Change-Id: I0304154200c646918f8e8dadc3bde527a490cedd --- .cargo_vcs_info.json | 2 +- Android.bp | 24 +++++----- CHANGELOG.md | 11 +++++ Cargo.toml | 2 +- Cargo.toml.orig | 2 +- METADATA | 25 +++++----- src/buf/buf_mut.rs | 35 ++++++++++++++ src/buf/uninit_slice.rs | 56 +++++++++++++++++++--- src/bytes_mut.rs | 3 +- tests/test_buf.rs | 1 + tests/test_buf_mut.rs | 124 +++++++++++++++++++++++++++++++++++++++++++----- 11 files changed, 236 insertions(+), 49 deletions(-) diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index b4c4c4e..ebd71a0 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "21ed3328364716fa30a4bf7502c913bbf0a90f45" + "sha1": "74e6e200fd671340d4d4a874f83776def04f6c7b" }, "path_in_vcs": "" } \ No newline at end of file diff --git a/Android.bp b/Android.bp index ee61c32..d605d03 100644 --- a/Android.bp +++ b/Android.bp @@ -23,7 +23,7 @@ rust_test { host_supported: true, crate_name: "test_buf", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_buf.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -48,7 +48,7 @@ rust_test { host_supported: true, crate_name: "test_buf_mut", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_buf_mut.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -73,7 +73,7 @@ rust_test { host_supported: true, crate_name: "test_bytes", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_bytes.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -98,7 +98,7 @@ rust_test { host_supported: true, crate_name: "test_bytes_odd_alloc", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_bytes_odd_alloc.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -123,7 +123,7 @@ rust_test { host_supported: true, crate_name: "test_bytes_vec_alloc", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_bytes_vec_alloc.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -148,7 +148,7 @@ rust_test { host_supported: true, crate_name: "test_chain", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_chain.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -173,7 +173,7 @@ rust_test { host_supported: true, crate_name: "test_debug", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_debug.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -198,7 +198,7 @@ rust_test { host_supported: true, crate_name: "test_iter", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_iter.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -223,7 +223,7 @@ rust_test { host_supported: true, crate_name: "test_reader", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_reader.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -248,7 +248,7 @@ rust_test { host_supported: true, crate_name: "test_serde", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_serde.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -273,7 +273,7 @@ rust_test { host_supported: true, crate_name: "test_take", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["tests/test_take.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -298,7 +298,7 @@ rust_library { host_supported: true, crate_name: "bytes", cargo_env_compat: true, - cargo_pkg_version: "1.4.0", + cargo_pkg_version: "1.5.0", srcs: ["src/lib.rs"], edition: "2018", features: [ diff --git a/CHANGELOG.md b/CHANGELOG.md index a1bad4a..47e4880 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# 1.5.0 (September 7, 2023) + +### Added + +- Add `UninitSlice::{new,init}` (#598, #599) +- Implement `BufMut` for `&mut [MaybeUninit]` (#597) + +### Changed + +- Mark `BytesMut::extend_from_slice` as inline (#595) + # 1.4.0 (January 31, 2023) ### Added diff --git a/Cargo.toml b/Cargo.toml index d0acb34..2c163aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2018" name = "bytes" -version = "1.4.0" +version = "1.5.0" authors = [ "Carl Lerche ", "Sean McArthur ", diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 4a96ec1..06b19e6 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -4,7 +4,7 @@ name = "bytes" # When releasing to crates.io: # - Update CHANGELOG.md. # - Create "v1.x.y" git tag. -version = "1.4.0" +version = "1.5.0" license = "MIT" authors = [ "Carl Lerche ", diff --git a/METADATA b/METADATA index 8f9837f..c5c023c 100644 --- a/METADATA +++ b/METADATA @@ -1,23 +1,20 @@ # This project was upgraded with external_updater. -# Usage: tools/external_updater/updater.sh update rust/crates/bytes -# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md +# Usage: tools/external_updater/updater.sh update external/rust/crates/bytes +# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md name: "bytes" description: "Types and traits for working with bytes" third_party { - url { - type: HOMEPAGE - value: "https://crates.io/crates/bytes" - } - url { - type: ARCHIVE - value: "https://static.crates.io/crates/bytes/bytes-1.4.0.crate" - } - version: "1.4.0" license_type: NOTICE last_upgrade_date { - year: 2023 - month: 2 - day: 15 + year: 2024 + month: 1 + day: 31 + } + homepage: "https://crates.io/crates/bytes" + identifier { + type: "Archive" + value: "https://static.crates.io/crates/bytes/bytes-1.5.0.crate" + version: "1.5.0" } } diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs index 685fcc7..c2ac39d 100644 --- a/src/buf/buf_mut.rs +++ b/src/buf/buf_mut.rs @@ -1419,6 +1419,41 @@ unsafe impl BufMut for &mut [u8] { } } +unsafe impl BufMut for &mut [core::mem::MaybeUninit] { + #[inline] + fn remaining_mut(&self) -> usize { + self.len() + } + + #[inline] + fn chunk_mut(&mut self) -> &mut UninitSlice { + UninitSlice::uninit(self) + } + + #[inline] + unsafe fn advance_mut(&mut self, cnt: usize) { + // Lifetime dance taken from `impl Write 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.chunk_mut()[..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() as *mut u8, val, cnt); + self.advance_mut(cnt); + } + } +} + unsafe impl BufMut for Vec { #[inline] fn remaining_mut(&self) -> usize { diff --git a/src/buf/uninit_slice.rs b/src/buf/uninit_slice.rs index 3161a14..c5d86e8 100644 --- a/src/buf/uninit_slice.rs +++ b/src/buf/uninit_slice.rs @@ -22,10 +22,44 @@ use core::ops::{ pub struct UninitSlice([MaybeUninit]); impl UninitSlice { - pub(crate) fn from_slice(slice: &mut [MaybeUninit]) -> &mut UninitSlice { + /// Creates a `&mut UninitSlice` wrapping a slice of initialised memory. + /// + /// # Examples + /// + /// ``` + /// use bytes::buf::UninitSlice; + /// + /// let mut buffer = [0u8; 64]; + /// let slice = UninitSlice::new(&mut buffer[..]); + /// ``` + #[inline] + pub fn new(slice: &mut [u8]) -> &mut UninitSlice { + unsafe { &mut *(slice as *mut [u8] as *mut [MaybeUninit] as *mut UninitSlice) } + } + + /// Creates a `&mut UninitSlice` wrapping a slice of uninitialised memory. + /// + /// # Examples + /// + /// ``` + /// use bytes::buf::UninitSlice; + /// use core::mem::MaybeUninit; + /// + /// let mut buffer = [MaybeUninit::uninit(); 64]; + /// let slice = UninitSlice::uninit(&mut buffer[..]); + /// + /// let mut vec = Vec::with_capacity(1024); + /// let spare: &mut UninitSlice = vec.spare_capacity_mut().into(); + /// ``` + #[inline] + pub fn uninit(slice: &mut [MaybeUninit]) -> &mut UninitSlice { unsafe { &mut *(slice as *mut [MaybeUninit] as *mut UninitSlice) } } + fn uninit_ref(slice: &[MaybeUninit]) -> &UninitSlice { + unsafe { &*(slice as *const [MaybeUninit] as *const UninitSlice) } + } + /// Create a `&mut UninitSlice` from a pointer and a length. /// /// # Safety @@ -48,7 +82,7 @@ impl UninitSlice { pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut UninitSlice { let maybe_init: &mut [MaybeUninit] = core::slice::from_raw_parts_mut(ptr as *mut _, len); - Self::from_slice(maybe_init) + Self::uninit(maybe_init) } /// Write a single byte at the specified offset. @@ -179,6 +213,18 @@ impl fmt::Debug for UninitSlice { } } +impl<'a> From<&'a mut [u8]> for &'a mut UninitSlice { + fn from(slice: &'a mut [u8]) -> Self { + UninitSlice::new(slice) + } +} + +impl<'a> From<&'a mut [MaybeUninit]> for &'a mut UninitSlice { + fn from(slice: &'a mut [MaybeUninit]) -> Self { + UninitSlice::uninit(slice) + } +} + macro_rules! impl_index { ($($t:ty),*) => { $( @@ -187,16 +233,14 @@ macro_rules! impl_index { #[inline] fn index(&self, index: $t) -> &UninitSlice { - let maybe_uninit: &[MaybeUninit] = &self.0[index]; - unsafe { &*(maybe_uninit as *const [MaybeUninit] as *const UninitSlice) } + UninitSlice::uninit_ref(&self.0[index]) } } impl IndexMut<$t> for UninitSlice { #[inline] fn index_mut(&mut self, index: $t) -> &mut UninitSlice { - let maybe_uninit: &mut [MaybeUninit] = &mut self.0[index]; - unsafe { &mut *(maybe_uninit as *mut [MaybeUninit] as *mut UninitSlice) } + UninitSlice::uninit(&mut self.0[index]) } } )* diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs index 70613b2..c5c2e52 100644 --- a/src/bytes_mut.rs +++ b/src/bytes_mut.rs @@ -761,6 +761,7 @@ impl BytesMut { /// /// assert_eq!(b"aaabbbcccddd", &buf[..]); /// ``` + #[inline] pub fn extend_from_slice(&mut self, extend: &[u8]) { let cnt = extend.len(); self.reserve(cnt); @@ -1101,7 +1102,7 @@ unsafe impl BufMut for BytesMut { if self.capacity() == self.len() { self.reserve(64); } - UninitSlice::from_slice(self.spare_capacity_mut()) + self.spare_capacity_mut().into() } // Specialize these methods so they can skip checking `remaining_mut` diff --git a/tests/test_buf.rs b/tests/test_buf.rs index fbad003..3940f92 100644 --- a/tests/test_buf.rs +++ b/tests/test_buf.rs @@ -72,6 +72,7 @@ fn test_vec_deque() { assert_eq!(b"world piece", &out[..]); } +#[allow(unused_allocation)] // This is intentional. #[test] fn test_deref_buf_forwards() { struct Special; diff --git a/tests/test_buf_mut.rs b/tests/test_buf_mut.rs index 53f4e86..33aa680 100644 --- a/tests/test_buf_mut.rs +++ b/tests/test_buf_mut.rs @@ -3,6 +3,7 @@ use bytes::buf::UninitSlice; use bytes::{BufMut, BytesMut}; use core::fmt::Write; +use core::mem::MaybeUninit; use core::usize; #[test] @@ -101,26 +102,123 @@ fn test_clone() { assert!(buf != buf2); } +fn do_test_slice_small(make: impl Fn(&mut [u8]) -> &mut T) +where + for<'r> &'r mut T: BufMut, +{ + let mut buf = [b'X'; 8]; + + let mut slice = make(&mut buf[..]); + slice.put_bytes(b'A', 2); + slice.put_u8(b'B'); + slice.put_slice(b"BCC"); + assert_eq!(2, slice.remaining_mut()); + assert_eq!(b"AABBCCXX", &buf[..]); + + let mut slice = make(&mut buf[..]); + slice.put_u32(0x61626364); + assert_eq!(4, slice.remaining_mut()); + assert_eq!(b"abcdCCXX", &buf[..]); + + let mut slice = make(&mut buf[..]); + slice.put_u32_le(0x30313233); + assert_eq!(4, slice.remaining_mut()); + assert_eq!(b"3210CCXX", &buf[..]); +} + +fn do_test_slice_large(make: impl Fn(&mut [u8]) -> &mut T) +where + for<'r> &'r mut T: BufMut, +{ + const LEN: usize = 100; + const FILL: [u8; LEN] = [b'Y'; LEN]; + + let test = |fill: &dyn Fn(&mut &mut T, usize)| { + for buf_len in 0..LEN { + let mut buf = [b'X'; LEN]; + for fill_len in 0..=buf_len { + let mut slice = make(&mut buf[..buf_len]); + fill(&mut slice, fill_len); + assert_eq!(buf_len - fill_len, slice.remaining_mut()); + let (head, tail) = buf.split_at(fill_len); + assert_eq!(&FILL[..fill_len], head); + assert!(tail.iter().all(|b| *b == b'X')); + } + } + }; + + test(&|slice, fill_len| slice.put_slice(&FILL[..fill_len])); + test(&|slice, fill_len| slice.put_bytes(FILL[0], fill_len)); +} + +fn do_test_slice_put_slice_panics(make: impl Fn(&mut [u8]) -> &mut T) +where + for<'r> &'r mut T: BufMut, +{ + let mut buf = [b'X'; 4]; + let mut slice = make(&mut buf[..]); + slice.put_slice(b"12345"); +} + +fn do_test_slice_put_bytes_panics(make: impl Fn(&mut [u8]) -> &mut T) +where + for<'r> &'r mut T: BufMut, +{ + let mut buf = [b'X'; 4]; + let mut slice = make(&mut buf[..]); + slice.put_bytes(b'1', 5); +} + +#[test] +fn test_slice_buf_mut_small() { + do_test_slice_small(|x| x); +} + #[test] -fn test_mut_slice() { - let mut v = vec![0, 0, 0, 0]; - let mut s = &mut v[..]; - s.put_u32(42); +fn test_slice_buf_mut_large() { + do_test_slice_large(|x| x); +} - assert_eq!(s.len(), 0); - assert_eq!(&v, &[0, 0, 0, 42]); +#[test] +#[should_panic] +fn test_slice_buf_mut_put_slice_overflow() { + do_test_slice_put_slice_panics(|x| x); } #[test] -fn test_slice_put_bytes() { - let mut v = [0, 0, 0, 0]; - let mut s = &mut v[..]; - s.put_u8(17); - s.put_bytes(19, 2); - assert_eq!(1, s.remaining_mut()); - assert_eq!(&[17, 19, 19, 0], &v[..]); +#[should_panic] +fn test_slice_buf_mut_put_bytes_overflow() { + do_test_slice_put_bytes_panics(|x| x); +} + +fn make_maybe_uninit_slice(slice: &mut [u8]) -> &mut [MaybeUninit] { + // SAFETY: [u8] has the same layout as [MaybeUninit]. + unsafe { core::mem::transmute(slice) } +} + +#[test] +fn test_maybe_uninit_buf_mut_small() { + do_test_slice_small(make_maybe_uninit_slice); +} + +#[test] +fn test_maybe_uninit_buf_mut_large() { + do_test_slice_large(make_maybe_uninit_slice); +} + +#[test] +#[should_panic] +fn test_maybe_uninit_buf_mut_put_slice_overflow() { + do_test_slice_put_slice_panics(make_maybe_uninit_slice); +} + +#[test] +#[should_panic] +fn test_maybe_uninit_buf_mut_put_bytes_overflow() { + do_test_slice_put_bytes_panics(make_maybe_uninit_slice); } +#[allow(unused_allocation)] // This is intentional. #[test] fn test_deref_bufmut_forwards() { struct Special; -- cgit v1.2.3