libsdb/
bit.rs

1use super::types::Byte64;
2use super::types::Byte128;
3use bytemuck::NoUninit;
4use bytemuck::Pod;
5use bytemuck::bytes_of;
6use bytemuck::pod_read_unaligned;
7use std::ffi::CStr;
8use std::ffi::c_char;
9use std::mem;
10
11pub fn from_bytes<To: Pod>(bytes: &[u8]) -> To {
12    let slice = &bytes[..size_of::<To>()];
13    pod_read_unaligned(slice)
14}
15
16pub fn to_byte_span<T: Pod>(src: &T) -> &[u8] {
17    bytes_of(src)
18}
19
20pub fn to_byte_vec<T: Pod>(src: &T) -> Vec<u8> {
21    let src_bytes = bytes_of(src);
22    src_bytes.to_vec()
23}
24
25pub fn to_byte64<T: NoUninit>(src: T) -> Byte64 {
26    let mut out: Byte64 = [0; 8];
27    let src_bytes = bytes_of(&src);
28    out[..src_bytes.len()].copy_from_slice(src_bytes);
29    out
30}
31
32pub fn to_byte128<T: NoUninit>(src: T) -> Byte128 {
33    let mut out: Byte128 = [0; 16];
34    let src_bytes = bytes_of(&src);
35    out[..src_bytes.len()].copy_from_slice(src_bytes);
36    out
37}
38
39pub fn from_array_bytes<T: Pod>(data: &[u8]) -> Vec<T> {
40    let type_size = mem::size_of::<T>();
41    let count = data.len() / type_size;
42    assert_eq!(count * type_size, data.len());
43    let mut vec = Vec::with_capacity(count);
44    for i in 0..count {
45        let offset = i * mem::size_of::<T>();
46        let obj: T = pod_read_unaligned(&data[offset..offset + mem::size_of::<T>()]);
47        vec.push(obj);
48    }
49    vec
50}
51
52pub fn cstr_view(data: &[u8]) -> &str {
53    assert!(data.iter().any(|d| { *d == 0 }), "Cannot find c-string");
54    let ptr = data.as_ptr() as *const c_char;
55    unsafe { CStr::from_ptr(ptr).to_str().unwrap() }
56}
57
58pub fn memcpy_bits(
59    dest: &mut [u8],
60    mut dest_bit: u32,
61    src: &[u8],
62    mut src_bit: u32,
63    mut n_bits: u32,
64) {
65    while n_bits > 0 {
66        let dest_mask = 1u8 << (dest_bit % 8);
67        dest[(dest_bit / 8) as usize] &= !dest_mask;
68
69        let src_mask = 1u8 << (src_bit % 8);
70        let corresponding_src_bit_set = src[(src_bit / 8) as usize] & src_mask;
71
72        if corresponding_src_bit_set != 0 {
73            dest[(dest_bit / 8) as usize] |= dest_mask;
74        }
75
76        n_bits -= 1;
77        src_bit += 1;
78        dest_bit += 1;
79    }
80}