@@ -6,6 +6,7 @@ use alloc::{
6
6
vec,
7
7
vec:: Vec ,
8
8
} ;
9
+ use bit_field:: BitField ;
9
10
use core:: { fmt, str, str:: FromStr } ;
10
11
11
12
pub struct Namespace {
@@ -63,7 +64,18 @@ impl Namespace {
63
64
let path = path. normalize ( ) ?;
64
65
65
66
let ( level, last_seg) = self . get_level_for_path_mut ( & path) ?;
66
- match level. values . insert ( last_seg, object) {
67
+ match level. values . insert ( last_seg, ( ObjectFlags :: new ( false ) , object) ) {
68
+ None => Ok ( ( ) ) ,
69
+ Some ( _) => Err ( AmlError :: NameCollision ( path) ) ,
70
+ }
71
+ }
72
+
73
+ pub fn create_alias ( & mut self , path : AmlName , object : Arc < Object > ) -> Result < ( ) , AmlError > {
74
+ assert ! ( path. is_absolute( ) ) ;
75
+ let path = path. normalize ( ) ?;
76
+
77
+ let ( level, last_seg) = self . get_level_for_path_mut ( & path) ?;
78
+ match level. values . insert ( last_seg, ( ObjectFlags :: new ( true ) , object) ) {
67
79
None => Ok ( ( ) ) ,
68
80
Some ( _) => Err ( AmlError :: NameCollision ( path) ) ,
69
81
}
@@ -75,7 +87,7 @@ impl Namespace {
75
87
76
88
let ( level, last_seg) = self . get_level_for_path_mut ( & path) ?;
77
89
match level. values . get ( & last_seg) {
78
- Some ( object) => Ok ( object. clone ( ) ) ,
90
+ Some ( ( _ , object) ) => Ok ( object. clone ( ) ) ,
79
91
None => Err ( AmlError :: ObjectDoesNotExist ( path. clone ( ) ) ) ,
80
92
}
81
93
}
@@ -97,7 +109,7 @@ impl Namespace {
97
109
let name = path. resolve ( & scope) ?;
98
110
match self . get_level_for_path ( & name) {
99
111
Ok ( ( level, last_seg) ) => {
100
- if let Some ( object) = level. values . get ( & last_seg) {
112
+ if let Some ( ( _ , object) ) = level. values . get ( & last_seg) {
101
113
return Ok ( ( name, object. clone ( ) ) ) ;
102
114
}
103
115
}
@@ -117,7 +129,7 @@ impl Namespace {
117
129
let name = path. resolve ( starting_scope) ?;
118
130
let ( level, last_seg) = self . get_level_for_path ( & path. resolve ( starting_scope) ?) ?;
119
131
120
- if let Some ( object) = level. values . get ( & last_seg) {
132
+ if let Some ( ( _ , object) ) = level. values . get ( & last_seg) {
121
133
Ok ( ( name, object. clone ( ) ) )
122
134
} else {
123
135
Err ( AmlError :: ObjectDoesNotExist ( path. clone ( ) ) )
@@ -207,6 +219,35 @@ impl Namespace {
207
219
208
220
Ok ( ( current_level, * last_seg) )
209
221
}
222
+
223
+ /// Traverse the namespace, calling `f` on each namespace level. `f` returns a `Result<bool, AmlError>` -
224
+ /// errors terminate the traversal and are propagated, and the `bool` on the successful path marks whether the
225
+ /// children of the level should also be traversed.
226
+ pub fn traverse < F > ( & mut self , mut f : F ) -> Result < ( ) , AmlError >
227
+ where
228
+ F : FnMut ( & AmlName , & NamespaceLevel ) -> Result < bool , AmlError > ,
229
+ {
230
+ fn traverse_level < F > ( level : & NamespaceLevel , scope : & AmlName , f : & mut F ) -> Result < ( ) , AmlError >
231
+ where
232
+ F : FnMut ( & AmlName , & NamespaceLevel ) -> Result < bool , AmlError > ,
233
+ {
234
+ for ( name, child) in level. children . iter ( ) {
235
+ let name = AmlName :: from_name_seg ( * name) . resolve ( scope) ?;
236
+
237
+ if f ( & name, child) ? {
238
+ traverse_level ( child, & name, f) ?;
239
+ }
240
+ }
241
+
242
+ Ok ( ( ) )
243
+ }
244
+
245
+ if f ( & AmlName :: root ( ) , & self . root ) ? {
246
+ traverse_level ( & self . root , & AmlName :: root ( ) , & mut f) ?;
247
+ }
248
+
249
+ Ok ( ( ) )
250
+ }
210
251
}
211
252
212
253
impl fmt:: Display for Namespace {
@@ -221,10 +262,18 @@ impl fmt::Display for Namespace {
221
262
level : & NamespaceLevel ,
222
263
indent_stack : String ,
223
264
) -> fmt:: Result {
224
- for ( i, ( name, object) ) in level. values . iter ( ) . enumerate ( ) {
265
+ for ( i, ( name, ( flags , object) ) ) in level. values . iter ( ) . enumerate ( ) {
225
266
let end = ( i == level. values . len ( ) - 1 )
226
267
&& level. children . iter ( ) . filter ( |( _, l) | l. kind == NamespaceLevelKind :: Scope ) . count ( ) == 0 ;
227
- writeln ! ( f, "{}{}{}: {:?}" , & indent_stack, if end { END } else { BRANCH } , name. as_str( ) , object) ?;
268
+ writeln ! (
269
+ f,
270
+ "{}{}{}: {}{:?}" ,
271
+ & indent_stack,
272
+ if end { END } else { BRANCH } ,
273
+ name. as_str( ) ,
274
+ if flags. is_alias( ) { "[A] " } else { "" } ,
275
+ object
276
+ ) ?;
228
277
229
278
// If the object has a corresponding scope, print it here
230
279
if let Some ( child_level) = level. children . get ( & name) {
@@ -265,10 +314,25 @@ pub enum NamespaceLevelKind {
265
314
266
315
pub struct NamespaceLevel {
267
316
pub kind : NamespaceLevelKind ,
268
- pub values : BTreeMap < NameSeg , Arc < Object > > ,
317
+ pub values : BTreeMap < NameSeg , ( ObjectFlags , Arc < Object > ) > ,
269
318
pub children : BTreeMap < NameSeg , NamespaceLevel > ,
270
319
}
271
320
321
+ #[ derive( Clone , Copy , Debug ) ]
322
+ pub struct ObjectFlags ( u8 ) ;
323
+
324
+ impl ObjectFlags {
325
+ pub fn new ( is_alias : bool ) -> ObjectFlags {
326
+ let mut flags = 0 ;
327
+ flags. set_bit ( 0 , is_alias) ;
328
+ ObjectFlags ( flags)
329
+ }
330
+
331
+ pub fn is_alias ( & self ) -> bool {
332
+ self . 0 . get_bit ( 0 )
333
+ }
334
+ }
335
+
272
336
impl NamespaceLevel {
273
337
pub fn new ( kind : NamespaceLevelKind ) -> NamespaceLevel {
274
338
NamespaceLevel { kind, values : BTreeMap :: new ( ) , children : BTreeMap :: new ( ) }
0 commit comments