#[cfg(test)]
mod tests;
pub use self::buf::Buf;
mod buf;
pub use self::bind::Bindable;
mod bind;
pub use self::load::{Load, LoadMut};
mod load;
pub use self::visit::Visit;
pub(crate) mod visit;
pub use self::validator::Validator;
mod validator;
pub use self::struct_padder::StructPadder;
mod struct_padder;
pub use self::buf_mut::BufMut;
mod buf_mut;
pub use self::cursor::Cursor;
mod cursor;
pub(crate) use self::raw_buf_mut::RawBufMut;
mod raw_buf_mut;
#[cfg(feature = "alloc")]
pub use self::aligned_buf::AlignedBuf;
#[cfg(feature = "alloc")]
mod aligned_buf;
pub use self::maybe_uninit::MaybeUninit;
mod maybe_uninit;
use core::mem::size_of;
use crate::error::Error;
use crate::traits::ZeroCopy;
pub type DefaultAlignment = usize;
#[inline]
pub fn max_capacity_for_align(align: usize) -> usize {
isize::MAX as usize - (align - 1)
}
pub fn aligned_buf(bytes: &[u8], align: usize) -> Result<&Buf, AlignedBuf> {
assert!(align.is_power_of_two(), "Alignment must be power of two");
let buf = Buf::new(bytes);
if buf.is_aligned_to(align) {
Ok(buf)
} else {
let mut buf = unsafe { AlignedBuf::with_capacity_and_custom_alignment(bytes.len(), align) };
unsafe {
buf.store_bytes(bytes);
}
Err(buf)
}
}
#[inline]
pub(crate) fn is_aligned_to(ptr: *const u8, align: usize) -> bool {
assert!(align.is_power_of_two(), "alignment is not a power-of-two");
(ptr as usize) & (align - 1) == 0
}
#[inline]
pub(crate) fn validate_array<T>(mut cursor: Cursor<'_>, len: usize) -> Result<(), Error>
where
T: ZeroCopy,
{
if !T::ANY_BITS && size_of::<T>() > 0 {
for _ in 0..len / size_of::<T>() {
unsafe {
T::validate(cursor)?;
cursor.advance::<T>();
}
}
}
Ok(())
}
pub(crate) fn padding_to(len: usize, align: usize) -> usize {
let mask = align - 1;
(align - (len & mask)) & mask
}