Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/fdt_mut/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,37 @@ impl FdtNodeMut<'_> {
None
}

/// Removes a property from this node by its name.
///
/// This is a convenience method that finds a property by name and calls
/// [`FdtPropertyMut::remove`] on it.
///
/// Returns `true` if the property was present and successfully removed,
/// `false` otherwise.
///
/// # Examples
///
/// ```
/// use dtoolkit::fdt_mut::FdtMut;
/// use dtoolkit::{Node, Property};
///
/// # let mut dtb = include_bytes!("../../tests/dtb/test_traversal.dtb").to_vec();
/// let mut fdt = FdtMut::new(&mut dtb).unwrap();
/// let mut node = fdt.find_node_mut("/a/b/c").unwrap();
/// assert!(node.property("prop").is_some());
/// assert!(node.remove_property("prop"));
/// assert!(node.property("prop").is_none());
/// assert!(!node.remove_property("prop"));
/// ```
pub fn remove_property(&mut self, name: &str) -> bool {
if let Some(prop) = self.property_mut(name) {
prop.remove();
true
} else {
false
}
}

/// Returns a mutable iterator over the properties of this node.
pub fn properties_mut(&mut self) -> FdtPropMutIter<'_> {
FdtPropMutIter {
Expand Down
31 changes: 31 additions & 0 deletions src/fdt_mut/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,37 @@ impl FdtPropertyMut<'_> {
.expect("Fdt should be valid");
FdtProperty { name, value }
}

/// Removes the property by overwriting its structure with `NOP` tags.
///
/// The memory previously occupied by this property will be replaced with
/// `NOP` tags, rendering it invisible to Device Tree iterators
/// without requiring data to be shifted.
///
/// # Examples
///
/// ```
/// use dtoolkit::fdt_mut::FdtMut;
/// use dtoolkit::{Node, Property};
///
/// # let mut dtb = include_bytes!("../../tests/dtb/test_traversal.dtb").to_vec();
/// let mut fdt = FdtMut::new(&mut dtb).unwrap();
/// let mut node = fdt.find_node_mut("/a/b/c").unwrap();
/// let prop = node.property_mut("prop").unwrap();
/// prop.remove();
/// assert!(node.property("prop").is_none());
/// ```
pub fn remove(self) {
let start = self.prop_offset;
let end = Fdt::align_tag_offset(self.value_offset + self.len);
let nop_bytes = FDT_NOP.to_be_bytes();

let mut offset = start;
while offset < end {
self.data.data[offset..offset + FDT_TAGSIZE].copy_from_slice(&nop_bytes);
offset += FDT_TAGSIZE;
}
}
}

impl Display for FdtPropertyMut<'_> {
Expand Down
34 changes: 34 additions & 0 deletions tests/fdt_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,37 @@ fn modify_property_shrink_and_grow() {
let err = prop_mut.set_value(long_val).unwrap_err();
assert_eq!(err, FdtMutError::ShiftingRequired);
}

#[test]
fn remove_property_via_handle() {
let dtb = include_bytes!("dtb/test_props.dtb");
let mut data = dtb.to_vec();

let mut fdt_mut = FdtMut::new(&mut data).unwrap();
let mut node_mut = fdt_mut.find_node_mut("/test-props").unwrap();
let prop_mut = node_mut.property_mut("str-prop").unwrap();
prop_mut.remove();

let fdt = Fdt::new(&data).unwrap();
let node = fdt.find_node("/test-props").unwrap();
assert!(node.property("str-prop").is_none());
// Verify other properties remain
assert!(node.property("u32-prop").is_some());
}

#[test]
fn remove_property_via_node() {
let dtb = include_bytes!("dtb/test_props.dtb");
let mut data = dtb.to_vec();

let mut fdt_mut = FdtMut::new(&mut data).unwrap();
let mut node_mut = fdt_mut.find_node_mut("/test-props").unwrap();

assert!(node_mut.remove_property("str-prop"));
assert!(!node_mut.remove_property("str-prop")); // Idempotent check

let fdt = Fdt::new(&data).unwrap();
let node = fdt.find_node("/test-props").unwrap();
assert!(node.property("str-prop").is_none());
assert!(node.property("u32-prop").is_some());
}
Loading