1use anyhow::Result;
2use anyhow::ensure;
3use std::ffi::CStr;
4
5#[must_use]
7pub fn u32_from_slice(data: &[u8]) -> u32 {
8 u32::from_le_bytes(*data.first_chunk::<4>().unwrap())
9}
10
11#[must_use]
13pub fn u64_from_slice(data: &[u8]) -> u64 {
14 u64::from_le_bytes(*data.first_chunk::<8>().unwrap())
15}
16
17pub fn or_from_slice(dest: &mut [u8], mask_bytes: &[u8]) {
19 for (i, v) in mask_bytes.iter().enumerate() {
20 dest[i] |= *v;
21 }
22}
23
24pub fn and_from_slice(dest: &mut [u8], mask_bytes: &[u8]) {
26 for (i, v) in mask_bytes.iter().enumerate() {
27 dest[i] &= *v;
28 }
29}
30
31#[must_use]
33pub fn slice_from_all_bytes<T: object::Pod>(data: &[u8]) -> &[T] {
34 object::slice_from_bytes(data, data.len() / size_of::<T>())
35 .unwrap()
36 .0
37}
38
39#[must_use]
40pub fn slice_from_all_bytes_mut<T: object::Pod>(data: &mut [u8]) -> &mut [T] {
41 object::slice_from_bytes_mut(data, data.len() / size_of::<T>())
42 .unwrap()
43 .0
44}
45
46pub fn read_u32(content: &mut &[u8]) -> Result<u32> {
47 ensure!(content.len() >= 4, "Not enough bytes to read u32");
48 let value = u32::from_le_bytes(content[..4].try_into()?);
49 *content = &content[4..];
50 Ok(value)
51}
52
53pub fn read_string(content: &mut &[u8]) -> Result<String> {
54 let cstr = CStr::from_bytes_until_nul(content)
55 .map_err(|_| anyhow::anyhow!("No null terminator found in string"))?;
56 let len = cstr.count_bytes() + 1; let s = cstr.to_string_lossy().to_string();
58 *content = &content[len..];
59 Ok(s)
60}
61
62pub fn read_uleb128(content: &mut &[u8]) -> Result<u64> {
63 leb128::read::unsigned(content)
64 .map_err(|e| anyhow::anyhow!("Failed to read ULEB128 value: {e}"))
65}