1#![forbid(unsafe_code)]
7
8pub fn read_as_u32_chunks<F, Num>(offset: Num, data: &mut [u8], mut read_u32: F)
10where
11 F: FnMut(Num) -> u32,
12 Num: Into<u64> + TryFrom<u64>,
13 <Num as TryFrom<u64>>::Error: std::fmt::Debug,
14{
15 let offset = offset.into();
16 let mut next_offset = offset;
17 let remaining_data = if offset & 3 != 0 {
18 let val = read_u32((offset & !3).try_into().unwrap());
19 let val = val.to_ne_bytes();
20 let u32_offset = (offset & 3) as usize;
21 let byte_count = std::cmp::min(4 - u32_offset, data.len());
22 data[..byte_count].copy_from_slice(&val[u32_offset..(byte_count + u32_offset)]);
23 next_offset += u64::try_from(byte_count).unwrap();
24 let (_, rem) = data.split_at_mut(byte_count);
25 rem
26 } else {
27 data
28 };
29
30 for next_chunk in remaining_data.chunks_exact_mut(4) {
31 let val = read_u32(next_offset.try_into().unwrap());
32 next_offset += 4;
33 next_chunk.copy_from_slice(&val.to_ne_bytes());
34 }
35 let extra_bytes = remaining_data.chunks_exact_mut(4).into_remainder();
36 if !extra_bytes.is_empty() {
37 let val = read_u32(next_offset.try_into().unwrap());
38 let val = val.to_ne_bytes();
39 extra_bytes.copy_from_slice(&val[..extra_bytes.len()]);
40 }
41}
42
43pub enum ReadWriteRequestType {
45 Read,
47 Write(u32),
49}
50
51pub fn write_as_u32_chunks<F, Num>(offset: Num, data: &[u8], mut read_write_u32: F)
56where
57 F: FnMut(Num, ReadWriteRequestType) -> Option<u32>,
58 Num: Into<u64> + TryFrom<u64>,
59 <Num as TryFrom<u64>>::Error: std::fmt::Debug,
60{
61 let offset = offset.into();
62 let mut next_offset = offset;
63 let remaining_data = if next_offset & 3 != 0 {
64 let val = read_write_u32(
65 (next_offset & !3).try_into().unwrap(),
66 ReadWriteRequestType::Read,
67 )
68 .expect("Read for ReadWriteFn didn't return u32");
69 let mut val = val.to_ne_bytes();
70 let u32_offset = (next_offset & 3) as usize;
71 let byte_count = std::cmp::min(4 - u32_offset, data.len());
72 val[u32_offset..(byte_count + u32_offset)].copy_from_slice(&data[..byte_count]);
73 next_offset += u64::try_from(byte_count).unwrap();
74 read_write_u32(
75 (offset & !3).try_into().unwrap(),
76 ReadWriteRequestType::Write(u32::from_ne_bytes(val)),
77 );
78 let (_, rem) = data.split_at(byte_count);
79 rem
80 } else {
81 data
82 };
83 for next_chunk in remaining_data.chunks_exact(4) {
84 let val = u32::from_ne_bytes(
85 next_chunk
86 .try_into()
87 .expect("4 byte chunk should convert to u32"),
88 );
89 read_write_u32(
90 next_offset.try_into().unwrap(),
91 ReadWriteRequestType::Write(val),
92 );
93 next_offset += 4;
94 }
95 let extra_bytes = remaining_data.chunks_exact(4).remainder();
96 if !extra_bytes.is_empty() {
97 let val = read_write_u32(next_offset.try_into().unwrap(), ReadWriteRequestType::Read)
98 .expect("Read for ReadWriteFn didn't return u32");
99 let mut val = val.to_ne_bytes();
100 for (i, &extra_data) in extra_bytes.iter().enumerate() {
101 val[i] = extra_data;
102 }
103 let val = u32::from_ne_bytes(val);
104 read_write_u32(
105 next_offset.try_into().unwrap(),
106 ReadWriteRequestType::Write(val),
107 );
108 }
109}