diff options
Diffstat (limited to 'third_party/rust/block-buffer/src/sealed.rs')
-rw-r--r-- | third_party/rust/block-buffer/src/sealed.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/third_party/rust/block-buffer/src/sealed.rs b/third_party/rust/block-buffer/src/sealed.rs new file mode 100644 index 0000000000..371a8b7031 --- /dev/null +++ b/third_party/rust/block-buffer/src/sealed.rs @@ -0,0 +1,67 @@ +use super::{ArrayLength, Block}; +use core::slice; + +/// Sealed trait for buffer kinds. +pub trait Sealed { + /// Invariant guaranteed by a buffer kind, i.e. with correct + /// buffer code this function always returns true. + fn invariant(pos: usize, block_size: usize) -> bool; + + /// Split input data into slice fo blocks and tail. + fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]); +} + +impl Sealed for super::Eager { + #[inline(always)] + fn invariant(pos: usize, block_size: usize) -> bool { + pos < block_size + } + + #[inline(always)] + fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]) { + let nb = data.len() / N::USIZE; + let blocks_len = nb * N::USIZE; + let tail_len = data.len() - blocks_len; + // SAFETY: we guarantee that created slices do not point + // outside of `data` + unsafe { + let blocks_ptr = data.as_ptr() as *const Block<N>; + let tail_ptr = data.as_ptr().add(blocks_len); + ( + slice::from_raw_parts(blocks_ptr, nb), + slice::from_raw_parts(tail_ptr, tail_len), + ) + } + } +} + +impl Sealed for super::Lazy { + #[inline(always)] + fn invariant(pos: usize, block_size: usize) -> bool { + pos <= block_size + } + + #[inline(always)] + fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]) { + if data.is_empty() { + return (&[], &[]); + } + let (nb, tail_len) = if data.len() % N::USIZE == 0 { + (data.len() / N::USIZE - 1, N::USIZE) + } else { + let nb = data.len() / N::USIZE; + (nb, data.len() - nb * N::USIZE) + }; + let blocks_len = nb * N::USIZE; + // SAFETY: we guarantee that created slices do not point + // outside of `data` + unsafe { + let blocks_ptr = data.as_ptr() as *const Block<N>; + let tail_ptr = data.as_ptr().add(blocks_len); + ( + slice::from_raw_parts(blocks_ptr, nb), + slice::from_raw_parts(tail_ptr, tail_len), + ) + } + } +} |