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>(data: &[u8]) -> (&[Block], &[u8]); } impl Sealed for super::Eager { #[inline(always)] fn invariant(pos: usize, block_size: usize) -> bool { pos < block_size } #[inline(always)] fn split_blocks>(data: &[u8]) -> (&[Block], &[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; 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>(data: &[u8]) -> (&[Block], &[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; let tail_ptr = data.as_ptr().add(blocks_len); ( slice::from_raw_parts(blocks_ptr, nb), slice::from_raw_parts(tail_ptr, tail_len), ) } } }