cloud-hypervisor/acpi_tables/src/aml.rs

89 lines
2.0 KiB
Rust
Raw Normal View History

// Copyright © 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
pub trait Aml {
fn to_bytes(&self) -> Vec<u8>;
}
pub struct Path {
root: bool,
name_parts: Vec<[u8; 4]>,
}
impl Aml for Path {
fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
if self.root {
bytes.push(b'\\');
}
match self.name_parts.len() {
0 => panic!("Name cannot be empty"),
1 => {}
2 => {
bytes.push(0x2e); /* DualNamePrefix */
}
n => {
bytes.push(0x2f); /* MultiNamePrefix */
bytes.push(n as u8);
}
};
for part in self.name_parts.clone().iter_mut() {
bytes.append(&mut part.to_vec());
}
bytes
}
}
impl Path {
pub fn new(name: &str) -> Self {
let root = name.starts_with('\\');
let offset = root as usize;
let mut name_parts = Vec::new();
for part in name[offset..].split('.') {
assert_eq!(part.len(), 4);
let mut name_part = [0u8; 4];
name_part.copy_from_slice(part.as_bytes());
name_parts.push(name_part);
}
Path { root, name_parts }
}
}
impl From<&str> for Path {
fn from(s: &str) -> Self {
Path::new(s)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_name_path() {
assert_eq!(
(&"_SB_".into() as &Path).to_bytes(),
[0x5Fu8, 0x53, 0x42, 0x5F]
);
assert_eq!(
(&"\\_SB_".into() as &Path).to_bytes(),
[0x5C, 0x5F, 0x53, 0x42, 0x5F]
);
assert_eq!(
(&"_SB_.COM1".into() as &Path).to_bytes(),
[0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31]
);
assert_eq!(
(&"_SB_.PCI0._HID".into() as &Path).to_bytes(),
[0x2F, 0x03, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x5F, 0x48, 0x49, 0x44]
);
}
}