pub(crate) struct CStr<'a>(&'a [u8]);
impl<'a> CStr<'a> {
#[inline(always)]
pub(crate) fn new(data: &'a [u8]) -> Option<Self> {
let end = data.iter().position(|&b| b == 0)?;
Some(Self(&data[..end]))
}
#[inline(always)]
pub(crate) fn len(&self) -> usize {
self.0.len()
}
#[inline(always)]
pub(crate) fn as_str(&self) -> Option<&'a str> {
core::str::from_utf8(self.0).ok()
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct FdtData<'a> {
bytes: &'a [u8],
}
impl<'a> FdtData<'a> {
#[inline(always)]
pub(crate) fn new(bytes: &'a [u8]) -> Self {
Self { bytes }
}
#[inline(always)]
pub(crate) fn u32(&mut self) -> Option<u32> {
let val = u32::from_be_bytes(self.bytes.get(..4)?.try_into().ok()?);
self.skip(4);
Some(val)
}
#[inline(always)]
pub(crate) fn u64(&mut self) -> Option<u64> {
let val = u64::from_be_bytes(self.bytes.get(..8)?.try_into().ok()?);
self.skip(8);
Some(val)
}
#[inline(always)]
pub(crate) fn skip(&mut self, n: usize) {
self.bytes = self.bytes.get(n..).unwrap_or_default();
}
#[inline(always)]
pub(crate) fn remaining(&self) -> &'a [u8] {
self.bytes
}
#[inline(always)]
pub(crate) fn peek_u32(&self) -> Option<u32> {
Some(u32::from_be_bytes(self.bytes.get(..4)?.try_into().ok()?))
}
#[inline(always)]
pub(crate) fn is_empty(&self) -> bool {
self.bytes.is_empty()
}
#[inline(always)]
pub(crate) fn skip_nops(&mut self) {
while self.peek_u32() == Some(crate::node::FDT_NOP) {
self.skip(4);
}
}
}
#[inline(always)]
pub(crate) fn skip_4_aligned(stream: &mut FdtData<'_>, len: usize) {
stream.skip((len + 3) & !0x3);
}