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