1#![cfg_attr(
7 not(all(feature = "read_core", feature = "write_core")),
8 allow(dead_code)
9)]
10
11use core::{mem, result, slice};
12
13type Result<T> = result::Result<T, ()>;
14
15pub unsafe trait Pod: Copy + 'static {}
26
27#[inline]
33pub fn from_bytes<T: Pod>(data: &[u8]) -> Result<(&T, &[u8])> {
34 let size = mem::size_of::<T>();
35 let tail = data.get(size..).ok_or(())?;
36 let ptr = data.as_ptr();
37 if (ptr as usize) % mem::align_of::<T>() != 0 {
38 return Err(());
39 }
40 let val = unsafe { &*ptr.cast() };
44 Ok((val, tail))
45}
46
47#[inline]
53pub fn from_bytes_mut<T: Pod>(data: &mut [u8]) -> Result<(&mut T, &mut [u8])> {
54 let size = mem::size_of::<T>();
55 if size > data.len() {
56 return Err(());
57 }
58 let (data, tail) = data.split_at_mut(size);
59 let ptr = data.as_mut_ptr();
60 if (ptr as usize) % mem::align_of::<T>() != 0 {
61 return Err(());
62 }
63 let val = unsafe { &mut *ptr.cast() };
67 Ok((val, tail))
68}
69
70#[inline]
76pub fn slice_from_bytes<T: Pod>(data: &[u8], count: usize) -> Result<(&[T], &[u8])> {
77 let size = count.checked_mul(mem::size_of::<T>()).ok_or(())?;
78 let tail = data.get(size..).ok_or(())?;
79 let ptr = data.as_ptr();
80 if (ptr as usize) % mem::align_of::<T>() != 0 {
81 return Err(());
82 }
83 let slice = unsafe { slice::from_raw_parts(ptr.cast(), count) };
87 Ok((slice, tail))
88}
89
90#[inline]
96pub fn slice_from_bytes_mut<T: Pod>(
97 data: &mut [u8],
98 count: usize,
99) -> Result<(&mut [T], &mut [u8])> {
100 let size = count.checked_mul(mem::size_of::<T>()).ok_or(())?;
101 if size > data.len() {
102 return Err(());
103 }
104 let (data, tail) = data.split_at_mut(size);
105 let ptr = data.as_mut_ptr();
106 if (ptr as usize) % mem::align_of::<T>() != 0 {
107 return Err(());
108 }
109 let slice = unsafe { slice::from_raw_parts_mut(ptr.cast(), count) };
113 Ok((slice, tail))
114}
115
116#[inline]
123pub fn slice_from_all_bytes<T: Pod>(data: &[u8]) -> Result<&[T]> {
124 let size = mem::size_of::<T>();
126 if size == 0 {
127 return Err(());
128 }
129 let count = data.len() / size;
130 let (slice, tail) = slice_from_bytes(data, count)?;
131 if !tail.is_empty() {
132 return Err(());
133 }
134 Ok(slice)
135}
136
137#[inline]
144pub fn slice_from_all_bytes_mut<T: Pod>(data: &mut [u8]) -> Result<&mut [T]> {
145 let size = mem::size_of::<T>();
147 if size == 0 {
148 return Err(());
149 }
150 let count = data.len() / size;
151 let (slice, tail) = slice_from_bytes_mut(data, count)?;
152 if !tail.is_empty() {
153 return Err(());
154 }
155 Ok(slice)
156}
157
158#[inline]
160pub fn bytes_of<T: Pod>(val: &T) -> &[u8] {
161 let size = mem::size_of::<T>();
162 unsafe { slice::from_raw_parts(slice::from_ref(val).as_ptr().cast(), size) }
167}
168
169#[inline]
171pub fn bytes_of_mut<T: Pod>(val: &mut T) -> &mut [u8] {
172 let size = mem::size_of::<T>();
173 unsafe { slice::from_raw_parts_mut(slice::from_mut(val).as_mut_ptr().cast(), size) }
178}
179
180#[inline]
182pub fn bytes_of_slice<T: Pod>(val: &[T]) -> &[u8] {
183 let size = val.len().wrapping_mul(mem::size_of::<T>());
184 unsafe { slice::from_raw_parts(val.as_ptr().cast(), size) }
189}
190
191#[inline]
193pub fn bytes_of_slice_mut<T: Pod>(val: &mut [T]) -> &mut [u8] {
194 let size = val.len().wrapping_mul(mem::size_of::<T>());
195 unsafe { slice::from_raw_parts_mut(val.as_mut_ptr().cast(), size) }
200}
201
202macro_rules! unsafe_impl_pod {
203 ($($struct_name:ident),+ $(,)?) => {
204 $(
205 unsafe impl Pod for $struct_name { }
206 )+
207 }
208}
209
210unsafe_impl_pod!(u8, u16, u32, u64);
211
212unsafe impl<const N: usize, T: Pod> Pod for [T; N] {}
213
214#[cfg(test)]
215mod tests {
216 use super::*;
217
218 #[test]
219 fn single() {
220 let x = u32::to_be(0x0123_4567);
221 let mut x_mut = x;
222 let bytes = bytes_of(&x);
223 let bytes_mut = bytes_of_mut(&mut x_mut);
224 assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67]);
225 assert_eq!(bytes, bytes_mut);
226
227 let x16 = [u16::to_be(0x0123), u16::to_be(0x4567)];
228
229 let (y, tail) = from_bytes::<u32>(bytes).unwrap();
230 let (y_mut, tail_mut) = from_bytes_mut::<u32>(bytes_mut).unwrap();
231 assert_eq!(*y, x);
232 assert_eq!(y, y_mut);
233 assert_eq!(tail, &[]);
234 assert_eq!(tail, tail_mut);
235
236 let (y, tail) = from_bytes::<u16>(bytes).unwrap();
237 let (y_mut, tail_mut) = from_bytes_mut::<u16>(bytes_mut).unwrap();
238 assert_eq!(*y, x16[0]);
239 assert_eq!(y, y_mut);
240 assert_eq!(tail, &bytes[2..]);
241 assert_eq!(tail, tail_mut);
242
243 let (y, tail) = from_bytes::<u16>(&bytes[2..]).unwrap();
244 let (y_mut, tail_mut) = from_bytes_mut::<u16>(&mut bytes_mut[2..]).unwrap();
245 assert_eq!(*y, x16[1]);
246 assert_eq!(y, y_mut);
247 assert_eq!(tail, &[]);
248 assert_eq!(tail, tail_mut);
249
250 assert_eq!(from_bytes::<u16>(&bytes[1..]), Err(()));
251 assert_eq!(from_bytes::<u16>(&bytes[3..]), Err(()));
252 assert_eq!(from_bytes::<u16>(&bytes[4..]), Err(()));
253 assert_eq!(from_bytes_mut::<u16>(&mut bytes_mut[1..]), Err(()));
254 assert_eq!(from_bytes_mut::<u16>(&mut bytes_mut[3..]), Err(()));
255 assert_eq!(from_bytes_mut::<u16>(&mut bytes_mut[4..]), Err(()));
256 }
257
258 #[test]
259 fn slice() {
260 let x = [
261 u16::to_be(0x0123),
262 u16::to_be(0x4567),
263 u16::to_be(0x89ab),
264 u16::to_be(0xcdef),
265 ];
266 let mut x_mut = x;
267
268 let bytes = bytes_of_slice(&x);
269 let bytes_mut = bytes_of_slice_mut(&mut x_mut);
270 assert_eq!(bytes, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
271 assert_eq!(bytes, bytes_mut);
272
273 let (y, tail) = slice_from_bytes::<u16>(bytes, 4).unwrap();
274 let (y_mut, tail_mut) = slice_from_bytes_mut::<u16>(bytes_mut, 4).unwrap();
275 assert_eq!(y, x);
276 assert_eq!(y, y_mut);
277 assert_eq!(tail, &[]);
278 assert_eq!(tail, tail_mut);
279
280 let (y, tail) = slice_from_bytes::<u16>(&bytes[2..], 2).unwrap();
281 let (y_mut, tail_mut) = slice_from_bytes_mut::<u16>(&mut bytes_mut[2..], 2).unwrap();
282 assert_eq!(y, &x[1..3]);
283 assert_eq!(y, y_mut);
284 assert_eq!(tail, &bytes[6..]);
285 assert_eq!(tail, tail_mut);
286
287 assert_eq!(slice_from_bytes::<u16>(bytes, 5), Err(()));
288 assert_eq!(slice_from_bytes::<u16>(&bytes[2..], 4), Err(()));
289 assert_eq!(slice_from_bytes::<u16>(&bytes[1..], 2), Err(()));
290 assert_eq!(slice_from_bytes_mut::<u16>(bytes_mut, 5), Err(()));
291 assert_eq!(slice_from_bytes_mut::<u16>(&mut bytes_mut[2..], 4), Err(()));
292 assert_eq!(slice_from_bytes_mut::<u16>(&mut bytes_mut[1..], 2), Err(()));
293 }
294
295 #[test]
296 fn slice_zero() {
297 assert_eq!(slice_from_all_bytes::<[u8; 0]>(&[]), Err(()));
298 assert_eq!(slice_from_all_bytes_mut::<[u8; 0]>(&mut []), Err(()));
299 }
300}