jvmti_rs/sys/
utils.rs

1#![allow(non_snake_case, non_camel_case_types)]
2
3#[repr(C)]
4#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
5pub struct BitfieldUnit<Storage, Align> {
6    storage: Storage,
7    align: [Align; 0],
8}
9
10impl<Storage, Align> BitfieldUnit<Storage, Align> {
11    #[inline]
12    pub const fn new(storage: Storage) -> Self {
13        Self { storage, align: [] }
14    }
15}
16
17impl<Storage, Align> BitfieldUnit<Storage, Align>
18    where
19        Storage: AsRef<[u8]> + AsMut<[u8]>,
20{
21    #[inline]
22    pub fn get_bit(&self, index: usize) -> bool {
23        debug_assert!(index / 8 < self.storage.as_ref().len());
24        let byte_index = index / 8;
25        let byte = self.storage.as_ref()[byte_index];
26        let bit_index = if cfg!(target_endian = "big") {
27            7 - (index % 8)
28        } else {
29            index % 8
30        };
31        let mask = 1 << bit_index;
32        byte & mask == mask
33    }
34    #[inline]
35    pub fn set_bit(&mut self, index: usize, val: bool) {
36        debug_assert!(index / 8 < self.storage.as_ref().len());
37        let byte_index = index / 8;
38        let byte = &mut self.storage.as_mut()[byte_index];
39        let bit_index = if cfg!(target_endian = "big") {
40            7 - (index % 8)
41        } else {
42            index % 8
43        };
44        let mask = 1 << bit_index;
45        if val {
46            *byte |= mask;
47        } else {
48            *byte &= !mask;
49        }
50    }
51    #[inline]
52    pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
53        debug_assert!(bit_width <= 64);
54        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
55        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
56        let mut val = 0;
57        for i in 0..(bit_width as usize) {
58            if self.get_bit(i + bit_offset) {
59                let index = if cfg!(target_endian = "big") {
60                    bit_width as usize - 1 - i
61                } else {
62                    i
63                };
64                val |= 1 << index;
65            }
66        }
67        val
68    }
69    #[inline]
70    pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
71        debug_assert!(bit_width <= 64);
72        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
73        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
74        for i in 0..(bit_width as usize) {
75            let mask = 1 << i;
76            let val_bit_is_set = val & mask == mask;
77            let index = if cfg!(target_endian = "big") {
78                bit_width as usize - 1 - i
79            } else {
80                i
81            };
82            self.set_bit(index + bit_offset, val_bit_is_set);
83        }
84    }
85}