From c4e11a1e7a4a20917363573256a389501cfefc61 Mon Sep 17 00:00:00 2001 From: Victor Koenders Date: Sun, 17 Mar 2024 19:51:43 +0100 Subject: [PATCH] Fixed compilation issues --- src/features/impl_alloc.rs | 81 +++++++++++++++++++++++++++----------- src/lib.rs | 8 +++- 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/features/impl_alloc.rs b/src/features/impl_alloc.rs index 3d65671d..ea2d2ea8 100644 --- a/src/features/impl_alloc.rs +++ b/src/features/impl_alloc.rs @@ -1,5 +1,5 @@ use crate::{ - de::{read::Reader, BorrowDecoder, Decode, Decoder}, + de::{BorrowDecoder, Decode, Decoder}, enc::{ self, write::{SizeWriter, Writer}, @@ -16,6 +16,9 @@ use alloc::{ vec::Vec, }; +#[cfg(not(feature = "unstable-strict-oom-checks"))] +use crate::de::read::Reader; + #[cfg(target_has_atomic = "ptr")] use alloc::sync::Arc; @@ -38,6 +41,7 @@ impl VecWriter { } } +#[cfg(not(feature = "unstable-strict-oom-checks"))] impl enc::write::Writer for VecWriter { #[inline(always)] fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> { @@ -48,6 +52,21 @@ impl enc::write::Writer for VecWriter { } } +#[cfg(feature = "unstable-strict-oom-checks")] +impl enc::write::Writer for VecWriter { + #[inline(always)] + fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> { + self.inner.try_reserve(bytes.len())?; + unsafe { + // Safety: We just reserved `bytes.len()` additional bytes + core::mem::MaybeUninit::copy_from_slice(self.inner.spare_capacity_mut(), bytes); + self.inner.set_len(self.inner.len() + bytes.len()); + } + + Ok(()) + } +} + /// Encode the given value into a `Vec` with the given `Config`. See the [config] module for more information. /// /// [config]: config/index.html @@ -263,25 +282,34 @@ where fn decode(decoder: &mut D) -> Result { let len = crate::de::decode_slice_len(decoder)?; + #[cfg(not(feature = "unstable-strict-oom-checks"))] if unty::type_equal::() { decoder.claim_container_read::(len)?; // optimize for reading u8 vecs let mut vec = alloc::vec::from_elem(0u8, len); decoder.reader().read(&mut vec)?; // Safety: Vec is Vec - Ok(unsafe { core::mem::transmute(vec) }) - } else { - decoder.claim_container_read::(len)?; + return Ok(unsafe { core::mem::transmute(vec) }); + } - let mut vec = Vec::with_capacity(len); - for _ in 0..len { - // See the documentation on `unclaim_bytes_read` as to why we're doing this here - decoder.unclaim_bytes_read(core::mem::size_of::()); + decoder.claim_container_read::(len)?; - vec.push(T::decode(decoder)?); - } - Ok(vec) + #[cfg(feature = "unstable-strict-oom-checks")] + let mut vec = Vec::try_with_capacity(len)?; + #[cfg(not(feature = "unstable-strict-oom-checks"))] + let mut vec = Vec::with_capacity(len); + + for _ in 0..len { + // See the documentation on `unclaim_bytes_read` as to why we're doing this here + decoder.unclaim_bytes_read(core::mem::size_of::()); + + // Should never fail because we allocated enough capacity + #[cfg(feature = "unstable-strict-oom-checks")] + debug_assert!(vec.push_within_capacity(T::decode(decoder)?).is_ok()); + #[cfg(not(feature = "unstable-strict-oom-checks"))] + vec.push(T::decode(decoder)?); } + Ok(vec) } } @@ -292,25 +320,33 @@ where fn borrow_decode>(decoder: &mut D) -> Result { let len = crate::de::decode_slice_len(decoder)?; + #[cfg(not(feature = "unstable-strict-oom-checks"))] if unty::type_equal::() { decoder.claim_container_read::(len)?; // optimize for reading u8 vecs - let mut vec = alloc::vec![0u8; len]; + let mut vec = alloc::vec::from_elem(0u8, len); decoder.reader().read(&mut vec)?; // Safety: Vec is Vec - Ok(unsafe { core::mem::transmute(vec) }) - } else { - decoder.claim_container_read::(len)?; + return Ok(unsafe { core::mem::transmute(vec) }); + } + decoder.claim_container_read::(len)?; - let mut vec = Vec::with_capacity(len); - for _ in 0..len { - // See the documentation on `unclaim_bytes_read` as to why we're doing this here - decoder.unclaim_bytes_read(core::mem::size_of::()); + #[cfg(feature = "unstable-strict-oom-checks")] + let mut vec = Vec::try_with_capacity(len)?; + #[cfg(not(feature = "unstable-strict-oom-checks"))] + let mut vec = Vec::with_capacity(len); - vec.push(T::borrow_decode(decoder)?); - } - Ok(vec) + for _ in 0..len { + // See the documentation on `unclaim_bytes_read` as to why we're doing this here + decoder.unclaim_bytes_read(core::mem::size_of::()); + + // Should never fail because we allocated enough capacity + #[cfg(feature = "unstable-strict-oom-checks")] + debug_assert!(vec.push_within_capacity(T::borrow_decode(decoder)?).is_ok()); + #[cfg(not(feature = "unstable-strict-oom-checks"))] + vec.push(T::borrow_decode(decoder)?); } + Ok(vec) } } @@ -404,6 +440,7 @@ where // TODO // Vec does not implement Into for Box<[T]> because it allocates again +#[cfg(not(feature = "unstable-strict-oom-checks"))] impl Decode for Box<[T]> where T: Decode + 'static, diff --git a/src/lib.rs b/src/lib.rs index db8b59a8..fab25dd0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,13 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr( feature = "unstable-strict-oom-checks", - feature(allocator_api, new_uninit) + feature( + allocator_api, + new_uninit, + maybe_uninit_write_slice, + vec_push_within_capacity, + try_with_capacity + ) )] //! Bincode is a crate for encoding and decoding using a tiny binary