1use core::{
2 ffi::CStr,
3 ops::{Deref, Range},
4};
5
6use crate::define::{FdtError, Token};
7
8#[derive(Clone)]
9pub struct Bytes<'a> {
10 pub(crate) all: &'a [u8],
11 range: Range<usize>,
12}
13
14impl Deref for Bytes<'_> {
15 type Target = [u8];
16
17 fn deref(&self) -> &Self::Target {
18 &self.all[self.range.clone()]
19 }
20}
21
22impl<'a> Bytes<'a> {
23 pub fn new(all: &'a [u8]) -> Self {
24 Self {
25 all,
26 range: 0..all.len(),
27 }
28 }
29 pub fn slice(&self, range: Range<usize>) -> Self {
30 assert!(range.end <= self.len());
31 Self {
32 all: self.all,
33 range: (self.range.start + range.start)..(self.range.start + range.end),
34 }
35 }
36
37 pub fn as_slice(&self) -> &'a [u8] {
38 &self.all[self.range.clone()]
39 }
40
41 pub fn len(&self) -> usize {
42 self.range.end - self.range.start
43 }
44
45 pub fn reader(&self) -> Reader<'a> {
46 Reader {
47 bytes: self.slice(0..self.len()),
48 iter: 0,
49 }
50 }
51
52 pub fn reader_at(&self, position: usize) -> Reader<'a> {
53 assert!(position < self.len());
54 Reader {
55 bytes: self.slice(position..self.len()),
56 iter: 0,
57 }
58 }
59
60 pub fn as_u32_iter(&self) -> U32Iter<'a> {
61 U32Iter {
62 reader: self.reader(),
63 }
64 }
65
66 pub fn as_str_iter(&self) -> StrIter<'a> {
67 StrIter {
68 reader: self.reader(),
69 }
70 }
71
72 pub fn is_empty(&self) -> bool {
73 self.len() == 0
74 }
75}
76
77#[derive(Clone)]
78pub struct Reader<'a> {
79 pub(crate) bytes: Bytes<'a>,
80 pub(crate) iter: usize,
81}
82
83impl<'a> Reader<'a> {
84 pub fn position(&self) -> usize {
85 self.bytes.range.start + self.iter
86 }
87
88 pub fn remain(&self) -> Bytes<'a> {
89 self.bytes.slice(self.iter..self.bytes.len())
90 }
91
92 pub fn read_bytes(&mut self, size: usize) -> Option<Bytes<'a>> {
93 if self.iter + size > self.bytes.len() {
94 return None;
95 }
96 let start = self.iter;
97 self.iter += size;
98 Some(self.bytes.slice(start..start + size))
99 }
100
101 pub fn read_u32(&mut self) -> Option<u32> {
102 let bytes = self.read_bytes(4)?;
103 Some(u32::from_be_bytes(bytes.as_slice().try_into().unwrap()))
104 }
105
106 pub fn read_u64(&mut self) -> Option<u64> {
107 let high = self.read_u32()? as u64;
108 let low = self.read_u32()? as u64;
109 Some((high << 32) | low)
110 }
111
112 pub fn read_cells(&mut self, cell_count: usize) -> Option<u64> {
113 let mut value: u64 = 0;
114 for _ in 0..cell_count {
115 let cell = self.read_u32()? as u64;
116 value = (value << 32) | cell;
117 }
118 Some(value)
119 }
120
121 pub fn read_token(&mut self) -> Result<Token, FdtError> {
122 let bytes = self.read_bytes(4).ok_or(FdtError::BufferTooSmall {
123 pos: self.position(),
124 })?;
125 Ok(u32::from_be_bytes(bytes.as_slice().try_into().unwrap()).into())
126 }
127
128 pub fn backtrack(&mut self, size: usize) {
129 assert!(size <= self.iter);
130 self.iter -= size;
131 }
132}
133
134#[derive(Clone)]
135pub struct U32Iter<'a> {
136 pub reader: Reader<'a>,
137}
138
139impl Iterator for U32Iter<'_> {
140 type Item = u32;
141
142 fn next(&mut self) -> Option<Self::Item> {
143 let bytes = self.reader.read_bytes(4)?;
144 Some(u32::from_be_bytes(bytes.as_slice().try_into().unwrap()))
145 }
146}
147
148#[derive(Clone)]
149pub struct StrIter<'a> {
150 pub reader: Reader<'a>,
151}
152
153impl<'a> Iterator for StrIter<'a> {
154 type Item = &'a str;
155
156 fn next(&mut self) -> Option<Self::Item> {
157 let remain = self.reader.remain();
158 if remain.is_empty() {
159 return None;
160 }
161 let s = CStr::from_bytes_until_nul(remain.as_slice())
162 .ok()?
163 .to_str()
164 .ok()?;
165 let str_len = s.len() + 1; self.reader.read_bytes(str_len)?; Some(s)
168 }
169}