Skip to content

Commit e786e84

Browse files
committed
feat: support for removing properties directly in FDT
1 parent 26e4c6e commit e786e84

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

src/fdt_mut/node.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,37 @@ impl FdtNodeMut<'_> {
4444
None
4545
}
4646

47+
/// Removes a property from this node by its name.
48+
///
49+
/// This is a convenience method that finds a property by name and calls
50+
/// [`FdtPropertyMut::remove`] on it.
51+
///
52+
/// Returns `true` if the property was present and successfully removed,
53+
/// `false` otherwise.
54+
///
55+
/// # Examples
56+
///
57+
/// ```
58+
/// use dtoolkit::fdt_mut::FdtMut;
59+
/// use dtoolkit::{Node, Property};
60+
///
61+
/// # let mut dtb = include_bytes!("../../tests/dtb/test_traversal.dtb").to_vec();
62+
/// let mut fdt = FdtMut::new(&mut dtb).unwrap();
63+
/// let mut node = fdt.find_node_mut("/a/b/c").unwrap();
64+
/// assert!(node.property("prop").is_some());
65+
/// assert!(node.remove_property("prop"));
66+
/// assert!(node.property("prop").is_none());
67+
/// assert!(!node.remove_property("prop"));
68+
/// ```
69+
pub fn remove_property(&mut self, name: &str) -> bool {
70+
if let Some(prop) = self.property_mut(name) {
71+
prop.remove();
72+
true
73+
} else {
74+
false
75+
}
76+
}
77+
4778
/// Returns a mutable iterator over the properties of this node.
4879
pub fn properties_mut(&mut self) -> FdtPropMutIter<'_> {
4980
FdtPropMutIter {

src/fdt_mut/property.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,37 @@ impl FdtPropertyMut<'_> {
141141
.expect("Fdt should be valid");
142142
FdtProperty { name, value }
143143
}
144+
145+
/// Removes the property by overwriting its structure with `NOP` tags.
146+
///
147+
/// The memory previously occupied by this property will be replaced with
148+
/// `NOP` tags, rendering it invisible to Device Tree iterators
149+
/// without requiring data to be shifted.
150+
///
151+
/// # Examples
152+
///
153+
/// ```
154+
/// use dtoolkit::fdt_mut::FdtMut;
155+
/// use dtoolkit::{Node, Property};
156+
///
157+
/// # let mut dtb = include_bytes!("../../tests/dtb/test_traversal.dtb").to_vec();
158+
/// let mut fdt = FdtMut::new(&mut dtb).unwrap();
159+
/// let mut node = fdt.find_node_mut("/a/b/c").unwrap();
160+
/// let prop = node.property_mut("prop").unwrap();
161+
/// prop.remove();
162+
/// assert!(node.property("prop").is_none());
163+
/// ```
164+
pub fn remove(self) {
165+
let start = self.prop_offset;
166+
let end = Fdt::align_tag_offset(self.value_offset + self.len);
167+
let nop_bytes = FDT_NOP.to_be_bytes();
168+
169+
let mut offset = start;
170+
while offset < end {
171+
self.data.data[offset..offset + FDT_TAGSIZE].copy_from_slice(&nop_bytes);
172+
offset += FDT_TAGSIZE;
173+
}
174+
}
144175
}
145176

146177
impl Display for FdtPropertyMut<'_> {

tests/fdt_mut.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,37 @@ fn modify_property_shrink_and_grow() {
7979
let err = prop_mut.set_value(long_val).unwrap_err();
8080
assert_eq!(err, FdtMutError::ShiftingRequired);
8181
}
82+
83+
#[test]
84+
fn remove_property_via_handle() {
85+
let dtb = include_bytes!("dtb/test_props.dtb");
86+
let mut data = dtb.to_vec();
87+
88+
let mut fdt_mut = FdtMut::new(&mut data).unwrap();
89+
let mut node_mut = fdt_mut.find_node_mut("/test-props").unwrap();
90+
let prop_mut = node_mut.property_mut("str-prop").unwrap();
91+
prop_mut.remove();
92+
93+
let fdt = Fdt::new(&data).unwrap();
94+
let node = fdt.find_node("/test-props").unwrap();
95+
assert!(node.property("str-prop").is_none());
96+
// Verify other properties remain
97+
assert!(node.property("u32-prop").is_some());
98+
}
99+
100+
#[test]
101+
fn remove_property_via_node() {
102+
let dtb = include_bytes!("dtb/test_props.dtb");
103+
let mut data = dtb.to_vec();
104+
105+
let mut fdt_mut = FdtMut::new(&mut data).unwrap();
106+
let mut node_mut = fdt_mut.find_node_mut("/test-props").unwrap();
107+
108+
assert!(node_mut.remove_property("str-prop"));
109+
assert!(!node_mut.remove_property("str-prop")); // Idempotent check
110+
111+
let fdt = Fdt::new(&data).unwrap();
112+
let node = fdt.find_node("/test-props").unwrap();
113+
assert!(node.property("str-prop").is_none());
114+
assert!(node.property("u32-prop").is_some());
115+
}

0 commit comments

Comments
 (0)