Skip to content

Commit e724953

Browse files
authored
Merge pull request #6 from YdrMaster/alpha3
Alpha3
2 parents 1c4d0c7 + e9e4b1f commit e724953

8 files changed

Lines changed: 264 additions & 133 deletions

File tree

CHANGELOG.md

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,56 @@ All notable changes to this project will be documented in this file.
1010

1111
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1212

13-
## 未发布
13+
## [0.2.0-alpha.3](https://github.com/YdrMaster/dtb-walker/releases/tag/0.2.0-alpha.3) - 2022-07-19
1414

15-
## Unreleased
15+
### Change
16+
17+
- 删除 `Path`,增加 `Context` 类型集中处理所有从父节点向子节点传递的信息。
18+
19+
---
20+
21+
- Removes `Path` Type, and adds `Context` to handle all information passed from parent node to child node.
22+
23+
## [0.2.0-alpha.2](https://github.com/YdrMaster/dtb-walker/releases/tag/0.2.0-alpha.2) - 2022-07-15
24+
25+
### Fixed
26+
27+
- 不带过滤器构造 `Dtb` 时应该拒绝所有不合规范的情况,而不是全部接受
28+
29+
---
30+
31+
- Build `Dtb` without filter should reject all non-conformances, instead of accepting them all
32+
33+
### Added
34+
35+
-`&[u8]` 构造 `Dtb` 时也可以使用过滤器
36+
37+
---
38+
39+
- Provides a method to build `Dtb` from `&[u8]` with a filter
1640

1741
## [0.2.0-alpha.1](https://github.com/YdrMaster/dtb-walker/releases/tag/0.2.0-alpha.1) - 2022-07-12
1842

43+
### Changed
44+
1945
- 规范化更新日志格式
2046
- 字符串统一使用一个封装的 `Str` 类型(包括节点名、属性名、`<string>` 类型的属性值、路径),类似于 `str` 但未检查是否符合 utf-8 编码
2147
- 格式化 `Str` 不再自带引号
2248
- 补全文档并禁止不写文档
23-
- github ci 自动运行一次示例
2449

2550
---
2651

2752
- standardizes the change log
2853
- uses an encapsulated `Str` type uniformly for strings (including node name, property name, property value of `<string>`, path), similar to `str` but not checked for utf-8 encoding
2954
- will not add quotes when formating `Str`
3055
- completes documentation and missing documentation is denied from now on
56+
57+
### Added
58+
59+
- github ci 会运行一次示例
60+
61+
---
62+
3163
- runs example during github ci
3264

3365
## [0.1.3](https://github.com/YdrMaster/dtb-walker/releases/tag/v0.1.3) - 2022-06-30

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "dtb-walker"
33
description = "A simple package for DTB depth-first walking."
4-
version = "0.2.0-alpha.1"
4+
version = "0.2.0-alpha.3"
55
edition = "2021"
66
authors = ["YdrMaster <ydrml@hotmail.com>"]
77
repository = "https://github.com/YdrMaster/dtb-walker.git"

src/context.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
use crate::{tree_on_stack::Node, Str};
2+
use core::fmt;
3+
4+
/// 遍历上下文。
5+
pub struct Context<'a>(Node<'a, Inner<'a>>);
6+
7+
struct Inner<'a> {
8+
name: Str<'a>,
9+
cells: Cells,
10+
}
11+
12+
impl Context<'_> {
13+
pub(crate) const ROOT: Self = Context(Node::root(Inner {
14+
name: Str(b""),
15+
cells: Cells::DEFAULT,
16+
}));
17+
18+
/// 返回路径层数。定义根节点的子节点层数为 0。
19+
#[inline]
20+
pub fn level(&self) -> usize {
21+
self.0.level()
22+
}
23+
24+
/// 如果这是根节点的路径则返回 `true`。
25+
#[inline]
26+
pub fn is_root(&self) -> bool {
27+
self.0.is_root()
28+
}
29+
30+
/// 返回路径最后一级的节点名。
31+
#[inline]
32+
pub fn name(&self) -> Str {
33+
self.0.as_ref().name
34+
}
35+
36+
#[inline]
37+
pub(crate) fn cells(&self) -> Cells {
38+
self.0.as_ref().cells
39+
}
40+
41+
/// 将路径字符串格式化到 `buf` 中。
42+
///
43+
/// 如果返回 `Ok(n)`,表示字符串长度为 `n`(`n` 不大于 `buf.len()`)。
44+
/// 如果返回 `Err(n)`,表示缓冲区长度无法存放整个字符串,实现保证 `n` 等于 `buf.len()`。
45+
pub fn fmt_path(&self, buf: &mut [u8]) -> Result<usize, usize> {
46+
self.0.fold(0, |len, inner| match buf.len() - len {
47+
0 => Err(buf.len()),
48+
mut rest => {
49+
let bytes = inner.name.as_bytes();
50+
buf[len] = b'/';
51+
rest -= 1;
52+
if bytes.len() > rest {
53+
buf[len + 1..].copy_from_slice(&bytes[..rest]);
54+
Err(buf.len())
55+
} else {
56+
buf[len + 1..][..bytes.len()].copy_from_slice(bytes);
57+
Ok(len + bytes.len() + 1)
58+
}
59+
}
60+
})
61+
}
62+
}
63+
64+
impl<'a> Context<'a> {
65+
#[inline]
66+
pub(crate) fn grow(&'a self, name: Str<'a>, cells: Cells) -> Self {
67+
Self(self.0.grow(Inner { name, cells }))
68+
}
69+
}
70+
71+
impl fmt::Display for Context<'_> {
72+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73+
self.0.fold((), |(), inner| {
74+
'/'.fmt(f)?;
75+
unsafe { inner.name.as_str_unchecked() }.fmt(f)
76+
})
77+
}
78+
}
79+
80+
#[derive(Clone, Copy)]
81+
pub(crate) struct Cells {
82+
pub address: u32,
83+
pub size: u32,
84+
pub interrupt: u32,
85+
}
86+
87+
impl Cells {
88+
pub const DEFAULT: Self = Self {
89+
address: 2,
90+
size: 1,
91+
interrupt: 1,
92+
};
93+
94+
#[inline]
95+
pub fn reg_size(&self) -> usize {
96+
(self.address + self.size) as _
97+
}
98+
}

src/lib.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,23 @@
1515
#![no_std]
1616
#![deny(warnings, unstable_features, missing_docs)] // cancel this line during developing
1717

18+
mod context;
1819
mod header;
1920
mod indent;
20-
mod path;
2121
mod property;
2222
mod str;
2323
mod structure_block;
24+
mod tree_on_stack;
2425
mod walker;
2526

2627
pub use self::str::Str;
27-
pub use path::Path;
2828
pub use property::{PHandle, Property, Reg, StrList};
2929
pub mod utils {
3030
//! 用于设备树解析、格式化的工具集。
3131
3232
pub use crate::indent::indent;
3333
}
34+
pub use context::Context;
3435
pub use header::HeaderError;
3536

3637
use core::{fmt, mem, slice};
@@ -50,11 +51,11 @@ impl Dtb<'static> {
5051
/// 如果指针指向一个有效的 DTB 首部,其中描述的整个二进制对象会被切片。
5152
#[inline]
5253
pub unsafe fn from_raw_parts(ptr: *const u8) -> Result<Self, HeaderError> {
53-
(*ptr.cast::<FdtHeader>()).verify(|_| true)?;
54+
(*ptr.cast::<FdtHeader>()).verify(|_| false)?;
5455
Ok(Self::from_raw_parts_unchecked(ptr))
5556
}
5657

57-
/// 构造设备树二进制对象。
58+
/// 构造设备树二进制对象,并可以选择接受某些不合规范的情况
5859
///
5960
/// # Safety
6061
///
@@ -91,13 +92,16 @@ pub enum ConvertError {
9192
}
9293

9394
impl<'a> Dtb<'a> {
94-
/// 从内存切片安全地创建设备树二进制对象。
95-
pub fn from_slice(slice: &'a [u8]) -> Result<Self, ConvertError> {
95+
/// 从内存切片安全地创建设备树二进制对象,可以选择接受某些不合规范的情况。
96+
pub fn from_slice_filtered(
97+
slice: &'a [u8],
98+
f: impl Fn(&HeaderError) -> bool,
99+
) -> Result<Self, ConvertError> {
96100
if slice.len() < mem::size_of::<FdtHeader>() {
97101
return Err(ConvertError::Truncated);
98102
}
99103
let header = unsafe { &*slice.as_ptr().cast::<FdtHeader>() };
100-
match header.verify(|_| true) {
104+
match header.verify(f) {
101105
Ok(()) => {
102106
let len = header.totalsize.into_u32() as usize;
103107
if len <= slice.len() {
@@ -109,6 +113,12 @@ impl<'a> Dtb<'a> {
109113
Err(e) => Err(ConvertError::Header(e)),
110114
}
111115
}
116+
117+
/// 从内存切片安全地创建设备树二进制对象。
118+
#[inline]
119+
pub fn from_slice(slice: &'a [u8]) -> Result<Self, ConvertError> {
120+
Self::from_slice_filtered(slice, |_| false)
121+
}
112122
}
113123

114124
impl Dtb<'_> {
@@ -119,7 +129,7 @@ impl Dtb<'_> {
119129
}
120130

121131
/// 遍历。
122-
pub fn walk(&self, mut f: impl FnMut(&Path<'_>, DtbObj) -> WalkOperation) {
132+
pub fn walk(&self, mut f: impl FnMut(&Context<'_>, DtbObj) -> WalkOperation) {
123133
let header = self.header();
124134
let off_struct = header.off_dt_struct.into_u32() as usize;
125135
let len_struct = header.size_dt_struct.into_u32() as usize;
@@ -137,7 +147,7 @@ impl Dtb<'_> {
137147
},
138148
strings: &self.0[off_strings..][..len_strings],
139149
}
140-
.walk_inner(&mut f, &Path::ROOT, RegCfg::DEFAULT, false);
150+
.walk_inner(&mut f, Some(Context::ROOT));
141151
}
142152

143153
#[inline]

src/path.rs

Lines changed: 0 additions & 74 deletions
This file was deleted.

src/property/reg.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,3 @@ pub(crate) struct RegCfg {
5353
pub address_cells: u32,
5454
pub size_cells: u32,
5555
}
56-
57-
impl RegCfg {
58-
pub const DEFAULT: Self = Self {
59-
address_cells: 2,
60-
size_cells: 1,
61-
};
62-
63-
#[inline]
64-
pub(crate) fn item_size(&self) -> usize {
65-
(self.address_cells + self.size_cells) as _
66-
}
67-
}

0 commit comments

Comments
 (0)