fdt_edit/node/
mod.rs

1use core::fmt::Debug;
2
3use alloc::{
4    collections::BTreeMap,
5    string::{String, ToString},
6    vec::Vec,
7};
8use fdt_raw::data::StrIter;
9
10use crate::{Phandle, Property, RangesEntry, Status, node::gerneric::NodeRefGen};
11
12mod clock;
13mod display;
14mod gerneric;
15mod interrupt_controller;
16mod iter;
17mod memory;
18mod pci;
19
20pub use clock::*;
21pub use display::*;
22pub use interrupt_controller::*;
23pub use iter::*;
24pub use memory::*;
25pub use pci::*;
26
27/// 节点类型枚举,用于模式匹配
28#[derive(Clone, Debug)]
29pub enum NodeKind<'a> {
30    Clock(NodeRefClock<'a>),
31    Pci(NodeRefPci<'a>),
32    InterruptController(NodeRefInterruptController<'a>),
33    Memory(NodeRefMemory<'a>),
34    Generic(NodeRefGen<'a>),
35}
36
37#[derive(Clone)]
38pub struct Node {
39    pub name: String,
40    /// 属性列表(保持原始顺序)
41    pub(crate) properties: Vec<Property>,
42    /// 属性名到索引的映射(用于快速查找)
43    pub(crate) prop_cache: BTreeMap<String, usize>,
44    pub(crate) children: Vec<Node>,
45    pub(crate) name_cache: BTreeMap<String, usize>,
46}
47
48impl Node {
49    pub fn new(name: &str) -> Self {
50        Self {
51            name: name.to_string(),
52            properties: Vec::new(),
53            prop_cache: BTreeMap::new(),
54            children: Vec::new(),
55            name_cache: BTreeMap::new(),
56        }
57    }
58
59    pub fn name(&self) -> &str {
60        &self.name
61    }
62
63    pub fn properties(&self) -> impl Iterator<Item = &Property> {
64        self.properties.iter()
65    }
66
67    pub fn children(&self) -> impl Iterator<Item = &Node> {
68        self.children.iter()
69    }
70
71    pub fn children_mut(&mut self) -> impl Iterator<Item = &mut Node> {
72        self.children.iter_mut()
73    }
74
75    pub fn add_child(&mut self, child: Node) {
76        let index = self.children.len();
77        self.name_cache.insert(child.name.clone(), index);
78        self.children.push(child);
79    }
80
81    pub fn add_property(&mut self, prop: Property) {
82        let name = prop.name.clone();
83        let index = self.properties.len();
84        self.prop_cache.insert(name, index);
85        self.properties.push(prop);
86    }
87
88    pub fn get_child(&self, name: &str) -> Option<&Node> {
89        if let Some(&index) = self.name_cache.get(name) {
90            self.children.get(index)
91        } else {
92            None
93        }
94    }
95
96    pub fn get_child_mut(&mut self, name: &str) -> Option<&mut Node> {
97        if let Some(&index) = self.name_cache.get(name) {
98            self.children.get_mut(index)
99        } else {
100            None
101        }
102    }
103
104    pub fn remove_child(&mut self, name: &str) -> Option<Node> {
105        if let Some(&index) = self.name_cache.get(name) {
106            self.name_cache.remove(name);
107            Some(self.children.remove(index))
108        } else {
109            None
110        }
111    }
112
113    pub fn set_property(&mut self, prop: Property) {
114        let name = prop.name.clone();
115        if let Some(&idx) = self.prop_cache.get(&name) {
116            // 更新已存在的属性
117            self.properties[idx] = prop;
118        } else {
119            // 添加新属性
120            let idx = self.properties.len();
121            self.prop_cache.insert(name, idx);
122            self.properties.push(prop);
123        }
124    }
125
126    pub fn get_property(&self, name: &str) -> Option<&Property> {
127        self.prop_cache.get(name).map(|&idx| &self.properties[idx])
128    }
129
130    pub fn get_property_mut(&mut self, name: &str) -> Option<&mut Property> {
131        self.prop_cache
132            .get(name)
133            .map(|&idx| &mut self.properties[idx])
134    }
135
136    pub fn remove_property(&mut self, name: &str) -> Option<Property> {
137        if let Some(&idx) = self.prop_cache.get(name) {
138            self.prop_cache.remove(name);
139            // 重建索引(移除元素后需要更新后续索引)
140            let prop = self.properties.remove(idx);
141            for (_, v) in self.prop_cache.iter_mut() {
142                if *v > idx {
143                    *v -= 1;
144                }
145            }
146            Some(prop)
147        } else {
148            None
149        }
150    }
151
152    pub fn address_cells(&self) -> Option<u32> {
153        self.get_property("#address-cells")
154            .and_then(|prop| prop.get_u32())
155    }
156
157    pub fn size_cells(&self) -> Option<u32> {
158        self.get_property("#size-cells")
159            .and_then(|prop| prop.get_u32())
160    }
161
162    pub fn phandle(&self) -> Option<Phandle> {
163        self.get_property("phandle")
164            .and_then(|prop| prop.get_u32())
165            .map(Phandle::from)
166    }
167
168    pub fn interrupt_parent(&self) -> Option<Phandle> {
169        self.get_property("interrupt-parent")
170            .and_then(|prop| prop.get_u32())
171            .map(Phandle::from)
172    }
173
174    pub fn status(&self) -> Option<Status> {
175        let prop = self.get_property("status")?;
176        let s = prop.as_str()?;
177        match s {
178            "okay" => Some(Status::Okay),
179            "disabled" => Some(Status::Disabled),
180            _ => None,
181        }
182    }
183
184    pub fn ranges(&self, parent_address_cells: u32) -> Option<Vec<RangesEntry>> {
185        let prop = self.get_property("ranges")?;
186        let mut entries = Vec::new();
187        let mut reader = prop.as_reader();
188
189        // 当前节点的 #address-cells 用于子节点地址
190        let child_address_cells = self.address_cells().unwrap_or(2) as usize;
191        // 父节点的 #address-cells 用于父总线地址
192        let parent_addr_cells = parent_address_cells as usize;
193        // 当前节点的 #size-cells
194        let size_cells = self.size_cells().unwrap_or(1) as usize;
195
196        while let (Some(child_addr), Some(parent_addr), Some(size)) = (
197            reader.read_cells(child_address_cells),
198            reader.read_cells(parent_addr_cells),
199            reader.read_cells(size_cells),
200        ) {
201            entries.push(RangesEntry {
202                child_bus_address: child_addr,
203                parent_bus_address: parent_addr,
204                length: size,
205            });
206        }
207
208        Some(entries)
209    }
210
211    pub fn compatible(&self) -> Option<StrIter<'_>> {
212        let prop = self.get_property("compatible")?;
213        Some(prop.as_str_iter())
214    }
215
216    pub fn compatibles(&self) -> impl Iterator<Item = &str> {
217        self.get_property("compatible")
218            .map(|prop| prop.as_str_iter())
219            .into_iter()
220            .flatten()
221    }
222
223    pub fn device_type(&self) -> Option<&str> {
224        let prop = self.get_property("device_type")?;
225        prop.as_str()
226    }
227
228    /// 通过精确路径删除子节点及其子树
229    /// 只支持精确路径匹配,不支持模糊匹配
230    ///
231    /// # 参数
232    /// - `path`: 删除路径,格式如 "soc/gpio@1000" 或 "/soc/gpio@1000"
233    ///
234    /// # 返回值
235    /// `Ok(Option<Node>)`: 如果找到并删除了节点,返回被删除的节点;如果路径不存在,返回 None
236    /// `Err(FdtError)`: 如果路径格式无效
237    ///
238    /// # 示例
239    /// ```rust
240    /// # use fdt_edit::Node;
241    /// let mut root = Node::new("");
242    /// // 添加测试节点
243    /// let mut soc = Node::new("soc");
244    /// soc.add_child(Node::new("gpio@1000"));
245    /// root.add_child(soc);
246    ///
247    /// // 精确删除节点
248    /// let removed = root.remove_by_path("soc/gpio@1000")?;
249    /// assert!(removed.is_some());
250    /// # Ok::<(), fdt_raw::FdtError>(())
251    /// ```
252    pub fn remove_by_path(&mut self, path: &str) -> Result<Option<Node>, fdt_raw::FdtError> {
253        let normalized_path = path.trim_start_matches('/');
254        if normalized_path.is_empty() {
255            return Err(fdt_raw::FdtError::InvalidInput);
256        }
257
258        let parts: Vec<&str> = normalized_path.split('/').collect();
259        if parts.is_empty() {
260            return Err(fdt_raw::FdtError::InvalidInput);
261        }
262
263        if parts.len() == 1 {
264            // 删除直接子节点(精确匹配)
265            let child_name = parts[0];
266            Ok(self.remove_child_exact(child_name))
267        } else {
268            // 需要递归到父节点进行删除
269            self.remove_child_recursive(&parts, 0)
270        }
271    }
272
273    /// 递归删除子节点的实现
274    /// 找到要删除节点的父节点,然后从父节点中删除目标子节点
275    fn remove_child_recursive(
276        &mut self,
277        parts: &[&str],
278        index: usize,
279    ) -> Result<Option<Node>, fdt_raw::FdtError> {
280        if index >= parts.len() - 1 {
281            // 已经到达要删除节点的父级
282            let child_name_to_remove = parts[index];
283            Ok(self.remove_child_exact(child_name_to_remove))
284        } else {
285            // 继续向下递归
286            let current_part = parts[index];
287
288            // 中间级别只支持精确匹配(使用缓存)
289            if let Some(&child_index) = self.name_cache.get(current_part) {
290                self.children[child_index].remove_child_recursive(parts, index + 1)
291            } else {
292                // 路径不存在
293                Ok(None)
294            }
295        }
296    }
297
298    /// 精确删除子节点,不支持部分匹配
299    fn remove_child_exact(&mut self, name: &str) -> Option<Node> {
300        if let Some(&index) = self.name_cache.get(name) {
301            let child = self.children.remove(index);
302            self.name_cache.remove(name);
303            Some(child)
304        } else {
305            None
306        }
307    }
308}
309
310impl From<&fdt_raw::Node<'_>> for Node {
311    fn from(raw: &fdt_raw::Node<'_>) -> Self {
312        let mut new_node = Node::new(raw.name());
313        // 复制属性
314        for raw_prop in raw.properties() {
315            let prop = Property::from(&raw_prop);
316            new_node.set_property(prop);
317        }
318        new_node
319    }
320}