Skip to content

Commit 088c596

Browse files
committed
add input2 method to block-buffer
1 parent 4ea08ec commit 088c596

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

block-buffer/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "block-buffer"
3-
version = "0.7.0"
3+
version = "0.7.1"
44
authors = ["RustCrypto Developers"]
55
license = "MIT/Apache-2.0"
66
description = "Fixed size buffer for block processing of data"

block-buffer/src/lib.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use byteorder::{ByteOrder, BE};
88
use byte_tools::zero;
99
use block_padding::{Padding, PadError};
1010
use generic_array::{GenericArray, ArrayLength};
11+
use core::slice;
1112

1213
/// Buffer for block processing of data
1314
#[derive(Clone, Default)]
@@ -22,6 +23,8 @@ unsafe fn cast<N: ArrayLength<u8>>(block: &[u8]) -> &GenericArray<u8, N> {
2223
&*(block.as_ptr() as *const GenericArray<u8, N>)
2324
}
2425

26+
27+
2528
impl<BlockSize: ArrayLength<u8>> BlockBuffer<BlockSize> {
2629
/// Process data in `input` in blocks of size `BlockSize` using function `f`.
2730
#[inline]
@@ -52,6 +55,41 @@ impl<BlockSize: ArrayLength<u8>> BlockBuffer<BlockSize> {
5255
self.pos += input.len();
5356
}
5457

58+
/// Process data in `input` in blocks of size `BlockSize` using function `f`, which accepts
59+
/// slice of blocks.
60+
#[inline]
61+
pub fn input2<F>(&mut self, mut input: &[u8], mut f: F)
62+
where F: FnMut(&[GenericArray<u8, BlockSize>])
63+
{
64+
// If there is already data in the buffer, process it if we have
65+
// enough to complete the chunk.
66+
let rem = self.remaining();
67+
if self.pos != 0 && input.len() >= rem {
68+
let (l, r) = input.split_at(rem);
69+
input = r;
70+
self.buffer[self.pos..].copy_from_slice(l);
71+
self.pos = 0;
72+
f(slice::from_ref(&self.buffer));
73+
}
74+
75+
// While we have at least a full buffer size chunks's worth of data,
76+
// process it data without copying into the buffer
77+
let n_blocks = input.len()/self.size();
78+
let (left, right) = input.split_at(n_blocks*self.size());
79+
// safe because we guarantee that `blocks` does not point outside of `input`
80+
let blocks = unsafe {
81+
slice::from_raw_parts(
82+
left.as_ptr() as *const GenericArray<u8, BlockSize>,
83+
n_blocks,
84+
)
85+
};
86+
f(blocks);
87+
88+
// Copy remaining data into the buffer.
89+
self.buffer[self.pos..self.pos+right.len()].copy_from_slice(right);
90+
self.pos += right.len();
91+
}
92+
5593
/// Variant that doesn't flush the buffer until there's additional
5694
/// data to be processed. Suitable for tweakable block ciphers
5795
/// like Threefish that need to know whether a block is the *last*

0 commit comments

Comments
 (0)