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 get_child(&self, name: &str) -> Option<&Node> {
82        if let Some(&index) = self.name_cache.get(name) {
83            self.children.get(index)
84        } else {
85            None
86        }
87    }
88
89    pub fn get_child_mut(&mut self, name: &str) -> Option<&mut Node> {
90        if let Some(&index) = self.name_cache.get(name) {
91            self.children.get_mut(index)
92        } else {
93            None
94        }
95    }
96
97    pub fn remove_child(&mut self, name: &str) -> Option<Node> {
98        if let Some(&index) = self.name_cache.get(name) {
99            self.name_cache.remove(name);
100            Some(self.children.remove(index))
101        } else {
102            None
103        }
104    }
105
106    pub fn set_property(&mut self, prop: Property) {
107        let name = prop.name.clone();
108        if let Some(&idx) = self.prop_cache.get(&name) {
109            // 更新已存在的属性
110            self.properties[idx] = prop;
111        } else {
112            // 添加新属性
113            let idx = self.properties.len();
114            self.prop_cache.insert(name, idx);
115            self.properties.push(prop);
116        }
117    }
118
119    pub fn get_property(&self, name: &str) -> Option<&Property> {
120        self.prop_cache.get(name).map(|&idx| &self.properties[idx])
121    }
122
123    pub fn get_property_mut(&mut self, name: &str) -> Option<&mut Property> {
124        self.prop_cache
125            .get(name)
126            .map(|&idx| &mut self.properties[idx])
127    }
128
129    pub fn remove_property(&mut self, name: &str) -> Option<Property> {
130        if let Some(&idx) = self.prop_cache.get(name) {
131            self.prop_cache.remove(name);
132            // 重建索引(移除元素后需要更新后续索引)
133            let prop = self.properties.remove(idx);
134            for (_, v) in self.prop_cache.iter_mut() {
135                if *v > idx {
136                    *v -= 1;
137                }
138            }
139            Some(prop)
140        } else {
141            None
142        }
143    }
144
145    pub fn address_cells(&self) -> Option<u32> {
146        self.get_property("#address-cells")
147            .and_then(|prop| prop.get_u32())
148    }
149
150    pub fn size_cells(&self) -> Option<u32> {
151        self.get_property("#size-cells")
152            .and_then(|prop| prop.get_u32())
153    }
154
155    pub fn phandle(&self) -> Option<Phandle> {
156        self.get_property("phandle")
157            .and_then(|prop| prop.get_u32())
158            .map(Phandle::from)
159    }
160
161    pub fn interrupt_parent(&self) -> Option<Phandle> {
162        self.get_property("interrupt-parent")
163            .and_then(|prop| prop.get_u32())
164            .map(Phandle::from)
165    }
166
167    pub fn status(&self) -> Option<Status> {
168        let prop = self.get_property("status")?;
169        let s = prop.as_str()?;
170        match s {
171            "okay" => Some(Status::Okay),
172            "disabled" => Some(Status::Disabled),
173            _ => None,
174        }
175    }
176
177    pub fn ranges(&self, parent_address_cells: u32) -> Option<Vec<RangesEntry>> {
178        let prop = self.get_property("ranges")?;
179        let mut entries = Vec::new();
180        let mut reader = prop.as_reader();
181
182        // 当前节点的 #address-cells 用于子节点地址
183        let child_address_cells = self.address_cells().unwrap_or(2) as usize;
184        // 父节点的 #address-cells 用于父总线地址
185        let parent_addr_cells = parent_address_cells as usize;
186        // 当前节点的 #size-cells
187        let size_cells = self.size_cells().unwrap_or(1) as usize;
188
189        while let (Some(child_addr), Some(parent_addr), Some(size)) = (
190            reader.read_cells(child_address_cells),
191            reader.read_cells(parent_addr_cells),
192            reader.read_cells(size_cells),
193        ) {
194            entries.push(RangesEntry {
195                child_bus_address: child_addr,
196                parent_bus_address: parent_addr,
197                length: size,
198            });
199        }
200
201        Some(entries)
202    }
203
204    pub fn compatible(&self) -> Option<StrIter<'_>> {
205        let prop = self.get_property("compatible")?;
206        Some(prop.as_str_iter())
207    }
208
209    pub fn compatibles(&self) -> impl Iterator<Item = &str> {
210        self.get_property("compatible")
211            .map(|prop| prop.as_str_iter())
212            .into_iter()
213            .flatten()
214    }
215
216    pub fn device_type(&self) -> Option<&str> {
217        let prop = self.get_property("device_type")?;
218        prop.as_str()
219    }
220
221    /// 通过精确路径删除子节点及其子树
222    /// 只支持精确路径匹配,不支持模糊匹配
223    ///
224    /// # 参数
225    /// - `path`: 删除路径,格式如 "soc/gpio@1000" 或 "/soc/gpio@1000"
226    ///
227    /// # 返回值
228    /// `Ok(Option<Node>)`: 如果找到并删除了节点,返回被删除的节点;如果路径不存在,返回 None
229    /// `Err(FdtError)`: 如果路径格式无效
230    ///
231    /// # 示例
232    /// ```rust
233    /// # use fdt_edit::Node;
234    /// let mut root = Node::new("");
235    /// // 添加测试节点
236    /// let mut soc = Node::new("soc");
237    /// soc.add_child(Node::new("gpio@1000"));
238    /// root.add_child(soc);
239    ///
240    /// // 精确删除节点
241    /// let removed = root.remove_by_path("soc/gpio@1000")?;
242    /// assert!(removed.is_some());
243    /// # Ok::<(), fdt_raw::FdtError>(())
244    /// ```
245    pub fn remove_by_path(&mut self, path: &str) -> Result<Option<Node>, fdt_raw::FdtError> {
246        let normalized_path = path.trim_start_matches('/');
247        if normalized_path.is_empty() {
248            return Err(fdt_raw::FdtError::InvalidInput);
249        }
250
251        let parts: Vec<&str> = normalized_path.split('/').collect();
252        if parts.is_empty() {
253            return Err(fdt_raw::FdtError::InvalidInput);
254        }
255
256        if parts.len() == 1 {
257            // 删除直接子节点(精确匹配)
258            let child_name = parts[0];
259            Ok(self.remove_child_exact(child_name))
260        } else {
261            // 需要递归到父节点进行删除
262            self.remove_child_recursive(&parts, 0)
263        }
264    }
265
266    /// 递归删除子节点的实现
267    /// 找到要删除节点的父节点,然后从父节点中删除目标子节点
268    fn remove_child_recursive(
269        &mut self,
270        parts: &[&str],
271        index: usize,
272    ) -> Result<Option<Node>, fdt_raw::FdtError> {
273        if index >= parts.len() - 1 {
274            // 已经到达要删除节点的父级
275            let child_name_to_remove = parts[index];
276            Ok(self.remove_child_exact(child_name_to_remove))
277        } else {
278            // 继续向下递归
279            let current_part = parts[index];
280
281            // 中间级别只支持精确匹配(使用缓存)
282            if let Some(&child_index) = self.name_cache.get(current_part) {
283                self.children[child_index].remove_child_recursive(parts, index + 1)
284            } else {
285                // 路径不存在
286                Ok(None)
287            }
288        }
289    }
290
291    /// 精确删除子节点,不支持部分匹配
292    fn remove_child_exact(&mut self, name: &str) -> Option<Node> {
293        if let Some(&index) = self.name_cache.get(name) {
294            let child = self.children.remove(index);
295            self.name_cache.remove(name);
296            Some(child)
297        } else {
298            None
299        }
300    }
301}
302
303impl From<&fdt_raw::Node<'_>> for Node {
304    fn from(raw: &fdt_raw::Node<'_>) -> Self {
305        let mut new_node = Node::new(raw.name());
306        // 复制属性
307        for raw_prop in raw.properties() {
308            let prop = Property::from(&raw_prop);
309            new_node.set_property(prop);
310        }
311        new_node
312    }
313}