Skip to content

Commit 294e992

Browse files
authored
Use boxed slices instead of vectors (#181)
1 parent 496aa73 commit 294e992

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

digest/src/lib.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub use dyn_digest::DynDigest;
4545
use generic_array::{ArrayLength, GenericArray};
4646

4747
#[cfg(feature = "alloc")]
48-
use alloc::vec::Vec;
48+
use alloc::boxed::Box;
4949

5050
/// Trait for updating digest state with input data.
5151
pub trait Update {
@@ -157,12 +157,16 @@ pub trait VariableOutput: core::marker::Sized {
157157
/// will be equal to `output_size`.
158158
fn finalize_variable<F: FnOnce(&[u8])>(self, f: F);
159159

160-
/// Retrieve result into vector and consume hasher.
160+
/// Retrieve result into a boxed slice and consume hasher.
161+
///
162+
/// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
163+
/// they have size of 2 and 3 words respectively.
161164
#[cfg(feature = "alloc")]
162165
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
163-
fn finalize_vec(self) -> Vec<u8> {
164-
let mut buf = Vec::with_capacity(self.output_size());
165-
self.finalize_variable(|res| buf.extend_from_slice(res));
166+
fn finalize_box(self) -> Box<[u8]> {
167+
let n = self.output_size();
168+
let mut buf = vec![0u8; n].into_boxed_slice();
169+
self.finalize_variable(|res| buf.copy_from_slice(res));
166170
buf
167171
}
168172
}
@@ -173,13 +177,16 @@ pub trait XofReader {
173177
/// Read output into the `buffer`. Can be called an unlimited number of times.
174178
fn read(&mut self, buffer: &mut [u8]);
175179

176-
/// Read output into a vector of the specified size.
180+
/// Read output into a boxed slice of the specified size.
177181
///
178182
/// Can be called an unlimited number of times in combination with `read`.
183+
///
184+
/// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
185+
/// they have size of 2 and 3 words respectively.
179186
#[cfg(feature = "alloc")]
180187
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
181-
fn read_vec(&mut self, n: usize) -> Vec<u8> {
182-
let mut buf = vec![0u8; n];
188+
fn read_box(&mut self, n: usize) -> Box<[u8]> {
189+
let mut buf = vec![0u8; n].into_boxed_slice();
183190
self.read(&mut buf);
184191
buf
185192
}
@@ -193,11 +200,14 @@ pub trait ExtendableOutput: core::marker::Sized {
193200
/// Retrieve XOF reader and consume hasher instance.
194201
fn finalize_xof(self) -> Self::Reader;
195202

196-
/// Retrieve result into vector of specified length.
203+
/// Retrieve result into a boxed slice of the specified size.
204+
///
205+
/// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
206+
/// they have size of 2 and 3 words respectively.
197207
#[cfg(feature = "alloc")]
198208
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
199-
fn finalize_vec(self, n: usize) -> Vec<u8> {
200-
let mut buf = vec![0u8; n];
209+
fn finalize_box(self, n: usize) -> Box<[u8]> {
210+
let mut buf = vec![0u8; n].into_boxed_slice();
201211
self.finalize_xof().read(&mut buf);
202212
buf
203213
}

0 commit comments

Comments
 (0)