1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use crate::{
private::{
PopBits,
PopBuffer,
PushBits,
PushBuffer,
},
Specifier,
};
#[inline]
fn push_buffer<T>() -> PushBuffer<<T as Specifier>::Bytes>
where
T: Specifier,
PushBuffer<T::Bytes>: Default,
{
<PushBuffer<<T as Specifier>::Bytes> as Default>::default()
}
#[doc(hidden)]
#[inline]
pub fn read_specifier<T>(bytes: &[u8], offset: usize) -> <T as Specifier>::Bytes
where
T: Specifier,
PushBuffer<T::Bytes>: Default + PushBits,
{
let end = offset + <T as Specifier>::BITS;
let ls_byte = offset / 8; let ms_byte = (end - 1) / 8; let lsb_offset = offset % 8; let msb_offset = end % 8; let msb_offset = if msb_offset == 0 { 8 } else { msb_offset };
let mut buffer = push_buffer::<T>();
if lsb_offset == 0 && msb_offset == 8 {
for byte in bytes[ls_byte..(ms_byte + 1)].iter().rev() {
buffer.push_bits(8, *byte)
}
} else {
if ls_byte != ms_byte {
buffer.push_bits(msb_offset as u32, bytes[ms_byte]);
}
if ms_byte - ls_byte >= 2 {
for byte in bytes[(ls_byte + 1)..ms_byte].iter().rev() {
buffer.push_bits(8, *byte);
}
}
if ls_byte == ms_byte {
buffer.push_bits(<T as Specifier>::BITS as u32, bytes[ls_byte] >> lsb_offset);
} else {
buffer.push_bits(8 - lsb_offset as u32, bytes[ls_byte] >> lsb_offset);
}
}
buffer.into_bytes()
}
#[doc(hidden)]
#[inline]
pub fn write_specifier<T>(
bytes: &mut [u8],
offset: usize,
new_val: <T as Specifier>::Bytes,
) where
T: Specifier,
PopBuffer<T::Bytes>: PopBits,
{
let end = offset + <T as Specifier>::BITS;
let ls_byte = offset / 8; let ms_byte = (end - 1) / 8; let lsb_offset = offset % 8; let msb_offset = end % 8; let msb_offset = if msb_offset == 0 { 8 } else { msb_offset };
let mut buffer = <PopBuffer<T::Bytes>>::from_bytes(new_val);
if lsb_offset == 0 && msb_offset == 8 {
for byte in bytes[ls_byte..(ms_byte + 1)].iter_mut() {
*byte = buffer.pop_bits(8);
}
} else {
let stays_same = bytes[ls_byte]
& (if ls_byte == ms_byte && msb_offset != 8 {
!((0x01 << msb_offset) - 1)
} else {
0u8
} | ((0x01 << lsb_offset as u32) - 1));
let overwrite = buffer.pop_bits(8 - lsb_offset as u32);
bytes[ls_byte] = stays_same | (overwrite << lsb_offset as u32);
if ms_byte - ls_byte >= 2 {
for byte in bytes[(ls_byte + 1)..ms_byte].iter_mut() {
*byte = buffer.pop_bits(8);
}
}
if ls_byte != ms_byte {
if msb_offset == 8 {
bytes[ms_byte] = buffer.pop_bits(msb_offset as u32);
} else {
let stays_same = bytes[ms_byte] & !((0x01 << msb_offset) - 1);
let overwrite = buffer.pop_bits(msb_offset as u32);
bytes[ms_byte] = stays_same | overwrite;
}
}
}
}