windows_metadata/reader/tables/
attribute.rs1use super::*;
2
3impl std::fmt::Debug for Attribute<'_> {
4 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
5 f.debug_tuple("Attribute")
6 .field(&self.ctor().parent().name())
7 .finish()
8 }
9}
10
11impl<'a> Attribute<'a> {
12 pub fn name(&self) -> &'a str {
13 self.ctor().parent().name()
14 }
15
16 pub fn namespace(&self) -> &'a str {
17 self.ctor().parent().namespace()
18 }
19
20 pub fn parent(&self) -> HasAttribute<'a> {
21 self.decode(0)
22 }
23
24 pub fn ctor(&self) -> AttributeType<'a> {
25 self.decode(1)
26 }
27
28 pub fn value(&self) -> Vec<(String, Value)> {
29 let signature = self.ctor().signature(&[]);
30 debug_assert_eq!(signature.flags, MethodCallAttributes::HASTHIS);
31 debug_assert_eq!(signature.return_type, Type::Void);
32
33 let mut values = Vec::with_capacity(signature.types.len());
34 let mut blob = self.blob(2);
35 let prolog = blob.read_u16();
36 debug_assert_eq!(prolog, 1);
37
38 for ty in &signature.types {
39 let value = read_value(&mut blob, ty);
40 values.push((String::new(), value));
41 }
42
43 let named_arg_count = blob.read_u16();
44 values.reserve(named_arg_count as usize);
45
46 for _ in 0..named_arg_count {
47 let _id = blob.read_u8();
48 let ty = blob.read_type_code(&[]);
51 let name = blob.read_utf8();
52 let value = read_value(&mut blob, &ty);
53 values.push((name, value));
54 }
55
56 debug_assert_eq!(blob.len(), 0);
57 values
58 }
59}
60
61fn read_value(blob: &mut Blob, ty: &Type) -> Value {
62 match ty {
63 Type::Bool => Value::Bool(blob.read_bool()),
64 Type::I8 => Value::I8(blob.read_i8()),
65 Type::U8 => Value::U8(blob.read_u8()),
66 Type::I16 => Value::I16(blob.read_i16()),
67 Type::U16 => Value::U16(blob.read_u16()),
68 Type::I32 => Value::I32(blob.read_i32()),
69 Type::U32 => Value::U32(blob.read_u32()),
70 Type::I64 => Value::I64(blob.read_i64()),
71 Type::U64 => Value::U64(blob.read_u64()),
72 Type::F32 => Value::F32(blob.read_f32()),
73 Type::F64 => Value::F64(blob.read_f64()),
74 Type::String => Value::Utf8(blob.read_utf8()),
75 Type::ClassName(tn) if tn == ("System", "Type") => {
76 let s = blob.read_utf8();
77 if let Some(dot) = s.rfind('.') {
78 Value::TypeName(TypeName::named(&s[..dot], &s[dot + 1..]))
79 } else {
80 Value::TypeName(TypeName::named("", &s))
81 }
82 }
83 Type::ValueName(tn) | Type::ClassName(tn) => {
84 Value::EnumValue(tn.clone(), Box::new(Value::I32(blob.read_i32())))
85 }
86 rest => panic!("{rest:?}"),
87 }
88}