Skip to content

Commit e7f9404

Browse files
authored
Merge pull request #12 from woshiluo/chosen
refactor(NodeSeq): support name without @
2 parents b3597a0 + f475d24 commit e7f9404

File tree

7 files changed

+226
-67
lines changed

7 files changed

+226
-67
lines changed

src/de_mut/cursor.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ pub enum MoveResult {
2828
Others,
2929
}
3030

31+
#[derive(Clone, Copy, Debug)]
32+
pub(super) struct MultiNodeCursor {
33+
pub start_cursor: BodyCursor,
34+
pub next_cursor: BodyCursor,
35+
pub skip_cursor: BodyCursor,
36+
#[allow(unused)]
37+
pub node_count: u32,
38+
}
39+
3140
impl<T: Type> AnyCursor<T> {
3241
/// 移动 `n` 格。
3342
pub fn step_n(&mut self, len: usize) {
@@ -147,12 +156,13 @@ impl TitleCursor {
147156
}
148157

149158
/// 生成组光标。
150-
pub fn take_group_on(&self, dtb: RefDtb, name: &str) -> (BodyCursor, usize, BodyCursor) {
159+
pub fn take_group_on(&self, dtb: RefDtb, name: &str) -> MultiNodeCursor {
151160
let name_bytes = name.as_bytes();
152161
let name_skip = align(name_bytes.len() + 1, BLOCK_LEN);
153162
let group = AnyCursor::<Body>(self.0, PhantomData);
154163

155-
let mut body = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
164+
let title_body = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
165+
let mut body = title_body;
156166
let mut len = 1;
157167

158168
let structure = &dtb.borrow().structure;
@@ -171,19 +181,30 @@ impl TitleCursor {
171181
}
172182
break;
173183
}
174-
(group, len, body)
184+
MultiNodeCursor {
185+
start_cursor: group,
186+
next_cursor: body,
187+
skip_cursor: title_body,
188+
node_count: len,
189+
}
175190
}
176191

177192
/// 生成节点光标。
178-
pub fn take_node_on(&self, dtb: RefDtb, name: &str) -> (BodyCursor, BodyCursor) {
193+
pub fn take_node_on(&self, dtb: RefDtb, name: &str) -> MultiNodeCursor {
179194
let name_bytes = name.as_bytes();
180195
let name_skip = align(name_bytes.len() + 1, BLOCK_LEN);
196+
let origin = AnyCursor::<Body>(self.0, PhantomData);
181197
let node = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
182198

183199
let mut body = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
184200

185201
body.escape_from(dtb);
186-
(node, body)
202+
MultiNodeCursor {
203+
start_cursor: origin,
204+
next_cursor: body,
205+
skip_cursor: node,
206+
node_count: 1,
207+
}
187208
}
188209
}
189210

src/de_mut/data.rs

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
use super::{BodyCursor, Cursor};
1+
use super::cursor::MultiNodeCursor;
2+
use super::{BodyCursor, Cursor};
23
use super::{DtError, PropCursor, RefDtb, RegConfig};
34

45
use core::marker::PhantomData;
56
use serde::{de, Deserialize};
67

78
#[derive(Clone, Copy, Debug)]
89
pub(super) enum ValueCursor {
9-
Prop(BodyCursor, PropCursor),
1010
Body(BodyCursor),
11+
Prop(BodyCursor, PropCursor),
12+
Node(MultiNodeCursor),
1113
}
1214

1315
#[derive(Clone, Copy)]
@@ -206,6 +208,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
206208
visitor.visit_some(self)
207209
}
208210
}
211+
ValueCursor::Node(_) => visitor.visit_some(self),
209212
ValueCursor::Body(_) => visitor.visit_some(self),
210213
}
211214
}
@@ -247,25 +250,30 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
247250
V: de::Visitor<'de>,
248251
{
249252
use super::{StructAccess, StructAccessType, Temp};
250-
match self.move_on() {
251-
Cursor::Title(c) => {
252-
let (name, _) = c.split_on(self.dtb);
253-
let cursor = match self.cursor {
254-
ValueCursor::Body(cursor) => cursor,
255-
_ => unreachable!(""),
256-
};
257-
258-
let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count();
259-
let name_bytes = &name.as_bytes()[..pre_len];
260-
let name = unsafe { core::str::from_utf8_unchecked(name_bytes) };
261-
262-
visitor.visit_seq(StructAccess {
263-
access_type: StructAccessType::Seq(name),
264-
temp: Temp::Node(cursor, cursor),
265-
de: self,
266-
})
253+
match self.cursor {
254+
ValueCursor::Node(result) => {
255+
let mut start_cursor = result.start_cursor;
256+
match start_cursor.move_on(self.dtb) {
257+
Cursor::Title(c) => {
258+
let (name, _) = c.split_on(self.dtb);
259+
260+
let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count();
261+
let name_bytes = &name.as_bytes()[..pre_len];
262+
let name = unsafe { core::str::from_utf8_unchecked(name_bytes) };
263+
264+
let de = self;
265+
de.cursor = ValueCursor::Body(start_cursor);
266+
267+
visitor.visit_seq(StructAccess {
268+
access_type: StructAccessType::Seq(name),
269+
temp: Temp::Uninit,
270+
de,
271+
})
272+
}
273+
_ => unreachable!("seq request on a none seq cursor"),
274+
}
267275
}
268-
_ => unreachable!("seq request on a none seq cursor"),
276+
_ => unreachable!("Seq request on a not-node cursor"),
269277
}
270278
}
271279

@@ -293,14 +301,19 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
293301
V: de::Visitor<'de>,
294302
{
295303
use super::{StructAccess, StructAccessType, Temp};
296-
if let ValueCursor::Body(cursor) = self.cursor {
297-
return visitor.visit_map(StructAccess {
304+
match self.cursor {
305+
ValueCursor::Node(_) => visitor.visit_map(StructAccess {
298306
access_type: StructAccessType::Map(false),
299-
temp: Temp::Node(cursor, cursor),
307+
temp: Temp::Uninit,
300308
de: self,
301-
});
302-
};
303-
unreachable!("Prop -> map")
309+
}),
310+
ValueCursor::Body(_) => visitor.visit_map(StructAccess {
311+
access_type: StructAccessType::Map(false),
312+
temp: Temp::Uninit,
313+
de: self,
314+
}),
315+
ValueCursor::Prop(_, _) => unreachable!("Prop -> map"),
316+
}
304317
}
305318

306319
fn deserialize_struct<V>(
@@ -313,14 +326,19 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
313326
V: de::Visitor<'de>,
314327
{
315328
use super::{StructAccess, StructAccessType, Temp};
316-
if let ValueCursor::Body(cursor) = self.cursor {
317-
return visitor.visit_map(StructAccess {
329+
match self.cursor {
330+
ValueCursor::Node(_) => visitor.visit_map(StructAccess {
318331
access_type: StructAccessType::Struct(fields),
319-
temp: Temp::Node(cursor, cursor),
332+
temp: Temp::Uninit,
320333
de: self,
321-
});
322-
};
323-
unreachable!("Prop -> struct {_name} {fields:?}")
334+
}),
335+
ValueCursor::Body(_) => visitor.visit_map(StructAccess {
336+
access_type: StructAccessType::Struct(fields),
337+
temp: Temp::Uninit,
338+
de: self,
339+
}),
340+
ValueCursor::Prop(_, _) => unreachable!("Prop -> struct {_name}"),
341+
}
324342
}
325343

326344
fn deserialize_enum<V>(

src/de_mut/node.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,14 @@ impl<'de> Iterator for NodeIter<'de, '_> {
124124
let dtb = self.node.dtb;
125125
if let Cursor::Title(c) = cursor.move_on(dtb) {
126126
let (name, _) = c.split_on(dtb);
127-
let (node_cursor, next) = c.take_node_on(dtb, name);
127+
let node_cursor = c.take_node_on(dtb, name);
128128
let res = Some(Self::Item {
129129
dtb,
130130
reg: self.node.reg,
131-
node: node_cursor,
131+
node: node_cursor.skip_cursor,
132132
name,
133133
});
134-
*cursor = next;
134+
*cursor = node_cursor.next_cursor;
135135
res
136136
} else {
137137
None
@@ -201,7 +201,8 @@ impl<'de> Deserialize<'de> for Node<'_> {
201201
if key == "/" {
202202
self_cursor = match value.cursor {
203203
ValueCursor::Body(cursor) => Some(cursor),
204-
ValueCursor::Prop(_, _) => {
204+
ValueCursor::Node(result) => Some(result.next_cursor),
205+
_ => {
205206
unreachable!("root of NodeSeq shouble be body cursor")
206207
}
207208
};
@@ -213,11 +214,12 @@ impl<'de> Deserialize<'de> for Node<'_> {
213214
props_start = Some(cursor);
214215
}
215216
}
216-
ValueCursor::Body(cursor) => {
217+
ValueCursor::Node(cursor) => {
217218
if nodes_start.is_none() {
218-
nodes_start = Some(cursor);
219+
nodes_start = Some(cursor.start_cursor);
219220
}
220221
}
222+
_ => unreachable!("unparsed(body) cursor"),
221223
}
222224
}
223225

src/de_mut/node_seq.rs

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,19 +133,19 @@ impl<'de> Iterator for NodeSeqIter<'de, '_> {
133133
// 子节点名字
134134
Cursor::Title(c) => {
135135
let (full_name, _) = c.split_on(self.de.dtb);
136-
let (node, next) = c.take_node_on(self.de.dtb, full_name);
136+
let node_reuslt = c.take_node_on(self.de.dtb, full_name);
137137

138138
let (pre_name, suf_name) = full_name.split_once('@').unwrap_or((full_name, ""));
139139
if self.seq.name != pre_name {
140140
return None;
141141
}
142142

143-
self.de.cursor = ValueCursor::Body(next);
143+
self.de.cursor = ValueCursor::Body(node_reuslt.next_cursor);
144144

145145
Some(Self::Item {
146146
dtb: self.de.dtb,
147147
reg: self.de.reg,
148-
body: node,
148+
body: node_reuslt.skip_cursor,
149149
at: suf_name,
150150
})
151151
}
@@ -173,3 +173,84 @@ impl<'de> NodeSeqItem<'de> {
173173
.unwrap()
174174
}
175175
}
176+
177+
#[cfg(test)]
178+
mod tests {
179+
use crate::buildin::{NodeSeq, Reg};
180+
use crate::{from_raw_mut, Dtb, DtbPtr};
181+
use serde_derive::Deserialize;
182+
183+
const RAW_DEVICE_TREE: &[u8] = include_bytes!("../../examples/bl808.dtb");
184+
const BUFFER_SIZE: usize = RAW_DEVICE_TREE.len();
185+
const RAW_DEVICE_TREE_QEMU: &[u8] = include_bytes!("../../examples/qemu-virt.dtb");
186+
const BUFFER_SIZE_QEMU: usize = RAW_DEVICE_TREE_QEMU.len();
187+
#[derive(Deserialize)]
188+
pub struct Tree<'a> {
189+
/// Memory information.
190+
pub memory: NodeSeq<'a>,
191+
}
192+
/// Memory range.
193+
#[derive(Deserialize)]
194+
#[serde(rename_all = "kebab-case")]
195+
pub struct Memory<'a> {
196+
pub reg: Reg<'a>,
197+
}
198+
#[test]
199+
fn test_nodeseq_without_at() {
200+
#[repr(align(8))]
201+
struct AlignedBuffer {
202+
pub data: [u8; RAW_DEVICE_TREE.len()],
203+
}
204+
let mut aligned_data: Box<AlignedBuffer> = Box::new(AlignedBuffer {
205+
data: [0; BUFFER_SIZE],
206+
});
207+
aligned_data.data[..BUFFER_SIZE].clone_from_slice(RAW_DEVICE_TREE);
208+
let mut slice = aligned_data.data.to_vec();
209+
let ptr = DtbPtr::from_raw(slice.as_mut_ptr()).unwrap();
210+
let dtb = Dtb::from(ptr).share();
211+
212+
let t: Tree = from_raw_mut(&dtb).unwrap();
213+
assert_eq!(t.memory.len(), 1);
214+
let range = t
215+
.memory
216+
.iter()
217+
.next()
218+
.unwrap()
219+
.deserialize::<Memory>()
220+
.reg
221+
.iter()
222+
.next()
223+
.unwrap()
224+
.0;
225+
assert_eq!(range, 1342177280..1408237568);
226+
}
227+
#[test]
228+
fn test_nodeseq_with_at() {
229+
#[repr(align(8))]
230+
struct AlignedBuffer {
231+
pub data: [u8; RAW_DEVICE_TREE_QEMU.len()],
232+
}
233+
let mut aligned_data: Box<AlignedBuffer> = Box::new(AlignedBuffer {
234+
data: [0; BUFFER_SIZE_QEMU],
235+
});
236+
aligned_data.data[..BUFFER_SIZE_QEMU].clone_from_slice(RAW_DEVICE_TREE_QEMU);
237+
let mut slice = aligned_data.data.to_vec();
238+
let ptr = DtbPtr::from_raw(slice.as_mut_ptr()).unwrap();
239+
let dtb = Dtb::from(ptr).share();
240+
241+
let t: Tree = from_raw_mut(&dtb).unwrap();
242+
assert_eq!(t.memory.len(), 1);
243+
let range = t
244+
.memory
245+
.iter()
246+
.next()
247+
.unwrap()
248+
.deserialize::<Memory>()
249+
.reg
250+
.iter()
251+
.next()
252+
.unwrap()
253+
.0;
254+
assert_eq!(range, 2147483648..6442450944);
255+
}
256+
}

0 commit comments

Comments
 (0)