1 | //! Utilities to help with buffering. |
2 | |
3 | #![allow (unsafe_code)] |
4 | |
5 | use core::mem::MaybeUninit; |
6 | use core::slice; |
7 | |
8 | /// Split an uninitialized byte slice into initialized and uninitialized parts. |
9 | /// |
10 | /// # Safety |
11 | /// |
12 | /// `init_len` must not be greater than `buf.len()`, and at least `init_len` |
13 | /// bytes must be initialized. |
14 | #[inline ] |
15 | pub(super) unsafe fn split_init( |
16 | buf: &mut [MaybeUninit<u8>], |
17 | init_len: usize, |
18 | ) -> (&mut [u8], &mut [MaybeUninit<u8>]) { |
19 | debug_assert!(init_len <= buf.len()); |
20 | let buf_ptr: *mut MaybeUninit = buf.as_mut_ptr(); |
21 | let uninit_len: usize = buf.len() - init_len; |
22 | let init: &mut [u8] = slice::from_raw_parts_mut(data:buf_ptr.cast::<u8>(), init_len); |
23 | let uninit: &mut [MaybeUninit] = slice::from_raw_parts_mut(data:buf_ptr.add(count:init_len), uninit_len); |
24 | (init, uninit) |
25 | } |
26 | |
27 | #[cfg (test)] |
28 | mod tests { |
29 | use super::*; |
30 | |
31 | #[test ] |
32 | fn test_split_init() { |
33 | let mut input_array = [ |
34 | MaybeUninit::new(0_u8), |
35 | MaybeUninit::new(1_u8), |
36 | MaybeUninit::new(2_u8), |
37 | MaybeUninit::new(3_u8), |
38 | ]; |
39 | let input_array_clone = input_array.clone(); |
40 | let input_array_ptr = input_array.as_ptr(); |
41 | let output_array = [0_u8, 1_u8, 2_u8, 3_u8]; |
42 | |
43 | unsafe { |
44 | let (init, uninit) = split_init(&mut input_array, 0); |
45 | assert_eq!(init, &[]); |
46 | assert_eq!(uninit.len(), input_array_clone.len()); |
47 | assert_eq!(uninit.as_ptr(), input_array_ptr); |
48 | |
49 | let (init, uninit) = split_init(&mut input_array, input_array_clone.len()); |
50 | assert_eq!(init, &output_array[..]); |
51 | assert_eq!(init.as_ptr(), input_array_ptr.cast()); |
52 | assert_eq!(uninit.len(), 0); |
53 | assert_eq!( |
54 | uninit.as_ptr(), |
55 | input_array_ptr.add(input_array_clone.len()) |
56 | ); |
57 | |
58 | let (init, uninit) = split_init(&mut input_array, 2); |
59 | assert_eq!(init, &output_array[..2]); |
60 | assert_eq!(init.as_ptr(), input_array_ptr.cast()); |
61 | assert_eq!(uninit.len(), 2); |
62 | assert_eq!(uninit.as_ptr(), input_array_ptr.add(2)); |
63 | } |
64 | } |
65 | |
66 | #[test ] |
67 | fn test_split_init_empty() { |
68 | unsafe { |
69 | let (init, uninit) = split_init(&mut [], 0); |
70 | assert!(init.is_empty()); |
71 | assert!(uninit.is_empty()); |
72 | } |
73 | } |
74 | } |
75 | |