fdt_edit/prop/mod.rs
1//! Device tree property representation and manipulation.
2//!
3//! This module provides the `Property` type which represents a mutable device tree
4//! property with a name and data, along with methods for accessing and modifying
5//! various property data formats.
6
7use core::ffi::CStr;
8
9use alloc::{
10 string::{String, ToString},
11 vec::Vec,
12};
13
14use fdt_raw::data::{Bytes, StrIter, U32Iter};
15// Re-export from fdt_raw
16use crate::Reader;
17
18/// A mutable device tree property.
19///
20/// Represents a property with a name and raw data. Provides methods for
21/// accessing and modifying the data in various formats (u32, u64, strings, etc.).
22#[derive(Clone)]
23pub struct Property {
24 /// Property name
25 pub name: String,
26 /// Raw property data
27 pub data: Vec<u8>,
28}
29
30impl Property {
31 /// Creates a new property with the given name and data.
32 pub fn new(name: &str, data: Vec<u8>) -> Self {
33 Self {
34 name: name.to_string(),
35 data,
36 }
37 }
38
39 /// Returns the property name.
40 pub fn name(&self) -> &str {
41 &self.name
42 }
43
44 /// Returns the property data as a big-endian u32.
45 ///
46 /// Returns None if the data is not exactly 4 bytes.
47 pub fn get_u32(&self) -> Option<u32> {
48 if self.data.len() != 4 {
49 return None;
50 }
51 Some(u32::from_be_bytes([
52 self.data[0],
53 self.data[1],
54 self.data[2],
55 self.data[3],
56 ]))
57 }
58
59 /// Sets the property data from a list of u32 values (as big-endian).
60 pub fn set_u32_ls(&mut self, values: &[u32]) {
61 self.data.clear();
62 for &value in values {
63 self.data.extend_from_slice(&value.to_be_bytes());
64 }
65 }
66
67 /// Returns an iterator over u32 values in the property data.
68 pub fn get_u32_iter(&self) -> U32Iter<'_> {
69 Bytes::new(&self.data).as_u32_iter()
70 }
71
72 /// Returns the property data as a big-endian u64.
73 ///
74 /// Returns None if the data is not exactly 8 bytes.
75 pub fn get_u64(&self) -> Option<u64> {
76 if self.data.len() != 8 {
77 return None;
78 }
79 Some(u64::from_be_bytes([
80 self.data[0],
81 self.data[1],
82 self.data[2],
83 self.data[3],
84 self.data[4],
85 self.data[5],
86 self.data[6],
87 self.data[7],
88 ]))
89 }
90
91 /// Sets the property data from a u64 value (as big-endian).
92 pub fn set_u64(&mut self, value: u64) {
93 self.data = value.to_be_bytes().to_vec();
94 }
95
96 /// Returns the property data as a null-terminated string.
97 ///
98 /// Returns None if the data is not a valid null-terminated UTF-8 string.
99 pub fn as_str(&self) -> Option<&str> {
100 CStr::from_bytes_with_nul(&self.data)
101 .ok()
102 .and_then(|cstr| cstr.to_str().ok())
103 }
104
105 /// Sets the property data from a string value.
106 ///
107 /// The string will be null-terminated.
108 pub fn set_string(&mut self, value: &str) {
109 let mut bytes = value.as_bytes().to_vec();
110 bytes.push(0); // Null-terminate
111 self.data = bytes;
112 }
113
114 /// Returns an iterator over null-terminated strings in the property data.
115 pub fn as_str_iter(&self) -> StrIter<'_> {
116 Bytes::new(&self.data).as_str_iter()
117 }
118
119 /// Sets the property data from a list of string values.
120 ///
121 /// Each string will be null-terminated.
122 pub fn set_string_ls(&mut self, values: &[&str]) {
123 self.data.clear();
124 for &value in values {
125 self.data.extend_from_slice(value.as_bytes());
126 self.data.push(0); // Null-terminate each string
127 }
128 }
129
130 /// Returns a reader for accessing the property data.
131 pub fn as_reader(&self) -> Reader<'_> {
132 Bytes::new(&self.data).reader()
133 }
134}
135
136impl From<&fdt_raw::Property<'_>> for Property {
137 fn from(value: &fdt_raw::Property<'_>) -> Self {
138 Self {
139 name: value.name().to_string(),
140 data: value.as_slice().to_vec(),
141 }
142 }
143}
144
145/// Ranges entry information for address translation.
146///
147/// Represents a single entry in a `ranges` property, mapping a child bus
148/// address range to a parent bus address range.
149#[derive(Debug, Clone, Copy, PartialEq, Eq)]
150pub struct RangesEntry {
151 /// Child bus address
152 pub child_bus_address: u64,
153 /// Parent bus address
154 pub parent_bus_address: u64,
155 /// Length of the region
156 pub length: u64,
157}