1use std::{mem, ptr};
2
3use light_bounded_vec::{
4 BoundedVec, BoundedVecMetadata, CyclicBoundedVec, CyclicBoundedVecMetadata,
5};
6
7pub unsafe fn read_value_at<T>(bytes: &[u8], offset: &mut usize) -> T
15where
16 T: Clone,
17{
18 let size = mem::size_of::<T>();
19 let ptr = bytes[*offset..*offset + size].as_ptr() as *const T;
20 *offset += size;
21 ptr::read(ptr)
22}
23
24pub unsafe fn read_bounded_vec_at<T>(
36 bytes: &[u8],
37 offset: &mut usize,
38 metadata: &BoundedVecMetadata,
39) -> BoundedVec<T>
40where
41 T: Clone,
42{
43 let size = mem::size_of::<T>() * metadata.capacity();
44 let ptr = bytes[*offset..*offset + size].as_ptr() as *const T;
45
46 let mut vec = BoundedVec::with_metadata(metadata);
47 let dst_ptr: *mut T = vec.as_mut_ptr();
48
49 for i in 0..metadata.length() {
50 let val = ptr::read(ptr.add(i));
51 unsafe { ptr::write(dst_ptr.add(i), val) };
53 }
54
55 *offset += size;
56
57 vec
58}
59
60pub unsafe fn read_cyclic_bounded_vec_at<T>(
69 bytes: &[u8],
70 offset: &mut usize,
71 metadata: &CyclicBoundedVecMetadata,
72) -> CyclicBoundedVec<T>
73where
74 T: Clone,
75{
76 let size = mem::size_of::<T>() * metadata.capacity();
77 let src_ptr = bytes[*offset..*offset + size].as_ptr() as *const T;
78
79 let mut vec = CyclicBoundedVec::with_metadata(metadata);
80 let dst_ptr: *mut T = vec.as_mut_ptr();
81
82 for i in 0..metadata.length() {
83 let val = ptr::read(src_ptr.add(i));
84 unsafe { ptr::write(dst_ptr.add(i), val) };
86 }
87
88 *offset += size;
89
90 vec
91}
92
93#[cfg(test)]
94mod test {
95 use std::slice;
96
97 use memoffset::offset_of;
98
99 use super::*;
100
101 #[test]
102 fn test_value_at() {
103 #[derive(Clone, Copy)]
104 #[repr(C)]
105 struct TestStruct {
106 a: isize,
107 b: usize,
108 c: i64,
109 d: u64,
110 e: i32,
111 f: u32,
112 g: i16,
113 _padding_1: [u8; 2],
114 h: u16,
115 _padding_2: [u8; 2],
116 i: i8,
117 _padding_3: [i8; 3],
118 j: u8,
119 _padding_4: [i8; 3],
120 }
121
122 let mut buf = vec![0_u8; mem::size_of::<TestStruct>()];
123 let s = buf.as_mut_ptr() as *mut TestStruct;
124
125 unsafe {
126 (*s).a = isize::MIN;
127 (*s).b = usize::MAX;
128 (*s).c = i64::MIN;
129 (*s).d = u64::MAX;
130 (*s).e = i32::MIN;
131 (*s).f = u32::MAX;
132 (*s).g = i16::MIN;
133 (*s).h = u16::MAX;
134 (*s).i = i8::MIN;
135 (*s).j = u8::MAX;
136
137 let mut offset = offset_of!(TestStruct, a);
138 assert_eq!(offset, 0);
139 assert_eq!(read_value_at::<isize>(&buf, &mut offset), isize::MIN);
140 assert_eq!(offset, 8);
141
142 let mut offset = offset_of!(TestStruct, b);
143 assert_eq!(offset, 8);
144 assert_eq!(read_value_at::<usize>(&buf, &mut offset), usize::MAX);
145 assert_eq!(offset, 16);
146
147 let mut offset = offset_of!(TestStruct, c);
148 assert_eq!(offset, 16);
149 assert_eq!(read_value_at::<i64>(&buf, &mut offset), i64::MIN);
150 assert_eq!(offset, 24);
151
152 let mut offset = offset_of!(TestStruct, d);
153 assert_eq!(offset, 24);
154 assert_eq!(read_value_at::<u64>(&buf, &mut offset), u64::MAX);
155 assert_eq!(offset, 32);
156
157 let mut offset = offset_of!(TestStruct, e);
158 assert_eq!(offset, 32);
159 assert_eq!(read_value_at::<i32>(&buf, &mut offset), i32::MIN);
160 assert_eq!(offset, 36);
161
162 let mut offset = offset_of!(TestStruct, f);
163 assert_eq!(offset, 36);
164 assert_eq!(read_value_at::<u32>(&buf, &mut offset), u32::MAX);
165 assert_eq!(offset, 40);
166
167 let mut offset = offset_of!(TestStruct, g);
168 assert_eq!(offset, 40);
169 assert_eq!(read_value_at::<i16>(&buf, &mut offset), i16::MIN);
170 assert_eq!(offset, 42);
171
172 let mut offset = offset_of!(TestStruct, h);
173 assert_eq!(offset, 44);
174 assert_eq!(read_value_at::<u16>(&buf, &mut offset), u16::MAX);
175 assert_eq!(offset, 46);
176
177 let mut offset = offset_of!(TestStruct, i);
178 assert_eq!(offset, 48);
179 assert_eq!(read_value_at::<i8>(&buf, &mut offset), i8::MIN);
180 assert_eq!(offset, 49);
181
182 let mut offset = offset_of!(TestStruct, j);
183 assert_eq!(offset, 52);
184 assert_eq!(read_value_at::<u8>(&buf, &mut offset), u8::MAX);
185 assert_eq!(offset, 53);
186 }
187 }
188
189 #[test]
190 fn test_read_bounded_vec_at() {
191 #[derive(Clone, Copy)]
192 #[repr(C)]
193 struct TestStruct {
194 a: [i64; 32],
195 b: [u64; 32],
196 c: [[u8; 32]; 32],
197 }
198
199 let mut buf = vec![0_u8; mem::size_of::<TestStruct>()];
200 let s = buf.as_mut_ptr() as *mut TestStruct;
201
202 unsafe {
203 for (i, element) in (*s).a.iter_mut().enumerate() {
204 *element = -(i as i64);
205 }
206 for (i, element) in (*s).b.iter_mut().enumerate() {
207 *element = i as u64;
208 }
209 for (i, element) in (*s).c.iter_mut().enumerate() {
210 *element = [i as u8; 32];
211 }
212
213 let metadata = BoundedVecMetadata::new_with_length(32, 32);
214 let mut offset = offset_of!(TestStruct, a);
215 assert_eq!(offset, 0);
216 let vec: BoundedVec<i64> = read_bounded_vec_at(&buf, &mut offset, &metadata);
217 for (i, element) in vec.iter().enumerate() {
218 assert_eq!(i as i64, -*element);
219 }
220 assert_eq!(offset, 256);
221
222 let metadata = BoundedVecMetadata::new_with_length(32, 32);
223 let mut offset = offset_of!(TestStruct, b);
224 assert_eq!(offset, 256);
225 let vec: BoundedVec<u64> = read_bounded_vec_at(&buf, &mut offset, &metadata);
226 for (i, element) in vec.iter().enumerate() {
227 assert_eq!(i as u64, *element);
228 }
229 assert_eq!(offset, 512);
230
231 let metadata = BoundedVecMetadata::new_with_length(32, 32);
232 let mut offset = offset_of!(TestStruct, c);
233 assert_eq!(offset, 512);
234 let vec: BoundedVec<[u8; 32]> = read_bounded_vec_at(&buf, &mut offset, &metadata);
235 for (i, element) in vec.iter().enumerate() {
236 assert_eq!(&[i as u8; 32], element);
237 }
238 assert_eq!(offset, 1536);
239 }
240 }
241
242 #[test]
243 fn test_read_cyclic_bounded_vec_at() {
244 #[derive(Clone, Copy)]
245 #[repr(C)]
246 struct TestStruct {
247 a: [i64; 32],
248 b: [u64; 32],
249 c: [[u8; 32]; 32],
250 }
251
252 let mut buf = vec![0_u8; mem::size_of::<TestStruct>()];
253 let s = buf.as_mut_ptr() as *mut TestStruct;
254
255 unsafe {
256 for (i, element) in (*s).a.iter_mut().enumerate() {
257 *element = -(i as i64);
258 }
259 for (i, element) in (*s).b.iter_mut().enumerate() {
260 *element = i as u64;
261 }
262 for (i, element) in (*s).c.iter_mut().enumerate() {
263 *element = [i as u8; 32];
264 }
265
266 let metadata = CyclicBoundedVecMetadata::new_with_indices(32, 32, 14, 13);
269 let mut offset = offset_of!(TestStruct, a);
270 assert_eq!(offset, 0);
271 let vec: CyclicBoundedVec<i64> =
272 read_cyclic_bounded_vec_at(&buf, &mut offset, &metadata);
273 assert_eq!(vec.capacity(), 32);
274 assert_eq!(vec.len(), 32);
275 assert_eq!(vec.first_index(), 14);
276 assert_eq!(vec.last_index(), 13);
277 assert_eq!(
278 vec.iter().collect::<Vec<_>>().as_slice(),
279 &[
280 &-14, &-15, &-16, &-17, &-18, &-19, &-20, &-21, &-22, &-23, &-24, &-25, &-26,
281 &-27, &-28, &-29, &-30, &-31, &-0, &-1, &-2, &-3, &-4, &-5, &-6, &-7, &-8, &-9,
282 &-10, &-11, &-12, &-13
283 ]
284 );
285 assert_eq!(offset, 256);
286
287 let metadata = CyclicBoundedVecMetadata::new_with_indices(32, 32, 14, 13);
288 let mut offset = offset_of!(TestStruct, b);
289 assert_eq!(offset, 256);
290 let vec: CyclicBoundedVec<u64> =
291 read_cyclic_bounded_vec_at(&buf, &mut offset, &metadata);
292 assert_eq!(vec.capacity(), 32);
293 assert_eq!(vec.len(), 32);
294 assert_eq!(vec.first_index(), 14);
295 assert_eq!(vec.last_index(), 13);
296 assert_eq!(
297 vec.iter().collect::<Vec<_>>().as_slice(),
298 &[
299 &14, &15, &16, &17, &18, &19, &20, &21, &22, &23, &24, &25, &26, &27, &28, &29,
300 &30, &31, &0, &1, &2, &3, &4, &5, &6, &7, &8, &9, &10, &11, &12, &13
301 ]
302 );
303 assert_eq!(offset, 512);
304
305 let metadata = CyclicBoundedVecMetadata::new_with_indices(32, 32, 14, 13);
306 let mut offset = offset_of!(TestStruct, c);
307 assert_eq!(offset, 512);
308 let vec: CyclicBoundedVec<[u8; 32]> =
309 read_cyclic_bounded_vec_at(&buf, &mut offset, &metadata);
310 assert_eq!(vec.capacity(), 32);
311 assert_eq!(vec.len(), 32);
312 assert_eq!(vec.first_index(), 14);
313 assert_eq!(vec.last_index(), 13);
314 assert_eq!(
315 vec.iter().collect::<Vec<_>>().as_slice(),
316 &[
317 &[14_u8; 32],
318 &[15_u8; 32],
319 &[16_u8; 32],
320 &[17_u8; 32],
321 &[18_u8; 32],
322 &[19_u8; 32],
323 &[20_u8; 32],
324 &[21_u8; 32],
325 &[22_u8; 32],
326 &[23_u8; 32],
327 &[24_u8; 32],
328 &[25_u8; 32],
329 &[26_u8; 32],
330 &[27_u8; 32],
331 &[28_u8; 32],
332 &[29_u8; 32],
333 &[30_u8; 32],
334 &[31_u8; 32],
335 &[0_u8; 32],
336 &[1_u8; 32],
337 &[2_u8; 32],
338 &[3_u8; 32],
339 &[4_u8; 32],
340 &[5_u8; 32],
341 &[6_u8; 32],
342 &[7_u8; 32],
343 &[8_u8; 32],
344 &[9_u8; 32],
345 &[10_u8; 32],
346 &[11_u8; 32],
347 &[12_u8; 32],
348 &[13_u8; 32],
349 ]
350 );
351 assert_eq!(offset, 1536);
352 }
353 }
354
355 #[test]
356 fn test_read_cyclic_bounded_vec_first_last() {
357 let mut vec = CyclicBoundedVec::<u32>::with_capacity(2);
358 vec.push(0);
359 vec.push(37);
360 vec.push(49);
361
362 let metadata_bytes = vec.metadata().to_le_bytes();
363 let metadata = CyclicBoundedVecMetadata::from_le_bytes(metadata_bytes);
364 let bytes = unsafe {
365 slice::from_raw_parts(
366 vec.as_mut_ptr() as *mut u8,
367 mem::size_of::<u32>() * vec.capacity(),
368 )
369 };
370
371 let mut offset = 0;
372 let vec_copy: CyclicBoundedVec<u32> =
373 unsafe { read_cyclic_bounded_vec_at(bytes, &mut offset, &metadata) };
374
375 assert_eq!(*vec.first().unwrap(), 37);
376 assert_eq!(vec.first(), vec_copy.first()); assert_eq!(*vec.last().unwrap(), 49);
378 assert_eq!(vec.last(), vec_copy.last()); }
380}