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 assert!(path.is_absolute());
96 let path = path.normalize()?;
97
98 if path != AmlName::root() {
104 let (level, last_seg) = self.get_level_for_path_mut(&path)?;
105
106 if !level.children.contains_key(&last_seg) {
111 level.children.insert(last_seg, NamespaceLevel::new(typ));
112 }
113 }
114
115 Ok(())
116 }
117
118 pub fn remove_level(&mut self, path: AmlName) -> Result<(), AmlError> {
119 assert!(path.is_absolute());
120 let path = path.normalize()?;
121
122 if path != AmlName::root() {
123 let (level, last_seg) = self.get_level_for_path_mut(&path)?;
124
125 match level.children.remove(&last_seg) {
126 Some(_) => Ok(()),
127 None => Err(AmlError::LevelDoesNotExist(path)),
128 }
129 } else {
130 Err(AmlError::TriedToRemoveRootNamespace)
131 }
132 }
133
134 pub fn add_value(&mut self, path: AmlName, value: AmlValue) -> Result<AmlHandle, AmlError> {
138 assert!(path.is_absolute());
139 let path = path.normalize()?;
140
141 let handle = self.next_handle;
142 self.next_handle.increment();
143 self.object_map.insert(handle, value);
144
145 let (level, last_seg) = self.get_level_for_path_mut(&path)?;
146 match level.values.insert(last_seg, handle) {
147 None => Ok(handle),
148 Some(_) => Err(AmlError::NameCollision(path)),
149 }
150 }
151
152 pub fn add_value_at_resolved_path(
156 &mut self,
157 path: AmlName,
158 scope: &AmlName,
159 value: AmlValue,
160 ) -> Result<AmlHandle, AmlError> {
161 self.add_value(path.resolve(scope)?, value)
162 }
163
164 pub fn add_alias_at_resolved_path(
167 &mut self,
168 path: AmlName,
169 scope: &AmlName,
170 target: AmlName,
171 ) -> Result<AmlHandle, AmlError> {
172 let path = path.resolve(scope)?;
173 let target = target.resolve(scope)?;
174
175 let handle = self.get_handle(&target)?;
176
177 let (level, last_seg) = self.get_level_for_path_mut(&path)?;
178 match level.values.insert(last_seg, handle) {
179 None => Ok(handle),
180 Some(_) => Err(AmlError::NameCollision(path)),
181 }
182 }
183
184 pub fn get(&self, handle: AmlHandle) -> Result<&AmlValue, AmlError> {
185 Ok(self.object_map.get(&handle).unwrap())
186 }
187
188 pub fn get_mut(&mut self, handle: AmlHandle) -> Result<&mut AmlValue, AmlError> {
189 Ok(self.object_map.get_mut(&handle).unwrap())
190 }
191
192 pub fn get_handle(&self, path: &AmlName) -> Result<AmlHandle, AmlError> {
193 let (level, last_seg) = self.get_level_for_path(path)?;
194 Ok(*level
195 .values
196 .get(&last_seg)
197 .ok_or(AmlError::ValueDoesNotExist(path.clone()))?)
198 }
199
200 pub fn get_by_path(&self, path: &AmlName) -> Result<&AmlValue, AmlError> {
201 let handle = self.get_handle(path)?;
202 Ok(self.get(handle).unwrap())
203 }
204
205 pub fn get_by_path_mut(&mut self, path: &AmlName) -> Result<&mut AmlValue, AmlError> {
206 let handle = self.get_handle(path)?;
207 Ok(self.get_mut(handle).unwrap())
208 }
209
210 pub fn search(
214 &self,
215 path: &AmlName,
216 starting_scope: &AmlName,
217 ) -> Result<(AmlName, AmlHandle), AmlError> {
218 if path.search_rules_apply() {
219 let mut scope = starting_scope.clone();
225 assert!(scope.is_absolute());
226 loop {
227 let name = path.resolve(&scope)?;
229 match self.get_level_for_path(&name) {
230 Ok((level, last_seg)) => {
231 if let Some(&handle) = level.values.get(&last_seg) {
232 return Ok((name, handle));
233 }
234 }
235
236 Err(AmlError::LevelDoesNotExist(_)) => (),
247 Err(err) => return Err(err),
248 }
249
250 match scope.parent() {
252 Ok(parent) => scope = parent,
253 Err(AmlError::RootHasNoParent) => {
255 return Err(AmlError::ValueDoesNotExist(path.clone()))
256 }
257 Err(err) => return Err(err),
258 }
259 }
260 } else {
261 let name = path.resolve(starting_scope)?;
263 let (level, last_seg) = self.get_level_for_path(&path.resolve(starting_scope)?)?;
267
268 if let Some(&handle) = level.values.get(&last_seg) {
269 Ok((name, handle))
270 } else {
271 Err(AmlError::ValueDoesNotExist(path.clone()))
272 }
273 }
274 }
275
276 pub fn search_for_level(
277 &self,
278 level_name: &AmlName,
279 starting_scope: &AmlName,
280 ) -> Result<AmlName, AmlError> {
281 if level_name.search_rules_apply() {
282 let mut scope = starting_scope.clone().normalize()?;
283 assert!(scope.is_absolute());
284
285 loop {
286 let name = level_name.resolve(&scope)?;
287 if let Ok((level, last_seg)) = self.get_level_for_path(&name) {
288 if let Some(_) = level.children.get(&last_seg) {
289 return Ok(name);
290 }
291 }
292
293 match scope.parent() {
295 Ok(parent) => scope = parent,
296 Err(AmlError::RootHasNoParent) => {
297 return Err(AmlError::LevelDoesNotExist(level_name.clone()))
298 }
299 Err(err) => return Err(err),
300 }
301 }
302 } else {
303 Ok(level_name.clone())
304 }
305 }
306
307 fn get_level_for_path(&self, path: &AmlName) -> Result<(&NamespaceLevel, NameSeg), AmlError> {
308 assert_ne!(*path, AmlName::root());
309
310 let (last_seg, levels) = path.0[1..].split_last().unwrap();
311 let last_seg = last_seg.as_segment().unwrap();
312
313 let mut traversed_path = AmlName::root();
315
316 let mut current_level = &self.root;
317 for level in levels {
318 traversed_path.0.push(*level);
319 current_level = current_level
320 .children
321 .get(&level.as_segment().unwrap())
322 .ok_or(AmlError::LevelDoesNotExist(traversed_path.clone()))?;
323 }
324
325 Ok((current_level, last_seg))
326 }
327
328 fn get_level_for_path_mut(
331 &mut self,
332 path: &AmlName,
333 ) -> Result<(&mut NamespaceLevel, NameSeg), AmlError> {
334 assert_ne!(*path, AmlName::root());
335
336 let (last_seg, levels) = path.0[1..].split_last().unwrap();
337 let last_seg = last_seg.as_segment().unwrap();
338
339 let mut traversed_path = AmlName::root();
343
344 let mut current_level = &mut self.root;
345 for level in levels {
346 traversed_path.0.push(*level);
347 current_level = current_level
348 .children
349 .get_mut(&level.as_segment().unwrap())
350 .ok_or(AmlError::LevelDoesNotExist(traversed_path.clone()))?;
351 }
352
353 Ok((current_level, last_seg))
354 }
355
356 pub fn traverse<F>(&mut self, mut f: F) -> Result<(), AmlError>
360 where
361 F: FnMut(&AmlName, &NamespaceLevel) -> Result<bool, AmlError>,
362 {
363 fn traverse_level<F>(
364 level: &NamespaceLevel,
365 scope: &AmlName,
366 f: &mut F,
367 ) -> Result<(), AmlError>
368 where
369 F: FnMut(&AmlName, &NamespaceLevel) -> Result<bool, AmlError>,
370 {
371 for (name, ref child) in level.children.iter() {
372 let name = AmlName::from_name_seg(*name).resolve(scope)?;
373
374 if f(&name, child)? {
375 traverse_level(child, &name, f)?;
376 }
377 }
378
379 Ok(())
380 }
381
382 if f(&AmlName::root(), &self.root)? {
383 traverse_level(&self.root, &AmlName::root(), &mut f)?;
384 }
385
386 Ok(())
387 }
388}
389
390impl fmt::Debug for Namespace {
391 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
392 const INDENT_PER_LEVEL: usize = 4;
393
394 fn print_level(
395 namespace: &Namespace,
396 f: &mut fmt::Formatter<'_>,
397 level_name: &str,
398 level: &NamespaceLevel,
399 indent: usize,
400 ) -> fmt::Result {
401 writeln!(f, "{:indent$}{}:", "", level_name, indent = indent)?;
402
403 for (name, handle) in level.values.iter() {
404 writeln!(
405 f,
406 "{:indent$}{}: {:?}",
407 "",
408 name.as_str(),
409 namespace.object_map.get(handle).unwrap(),
410 indent = indent + INDENT_PER_LEVEL
411 )?;
412 }
413
414 for (name, sub_level) in level.children.iter() {
415 print_level(
416 namespace,
417 f,
418 name.as_str(),
419 sub_level,
420 indent + INDENT_PER_LEVEL,
421 )?;
422 }
423
424 Ok(())
425 }
426
427 print_level(self, f, "\\", &self.root, 0)
428 }
429}
430
431#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
432pub struct AmlName(Vec<NameComponent>);
433
434impl AmlName {
435 pub fn root() -> AmlName {
436 AmlName(alloc::vec![NameComponent::Root])
437 }
438
439 pub fn from_name_seg(seg: NameSeg) -> AmlName {
440 AmlName(alloc::vec![NameComponent::Segment(seg)])
441 }
442
443 pub fn from_components(components: Vec<NameComponent>) -> AmlName {
444 assert!(components.len() > 0);
445 AmlName(components)
446 }
447
448 pub fn from_str(mut string: &str) -> Result<AmlName, AmlError> {
450 if string.len() == 0 {
451 return Err(AmlError::EmptyNamesAreInvalid);
452 }
453
454 let mut components = Vec::new();
455
456 if string.starts_with('\\') {
458 components.push(NameComponent::Root);
459 string = &string[1..];
460 }
461
462 if string.len() > 0 {
463 for mut part in string.split('.') {
465 while part.starts_with('^') {
467 components.push(NameComponent::Prefix);
468 part = &part[1..];
469 }
470
471 components.push(NameComponent::Segment(NameSeg::from_str(part)?));
472 }
473 }
474
475 Ok(AmlName(components))
476 }
477
478 pub fn as_string(&self) -> String {
479 self.0
480 .iter()
481 .fold(String::new(), |name, component| match component {
482 NameComponent::Root => name + "\\",
483 NameComponent::Prefix => name + "^",
484 NameComponent::Segment(seg) => name + seg.as_str() + ".",
485 })
486 .trim_end_matches('.')
487 .to_string()
488 }
489
490 pub fn is_normal(&self) -> bool {
493 !self.0.contains(&NameComponent::Prefix)
494 }
495
496 pub fn is_absolute(&self) -> bool {
497 self.0.first() == Some(&NameComponent::Root)
498 }
499
500 pub fn search_rules_apply(&self) -> bool {
503 if self.0.len() != 1 {
504 return false;
505 }
506
507 match self.0[0] {
508 NameComponent::Segment(_) => true,
509 _ => false,
510 }
511 }
512
513 pub fn normalize(self) -> Result<AmlName, AmlError> {
516 if self.is_normal() {
521 return Ok(self);
522 }
523
524 Ok(AmlName(self.0.iter().try_fold(
525 Vec::new(),
526 |mut name, &component| match component {
527 seg @ NameComponent::Segment(_) => {
528 name.push(seg);
529 Ok(name)
530 }
531
532 NameComponent::Root => {
533 name.push(NameComponent::Root);
534 Ok(name)
535 }
536
537 NameComponent::Prefix => {
538 if let Some(NameComponent::Segment(_)) = name.iter().last() {
539 name.pop().unwrap();
540 Ok(name)
541 } else {
542 Err(AmlError::InvalidNormalizedName(self.clone()))
543 }
544 }
545 },
546 )?))
547 }
548
549 pub fn parent(&self) -> Result<AmlName, AmlError> {
552 let mut normalized_self = self.clone().normalize()?;
554
555 match normalized_self.0.last() {
556 None | Some(NameComponent::Root) => Err(AmlError::RootHasNoParent),
557 Some(NameComponent::Segment(_)) => {
558 normalized_self.0.pop();
559 Ok(normalized_self)
560 }
561 Some(NameComponent::Prefix) => unreachable!(), }
563 }
564
565 pub fn resolve(&self, scope: &AmlName) -> Result<AmlName, AmlError> {
568 assert!(scope.is_absolute());
569
570 if self.is_absolute() {
571 return Ok(self.clone());
572 }
573
574 let mut resolved_path = scope.clone();
575 resolved_path.0.extend_from_slice(&(self.0));
576 resolved_path.normalize()
577 }
578}
579
580impl fmt::Display for AmlName {
581 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
582 write!(f, "{}", self.as_string())
583 }
584}
585
586#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
587pub enum NameComponent {
588 Root,
589 Prefix,
590 Segment(NameSeg),
591}
592
593impl NameComponent {
594 pub fn as_segment(self) -> Result<NameSeg, ()> {
595 match self {
596 NameComponent::Segment(seg) => Ok(seg),
597 NameComponent::Root | NameComponent::Prefix => Err(()),
598 }
599 }
600}