1use core::convert::TryInto;
6pub struct CStr<'a>(&'a [u8]);
7
8impl<'a> CStr<'a> {
9 pub fn new(data: &'a [u8]) -> Option<Self> {
10 let end = data.iter().position(|&b| b == 0)?;
11 Some(Self(&data[..end]))
12 }
13
14 pub fn len(&self) -> usize {
16 self.0.len()
17 }
18
19 pub fn as_str(&self) -> Option<&'a str> {
20 core::str::from_utf8(self.0).ok()
21 }
22}
23
24#[derive(Debug, Clone, Copy)]
25#[repr(transparent)]
26pub struct BigEndianU32(u32);
27
28impl BigEndianU32 {
29 pub fn get(self) -> u32 {
30 self.0
31 }
32
33 pub(crate) fn from_bytes(bytes: &[u8]) -> Option<Self> {
34 Some(BigEndianU32(u32::from_be_bytes(bytes.get(..4)?.try_into().unwrap())))
35 }
36}
37
38#[derive(Debug, Clone, Copy)]
39#[repr(transparent)]
40pub struct BigEndianU64(u64);
41
42impl BigEndianU64 {
43 pub fn get(&self) -> u64 {
44 self.0
45 }
46
47 pub(crate) fn from_bytes(bytes: &[u8]) -> Option<Self> {
48 Some(BigEndianU64(u64::from_be_bytes(bytes.get(..8)?.try_into().unwrap())))
49 }
50}
51
52#[derive(Debug, Clone, Copy)]
53pub struct FdtData<'a> {
54 bytes: &'a [u8],
55}
56
57impl<'a> FdtData<'a> {
58 pub fn new(bytes: &'a [u8]) -> Self {
59 Self { bytes }
60 }
61
62 pub fn u32(&mut self) -> Option<BigEndianU32> {
63 let ret = BigEndianU32::from_bytes(self.bytes)?;
64 self.skip(4);
65
66 Some(ret)
67 }
68
69 pub fn u64(&mut self) -> Option<BigEndianU64> {
70 let ret = BigEndianU64::from_bytes(self.bytes)?;
71 self.skip(8);
72
73 Some(ret)
74 }
75
76 pub fn skip(&mut self, n_bytes: usize) {
77 self.bytes = self.bytes.get(n_bytes..).unwrap_or_default()
78 }
79
80 pub fn remaining(&self) -> &'a [u8] {
81 self.bytes
82 }
83
84 pub fn peek_u32(&self) -> Option<BigEndianU32> {
85 Self::new(self.remaining()).u32()
86 }
87
88 pub fn is_empty(&self) -> bool {
89 self.remaining().is_empty()
90 }
91
92 pub fn skip_nops(&mut self) {
93 while let Some(crate::node::FDT_NOP) = self.peek_u32().map(|n| n.get()) {
94 let _ = self.u32();
95 }
96 }
97
98 pub fn take(&mut self, bytes: usize) -> Option<&'a [u8]> {
99 if self.bytes.len() >= bytes {
100 let ret = &self.bytes[..bytes];
101 self.skip(bytes);
102
103 return Some(ret);
104 }
105
106 None
107 }
108}