Skip to main content

leodos_protocols/utils/
bits.rs

1//! Bitfield extraction, checksums, and header trait.
2
3use zerocopy::network_endian::{U16, U32};
4
5/// Returns the bits from `bitmap` specified by `mask`, right-aligned.
6pub const fn get_bits_u16(bitmap: U16, mask: u16) -> u16 {
7    (bitmap.get() & mask) >> mask.trailing_zeros()
8}
9
10/// Returns `bitmap` with the bits specified by `mask` set to `value`.
11pub fn set_bits_u16(bitmap: &mut U16, mask: u16, value: u16) {
12    bitmap.set((bitmap.get() & !mask) | (value << mask.trailing_zeros()));
13}
14
15/// Returns the bits from `bitmap` specified by `mask`, right-aligned.
16pub const fn get_bits_u32(bitmap: U32, mask: u32) -> u32 {
17    (bitmap.get() & mask) >> mask.trailing_zeros()
18}
19
20/// Returns `bitmap` with the bits specified by `mask` set to `value`.
21pub fn set_bits_u32(bitmap: &mut U32, mask: u32, value: u32) {
22    bitmap.set((bitmap.get() & !mask) | (value << mask.trailing_zeros()));
23}
24
25/// Returns true if any bit in `mask` is set in `bitmap`.
26pub const fn check_bits_u8(bitmap: u8, mask: u8) -> bool {
27    bitmap & mask != 0
28}
29
30/// Returns the bits from `bitmap` specified by `mask`, right-aligned.
31pub const fn get_bits_u8(bitmap: u8, mask: u8) -> u8 {
32    (bitmap & mask) >> mask.trailing_zeros()
33}
34
35/// Returns `bitmap` with the bits specified by `mask` set to `value`.
36pub const fn set_bits_u8(bitmap: &mut u8, mask: u8, value: u8) {
37    *bitmap = (*bitmap & !mask) | (value << mask.trailing_zeros())
38}
39
40/// Returns the minimum number of bytes required to represent the given u64 value.
41pub fn min_len(v: u64) -> usize {
42    for len in 1..=8 {
43        if v < (1u64 << (len * 8)) {
44            return len;
45        }
46    }
47    8
48}
49
50/// Computes an XOR checksum over a byte slice.
51pub fn checksum_u8(bytes: &[u8]) -> u8 {
52    bytes.iter().fold(0, |acc, &byte| acc ^ byte)
53}
54
55/// Returns true if the XOR checksum of the slice (including the checksum byte) is zero.
56pub fn validate_checksum_u8(bytes: &[u8]) -> bool {
57    checksum_u8(bytes) == 0
58}