diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/block-buffer/src/sealed.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
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), + ) + } + } +} |