Skip to content

Commit 84e658d

Browse files
committed
tag: move Tag and Tags structures into tag module
Signed-off-by: Zhouqi Jiang <luojia@hust.edu.cn>
1 parent fe12193 commit 84e658d

File tree

6 files changed

+157
-148
lines changed

6 files changed

+157
-148
lines changed

src/de.rs

Lines changed: 1 addition & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use crate::{
1414
common::*,
1515
error::{Error, Result},
16+
tag::{Tag, Tags},
1617
};
1718
use core::iter::Peekable;
1819
use serde::de;
@@ -95,153 +96,6 @@ impl DeviceTree {
9596
}
9697
}
9798

98-
#[derive(Debug, Clone)]
99-
struct Tags<'a> {
100-
structure: &'a [u8],
101-
string_table: &'a [u8],
102-
cur: usize,
103-
offset_from_file_begin: usize,
104-
}
105-
106-
#[inline]
107-
fn align_up_u32(val: usize) -> usize {
108-
val + (4 - (val % 4)) % 4
109-
}
110-
111-
impl<'a> Tags<'a> {
112-
#[inline]
113-
fn file_index(&self) -> usize {
114-
self.cur + self.offset_from_file_begin
115-
}
116-
#[inline]
117-
fn read_cur_u32(&mut self) -> Result<u32> {
118-
if self.cur >= (u32::MAX - 4) as usize {
119-
return Err(Error::u32_index_space_overflow(
120-
self.cur as u32,
121-
self.file_index(),
122-
));
123-
}
124-
let ans = u32::from_be_bytes([
125-
self.structure[self.cur],
126-
self.structure[self.cur + 1],
127-
self.structure[self.cur + 2],
128-
self.structure[self.cur + 3],
129-
]);
130-
self.cur += 4;
131-
Ok(ans)
132-
}
133-
#[inline]
134-
fn read_string0_align(&mut self) -> Result<&'a [u8]> {
135-
let begin = self.cur;
136-
while self.cur < self.structure.len() {
137-
if self.structure[self.cur] == b'\0' {
138-
let end = self.cur;
139-
self.cur = align_up_u32(end + 1);
140-
return Ok(&self.structure[begin..end]);
141-
}
142-
self.cur += 1;
143-
}
144-
Err(Error::string_eof_unpexpected(self.file_index()))
145-
}
146-
#[inline]
147-
fn read_slice_align(&mut self, len: u32) -> Result<&'a [u8]> {
148-
let begin = self.cur;
149-
let end = self.cur + len as usize;
150-
if end > self.structure.len() {
151-
let remaining_length = self.structure.len() as u32 - begin as u32;
152-
return Err(Error::slice_eof_unpexpected(
153-
len,
154-
remaining_length,
155-
self.file_index(),
156-
));
157-
}
158-
self.cur = align_up_u32(end);
159-
Ok(&self.structure[begin..end])
160-
}
161-
#[inline]
162-
fn read_table_string(&mut self, pos: u32) -> Result<&'a [u8]> {
163-
let begin = pos as usize;
164-
if begin >= self.string_table.len() {
165-
let bound_offset = self.string_table.len() as u32;
166-
return Err(Error::table_string_offset(
167-
pos,
168-
bound_offset,
169-
self.file_index(),
170-
));
171-
}
172-
let mut cur = begin;
173-
while cur < self.string_table.len() {
174-
if self.string_table[cur] == b'\0' {
175-
return Ok(&self.string_table[begin..cur]);
176-
}
177-
cur += 1;
178-
}
179-
Err(Error::table_string_offset(
180-
pos,
181-
cur as u32,
182-
self.file_index(),
183-
))
184-
}
185-
}
186-
187-
impl<'a> Iterator for Tags<'a> {
188-
type Item = Result<(Tag<'a>, usize)>; // Tag, byte index from file begin
189-
fn next(&mut self) -> Option<Self::Item> {
190-
if self.cur > self.structure.len() - core::mem::size_of::<u32>() {
191-
return Some(Err(Error::tag_eof_unexpected(
192-
self.cur as u32,
193-
self.structure.len() as u32,
194-
self.file_index(),
195-
)));
196-
}
197-
let ans = loop {
198-
match self.read_cur_u32() {
199-
// begin of structure tag
200-
Ok(FDT_BEGIN_NODE) => break Some(self.read_string0_align().map(Tag::Begin)),
201-
Ok(FDT_PROP) => {
202-
let val_size = match self.read_cur_u32() {
203-
Ok(v) => v,
204-
Err(e) => break Some(Err(e)),
205-
};
206-
let name_offset = match self.read_cur_u32() {
207-
Ok(v) => v,
208-
Err(e) => break Some(Err(e)),
209-
};
210-
// get value slice
211-
let val = match self.read_slice_align(val_size) {
212-
Ok(slice) => slice,
213-
Err(e) => break Some(Err(e)),
214-
};
215-
216-
// lookup name in strings table
217-
let prop_name = match self.read_table_string(name_offset) {
218-
Ok(slice) => slice,
219-
Err(e) => break Some(Err(e)),
220-
};
221-
break Some(Ok(Tag::Prop(val, prop_name)));
222-
}
223-
Ok(FDT_END_NODE) => break Some(Ok(Tag::End)),
224-
Ok(FDT_NOP) => self.cur += 4,
225-
Ok(FDT_END) => break None,
226-
Ok(invalid) => break Some(Err(Error::invalid_tag_id(invalid, self.file_index()))),
227-
Err(e) => break Some(Err(e)),
228-
}
229-
};
230-
match ans {
231-
Some(Ok(tag)) => Some(Ok((tag, self.file_index()))),
232-
Some(Err(e)) => Some(Err(e)),
233-
None => None,
234-
}
235-
}
236-
}
237-
238-
#[derive(Clone, Copy, Debug)]
239-
pub enum Tag<'a> {
240-
Begin(&'a [u8]),
241-
Prop(&'a [u8], &'a [u8]),
242-
End,
243-
}
244-
24599
#[derive(Debug, Clone)]
246100
pub struct Deserializer<'a> {
247101
tags: Peekable<Tags<'a>>,

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub mod error;
2323

2424
mod common;
2525
mod de_mut;
26+
mod tag;
2627
mod value;
2728

2829
pub use value::compatible::Compatible;

src/tag.rs

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
use crate::common::{FDT_BEGIN_NODE, FDT_END, FDT_END_NODE, FDT_NOP, FDT_PROP};
2+
use crate::error::{Error, Result};
3+
4+
#[derive(Debug, Clone)]
5+
pub struct Tags<'a> {
6+
pub(crate) structure: &'a [u8],
7+
pub(crate) string_table: &'a [u8],
8+
pub(crate) cur: usize,
9+
pub(crate) offset_from_file_begin: usize,
10+
}
11+
12+
#[inline]
13+
fn align_up_u32(val: usize) -> usize {
14+
val + (4 - (val % 4)) % 4
15+
}
16+
17+
impl<'a> Tags<'a> {
18+
#[inline]
19+
fn file_index(&self) -> usize {
20+
self.cur + self.offset_from_file_begin
21+
}
22+
#[inline]
23+
fn read_cur_u32(&mut self) -> Result<u32> {
24+
if self.cur >= (u32::MAX - 4) as usize {
25+
return Err(Error::u32_index_space_overflow(
26+
self.cur as u32,
27+
self.file_index(),
28+
));
29+
}
30+
let ans = u32::from_be_bytes([
31+
self.structure[self.cur],
32+
self.structure[self.cur + 1],
33+
self.structure[self.cur + 2],
34+
self.structure[self.cur + 3],
35+
]);
36+
self.cur += 4;
37+
Ok(ans)
38+
}
39+
#[inline]
40+
fn read_string0_align(&mut self) -> Result<&'a [u8]> {
41+
let begin = self.cur;
42+
while self.cur < self.structure.len() {
43+
if self.structure[self.cur] == b'\0' {
44+
let end = self.cur;
45+
self.cur = align_up_u32(end + 1);
46+
return Ok(&self.structure[begin..end]);
47+
}
48+
self.cur += 1;
49+
}
50+
Err(Error::string_eof_unpexpected(self.file_index()))
51+
}
52+
#[inline]
53+
fn read_slice_align(&mut self, len: u32) -> Result<&'a [u8]> {
54+
let begin = self.cur;
55+
let end = self.cur + len as usize;
56+
if end > self.structure.len() {
57+
let remaining_length = self.structure.len() as u32 - begin as u32;
58+
return Err(Error::slice_eof_unpexpected(
59+
len,
60+
remaining_length,
61+
self.file_index(),
62+
));
63+
}
64+
self.cur = align_up_u32(end);
65+
Ok(&self.structure[begin..end])
66+
}
67+
#[inline]
68+
fn read_table_string(&mut self, pos: u32) -> Result<&'a [u8]> {
69+
let begin = pos as usize;
70+
if begin >= self.string_table.len() {
71+
let bound_offset = self.string_table.len() as u32;
72+
return Err(Error::table_string_offset(
73+
pos,
74+
bound_offset,
75+
self.file_index(),
76+
));
77+
}
78+
let mut cur = begin;
79+
while cur < self.string_table.len() {
80+
if self.string_table[cur] == b'\0' {
81+
return Ok(&self.string_table[begin..cur]);
82+
}
83+
cur += 1;
84+
}
85+
Err(Error::table_string_offset(
86+
pos,
87+
cur as u32,
88+
self.file_index(),
89+
))
90+
}
91+
}
92+
93+
impl<'a> Iterator for Tags<'a> {
94+
type Item = Result<(Tag<'a>, usize)>; // Tag, byte index from file begin
95+
fn next(&mut self) -> Option<Self::Item> {
96+
if self.cur > self.structure.len() - core::mem::size_of::<u32>() {
97+
return Some(Err(Error::tag_eof_unexpected(
98+
self.cur as u32,
99+
self.structure.len() as u32,
100+
self.file_index(),
101+
)));
102+
}
103+
let ans = loop {
104+
match self.read_cur_u32() {
105+
// begin of structure tag
106+
Ok(FDT_BEGIN_NODE) => break Some(self.read_string0_align().map(Tag::Begin)),
107+
Ok(FDT_PROP) => {
108+
let val_size = match self.read_cur_u32() {
109+
Ok(v) => v,
110+
Err(e) => break Some(Err(e)),
111+
};
112+
let name_offset = match self.read_cur_u32() {
113+
Ok(v) => v,
114+
Err(e) => break Some(Err(e)),
115+
};
116+
// get value slice
117+
let val = match self.read_slice_align(val_size) {
118+
Ok(slice) => slice,
119+
Err(e) => break Some(Err(e)),
120+
};
121+
122+
// lookup name in strings table
123+
let prop_name = match self.read_table_string(name_offset) {
124+
Ok(slice) => slice,
125+
Err(e) => break Some(Err(e)),
126+
};
127+
break Some(Ok(Tag::Prop(val, prop_name)));
128+
}
129+
Ok(FDT_END_NODE) => break Some(Ok(Tag::End)),
130+
Ok(FDT_NOP) => self.cur += 4,
131+
Ok(FDT_END) => break None,
132+
Ok(invalid) => break Some(Err(Error::invalid_tag_id(invalid, self.file_index()))),
133+
Err(e) => break Some(Err(e)),
134+
}
135+
};
136+
match ans {
137+
Some(Ok(tag)) => Some(Ok((tag, self.file_index()))),
138+
Some(Err(e)) => Some(Err(e)),
139+
None => None,
140+
}
141+
}
142+
}
143+
144+
#[derive(Clone, Copy, Debug)]
145+
pub enum Tag<'a> {
146+
Begin(&'a [u8]),
147+
Prop(&'a [u8], &'a [u8]),
148+
End,
149+
}

src/value/compatible.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ impl<'de: 'a, 'a> Deserialize<'de> for Compatible<'a> {
2525
impl<'de: 'a, 'a> Visitor<'de> for StrListVisitor<'de, 'a> {
2626
type Value = Compatible<'a>;
2727

28-
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> std::fmt::Result {
28+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2929
write!(formatter, "string list")
3030
}
3131

src/value/cpu.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// /// ISA independent processor description.
2+
// pub struct CpuMut<'a> {
3+
// memory: &'a mut [u8],
4+
// }

src/value/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod compatible;
2+
pub mod cpu;
23
mod tree;

0 commit comments

Comments
 (0)