Skip to content

Commit ed66bb1

Browse files
committed
refactor: minimize unsafe
Signed-off-by: Woshiluo Luo <woshiluo.luo@outlook.com> fix: fmt Signed-off-by: Woshiluo Luo <woshiluo.luo@outlook.com>
1 parent 45084e0 commit ed66bb1

File tree

5 files changed

+39
-46
lines changed

5 files changed

+39
-46
lines changed

src/de_mut/cursor.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,16 +129,18 @@ impl TitleCursor {
129129
/// 切分节点名。
130130
pub fn split_on<'de>(&self, dtb: RefDtb<'de>) -> (&'de str, BodyCursor) {
131131
let mut index = self.0 + 1;
132+
let mut len = 0;
132133

133134
let structure = &dtb.borrow().structure;
134-
let ptr = structure[index..].as_ptr() as *const u8;
135135
while let Some(block) = structure.get(index) {
136136
index += 1;
137137
if block.is_end_of_str() {
138138
let end = block.str_end();
139-
let s = unsafe { core::slice::from_raw_parts(ptr, end.offset_from(ptr) as _) };
140-
let s = unsafe { core::str::from_utf8_unchecked(s) };
139+
len += end;
140+
let s = structure[self.0 + 1].lead_str(len);
141141
return (s, AnyCursor(index, PhantomData));
142+
} else {
143+
len += 4;
142144
}
143145
}
144146
todo!()
@@ -158,12 +160,7 @@ impl TitleCursor {
158160
body.skip_str_on(dtb);
159161
body.escape_from(dtb);
160162
if let Cursor::Title(c) = body.move_on(dtb) {
161-
let s = unsafe {
162-
core::slice::from_raw_parts(
163-
structure[c.0 + 1..].as_ptr() as *const u8,
164-
name_bytes.len() + 1,
165-
)
166-
};
163+
let s = structure[c.0 + 1].lead_slice(name_bytes.len() + 1);
167164
if let [name @ .., b'@'] = s {
168165
if name == name_bytes {
169166
body.0 += 1 + name_skip;
@@ -213,15 +210,15 @@ impl PropCursor {
213210

214211
pub fn data_on<'a>(&self, dtb: RefDtb<'a>) -> &'a [u8] {
215212
if let [_, len_data, _, data @ ..] = &dtb.borrow().structure[self.0..] {
216-
unsafe { core::slice::from_raw_parts(data.as_ptr() as _, len_data.as_usize()) }
213+
data[0].lead_slice(len_data.as_usize())
217214
} else {
218215
todo!()
219216
}
220217
}
221218

222219
pub fn map_on<T>(&self, dtb: RefDtb<'_>, f: impl FnOnce(&[u8]) -> T) -> T {
223220
if let [_, len_data, _, data @ ..] = &dtb.borrow().structure[self.0..] {
224-
f(unsafe { core::slice::from_raw_parts(data.as_ptr() as _, len_data.as_usize()) })
221+
f(data[0].lead_slice(len_data.as_usize()))
225222
} else {
226223
todo!()
227224
}

src/de_mut/node_seq.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{BodyCursor, Cursor, RefDtb, RegConfig, ValueCursor, ValueDeserializer};
1+
use super::{BodyCursor, Cursor, RefDtb, RegConfig, ValueCursor, ValueDeserializer};
22
use core::{fmt::Debug, marker::PhantomData};
33
use serde::de::SeqAccess;
44
use serde::{de, Deserialize};
@@ -63,9 +63,7 @@ impl<'de> Deserialize<'de> for NodeSeq<'_> {
6363
Cursor::Title(c) => {
6464
let (name, _) = c.split_on(starter.dtb);
6565

66-
let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count();
67-
let name_bytes = &name.as_bytes()[..pre_len];
68-
let name = unsafe { core::str::from_utf8_unchecked(name_bytes) };
66+
let (name, _) = name.split_once('@').unwrap_or((name, ""));
6967
Ok(NodeSeq {
7068
name,
7169
count,
@@ -137,14 +135,8 @@ impl<'de> Iterator for NodeSeqIter<'de, '_> {
137135
let (full_name, _) = c.split_on(self.de.dtb);
138136
let (node, next) = c.take_node_on(self.de.dtb, full_name);
139137

140-
let pre_len = full_name
141-
.as_bytes()
142-
.iter()
143-
.take_while(|b| **b != b'@')
144-
.count();
145-
let name_bytes = &full_name.as_bytes()[..pre_len];
146-
let name = unsafe { core::str::from_utf8_unchecked(name_bytes) };
147-
if self.seq.name != name {
138+
let (pre_name, suf_name) = full_name.split_once('@').unwrap_or((full_name, ""));
139+
if self.seq.name != pre_name {
148140
return None;
149141
}
150142

@@ -154,7 +146,7 @@ impl<'de> Iterator for NodeSeqIter<'de, '_> {
154146
dtb: self.de.dtb,
155147
reg: self.de.reg,
156148
body: node,
157-
at: &full_name[pre_len + 1..],
149+
at: suf_name,
158150
})
159151
}
160152
_ => None,

src/de_mut/reg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{PropCursor, RefDtb, StructureBlock, ValueCursor, BLOCK_LEN};
1+
use super::{PropCursor, RefDtb, ValueCursor, BLOCK_LEN};
22
use core::{fmt::Debug, ops::Range};
33
use serde::Deserialize;
44

@@ -85,7 +85,7 @@ impl Iterator for RegIter<'_> {
8585
type Item = RegRegion;
8686

8787
fn next(&mut self) -> Option<Self::Item> {
88-
let len = BLOCK_LEN * (self.config.address_cells + self.config.size_cells) as usize;
88+
let len = BLOCK_LEN * (self.config.address_cells + self.config.size_cells);
8989
if self.data.len() >= len {
9090
let (current_block, data) = self.data.split_at(len);
9191
self.data = data;

src/de_mut/struct_access.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> {
5656
Cursor::Title(c) => {
5757
let (name, _) = c.split_on(self.de.dtb);
5858

59-
let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count();
59+
let (pre_name, _) = name.split_once('@').unwrap_or((name, ""));
6060
// 子节点名字不带 @ 或正在解析 Node 类型
61-
if pre_len == name.as_bytes().len() || check_contains(name) {
61+
if pre_name == name || check_contains(name) {
6262
let (node, next) = c.take_node_on(self.de.dtb, name);
6363
self.de.cursor = ValueCursor::Body(next);
6464
if check_contains(name) {
@@ -68,13 +68,11 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> {
6868
}
6969
// @ 之前的部分是真正的名字,用这个名字搜索连续的一组
7070
else {
71-
let name_bytes = &name.as_bytes()[..pre_len];
72-
let name = unsafe { core::str::from_utf8_unchecked(name_bytes) };
73-
let (group, _, next) = c.take_group_on(self.de.dtb, name);
71+
let (group, _, next) = c.take_group_on(self.de.dtb, pre_name);
7472
self.de.cursor = ValueCursor::Body(next);
75-
if check_contains(name) {
73+
if check_contains(pre_name) {
7674
self.temp = Temp::Group(group);
77-
break name;
75+
break pre_name;
7876
}
7977
}
8078
}

src/de_mut/structs.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,23 @@ impl TryFrom<usize> for DtbPtr {
1919
}
2020

2121
impl DtbPtr {
22+
const fn get_header(ptr: &*mut u8) -> &Header {
23+
unsafe { &*(*ptr as *const Header) }
24+
}
25+
2226
/// 验证指针指向的设备树,并构造 `DtbPtr`。
2327
pub fn from_raw(ptr: *mut u8) -> Result<Self, DtError> {
24-
let ptr = ptr as usize;
25-
if ptr & (ALIGN - 1) != 0 {
26-
Err(DtError::unaligned(ptr))
28+
if (ptr as usize) & (ALIGN - 1) != 0 {
29+
Err(DtError::unaligned(ptr as _))
2730
} else {
28-
unsafe { &*(ptr as *const Header) }
29-
.verify()
30-
.map(|_| Self(ptr))
31+
{ Self::get_header(&ptr) }.verify().map(|_| Self(ptr as _))
3132
}
3233
}
3334

3435
/// 计算能容纳整个设备树的最小对齐。
3536
pub const fn align(&self) -> usize {
36-
let header = unsafe { &*(self.0 as *const Header) };
37+
let ptr = self.0 as *mut u8;
38+
let header = Self::get_header(&ptr);
3739
let len = u32::from_be(header.total_size) as usize;
3840
let mut res = ALIGN;
3941
while res < len {
@@ -76,14 +78,13 @@ impl StructureBlock {
7678
}
7779

7880
/// '\0' 结尾字符串的实际结尾。
79-
pub fn str_end(&self) -> *const u8 {
80-
let remnant = match self.0.to_ne_bytes() {
81+
pub fn str_end(&self) -> usize {
82+
match self.0.to_ne_bytes() {
8183
[0, _, _, _] => 0,
8284
[_, 0, _, _] => 1,
8385
[_, _, 0, _] => 2,
8486
[_, _, _, _] => 3,
85-
};
86-
unsafe { (self as *const _ as *const u8).add(remnant) }
87+
}
8788
}
8889

8990
/// 转换为描述字节长度或偏移的数值。
@@ -93,11 +94,16 @@ impl StructureBlock {
9394

9495
/// 构造字节切片。
9596
///
96-
/// TODO
97-
#[allow(unused)]
97+
/// ### Safety
98+
///
99+
/// 保证 当前位置 + 长度 不会超过文件大小。
98100
pub fn lead_slice<'a>(&self, len: usize) -> &'a [u8] {
99101
unsafe { core::slice::from_raw_parts(self as *const _ as *const u8, len) }
100102
}
103+
pub fn lead_str<'a>(&self, len: usize) -> &'a str {
104+
let slice = self.lead_slice(len);
105+
unsafe { core::str::from_utf8_unchecked(slice) }
106+
}
101107
}
102108

103109
/// 设备树的映射形式。

0 commit comments

Comments
 (0)