fdt_parser/
property.rs

1use core::{ffi::CStr, iter};
2
3use crate::{
4    base::Fdt,
5    data::{Buffer, Raw},
6    FdtError, Token,
7};
8
9#[derive(Clone)]
10pub struct Property<'a> {
11    pub name: &'a str,
12    pub(crate) data: Raw<'a>,
13}
14
15impl<'a> Property<'a> {
16    pub fn raw_value(&self) -> &'a [u8] {
17        self.data.value()
18    }
19
20    pub fn u32(&self) -> Result<u32, FdtError> {
21        self.data.buffer().take_u32()
22    }
23
24    pub fn u64(&self) -> Result<u64, FdtError> {
25        self.data.buffer().take_u64()
26    }
27
28    pub fn str(&self) -> Result<&'a str, FdtError> {
29        let res = CStr::from_bytes_until_nul(self.data.value())?.to_str()?;
30        Ok(res)
31    }
32
33    pub fn str_list(&self) -> impl Iterator<Item = &'a str> + 'a {
34        let mut value = self.data.buffer();
35        iter::from_fn(move || value.take_str().ok())
36    }
37
38    pub fn u32_list(&self) -> impl Iterator<Item = u32> + 'a {
39        let mut value = self.data.buffer();
40        iter::from_fn(move || value.take_u32().ok())
41    }
42
43    pub fn u64_list(&self) -> impl Iterator<Item = u64> + 'a {
44        let mut value = self.data.buffer();
45        iter::from_fn(move || value.take_u64().ok())
46    }
47}
48
49impl core::fmt::Debug for Property<'_> {
50    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51        write!(f, "{} = [", self.name)?;
52        for v in self.u32_list() {
53            write!(f, "{:#x}, ", v)?;
54        }
55        write!(f, "]")?;
56        Ok(())
57    }
58}
59
60pub(crate) struct PropIter<'a> {
61    fdt: Fdt<'a>,
62    reader: Buffer<'a>,
63    has_err: bool,
64}
65
66impl<'a> PropIter<'a> {
67    pub fn new(fdt: Fdt<'a>, reader: Buffer<'a>) -> Self {
68        Self {
69            fdt,
70            reader,
71            has_err: false,
72        }
73    }
74
75    fn try_next(&mut self) -> Result<Option<Property<'a>>, FdtError> {
76        loop {
77            match self.reader.take_token()? {
78                Token::Prop => break,
79                Token::Nop => {}
80                _ => return Ok(None),
81            }
82        }
83        let prop = self.reader.take_prop(&self.fdt)?;
84        Ok(Some(prop))
85    }
86}
87
88impl<'a> Iterator for PropIter<'a> {
89    type Item = Result<Property<'a>, FdtError>;
90
91    fn next(&mut self) -> Option<Self::Item> {
92        if self.has_err {
93            return None;
94        }
95        match self.try_next() {
96            Ok(Some(prop)) => Some(Ok(prop)),
97            Ok(None) => None,
98            Err(e) => {
99                self.has_err = true;
100                Some(Err(e))
101            }
102        }
103    }
104}