1use crate::{
2 error::{Error, ErrorKind},
3 traits::FlatBase,
4};
5use core::{ptr, ptr::NonNull};
6
7pub fn check_align_and_min_size<T: FlatBase + ?Sized>(bytes: &[u8]) -> Result<(), Error> {
9 if bytes.as_ptr().align_offset(T::ALIGN) != 0 {
10 Err(Error {
11 kind: ErrorKind::BadAlign,
12 pos: 0,
13 })
14 } else if bytes.len() < T::MIN_SIZE {
15 Err(Error {
16 kind: ErrorKind::InsufficientSize,
17 pos: 0,
18 })
19 } else {
20 Ok(())
21 }
22}
23
24pub unsafe fn slice_ptr_len<T>(slice: *mut [T]) -> usize {
25 unsafe { NonNull::new_unchecked(slice) }.len()
26}
27
28pub unsafe fn set_slice_ptr_len<T>(bytes: *mut [T], len: usize) -> *mut [T] {
29 ptr::slice_from_raw_parts_mut(bytes as *mut T, len)
30}
31
32pub unsafe fn offset_slice_ptr_start<T>(slice: *mut [T], count: isize) -> *mut [T] {
33 let (ptr, len) = (slice as *mut T, slice_ptr_len(slice));
34 ptr::slice_from_raw_parts_mut(ptr.offset(count), (len as isize - count) as usize)
35}
36
37#[doc(hidden)]
38#[macro_export]
39macro_rules! cast_wide_ptr_with_offset {
40 ($Type:ty, $ptr:expr, $count:expr $(,)?) => {{
41 let wptr = $ptr as *mut [u8];
42 let (ptr, len) = (wptr as *mut u8, ::core::ptr::NonNull::new_unchecked(wptr as *mut [u8]).len());
43 ::core::ptr::slice_from_raw_parts_mut(ptr.offset($count as isize), len) as *mut $Type
44 }};
45}
46pub use cast_wide_ptr_with_offset;