-
Notifications
You must be signed in to change notification settings - Fork 126
Open
Description
I wrote the function box_from_prefix
that is similar to read_from_prefix except that it is infallible (or potentially just emit alloc errors). This is my first try at implementing it with unsafe:
fn box_from_prefix<T: FromBytes>(src: &[u8]) -> (Box<[T]>, &[u8]) {
let dst_count = src.len() / size_of::<T>();
let dst_size = dst_count * size_of::<T>();
let mut dst: Box<[MaybeUninit<T>]> = Box::new_uninit_slice(dst_count);
unsafe {
std::ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr() as *mut u8, dst_size);
(dst.assume_init(), &src[dst_size..])
}
}
And this is my safe implementation that unnecessarily needs an extra IntoBytes
trait bound and also requieres to zero initialize the memory.
fn box_from_prefix2<T: FromBytes + IntoBytes>(src: &[u8]) -> (Box<[T]>, &[u8]) {
let dst_count = src.len() / size_of::<T>();
let dst_size = dst_count * size_of::<T>();
let mut dst: Box<[T]> = FromZeros::new_box_zeroed_with_elems(dst_count).unwrap();
let dst_bytes = dst.as_mut_bytes();
let (src_bytes, rest) = src.split_at(dst_size);
dst_bytes.copy_from_slice(src_bytes);
(dst, rest)
}
Maybe there's another way to read directly into a box or vec that I haven't thought about.
Metadata
Metadata
Assignees
Labels
No labels