Skip to content

Commit af86aa2

Browse files
committed
feat: add matrix in de_mut
Signed-off-by: Woshiluo Luo <woshiluo.luo@outlook.com>
1 parent 59d640d commit af86aa2

File tree

4 files changed

+119
-4
lines changed

4 files changed

+119
-4
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ Cargo.lock
44

55
# Visual Studio Code configuration files
66
.vscode/
7-
*.dts
7+
8+
*.dtb
9+
!examples/*.dtb

src/de_mut/matrix.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use crate::de_mut::ValueCursor;
2+
use serde::{Deserialize, Serialize};
3+
4+
pub struct Matrix<'de, const T: usize> {
5+
data: &'de [u32],
6+
}
7+
8+
pub struct MatrixItem<'de, const T: usize> {
9+
offset: usize,
10+
data: &'de [u32],
11+
}
12+
13+
impl<'de, const T: usize> Matrix<'de, T> {
14+
// Block size in bytes.
15+
pub fn get_block_size() -> usize {
16+
T * 4
17+
}
18+
19+
pub fn iter(&self) -> MatrixItem<'de, T> {
20+
MatrixItem {
21+
offset: 0,
22+
data: self.data,
23+
}
24+
}
25+
}
26+
27+
impl<'de, const T: usize> Iterator for MatrixItem<'de, T> {
28+
type Item = &'de [u32];
29+
30+
fn next(&mut self) -> Option<Self::Item> {
31+
if self.data.len() <= self.offset {
32+
return None;
33+
}
34+
let result = &self.data[self.offset..self.offset + T];
35+
self.offset += T;
36+
Some(result)
37+
}
38+
}
39+
40+
impl<'de, const T: usize> Deserialize<'de> for Matrix<'de, T> {
41+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
42+
where
43+
D: serde::Deserializer<'de>,
44+
{
45+
let value_deserialzer = super::ValueDeserializer::deserialize(deserializer)?;
46+
let data = match value_deserialzer.cursor {
47+
ValueCursor::Prop(_, cursor) => cursor.data_on(value_deserialzer.dtb),
48+
_ => unreachable!(),
49+
};
50+
if data.len() % Self::get_block_size() != 0 {
51+
panic!("unaligned matrix");
52+
}
53+
let (prefix, data, suffix) = unsafe { data.align_to::<u32>() };
54+
if prefix.len() != 0 || suffix.len() != 0 {
55+
panic!("Not support unaligned data");
56+
}
57+
58+
Ok(Self { data })
59+
}
60+
}
61+
62+
impl<'se, const T: usize> Serialize for Matrix<'se, T> {
63+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
64+
where
65+
S: serde::Serializer,
66+
{
67+
use serde::ser::SerializeSeq;
68+
let mut seq = serializer.serialize_seq(Some(self.data.len()))?;
69+
for x in self.data {
70+
seq.serialize_element(x)?;
71+
}
72+
seq.end()
73+
}
74+
}
75+
76+
#[cfg(test)]
77+
mod tests {
78+
use super::Matrix;
79+
use crate::{Dtb, DtbPtr, buildin::Node, from_raw_mut};
80+
use serde_derive::Serialize;
81+
82+
const MAX_SIZE: usize = 256;
83+
#[test]
84+
fn base_ser_test() {
85+
#[derive(Serialize)]
86+
struct Base {
87+
pub hello: [u32; 16],
88+
}
89+
let array: [u32; 16] = [0xdeadbeef; 16];
90+
let mut buf1 = [0u8; MAX_SIZE];
91+
92+
{
93+
let base = Base { hello: array };
94+
crate::ser::to_dtb(&base, &[], &mut buf1).unwrap();
95+
}
96+
97+
let ptr = DtbPtr::from_raw(buf1.as_mut_ptr()).unwrap();
98+
let dtb = Dtb::from(ptr).share();
99+
let node: Node = from_raw_mut(&dtb).unwrap();
100+
let matrix = node.get_prop("hello").unwrap().deserialize::<Matrix<4>>();
101+
let mut count = 0;
102+
for x in matrix.iter() {
103+
for y in x {
104+
count += 1;
105+
assert_eq!(u32::from_be(*y), 0xdeadbeef);
106+
}
107+
}
108+
assert_eq!(count, 16);
109+
}
110+
}

src/de_mut/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use serde::de;
77
mod cursor;
88
mod data;
99
// mod group;
10+
mod matrix;
1011
pub(crate) mod node;
1112
mod node_seq;
1213
mod reg;
@@ -18,11 +19,11 @@ mod structs;
1819
const VALUE_DESERIALIZER_NAME: &str = "$serde_device_tree$de_mut$ValueDeserializer";
1920
pub(crate) const NODE_NAME: &str = "$serde_device_tree$de_mut$Node";
2021
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";
22+
// pub(crate) const NODE_PROP_ITEM_NAME: &str = "$serde_device_tree$de_mut$Node$PropItem";
2223

2324
pub use structs::{Dtb, DtbPtr};
2425
pub mod buildin {
25-
pub use super::{node::Node, node_seq::NodeSeq, reg::Reg, str_seq::StrSeq};
26+
pub use super::{matrix::Matrix, node::Node, node_seq::NodeSeq, reg::Reg, str_seq::StrSeq};
2627
}
2728

2829
use cursor::{BodyCursor, Cursor, MultiNodeCursor, PropCursor};

src/ser/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ where
3939
let writer_len = writer.len();
4040
let (data_block, string_block) = writer.split_at_mut(writer.len() - offset);
4141
let (header, data_block) = data_block.split_at_mut(HEADER_LEN as usize + RSVMAP_LEN);
42+
let struct_len;
4243
{
4344
let mut patch_list = crate::ser::patch::PatchList::new(list);
4445
let mut block = crate::ser::string_block::StringBlock::new(string_block, &mut offset);
@@ -47,6 +48,7 @@ where
4748
crate::ser::serializer::Serializer::new(&mut dst, &mut block, &mut patch_list);
4849
data.serialize(&mut ser)?;
4950
ser.dst.step_by_u32(FDT_END);
51+
struct_len = ser.dst.get_offset();
5052
}
5153
// Make header
5254
{
@@ -60,7 +62,7 @@ where
6062
header.last_comp_version = u32::from_be(SUPPORTED_VERSION); // TODO: maybe 16
6163
header.boot_cpuid_phys = 0; // TODO: wtf is this prop
6264
header.size_dt_strings = u32::from_be(offset as u32);
63-
header.size_dt_struct = u32::from_be(data_block.len() as u32); // TODO: correct?
65+
header.size_dt_struct = u32::from_be(struct_len as u32);
6466
}
6567
Ok(())
6668
}

0 commit comments

Comments
 (0)