Skip to content

Commit 7d58543

Browse files
committed
feat: add StrSeq Reg Node serialize
feat: add re_encode example Signed-off-by: Woshiluo Luo <[email protected]>
1 parent 9bc3c29 commit 7d58543

File tree

11 files changed

+180
-39
lines changed

11 files changed

+180
-39
lines changed

examples/re_encode.rs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use serde_device_tree::{Dtb, DtbPtr, buildin::Node, error::Error, from_raw_mut};
2+
3+
use std::io::prelude::*;
4+
5+
const RAW_DEVICE_TREE: &[u8] = include_bytes!("qemu-virt.dtb");
6+
const BUFFER_SIZE: usize = RAW_DEVICE_TREE.len();
7+
8+
#[repr(align(8))]
9+
struct AlignedBuffer {
10+
pub data: [u8; RAW_DEVICE_TREE.len()],
11+
}
12+
13+
fn main() -> Result<(), Error> {
14+
let mut aligned_data: Box<AlignedBuffer> = Box::new(AlignedBuffer {
15+
data: [0; BUFFER_SIZE],
16+
});
17+
aligned_data.data[..BUFFER_SIZE].clone_from_slice(RAW_DEVICE_TREE);
18+
let mut buf = [0u8; RAW_DEVICE_TREE.len() * 2];
19+
let mut slice = aligned_data.data.to_vec();
20+
let ptr = DtbPtr::from_raw(slice.as_mut_ptr())?;
21+
let dtb = Dtb::from(ptr).share();
22+
23+
let root: Node = from_raw_mut(&dtb).unwrap();
24+
serde_device_tree::ser::to_dtb(&root, &[], &mut buf).unwrap();
25+
26+
let mut file = std::fs::File::create("gen.dtb").unwrap();
27+
file.write_all(&buf).unwrap();
28+
29+
Ok(())
30+
}

src/de_mut/cursor.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ pub enum MoveResult {
2929
}
3030

3131
#[derive(Clone, Copy, Debug)]
32-
pub(super) struct MultiNodeCursor {
32+
pub(crate) struct MultiNodeCursor {
3333
pub start_cursor: BodyCursor,
34-
pub next_cursor: BodyCursor,
3534
pub skip_cursor: BodyCursor,
35+
pub data_cursor: BodyCursor,
3636
#[allow(unused)]
3737
pub node_count: u32,
3838
}
@@ -51,6 +51,7 @@ impl<T: Type> AnyCursor<T> {
5151

5252
impl BodyCursor {
5353
pub const ROOT: Self = Self(2, PhantomData);
54+
pub const STARTER: Self = Self(0, PhantomData);
5455

5556
/// 移动到下一个项目。
5657
pub fn move_on(&mut self, dtb: RefDtb) -> Cursor {
@@ -82,6 +83,7 @@ impl BodyCursor {
8283
}
8384
todo!()
8485
}
86+
8587
/// 移动指针至下一块
8688
pub fn move_next(&mut self, dtb: RefDtb) -> MoveResult {
8789
use StructureBlock as B;
@@ -183,8 +185,8 @@ impl TitleCursor {
183185
}
184186
MultiNodeCursor {
185187
start_cursor: group,
186-
next_cursor: body,
187-
skip_cursor: title_body,
188+
skip_cursor: body,
189+
data_cursor: title_body,
188190
node_count: len,
189191
}
190192
}
@@ -201,8 +203,8 @@ impl TitleCursor {
201203
body.escape_from(dtb);
202204
MultiNodeCursor {
203205
start_cursor: origin,
204-
next_cursor: body,
205-
skip_cursor: node,
206+
skip_cursor: body,
207+
data_cursor: node,
206208
node_count: 1,
207209
}
208210
}

src/de_mut/data.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub(super) enum ValueCursor {
1010
Body(BodyCursor),
1111
Prop(BodyCursor, PropCursor),
1212
Node(MultiNodeCursor),
13+
NodeIn(MultiNodeCursor),
1314
}
1415

1516
#[derive(Clone, Copy)]
@@ -208,8 +209,9 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
208209
visitor.visit_some(self)
209210
}
210211
}
211-
ValueCursor::Node(_) => visitor.visit_some(self),
212+
ValueCursor::NodeIn(_) => visitor.visit_some(self),
212213
ValueCursor::Body(_) => visitor.visit_some(self),
214+
ValueCursor::Node(_) => unreachable!("Node to option(NodeIn instead)"),
213215
}
214216
}
215217

@@ -251,7 +253,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
251253
{
252254
use super::{StructAccess, StructAccessType, Temp};
253255
match self.cursor {
254-
ValueCursor::Node(result) => {
256+
ValueCursor::NodeIn(result) => {
255257
let mut start_cursor = result.start_cursor;
256258
match start_cursor.move_on(self.dtb) {
257259
Cursor::Title(c) => {
@@ -302,7 +304,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
302304
{
303305
use super::{StructAccess, StructAccessType, Temp};
304306
match self.cursor {
305-
ValueCursor::Node(_) => visitor.visit_map(StructAccess {
307+
ValueCursor::NodeIn(_) => visitor.visit_map(StructAccess {
306308
access_type: StructAccessType::Map(false),
307309
temp: Temp::Uninit,
308310
de: self,
@@ -313,6 +315,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
313315
de: self,
314316
}),
315317
ValueCursor::Prop(_, _) => unreachable!("Prop -> map"),
318+
ValueCursor::Node(_) => unreachable!("Node -> map (Use NodeIn instead)"),
316319
}
317320
}
318321

@@ -327,7 +330,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
327330
{
328331
use super::{StructAccess, StructAccessType, Temp};
329332
match self.cursor {
330-
ValueCursor::Node(_) => visitor.visit_map(StructAccess {
333+
ValueCursor::NodeIn(_) => visitor.visit_map(StructAccess {
331334
access_type: StructAccessType::Struct(fields),
332335
temp: Temp::Uninit,
333336
de: self,
@@ -338,6 +341,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
338341
de: self,
339342
}),
340343
ValueCursor::Prop(_, _) => unreachable!("Prop -> struct {_name}"),
344+
ValueCursor::Node(_) => unreachable!("Node -> struct {_name} (Use NodeIn instead)"),
341345
}
342346
}
343347

src/de_mut/mod.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use serde::de;
77
mod cursor;
88
mod data;
99
// mod group;
10-
mod node;
10+
pub(crate) mod node;
1111
mod node_seq;
1212
mod reg;
1313
mod str_seq;
@@ -16,13 +16,16 @@ mod struct_access;
1616
mod structs;
1717

1818
const VALUE_DESERIALIZER_NAME: &str = "$serde_device_tree$de_mut$ValueDeserializer";
19+
pub(crate) const NODE_NAME: &str = "$serde_device_tree$de_mut$Node";
20+
pub(crate) const NODE_NODE_ITEM_NAME: &str = "$serde_device_tree$de_mut$Node$NodeItem";
21+
pub(crate) const NODE_PROP_ITEM_NAME: &str = "$serde_device_tree$de_mut$Node$PropItem";
1922

2023
pub use structs::{Dtb, DtbPtr};
2124
pub mod buildin {
2225
pub use super::{node::Node, node_seq::NodeSeq, reg::Reg, str_seq::StrSeq};
2326
}
2427

25-
use cursor::{BodyCursor, Cursor, PropCursor};
28+
use cursor::{BodyCursor, Cursor, MultiNodeCursor, PropCursor};
2629
use data::{ValueCursor, ValueDeserializer};
2730
use reg::RegConfig;
2831
use struct_access::{StructAccess, StructAccessType, Temp};
@@ -41,7 +44,12 @@ where
4144
let mut d = ValueDeserializer {
4245
dtb,
4346
reg: RegConfig::DEFAULT,
44-
cursor: ValueCursor::Body(BodyCursor::ROOT),
47+
cursor: ValueCursor::NodeIn(MultiNodeCursor {
48+
start_cursor: BodyCursor::STARTER,
49+
skip_cursor: BodyCursor::ROOT, // This item will never be used.
50+
data_cursor: BodyCursor::ROOT,
51+
node_count: 1,
52+
}),
4553
};
4654
T::deserialize(&mut d).and_then(|t| {
4755
// 解析必须完成

src/de_mut/node.rs

+50-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
use super::{BodyCursor, Cursor, PropCursor, RefDtb, RegConfig, ValueCursor, ValueDeserializer};
1+
use super::{
2+
BodyCursor, Cursor, MultiNodeCursor, PropCursor, RefDtb, RegConfig, ValueCursor,
3+
ValueDeserializer,
4+
};
25
use core::fmt::Debug;
36
use core::marker::PhantomData;
47
use serde::de::MapAccess;
5-
use serde::{Deserialize, de};
8+
use serde::{Deserialize, Serialize, de};
69

710
// TODO: Spec 2.3.5 said that we should not inherited from ancestors and the size-cell &
811
// address-cells should only used for current node's children.
@@ -27,7 +30,7 @@ pub struct NodeIter<'de, 'b> {
2730
pub struct NodeItem<'de> {
2831
dtb: RefDtb<'de>,
2932
reg: RegConfig,
30-
node: BodyCursor,
33+
node: MultiNodeCursor,
3134
name: &'de str,
3235
}
3336

@@ -81,6 +84,16 @@ impl<'de> Node<'de> {
8184
pub fn get_prop<'b>(&'b self, name: &str) -> Option<PropItem<'b>> {
8285
self.props().find(|prop| prop.get_name() == name)
8386
}
87+
88+
pub fn name(&self) -> &'de str {
89+
let cursor = self.cursor.clone().move_on(self.dtb);
90+
if let Cursor::Title(c) = cursor {
91+
let (name, _) = c.split_on(self.dtb);
92+
name
93+
} else {
94+
todo!();
95+
}
96+
}
8497
}
8598

8699
impl Debug for Node<'_> {
@@ -128,10 +141,10 @@ impl<'de> Iterator for NodeIter<'de, '_> {
128141
let res = Some(Self::Item {
129142
dtb,
130143
reg: self.node.reg,
131-
node: node_cursor.skip_cursor,
144+
node: node_cursor,
132145
name,
133146
});
134-
*cursor = node_cursor.next_cursor;
147+
*cursor = node_cursor.skip_cursor;
135148
res
136149
} else {
137150
None
@@ -200,10 +213,9 @@ impl<'de> Deserialize<'de> for Node<'_> {
200213
reg = Some(value.reg);
201214
if key == "/" {
202215
self_cursor = match value.cursor {
203-
ValueCursor::Body(cursor) => Some(cursor),
204-
ValueCursor::Node(result) => Some(result.next_cursor),
216+
ValueCursor::NodeIn(result) => Some(result.start_cursor),
205217
_ => {
206-
unreachable!("root of NodeSeq shouble be body cursor")
218+
unreachable!("root of NodeSeq shouble be NodeIn cursor")
207219
}
208220
};
209221
continue;
@@ -214,7 +226,7 @@ impl<'de> Deserialize<'de> for Node<'_> {
214226
props_start = Some(cursor);
215227
}
216228
}
217-
ValueCursor::Node(cursor) => {
229+
ValueCursor::NodeIn(cursor) => {
218230
if nodes_start.is_none() {
219231
nodes_start = Some(cursor.start_cursor);
220232
}
@@ -249,7 +261,7 @@ impl<'de> NodeItem<'de> {
249261
T::deserialize(&mut ValueDeserializer {
250262
dtb: self.dtb,
251263
reg: self.reg,
252-
cursor: ValueCursor::Body(self.node),
264+
cursor: ValueCursor::NodeIn(self.node),
253265
})
254266
.unwrap()
255267
}
@@ -271,13 +283,13 @@ impl<'de> NodeItem<'de> {
271283
}
272284
}
273285

274-
pub fn get_full_name(&self) -> &str {
286+
pub fn get_full_name(&self) -> &'de str {
275287
self.name
276288
}
277289
}
278290

279291
impl<'de> PropItem<'de> {
280-
pub fn get_name(&self) -> &str {
292+
pub fn get_name(&self) -> &'de str {
281293
self.name
282294
}
283295
pub fn deserialize<T: Deserialize<'de>>(&self) -> T {
@@ -290,6 +302,32 @@ impl<'de> PropItem<'de> {
290302
.unwrap()
291303
}
292304
}
305+
impl<'se> Serialize for NodeItem<'se> {
306+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
307+
where
308+
S: serde::Serializer,
309+
{
310+
serializer.serialize_newtype_struct(crate::de_mut::NODE_NODE_ITEM_NAME, self)
311+
}
312+
}
313+
314+
impl<'se> Serialize for PropItem<'se> {
315+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
316+
where
317+
S: serde::Serializer,
318+
{
319+
serializer.serialize_bytes(self.prop.data_on(self.dtb))
320+
}
321+
}
322+
323+
impl<'se> Serialize for Node<'se> {
324+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
325+
where
326+
S: serde::Serializer,
327+
{
328+
serializer.serialize_newtype_struct(crate::de_mut::NODE_NAME, self)
329+
}
330+
}
293331

294332
#[cfg(test)]
295333
mod tests {

src/de_mut/node_seq.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,12 @@ impl<'de> Iterator for NodeSeqIter<'de, '_> {
140140
return None;
141141
}
142142

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

145145
Some(Self::Item {
146146
dtb: self.de.dtb,
147147
reg: self.de.reg,
148-
body: node_reuslt.skip_cursor,
148+
body: node_reuslt.data_cursor,
149149
at: suf_name,
150150
})
151151
}

src/de_mut/reg.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::{BLOCK_LEN, PropCursor, RefDtb, ValueCursor};
22
use core::{fmt::Debug, ops::Range};
3-
use serde::Deserialize;
3+
use serde::{Deserialize, Serialize};
44

55
/// 节点地址空间。
66
pub struct Reg<'de>(Inner<'de>);
@@ -116,3 +116,13 @@ impl Iterator for RegIter<'_> {
116116
}
117117
}
118118
}
119+
120+
impl<'se> Serialize for Reg<'se> {
121+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
122+
where
123+
S: serde::Serializer,
124+
{
125+
// Pass bytes directly for Reg.
126+
serializer.serialize_bytes(self.0.cursor.data_on(self.0.dtb))
127+
}
128+
}

src/de_mut/str_seq.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::{PropCursor, RefDtb, ValueCursor};
22
use core::fmt::Debug;
3-
use serde::Deserialize;
3+
use serde::{Deserialize, Serialize};
44

55
/// 一组 '\0' 分隔字符串的映射。
66
///
@@ -90,3 +90,13 @@ impl<'de> Iterator for StrSeqIter<'de> {
9090
}
9191
}
9292
}
93+
94+
impl<'se> Serialize for StrSeq<'se> {
95+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
96+
where
97+
S: serde::Serializer,
98+
{
99+
// Pass bytes directly for StrSeq.
100+
serializer.serialize_bytes(self.0.cursor.data_on(self.0.dtb))
101+
}
102+
}

0 commit comments

Comments
 (0)