1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2023 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker //! This module implements FDT property value conversions as defined by the device tree format.
6*bb4ee6a4SAndroid Build Coastguard Worker
7*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::size_of_val;
8*bb4ee6a4SAndroid Build Coastguard Worker
9*bb4ee6a4SAndroid Build Coastguard Worker use crate::fdt::c_str_to_string;
10*bb4ee6a4SAndroid Build Coastguard Worker use crate::fdt::Error;
11*bb4ee6a4SAndroid Build Coastguard Worker use crate::fdt::Result;
12*bb4ee6a4SAndroid Build Coastguard Worker use crate::fdt::SIZE_U32;
13*bb4ee6a4SAndroid Build Coastguard Worker use crate::fdt::SIZE_U64;
14*bb4ee6a4SAndroid Build Coastguard Worker
15*bb4ee6a4SAndroid Build Coastguard Worker /// Conversion into an FDT property value.
16*bb4ee6a4SAndroid Build Coastguard Worker ///
17*bb4ee6a4SAndroid Build Coastguard Worker /// Implementing `ToFdtPropval` for a type defines its conversion to a raw
18*bb4ee6a4SAndroid Build Coastguard Worker /// FDT property value (a byte vector).
19*bb4ee6a4SAndroid Build Coastguard Worker pub trait ToFdtPropval {
20*bb4ee6a4SAndroid Build Coastguard Worker // Convert the type to its byte representation as an FDT property.
to_propval(self) -> Result<Vec<u8>>21*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>>;
22*bb4ee6a4SAndroid Build Coastguard Worker }
23*bb4ee6a4SAndroid Build Coastguard Worker
24*bb4ee6a4SAndroid Build Coastguard Worker #[inline]
u32_to_bytes(value: &[u32]) -> Vec<u8>25*bb4ee6a4SAndroid Build Coastguard Worker fn u32_to_bytes(value: &[u32]) -> Vec<u8> {
26*bb4ee6a4SAndroid Build Coastguard Worker let mut bytes = Vec::with_capacity(size_of_val(value));
27*bb4ee6a4SAndroid Build Coastguard Worker for val in value {
28*bb4ee6a4SAndroid Build Coastguard Worker bytes.extend_from_slice(&val.to_be_bytes())
29*bb4ee6a4SAndroid Build Coastguard Worker }
30*bb4ee6a4SAndroid Build Coastguard Worker bytes
31*bb4ee6a4SAndroid Build Coastguard Worker }
32*bb4ee6a4SAndroid Build Coastguard Worker
33*bb4ee6a4SAndroid Build Coastguard Worker #[inline]
u64_to_bytes(value: &[u64]) -> Vec<u8>34*bb4ee6a4SAndroid Build Coastguard Worker fn u64_to_bytes(value: &[u64]) -> Vec<u8> {
35*bb4ee6a4SAndroid Build Coastguard Worker let mut bytes = Vec::with_capacity(size_of_val(value));
36*bb4ee6a4SAndroid Build Coastguard Worker for val in value {
37*bb4ee6a4SAndroid Build Coastguard Worker bytes.extend_from_slice(&val.to_be_bytes())
38*bb4ee6a4SAndroid Build Coastguard Worker }
39*bb4ee6a4SAndroid Build Coastguard Worker bytes
40*bb4ee6a4SAndroid Build Coastguard Worker }
41*bb4ee6a4SAndroid Build Coastguard Worker
42*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for () {
to_propval(self) -> Result<Vec<u8>>43*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
44*bb4ee6a4SAndroid Build Coastguard Worker Ok(vec![])
45*bb4ee6a4SAndroid Build Coastguard Worker }
46*bb4ee6a4SAndroid Build Coastguard Worker }
47*bb4ee6a4SAndroid Build Coastguard Worker
48*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for &[u8] {
to_propval(self) -> Result<Vec<u8>>49*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
50*bb4ee6a4SAndroid Build Coastguard Worker Ok(self.into())
51*bb4ee6a4SAndroid Build Coastguard Worker }
52*bb4ee6a4SAndroid Build Coastguard Worker }
53*bb4ee6a4SAndroid Build Coastguard Worker
54*bb4ee6a4SAndroid Build Coastguard Worker impl<const N: usize> ToFdtPropval for &[u8; N] {
to_propval(self) -> Result<Vec<u8>>55*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
56*bb4ee6a4SAndroid Build Coastguard Worker Ok(self.to_vec())
57*bb4ee6a4SAndroid Build Coastguard Worker }
58*bb4ee6a4SAndroid Build Coastguard Worker }
59*bb4ee6a4SAndroid Build Coastguard Worker
60*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for Vec<u8> {
to_propval(self) -> Result<Vec<u8>>61*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
62*bb4ee6a4SAndroid Build Coastguard Worker Ok(self)
63*bb4ee6a4SAndroid Build Coastguard Worker }
64*bb4ee6a4SAndroid Build Coastguard Worker }
65*bb4ee6a4SAndroid Build Coastguard Worker
66*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for u32 {
to_propval(self) -> Result<Vec<u8>>67*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
68*bb4ee6a4SAndroid Build Coastguard Worker Ok(u32_to_bytes(std::slice::from_ref(&self)))
69*bb4ee6a4SAndroid Build Coastguard Worker }
70*bb4ee6a4SAndroid Build Coastguard Worker }
71*bb4ee6a4SAndroid Build Coastguard Worker
72*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for &[u32] {
to_propval(self) -> Result<Vec<u8>>73*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
74*bb4ee6a4SAndroid Build Coastguard Worker Ok(u32_to_bytes(self))
75*bb4ee6a4SAndroid Build Coastguard Worker }
76*bb4ee6a4SAndroid Build Coastguard Worker }
77*bb4ee6a4SAndroid Build Coastguard Worker
78*bb4ee6a4SAndroid Build Coastguard Worker impl<const N: usize> ToFdtPropval for &[u32; N] {
to_propval(self) -> Result<Vec<u8>>79*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
80*bb4ee6a4SAndroid Build Coastguard Worker Ok(u32_to_bytes(self))
81*bb4ee6a4SAndroid Build Coastguard Worker }
82*bb4ee6a4SAndroid Build Coastguard Worker }
83*bb4ee6a4SAndroid Build Coastguard Worker
84*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for Vec<u32> {
to_propval(self) -> Result<Vec<u8>>85*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
86*bb4ee6a4SAndroid Build Coastguard Worker Ok(u32_to_bytes(self.as_slice()))
87*bb4ee6a4SAndroid Build Coastguard Worker }
88*bb4ee6a4SAndroid Build Coastguard Worker }
89*bb4ee6a4SAndroid Build Coastguard Worker
90*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for u64 {
to_propval(self) -> Result<Vec<u8>>91*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
92*bb4ee6a4SAndroid Build Coastguard Worker Ok(u64_to_bytes(std::slice::from_ref(&self)))
93*bb4ee6a4SAndroid Build Coastguard Worker }
94*bb4ee6a4SAndroid Build Coastguard Worker }
95*bb4ee6a4SAndroid Build Coastguard Worker
96*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for &[u64] {
to_propval(self) -> Result<Vec<u8>>97*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
98*bb4ee6a4SAndroid Build Coastguard Worker Ok(u64_to_bytes(self))
99*bb4ee6a4SAndroid Build Coastguard Worker }
100*bb4ee6a4SAndroid Build Coastguard Worker }
101*bb4ee6a4SAndroid Build Coastguard Worker
102*bb4ee6a4SAndroid Build Coastguard Worker impl<const N: usize> ToFdtPropval for &[u64; N] {
to_propval(self) -> Result<Vec<u8>>103*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
104*bb4ee6a4SAndroid Build Coastguard Worker Ok(u64_to_bytes(self))
105*bb4ee6a4SAndroid Build Coastguard Worker }
106*bb4ee6a4SAndroid Build Coastguard Worker }
107*bb4ee6a4SAndroid Build Coastguard Worker
108*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for Vec<u64> {
to_propval(self) -> Result<Vec<u8>>109*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
110*bb4ee6a4SAndroid Build Coastguard Worker Ok(u64_to_bytes(self.as_slice()))
111*bb4ee6a4SAndroid Build Coastguard Worker }
112*bb4ee6a4SAndroid Build Coastguard Worker }
113*bb4ee6a4SAndroid Build Coastguard Worker
114*bb4ee6a4SAndroid Build Coastguard Worker #[inline]
is_valid_string_property(val: &str) -> bool115*bb4ee6a4SAndroid Build Coastguard Worker fn is_valid_string_property(val: &str) -> bool {
116*bb4ee6a4SAndroid Build Coastguard Worker // Although the devicetree spec says string properties should be printable, neither libfdt nor
117*bb4ee6a4SAndroid Build Coastguard Worker // the kernel device tree API verify that, so only check for zero bytes.
118*bb4ee6a4SAndroid Build Coastguard Worker !val.contains('\0')
119*bb4ee6a4SAndroid Build Coastguard Worker }
120*bb4ee6a4SAndroid Build Coastguard Worker
121*bb4ee6a4SAndroid Build Coastguard Worker #[inline]
str_to_bytes<T: AsRef<str>>(value: &[T]) -> Result<Vec<u8>>122*bb4ee6a4SAndroid Build Coastguard Worker fn str_to_bytes<T: AsRef<str>>(value: &[T]) -> Result<Vec<u8>> {
123*bb4ee6a4SAndroid Build Coastguard Worker let total_length = value.iter().map(|s| s.as_ref().len() + 1).sum();
124*bb4ee6a4SAndroid Build Coastguard Worker let mut bytes = Vec::with_capacity(total_length);
125*bb4ee6a4SAndroid Build Coastguard Worker for s in value {
126*bb4ee6a4SAndroid Build Coastguard Worker let s = s.as_ref();
127*bb4ee6a4SAndroid Build Coastguard Worker if !is_valid_string_property(s) {
128*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::InvalidString(s.to_owned()));
129*bb4ee6a4SAndroid Build Coastguard Worker }
130*bb4ee6a4SAndroid Build Coastguard Worker bytes.extend_from_slice(s.as_bytes());
131*bb4ee6a4SAndroid Build Coastguard Worker bytes.push(0);
132*bb4ee6a4SAndroid Build Coastguard Worker }
133*bb4ee6a4SAndroid Build Coastguard Worker Ok(bytes)
134*bb4ee6a4SAndroid Build Coastguard Worker }
135*bb4ee6a4SAndroid Build Coastguard Worker
136*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for &str {
to_propval(self) -> Result<Vec<u8>>137*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
138*bb4ee6a4SAndroid Build Coastguard Worker str_to_bytes(std::slice::from_ref(&self))
139*bb4ee6a4SAndroid Build Coastguard Worker }
140*bb4ee6a4SAndroid Build Coastguard Worker }
141*bb4ee6a4SAndroid Build Coastguard Worker
142*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for &[&str] {
to_propval(self) -> Result<Vec<u8>>143*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
144*bb4ee6a4SAndroid Build Coastguard Worker str_to_bytes(self)
145*bb4ee6a4SAndroid Build Coastguard Worker }
146*bb4ee6a4SAndroid Build Coastguard Worker }
147*bb4ee6a4SAndroid Build Coastguard Worker
148*bb4ee6a4SAndroid Build Coastguard Worker impl<const N: usize> ToFdtPropval for &[&str; N] {
to_propval(self) -> Result<Vec<u8>>149*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
150*bb4ee6a4SAndroid Build Coastguard Worker str_to_bytes(self)
151*bb4ee6a4SAndroid Build Coastguard Worker }
152*bb4ee6a4SAndroid Build Coastguard Worker }
153*bb4ee6a4SAndroid Build Coastguard Worker
154*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for String {
to_propval(self) -> Result<Vec<u8>>155*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
156*bb4ee6a4SAndroid Build Coastguard Worker if !is_valid_string_property(&self) {
157*bb4ee6a4SAndroid Build Coastguard Worker Err(Error::InvalidString(self))
158*bb4ee6a4SAndroid Build Coastguard Worker } else {
159*bb4ee6a4SAndroid Build Coastguard Worker let mut bytes = self.into_bytes();
160*bb4ee6a4SAndroid Build Coastguard Worker bytes.push(0);
161*bb4ee6a4SAndroid Build Coastguard Worker Ok(bytes)
162*bb4ee6a4SAndroid Build Coastguard Worker }
163*bb4ee6a4SAndroid Build Coastguard Worker }
164*bb4ee6a4SAndroid Build Coastguard Worker }
165*bb4ee6a4SAndroid Build Coastguard Worker
166*bb4ee6a4SAndroid Build Coastguard Worker impl ToFdtPropval for Vec<String> {
to_propval(self) -> Result<Vec<u8>>167*bb4ee6a4SAndroid Build Coastguard Worker fn to_propval(self) -> Result<Vec<u8>> {
168*bb4ee6a4SAndroid Build Coastguard Worker str_to_bytes(&self)
169*bb4ee6a4SAndroid Build Coastguard Worker }
170*bb4ee6a4SAndroid Build Coastguard Worker }
171*bb4ee6a4SAndroid Build Coastguard Worker
172*bb4ee6a4SAndroid Build Coastguard Worker /// Conversion from an FDT property value.
173*bb4ee6a4SAndroid Build Coastguard Worker ///
174*bb4ee6a4SAndroid Build Coastguard Worker /// Implementing `FromFdtPropval` for a type defines its construction from a raw
175*bb4ee6a4SAndroid Build Coastguard Worker /// FDT property value (a byte slice).
176*bb4ee6a4SAndroid Build Coastguard Worker pub trait FromFdtPropval {
177*bb4ee6a4SAndroid Build Coastguard Worker // Try to convert FDT property bytes to `Self`, return `None` if impossible.
from_propval(propval: &[u8]) -> Option<Self> where Self: Sized178*bb4ee6a4SAndroid Build Coastguard Worker fn from_propval(propval: &[u8]) -> Option<Self>
179*bb4ee6a4SAndroid Build Coastguard Worker where
180*bb4ee6a4SAndroid Build Coastguard Worker Self: Sized;
181*bb4ee6a4SAndroid Build Coastguard Worker }
182*bb4ee6a4SAndroid Build Coastguard Worker
183*bb4ee6a4SAndroid Build Coastguard Worker impl FromFdtPropval for () {
from_propval(propval: &[u8]) -> Option<Self>184*bb4ee6a4SAndroid Build Coastguard Worker fn from_propval(propval: &[u8]) -> Option<Self> {
185*bb4ee6a4SAndroid Build Coastguard Worker propval.is_empty().then_some(())
186*bb4ee6a4SAndroid Build Coastguard Worker }
187*bb4ee6a4SAndroid Build Coastguard Worker }
188*bb4ee6a4SAndroid Build Coastguard Worker
189*bb4ee6a4SAndroid Build Coastguard Worker impl FromFdtPropval for Vec<u8> {
from_propval(propval: &[u8]) -> Option<Self>190*bb4ee6a4SAndroid Build Coastguard Worker fn from_propval(propval: &[u8]) -> Option<Self> {
191*bb4ee6a4SAndroid Build Coastguard Worker Some(propval.into())
192*bb4ee6a4SAndroid Build Coastguard Worker }
193*bb4ee6a4SAndroid Build Coastguard Worker }
194*bb4ee6a4SAndroid Build Coastguard Worker
195*bb4ee6a4SAndroid Build Coastguard Worker impl FromFdtPropval for u32 {
from_propval(propval: &[u8]) -> Option<Self>196*bb4ee6a4SAndroid Build Coastguard Worker fn from_propval(propval: &[u8]) -> Option<Self> {
197*bb4ee6a4SAndroid Build Coastguard Worker if propval.len() == SIZE_U32 {
198*bb4ee6a4SAndroid Build Coastguard Worker Some(u32::from_be_bytes(propval.try_into().unwrap()))
199*bb4ee6a4SAndroid Build Coastguard Worker } else {
200*bb4ee6a4SAndroid Build Coastguard Worker None
201*bb4ee6a4SAndroid Build Coastguard Worker }
202*bb4ee6a4SAndroid Build Coastguard Worker }
203*bb4ee6a4SAndroid Build Coastguard Worker }
204*bb4ee6a4SAndroid Build Coastguard Worker
205*bb4ee6a4SAndroid Build Coastguard Worker impl FromFdtPropval for Vec<u32> {
from_propval(propval: &[u8]) -> Option<Self>206*bb4ee6a4SAndroid Build Coastguard Worker fn from_propval(propval: &[u8]) -> Option<Self> {
207*bb4ee6a4SAndroid Build Coastguard Worker if propval.len() % SIZE_U32 != 0 {
208*bb4ee6a4SAndroid Build Coastguard Worker None
209*bb4ee6a4SAndroid Build Coastguard Worker } else {
210*bb4ee6a4SAndroid Build Coastguard Worker Some(
211*bb4ee6a4SAndroid Build Coastguard Worker propval
212*bb4ee6a4SAndroid Build Coastguard Worker .chunks(SIZE_U32)
213*bb4ee6a4SAndroid Build Coastguard Worker .map(|v| u32::from_be_bytes(v.try_into().unwrap()))
214*bb4ee6a4SAndroid Build Coastguard Worker .collect(),
215*bb4ee6a4SAndroid Build Coastguard Worker )
216*bb4ee6a4SAndroid Build Coastguard Worker }
217*bb4ee6a4SAndroid Build Coastguard Worker }
218*bb4ee6a4SAndroid Build Coastguard Worker }
219*bb4ee6a4SAndroid Build Coastguard Worker
220*bb4ee6a4SAndroid Build Coastguard Worker impl FromFdtPropval for u64 {
from_propval(propval: &[u8]) -> Option<Self>221*bb4ee6a4SAndroid Build Coastguard Worker fn from_propval(propval: &[u8]) -> Option<Self> {
222*bb4ee6a4SAndroid Build Coastguard Worker if propval.len() == SIZE_U64 {
223*bb4ee6a4SAndroid Build Coastguard Worker Some(u64::from_be_bytes(propval.try_into().unwrap()))
224*bb4ee6a4SAndroid Build Coastguard Worker } else {
225*bb4ee6a4SAndroid Build Coastguard Worker None
226*bb4ee6a4SAndroid Build Coastguard Worker }
227*bb4ee6a4SAndroid Build Coastguard Worker }
228*bb4ee6a4SAndroid Build Coastguard Worker }
229*bb4ee6a4SAndroid Build Coastguard Worker
230*bb4ee6a4SAndroid Build Coastguard Worker impl FromFdtPropval for Vec<u64> {
from_propval(propval: &[u8]) -> Option<Self>231*bb4ee6a4SAndroid Build Coastguard Worker fn from_propval(propval: &[u8]) -> Option<Self> {
232*bb4ee6a4SAndroid Build Coastguard Worker if propval.len() % SIZE_U64 != 0 {
233*bb4ee6a4SAndroid Build Coastguard Worker None
234*bb4ee6a4SAndroid Build Coastguard Worker } else {
235*bb4ee6a4SAndroid Build Coastguard Worker Some(
236*bb4ee6a4SAndroid Build Coastguard Worker propval
237*bb4ee6a4SAndroid Build Coastguard Worker .chunks(SIZE_U64)
238*bb4ee6a4SAndroid Build Coastguard Worker .map(|v| u64::from_be_bytes(v.try_into().unwrap()))
239*bb4ee6a4SAndroid Build Coastguard Worker .collect(),
240*bb4ee6a4SAndroid Build Coastguard Worker )
241*bb4ee6a4SAndroid Build Coastguard Worker }
242*bb4ee6a4SAndroid Build Coastguard Worker }
243*bb4ee6a4SAndroid Build Coastguard Worker }
244*bb4ee6a4SAndroid Build Coastguard Worker
245*bb4ee6a4SAndroid Build Coastguard Worker impl FromFdtPropval for String {
from_propval(propval: &[u8]) -> Option<Self>246*bb4ee6a4SAndroid Build Coastguard Worker fn from_propval(propval: &[u8]) -> Option<Self> {
247*bb4ee6a4SAndroid Build Coastguard Worker c_str_to_string(propval)
248*bb4ee6a4SAndroid Build Coastguard Worker }
249*bb4ee6a4SAndroid Build Coastguard Worker }
250*bb4ee6a4SAndroid Build Coastguard Worker
251*bb4ee6a4SAndroid Build Coastguard Worker impl FromFdtPropval for Vec<String> {
from_propval(propval: &[u8]) -> Option<Self>252*bb4ee6a4SAndroid Build Coastguard Worker fn from_propval(propval: &[u8]) -> Option<Self> {
253*bb4ee6a4SAndroid Build Coastguard Worker if Some(&0) == propval.last() {
254*bb4ee6a4SAndroid Build Coastguard Worker Some(
255*bb4ee6a4SAndroid Build Coastguard Worker propval
256*bb4ee6a4SAndroid Build Coastguard Worker .split(|&b| b == 0u8)
257*bb4ee6a4SAndroid Build Coastguard Worker .take_while(|s| !s.is_empty())
258*bb4ee6a4SAndroid Build Coastguard Worker .filter_map(|b| String::from_utf8(b.into()).ok())
259*bb4ee6a4SAndroid Build Coastguard Worker .collect(),
260*bb4ee6a4SAndroid Build Coastguard Worker )
261*bb4ee6a4SAndroid Build Coastguard Worker } else {
262*bb4ee6a4SAndroid Build Coastguard Worker None
263*bb4ee6a4SAndroid Build Coastguard Worker }
264*bb4ee6a4SAndroid Build Coastguard Worker }
265*bb4ee6a4SAndroid Build Coastguard Worker }
266*bb4ee6a4SAndroid Build Coastguard Worker
267*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
268*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
269*bb4ee6a4SAndroid Build Coastguard Worker use super::*;
270*bb4ee6a4SAndroid Build Coastguard Worker
271*bb4ee6a4SAndroid Build Coastguard Worker #[test]
fdt_as_propval()272*bb4ee6a4SAndroid Build Coastguard Worker fn fdt_as_propval() {
273*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(().to_propval().unwrap(), []);
274*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!([0u8, 1u8, 2u8].to_propval().unwrap(), [0u8, 1u8, 2u8]);
275*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(0x1u32.to_propval().unwrap(), [0u8, 0, 0, 1]);
276*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
277*bb4ee6a4SAndroid Build Coastguard Worker 0x12345678u32.to_propval().unwrap(),
278*bb4ee6a4SAndroid Build Coastguard Worker [0x12u8, 0x34, 0x56, 0x78]
279*bb4ee6a4SAndroid Build Coastguard Worker );
280*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
281*bb4ee6a4SAndroid Build Coastguard Worker 0x12345678ABCDu64.to_propval().unwrap(),
282*bb4ee6a4SAndroid Build Coastguard Worker [0x00u8, 0x00, 0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD]
283*bb4ee6a4SAndroid Build Coastguard Worker );
284*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
285*bb4ee6a4SAndroid Build Coastguard Worker [0x1u32, 0xABCDu32].to_propval().unwrap(),
286*bb4ee6a4SAndroid Build Coastguard Worker [0x00u8, 0x00, 0x00, 0x01, 0x00, 0x00, 0xAB, 0xCD]
287*bb4ee6a4SAndroid Build Coastguard Worker );
288*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
289*bb4ee6a4SAndroid Build Coastguard Worker [0x1u64, 0xABCD00000000u64].to_propval().unwrap(),
290*bb4ee6a4SAndroid Build Coastguard Worker [
291*bb4ee6a4SAndroid Build Coastguard Worker 0x00u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xAB, 0xCD, 0x00,
292*bb4ee6a4SAndroid Build Coastguard Worker 0x00, 0x00, 0x00,
293*bb4ee6a4SAndroid Build Coastguard Worker ]
294*bb4ee6a4SAndroid Build Coastguard Worker );
295*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
296*bb4ee6a4SAndroid Build Coastguard Worker "abc def".to_propval().unwrap(),
297*bb4ee6a4SAndroid Build Coastguard Worker [0x61u8, 0x62, 0x63, 0x20, 0x64, 0x65, 0x66, 0x00,]
298*bb4ee6a4SAndroid Build Coastguard Worker );
299*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
300*bb4ee6a4SAndroid Build Coastguard Worker ["abc def", "ghi jkl", "mno pqr"].to_propval().unwrap(),
301*bb4ee6a4SAndroid Build Coastguard Worker [
302*bb4ee6a4SAndroid Build Coastguard Worker 0x61u8, 0x62, 0x63, 0x20, 0x64, 0x65, 0x66, 0x00, 0x67u8, 0x68, 0x69, 0x20, 0x6A,
303*bb4ee6a4SAndroid Build Coastguard Worker 0x6B, 0x6C, 0x00, 0x6Du8, 0x6E, 0x6F, 0x20, 0x70, 0x71, 0x72, 0x00,
304*bb4ee6a4SAndroid Build Coastguard Worker ]
305*bb4ee6a4SAndroid Build Coastguard Worker );
306*bb4ee6a4SAndroid Build Coastguard Worker "abc\0def".to_propval().expect_err("invalid string");
307*bb4ee6a4SAndroid Build Coastguard Worker }
308*bb4ee6a4SAndroid Build Coastguard Worker
309*bb4ee6a4SAndroid Build Coastguard Worker #[test]
fdt_from_propval()310*bb4ee6a4SAndroid Build Coastguard Worker fn fdt_from_propval() {
311*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(Vec::<u8>::from_propval(&[]).unwrap(), []);
312*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(u32::from_propval(&[0, 0, 0, 1]).unwrap(), 1u32);
313*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
314*bb4ee6a4SAndroid Build Coastguard Worker u32::from_propval(&[0x12u8, 0x34, 0x56, 0x78]).unwrap(),
315*bb4ee6a4SAndroid Build Coastguard Worker 0x12345678u32
316*bb4ee6a4SAndroid Build Coastguard Worker );
317*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
318*bb4ee6a4SAndroid Build Coastguard Worker u64::from_propval(&[0x00u8, 0x00, 0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD]).unwrap(),
319*bb4ee6a4SAndroid Build Coastguard Worker 0x12345678ABCDu64
320*bb4ee6a4SAndroid Build Coastguard Worker );
321*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
322*bb4ee6a4SAndroid Build Coastguard Worker Vec::<u32>::from_propval(&[0x00u8, 0x00, 0x00, 0x01, 0x00, 0x00, 0xAB, 0xCD]).unwrap(),
323*bb4ee6a4SAndroid Build Coastguard Worker [0x1u32, 0xABCDu32]
324*bb4ee6a4SAndroid Build Coastguard Worker );
325*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
326*bb4ee6a4SAndroid Build Coastguard Worker Vec::<u64>::from_propval(&[
327*bb4ee6a4SAndroid Build Coastguard Worker 0x00u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xAB, 0xCD, 0x00,
328*bb4ee6a4SAndroid Build Coastguard Worker 0x00, 0x00, 0x00
329*bb4ee6a4SAndroid Build Coastguard Worker ])
330*bb4ee6a4SAndroid Build Coastguard Worker .unwrap(),
331*bb4ee6a4SAndroid Build Coastguard Worker [0x1u64, 0xABCD00000000u64]
332*bb4ee6a4SAndroid Build Coastguard Worker );
333*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
334*bb4ee6a4SAndroid Build Coastguard Worker String::from_propval(&[0x61u8, 0x62, 0x63, 0x20, 0x64, 0x65, 0x66, 0x00]).unwrap(),
335*bb4ee6a4SAndroid Build Coastguard Worker "abc def"
336*bb4ee6a4SAndroid Build Coastguard Worker );
337*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
338*bb4ee6a4SAndroid Build Coastguard Worker Vec::<String>::from_propval(&[
339*bb4ee6a4SAndroid Build Coastguard Worker 0x61u8, 0x62, 0x63, 0x20, 0x64, 0x65, 0x66, 0x00, 0x67u8, 0x68, 0x69, 0x20, 0x6A,
340*bb4ee6a4SAndroid Build Coastguard Worker 0x6B, 0x6C, 0x00, 0x6Du8, 0x6E, 0x6F, 0x20, 0x70, 0x71, 0x72, 0x00,
341*bb4ee6a4SAndroid Build Coastguard Worker ])
342*bb4ee6a4SAndroid Build Coastguard Worker .unwrap(),
343*bb4ee6a4SAndroid Build Coastguard Worker ["abc def", "ghi jkl", "mno pqr"],
344*bb4ee6a4SAndroid Build Coastguard Worker );
345*bb4ee6a4SAndroid Build Coastguard Worker
346*bb4ee6a4SAndroid Build Coastguard Worker assert!(Vec::<String>::from_propval(&[
347*bb4ee6a4SAndroid Build Coastguard Worker 0x61u8, 0x62, 0x63, 0x20, 0x64, 0x65, 0x66, 0x00, 0x67u8, 0x68,
348*bb4ee6a4SAndroid Build Coastguard Worker ])
349*bb4ee6a4SAndroid Build Coastguard Worker .is_none());
350*bb4ee6a4SAndroid Build Coastguard Worker assert!(String::from_propval(&[0x61u8, 0x62, 0x63]).is_none());
351*bb4ee6a4SAndroid Build Coastguard Worker assert!(u32::from_propval(&[0x61u8, 0x62]).is_none());
352*bb4ee6a4SAndroid Build Coastguard Worker assert!(u64::from_propval(&[0x61u8, 0x62, 0x61u8, 0x62, 0x61u8, 0x62]).is_none());
353*bb4ee6a4SAndroid Build Coastguard Worker }
354*bb4ee6a4SAndroid Build Coastguard Worker }
355