Skip to content

Commit

Permalink
TODO
Browse files Browse the repository at this point in the history
  • Loading branch information
phadej committed Jan 10, 2025
1 parent a1996f2 commit 4358955
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 0 deletions.
8 changes: 8 additions & 0 deletions hs-bindgen/examples/bitfields.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
struct flags {
char fieldX;
int flagA : 1;
int flagB : 1;
int flagC : 1;
char fieldY;
int bits : 2;
};
202 changes: 202 additions & 0 deletions hs-bindgen/fixtures/bitfields.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/* automatically generated by rust-bindgen 0.70.1 */

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage> {
storage: Storage,
}
impl<Storage> __BindgenBitfieldUnit<Storage> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage }
}
}
impl<Storage> __BindgenBitfieldUnit<Storage>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
let byte_index = index / 8;
let byte = self.storage.as_ref()[byte_index];
let bit_index = if cfg!(target_endian = "big") {
7 - (index % 8)
} else {
index % 8
};
let mask = 1 << bit_index;
byte & mask == mask
}
#[inline]
pub fn set_bit(&mut self, index: usize, val: bool) {
debug_assert!(index / 8 < self.storage.as_ref().len());
let byte_index = index / 8;
let byte = &mut self.storage.as_mut()[byte_index];
let bit_index = if cfg!(target_endian = "big") {
7 - (index % 8)
} else {
index % 8
};
let mask = 1 << bit_index;
if val {
*byte |= mask;
} else {
*byte &= !mask;
}
}
#[inline]
pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
debug_assert!(bit_width <= 64);
debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
debug_assert!(
(bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(),
);
let mut val = 0;
for i in 0..(bit_width as usize) {
if self.get_bit(i + bit_offset) {
let index = if cfg!(target_endian = "big") {
bit_width as usize - 1 - i
} else {
i
};
val |= 1 << index;
}
}
val
}
#[inline]
pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
debug_assert!(bit_width <= 64);
debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
debug_assert!(
(bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(),
);
for i in 0..(bit_width as usize) {
let mask = 1 << i;
let val_bit_is_set = val & mask == mask;
let index = if cfg!(target_endian = "big") {
bit_width as usize - 1 - i
} else {
i
};
self.set_bit(index + bit_offset, val_bit_is_set);
}
}
}
#[repr(C)]
#[repr(align(4))]
#[derive(Debug, Copy, Clone)]
pub struct flags {
pub fieldX: ::std::os::raw::c_char,
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>,
pub fieldY: ::std::os::raw::c_char,
pub _bitfield_align_2: [u8; 0],
pub _bitfield_2: __BindgenBitfieldUnit<[u8; 1usize]>,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of flags"][::std::mem::size_of::<flags>() - 4usize];
["Alignment of flags"][::std::mem::align_of::<flags>() - 4usize];
["Offset of field: flags::fieldX"][::std::mem::offset_of!(flags, fieldX) - 0usize];
["Offset of field: flags::fieldY"][::std::mem::offset_of!(flags, fieldY) - 2usize];
};
impl flags {
#[inline]
pub fn flagA(&self) -> ::std::os::raw::c_int {
unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) }
}
#[inline]
pub fn set_flagA(&mut self, val: ::std::os::raw::c_int) {
unsafe {
let val: u32 = ::std::mem::transmute(val);
self._bitfield_1.set(0usize, 1u8, val as u64)
}
}
#[inline]
pub fn flagB(&self) -> ::std::os::raw::c_int {
unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) }
}
#[inline]
pub fn set_flagB(&mut self, val: ::std::os::raw::c_int) {
unsafe {
let val: u32 = ::std::mem::transmute(val);
self._bitfield_1.set(1usize, 1u8, val as u64)
}
}
#[inline]
pub fn flagC(&self) -> ::std::os::raw::c_int {
unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) }
}
#[inline]
pub fn set_flagC(&mut self, val: ::std::os::raw::c_int) {
unsafe {
let val: u32 = ::std::mem::transmute(val);
self._bitfield_1.set(2usize, 1u8, val as u64)
}
}
#[inline]
pub fn new_bitfield_1(
flagA: ::std::os::raw::c_int,
flagB: ::std::os::raw::c_int,
flagC: ::std::os::raw::c_int,
) -> __BindgenBitfieldUnit<[u8; 1usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default();
__bindgen_bitfield_unit
.set(
0usize,
1u8,
{
let flagA: u32 = unsafe { ::std::mem::transmute(flagA) };
flagA as u64
},
);
__bindgen_bitfield_unit
.set(
1usize,
1u8,
{
let flagB: u32 = unsafe { ::std::mem::transmute(flagB) };
flagB as u64
},
);
__bindgen_bitfield_unit
.set(
2usize,
1u8,
{
let flagC: u32 = unsafe { ::std::mem::transmute(flagC) };
flagC as u64
},
);
__bindgen_bitfield_unit
}
#[inline]
pub fn bits(&self) -> ::std::os::raw::c_int {
unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 2u8) as u32) }
}
#[inline]
pub fn set_bits(&mut self, val: ::std::os::raw::c_int) {
unsafe {
let val: u32 = ::std::mem::transmute(val);
self._bitfield_2.set(0usize, 2u8, val as u64)
}
}
#[inline]
pub fn new_bitfield_2(
bits: ::std::os::raw::c_int,
) -> __BindgenBitfieldUnit<[u8; 1usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default();
__bindgen_bitfield_unit
.set(
0usize,
2u8,
{
let bits: u32 = unsafe { ::std::mem::transmute(bits) };
bits as u64
},
);
__bindgen_bitfield_unit
}
}
1 change: 1 addition & 0 deletions hs-bindgen/tests/golden.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ main' packageRoot bg = testGroup "golden"
, golden "anonymous"
, golden "simple_func"
, golden "weird01"
, golden "bitfields"
]
where
golden name = testGroup name
Expand Down

0 comments on commit 4358955

Please sign in to comment.