From 09134e6f19ca1f7445dba7664535b0b954575598 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Fri, 20 Jan 2023 14:15:27 -0500 Subject: [PATCH] New reader API that allows providing the scratch buffer. Signed-off-by: Itamar Turner-Trauring --- ciborium/src/de/mod.rs | 22 ++++++++++++++++++++-- ciborium/src/lib.rs | 2 ++ ciborium/tests/codec.rs | 7 ++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/ciborium/src/de/mod.rs b/ciborium/src/de/mod.rs index b68458d..1952a4b 100644 --- a/ciborium/src/de/mod.rs +++ b/ciborium/src/de/mod.rs @@ -815,17 +815,35 @@ where } } -/// Deserializes as CBOR from a type with [`impl ciborium_io::Read`](ciborium_io::Read) +/// Deserializes as CBOR from a type with [`impl +/// ciborium_io::Read`](ciborium_io::Read) using a 4KB buffer on the stack. +/// +/// If you want to deserialize faster at the cost of more memory, consider using +/// [`from_reader_with_buffer`](from_reader_with_buffer) with a larger buffer, +/// for example 64KB. #[inline] pub fn from_reader(reader: R) -> Result> where R::Error: core::fmt::Debug, { let mut scratch = [0; 4096]; + from_reader_with_buffer(reader, &mut scratch) +} +/// Deserializes as CBOR from a type with [`impl +/// ciborium_io::Read`](ciborium_io::Read), using a caller-specific buffer as a +/// temporary scratch space. +#[inline] +pub fn from_reader_with_buffer( + reader: R, + scratch_buffer: &mut [u8], +) -> Result> +where + R::Error: core::fmt::Debug, +{ let mut reader = Deserializer { decoder: reader.into(), - scratch: &mut scratch, + scratch: scratch_buffer, recurse: 256, }; diff --git a/ciborium/src/lib.rs b/ciborium/src/lib.rs index 9696e5f..f143943 100644 --- a/ciborium/src/lib.rs +++ b/ciborium/src/lib.rs @@ -100,6 +100,8 @@ pub mod value; // Re-export the [items recommended by serde](https://serde.rs/conventions.html). #[doc(inline)] pub use crate::de::from_reader; +#[doc(inline)] +pub use crate::de::from_reader_with_buffer; #[doc(inline)] pub use crate::ser::into_writer; diff --git a/ciborium/tests/codec.rs b/ciborium/tests/codec.rs index d5df9a7..d737059 100644 --- a/ciborium/tests/codec.rs +++ b/ciborium/tests/codec.rs @@ -7,7 +7,7 @@ use std::convert::TryFrom; use std::fmt::Debug; use ciborium::value::Value; -use ciborium::{cbor, de::from_reader, ser::into_writer}; +use ciborium::{cbor, de::from_reader, de::from_reader_with_buffer, ser::into_writer}; use rstest::rstest; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -309,6 +309,11 @@ fn codec<'de, T: Serialize + Clone, V: Debug + PartialEq + DeserializeOwned, F: eprintln!("{:x?} == {:x?}", &value, &decoded); assert!(veq(&value, &decoded)); + let mut scratch = vec![0; 65536]; + let decoded: Value = from_reader_with_buffer(&bytes[..], &mut scratch).unwrap(); + eprintln!("{:x?} == {:x?}", &value, &decoded); + assert!(veq(&value, &decoded)); + let decoded: V = value.deserialized().unwrap(); let answer = equality(input); eprintln!("{:x?} == {:x?}", answer, decoded);