1use crate::{name_object::NameSeg, value::AmlValue, AmlError};
2use alloc::{
3 collections::BTreeMap,
4 string::{String, ToString},
5 vec::Vec,
6};
7use core::fmt;
8
9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
18pub struct AmlHandle(u32);
19
20impl AmlHandle {
21 pub(self) fn increment(&mut self) {
22 self.0 += 1;
23 }
24}
25
26#[derive(Clone, Copy, PartialEq, Eq, Debug)]
27pub enum LevelType {
28 Scope,
29 Device,
30 Processor,
33 PowerResource,
35 ThermalZone,
37 MethodLocals,
40}
41
42#[derive(Clone, Debug)]
43pub struct NamespaceLevel {
44 pub typ: LevelType,
45 pub children: BTreeMap<NameSeg, NamespaceLevel>,
46 pub values: BTreeMap<NameSeg, AmlHandle>,
47}
48
49impl NamespaceLevel {
50 pub(crate) fn new(typ: LevelType) -> NamespaceLevel {
51 NamespaceLevel {
52 typ,
53 children: BTreeMap::new(),
54 values: BTreeMap::new(),
55 }
56 }
57}
58
59#[derive(Clone)]
60pub struct Namespace {
61 next_handle: AmlHandle,
65
66 object_map: BTreeMap<AmlHandle, AmlValue>,
70
71 root: NamespaceLevel,
75}
76
77impl Namespace {
78 pub fn new() -> Namespace {
79 Namespace {
80 next_handle: AmlHandle(0),
81 object_map: BTreeMap::new(),
82 root: NamespaceLevel::new(LevelType::Scope),
83 }
84 }
85
86 pub fn add_level(&mut self, path: AmlName, typ: LevelType) -> Result<(), AmlError> {
95 let path = path.normalize().unwrap_or(AmlName::root());
96
97 if path != AmlName::root() {
103 let (level, last_seg) = self.get_level_for_path_mut(&path)?;
104
105 if !level.children.contains_key(&last_seg) {
110 level.children.insert(last_seg, NamespaceLevel::new(typ));
111 }
112 }
113
114 Ok(())
115 }
116
117 pub fn remove_level(&mut self, path: AmlName) -> Result<(), AmlError> {
118 let path = path.normalize().unwrap_or(AmlName::root());
119
120 if path != AmlName::root() {
121 let (level, last_seg) = self.get_level_for_path_mut(&path)?;
122
123 match level.children.remove(&last_seg) {
124 Some(_) => Ok(()),
125 None => Err(AmlError::LevelDoesNotExist(path)),
126 }
127 } else {
128 Err(AmlError::TriedToRemoveRootNamespace)
129 }
130 }
131
132 pub fn add_value(&mut self, path: AmlName, value: AmlValue) -> Result<AmlHandle, AmlError> {
136 let path = path.normalize().unwrap_or(AmlName::root());
137
138 let handle = self.next_handle;
139 self.next_handle.increment();
140 self.object_map.insert(handle, value);
141
142 let (level, last_seg) = self.get_level_for_path_mut(&path)?;
143 match level.values.insert(last_seg, handle) {
144 None => Ok(handle),
145 Some(_) => Err(AmlError::NameCollision(path)),
146 }
147 }
148
149 pub fn add_value_at_resolved_path(
153 &mut self,
154 path: AmlName,
155 scope: &AmlName,
156 value: AmlValue,
157 ) -> Result<AmlHandle, AmlError> {
158 self.add_value(path.resolve(scope)?, value)
159 }
160
161 pub fn add_alias_at_resolved_path(
164 &mut self,
165 path: AmlName,
166 scope: &AmlName,
167 target: AmlName,
168 ) -> Result<AmlHandle, AmlError> {
169 let path = path.resolve(scope)?;
170 let target = target.resolve(scope)?;
171
172 let handle = self.get_handle(&target)?;
173
174 let (level, last_seg) = self.get_level_for_path_mut(&path)?;
175 match level.values.insert(last_seg, handle) {
176 None => Ok(handle),
177 Some(_) => Err(AmlError::NameCollision(path)),
178 }
179 }
180
181 pub fn get(&self, handle: AmlHandle) -> Result<&AmlValue, AmlError> {
182 Ok(self.object_map.get(&handle).unwrap())
183 }
184
185 pub fn get_mut(&mut self, handle: AmlHandle) -> Result<&mut AmlValue, AmlError> {
186 Ok(self.object_map.get_mut(&handle).unwrap())
187 }
188
189 pub fn get_handle(&self, path: &AmlName) -> Result<AmlHandle, AmlError> {
190 let (level, last_seg) = self.get_level_for_path(path)?;
191 Ok(*level
192 .values
193 .get(&last_seg)
194 .ok_or(AmlError::ValueDoesNotExist(path.clone()))?)
195 }
196
197 pub fn get_by_path(&self, path: &AmlName) -> Result<&AmlValue, AmlError> {
198 let handle = self.get_handle(path)?;
199 Ok(self.get(handle).unwrap())
200 }
201
202 pub fn get_by_path_mut(&mut self, path: &AmlName) -> Result<&mut AmlValue, AmlError> {
203 let handle = self.get_handle(path)?;
204 Ok(self.get_mut(handle).unwrap())
205 }
206
207 pub fn search(
211 &self,
212 path: &AmlName,
213 starting_scope: &AmlName,
214 ) -> Result<(AmlName, AmlHandle), AmlError> {
215 if path.search_rules_apply() {
216 let scope = starting_scope.clone();
222 let mut scope = scope.normalize().unwrap_or(AmlName::root());
223 loop {
224 let name = path.resolve(&scope)?;
226 match self.get_level_for_path(&name) {
227 Ok((level, last_seg)) => {
228 if let Some(&handle) = level.values.get(&last_seg) {
229 return Ok((name, handle));
230 }
231 }
232
233 Err(AmlError::LevelDoesNotExist(_)) => (),
244 Err(err) => return Err(err),
245 }
246
247 match scope.parent() {
249 Ok(parent) => scope = parent,
250 Err(AmlError::RootHasNoParent) => {
252 return Err(AmlError::ValueDoesNotExist(path.clone()))
253 }
254 Err(err) => return Err(err),
255 }
256 }
257 } else {
258 let name = path.resolve(starting_scope)?;
260 let (level, last_seg) = self.get_level_for_path(&path.resolve(starting_scope)?)?;
264
265 if let Some(&handle) = level.values.get(&last_seg) {
266 Ok((name, handle))
267 } else {
268 Err(AmlError::ValueDoesNotExist(path.clone()))
269 }
270 }
271 }
272
273 pub fn search_for_level(
274 &self,
275 level_name: &AmlName,
276 starting_scope: &AmlName,
277 ) -> Result<AmlName, AmlError> {
278 if level_name.search_rules_apply() {
279 let scope = starting_scope.clone().normalize()?;
280 let mut scope = scope.normalize().unwrap_or(AmlName::root());
281
282 loop {
283 let name = level_name.resolve(&scope)?;
284 if let Ok((level, last_seg)) = self.get_level_for_path(&name) {
285 if let Some(_) = level.children.get(&last_seg) {
286 return Ok(name);
287 }
288 }
289
290 match scope.parent() {
292 Ok(parent) => scope = parent,
293 Err(AmlError::RootHasNoParent) => {
294 return Err(AmlError::LevelDoesNotExist(level_name.clone()))
295 }
296 Err(err) => return Err(err),
297 }
298 }
299 } else {
300 Ok(level_name.clone())
301 }
302 }
303
304 fn get_level_for_path(&self, path: &AmlName) -> Result<(&NamespaceLevel, NameSeg), AmlError> {
305 assert_ne!(*path, AmlName::root());
306
307 let (last_seg, levels) = path.0[1..].split_last().unwrap();
308 let last_seg = last_seg.as_segment().unwrap();
309
310 let mut traversed_path = AmlName::root();
312
313 let mut current_level = &self.root;
314 for level in levels {
315 traversed_path.0.push(*level);
316 current_level = current_level
317 .children
318 .get(&level.as_segment().unwrap())
319 .ok_or(AmlError::LevelDoesNotExist(traversed_path.clone()))?;
320 }
321
322 Ok((current_level, last_seg))
323 }
324
325 fn get_level_for_path_mut(
328 &mut self,
329 path: &AmlName,
330 ) -> Result<(&mut NamespaceLevel, NameSeg), AmlError> {
331 assert_ne!(*path, AmlName::root());
332
333 let (last_seg, levels) = path.0[1..].split_last().unwrap();
334 let last_seg = last_seg.as_segment().unwrap();
335
336 let mut traversed_path = AmlName::root();
340
341 let mut current_level = &mut self.root;
342 for level in levels {
343 traversed_path.0.push(*level);
344 current_level = current_level
345 .children
346 .get_mut(&level.as_segment().unwrap())
347 .ok_or(AmlError::LevelDoesNotExist(traversed_path.clone()))?;
348 }
349
350 Ok((current_level, last_seg))
351 }
352
353 pub fn traverse<F>(&mut self, mut f: F) -> Result<(), AmlError>
357 where
358 F: FnMut(&AmlName, &NamespaceLevel) -> Result<bool, AmlError>,
359 {
360 fn traverse_level<F>(
361 level: &NamespaceLevel,
362 scope: &AmlName,
363 f: &mut F,
364 ) -> Result<(), AmlError>
365 where
366 F: FnMut(&AmlName, &NamespaceLevel) -> Result<bool, AmlError>,
367 {
368 for (name, ref child) in level.children.iter() {
369 let name = AmlName::from_name_seg(*name).resolve(scope)?;
370
371 if f(&name, child)? {
372 traverse_level(child, &name, f)?;
373 }
374 }
375
376 Ok(())
377 }
378
379 if f(&AmlName::root(), &self.root)? {
380 traverse_level(&self.root, &AmlName::root(), &mut f)?;
381 }
382
383 Ok(())
384 }
385}
386
387impl fmt::Debug for Namespace {
388 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
389 const INDENT_PER_LEVEL: usize = 4;
390
391 fn print_level(
392 namespace: &Namespace,
393 f: &mut fmt::Formatter<'_>,
394 level_name: &str,
395 level: &NamespaceLevel,
396 indent: usize,
397 ) -> fmt::Result {
398 writeln!(f, "{:indent$}{}:", "", level_name, indent = indent)?;
399
400 for (name, handle) in level.values.iter() {
401 writeln!(
402 f,
403 "{:indent$}{}: {:?}",
404 "",
405 name.as_str(),
406 namespace.object_map.get(handle).unwrap(),
407 indent = indent + INDENT_PER_LEVEL
408 )?;
409 }
410
411 for (name, sub_level) in level.children.iter() {
412 print_level(
413 namespace,
414 f,
415 name.as_str(),
416 sub_level,
417 indent + INDENT_PER_LEVEL,
418 )?;
419 }
420
421 Ok(())
422 }
423
424 print_level(self, f, "\\", &self.root, 0)
425 }
426}
427
428#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
429pub struct AmlName(Vec<NameComponent>);
430
431impl AmlName {
432 pub fn root() -> AmlName {
433 AmlName(alloc::vec![NameComponent::Root])
434 }
435
436 pub fn from_name_seg(seg: NameSeg) -> AmlName {
437 AmlName(alloc::vec![NameComponent::Segment(seg)])
438 }
439
440 pub fn from_components(components: Vec<NameComponent>) -> AmlName {
441 assert!(components.len() > 0);
442 AmlName(components)
443 }
444
445 pub fn from_str(mut string: &str) -> Result<AmlName, AmlError> {
447 if string.len() == 0 {
448 return Err(AmlError::EmptyNamesAreInvalid);
449 }
450
451 let mut components = Vec::new();
452
453 if string.starts_with('\\') {
455 components.push(NameComponent::Root);
456 string = &string[1..];
457 }
458
459 if string.len() > 0 {
460 for mut part in string.split('.') {
462 while part.starts_with('^') {
464 components.push(NameComponent::Prefix);
465 part = &part[1..];
466 }
467
468 components.push(NameComponent::Segment(NameSeg::from_str(part)?));
469 }
470 }
471
472 Ok(AmlName(components))
473 }
474
475 pub fn as_string(&self) -> String {
476 self.0
477 .iter()
478 .fold(String::new(), |name, component| match component {
479 NameComponent::Root => name + "\\",
480 NameComponent::Prefix => name + "^",
481 NameComponent::Segment(seg) => name + seg.as_str() + ".",
482 })
483 .trim_end_matches('.')
484 .to_string()
485 }
486
487 pub fn is_normal(&self) -> bool {
490 !self.0.contains(&NameComponent::Prefix)
491 }
492
493 pub fn is_absolute(&self) -> bool {
494 self.0.first() == Some(&NameComponent::Root)
495 }
496
497 pub fn search_rules_apply(&self) -> bool {
500 if self.0.len() != 1 {
501 return false;
502 }
503
504 match self.0[0] {
505 NameComponent::Segment(_) => true,
506 _ => false,
507 }
508 }
509
510 pub fn normalize(self) -> Result<AmlName, AmlError> {
513 if self.is_normal() {
518 return Ok(self);
519 }
520
521 Ok(AmlName(self.0.iter().try_fold(
522 Vec::new(),
523 |mut name, &component| match component {
524 seg @ NameComponent::Segment(_) => {
525 name.push(seg);
526 Ok(name)
527 }
528
529 NameComponent::Root => {
530 name.push(NameComponent::Root);
531 Ok(name)
532 }
533
534 NameComponent::Prefix => {
535 if let Some(NameComponent::Segment(_)) = name.iter().last() {
536 name.pop().unwrap();
537 Ok(name)
538 } else {
539 Err(AmlError::InvalidNormalizedName(self.clone()))
540 }
541 }
542 },
543 )?))
544 }
545
546 pub fn parent(&self) -> Result<AmlName, AmlError> {
549 let mut normalized_self = self.clone().normalize()?;
551
552 match normalized_self.0.last() {
553 None | Some(NameComponent::Root) => Err(AmlError::RootHasNoParent),
554 Some(NameComponent::Segment(_)) => {
555 normalized_self.0.pop();
556 Ok(normalized_self)
557 }
558 Some(NameComponent::Prefix) => unreachable!(), }
560 }
561
562 pub fn resolve(&self, scope: &AmlName) -> Result<AmlName, AmlError> {
565 let scope = scope.clone().normalize().unwrap_or(AmlName::root());
566
567 if self.is_absolute() {
568 return Ok(self.clone());
569 }
570
571 let mut resolved_path = scope.clone();
572 resolved_path.0.extend_from_slice(&(self.0));
573 resolved_path.normalize()
574 }
575}
576
577impl fmt::Display for AmlName {
578 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
579 write!(f, "{}", self.as_string())
580 }
581}
582
583#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
584pub enum NameComponent {
585 Root,
586 Prefix,
587 Segment(NameSeg),
588}
589
590impl NameComponent {
591 pub fn as_segment(self) -> Result<NameSeg, ()> {
592 match self {
593 NameComponent::Segment(seg) => Ok(seg),
594 NameComponent::Root | NameComponent::Prefix => Err(()),
595 }
596 }
597}