fdt_raw/
data.rs

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; // 包括 null 终止符
166        self.reader.read_bytes(str_len)?; // 移动读取位置
167        Some(s)
168    }
169}