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