| 1 | use super::*; |
| 2 | |
| 3 | impl std::fmt::Debug for Attribute { |
| 4 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 5 | f.debug_tuple(name:"Attribute" ).field(&self.name()).finish() |
| 6 | } |
| 7 | } |
| 8 | |
| 9 | impl Attribute { |
| 10 | pub fn ty(&self) -> AttributeType { |
| 11 | self.decode(1) |
| 12 | } |
| 13 | |
| 14 | pub fn name(&self) -> &'static str { |
| 15 | let AttributeType::MemberRef(ctor) = self.ty(); |
| 16 | let MemberRefParent::TypeRef(ty) = ctor.parent(); |
| 17 | ty.name() |
| 18 | } |
| 19 | |
| 20 | pub fn args(&self) -> Vec<(&'static str, Value)> { |
| 21 | let AttributeType::MemberRef(member) = self.ty(); |
| 22 | let mut sig = member.blob(2); |
| 23 | let mut values = self.blob(2); |
| 24 | let prolog = values.read_u16(); |
| 25 | std::debug_assert_eq!(prolog, 1); |
| 26 | let this_and_gen_param_count = sig.read_usize(); |
| 27 | std::debug_assert_eq!(this_and_gen_param_count, 32); |
| 28 | let fixed_arg_count = sig.read_usize(); |
| 29 | let ret_type = sig.read_usize(); |
| 30 | std::debug_assert_eq!(ret_type, 1); |
| 31 | let mut args = Vec::with_capacity(fixed_arg_count); |
| 32 | let reader = self.reader(); |
| 33 | |
| 34 | for _ in 0..fixed_arg_count { |
| 35 | let arg = match Type::from_blob(&mut sig, None, &[]) { |
| 36 | Type::Bool => Value::Bool(values.read_bool()), |
| 37 | Type::I8 => Value::I8(values.read_i8()), |
| 38 | Type::U8 => Value::U8(values.read_u8()), |
| 39 | Type::I16 => Value::I16(values.read_i16()), |
| 40 | Type::U16 => Value::U16(values.read_u16()), |
| 41 | Type::I32 => Value::I32(values.read_i32()), |
| 42 | Type::U32 => Value::U32(values.read_u32()), |
| 43 | Type::I64 => Value::I64(values.read_i64()), |
| 44 | Type::U64 => Value::U64(values.read_u64()), |
| 45 | Type::String => Value::Str(values.read_str()), |
| 46 | Type::Type => Value::TypeName(TypeName::parse(values.read_str())), |
| 47 | Type::CppEnum(ty) => { |
| 48 | let underlying_type = ty.def.underlying_type(); |
| 49 | values.read_integer(underlying_type) |
| 50 | } |
| 51 | Type::Enum(ty) => { |
| 52 | let underlying_type = ty.def.underlying_type(); |
| 53 | values.read_integer(underlying_type) |
| 54 | } |
| 55 | rest => panic!(" {rest:?}" ), |
| 56 | }; |
| 57 | |
| 58 | args.push(("" , arg)); |
| 59 | } |
| 60 | |
| 61 | let named_arg_count = values.read_u16(); |
| 62 | args.reserve(named_arg_count as usize); |
| 63 | |
| 64 | for _ in 0..named_arg_count { |
| 65 | let _id = values.read_u8(); |
| 66 | let arg_type = values.read_u8(); |
| 67 | let mut name = values.read_str(); |
| 68 | let arg = match arg_type { |
| 69 | ELEMENT_TYPE_BOOLEAN => Value::Bool(values.read_bool()), |
| 70 | ELEMENT_TYPE_I2 => Value::I16(values.read_i16()), |
| 71 | ELEMENT_TYPE_I4 => Value::I32(values.read_i32()), |
| 72 | ELEMENT_TYPE_U4 => Value::U32(values.read_u32()), |
| 73 | ELEMENT_TYPE_STRING => Value::Str(values.read_str()), |
| 74 | 0x50 => Value::TypeName(TypeName::parse(values.read_str())), |
| 75 | 0x55 => { |
| 76 | let tn = TypeName::parse(name); |
| 77 | let def = reader.unwrap_full_name(tn.namespace(), tn.name()); |
| 78 | name = values.read_str(); |
| 79 | let underlying_type = def.underlying_type(); |
| 80 | values.read_integer(underlying_type) |
| 81 | } |
| 82 | rest => panic!(" {rest:?}" ), |
| 83 | }; |
| 84 | args.push((name, arg)); |
| 85 | } |
| 86 | |
| 87 | debug_assert_eq!(sig.len(), 0); |
| 88 | debug_assert_eq!(values.len(), 0); |
| 89 | args |
| 90 | } |
| 91 | } |
| 92 | |