/// <summary> /// /// </summary> /// <param name="source"></param> /// <returns></returns> private TraitsData_Slot ParseSlot(Stream source) { TraitsData_Slot s = new TraitsData_Slot(); s.SlotID = VariableLengthInteger.ReadU30(source); s.TypeName = VariableLengthInteger.ReadU30(source); s.Vindex = VariableLengthInteger.ReadU30(source); if (0 != s.Vindex) { byte kind = VariableLengthInteger.ReadU8(source); if (!Enum.IsDefined(typeof(OptionType), kind)) { AbcFormatException fe = new AbcFormatException("TraitsData Slot invalid constant type 0x" + kind.ToString("X02")); Log.Error(this, fe); throw fe; } s.Vkind = (OptionType)kind; } else { s.Vkind = OptionType.TotallyInvalid; } return s; }
/// <summary> /// /// </summary> /// <param name="source"></param> public void Parse(Stream source) { // UNTESTED Name = VariableLengthInteger.ReadU30(source); byte kind = VariableLengthInteger.ReadU8(source); byte kindType = (byte)(kind & 0x0F); byte kindAttr = (byte)((kind & 0xF0) >> 4); if (!Enum.IsDefined(typeof(TraitType), kindType)) { AbcFormatException fe = new AbcFormatException("Invalid Traits_info kind " + kindType.ToString("d")); Log.Error(this, fe); throw fe; } Type = (TraitType)kindType; // // "Any other combination of attribute with kind is ignored." // - so we test for it. // AttribFinal = (kindAttr & 0x01) != 0 ? true : false; AttribOverride = (kindAttr & 0x02) != 0 ? true : false; AttribMetadata = (kindAttr & 0x04) != 0 ? true : false; if (AttribFinal && (!((Type == TraitType.Trait_Getter) || (Type == TraitType.Trait_Setter) || (Type == TraitType.Trait_Method)))) { AbcFormatException fe = new AbcFormatException("ATTR_Final with trait type " + Enum.GetName(typeof(TraitType), Type)); Log.Error(this, fe); throw fe; } if (AttribOverride && (!((Type == TraitType.Trait_Getter) || (Type == TraitType.Trait_Setter) || (Type == TraitType.Trait_Method)))) { AbcFormatException fe = new AbcFormatException("ATTR_Override with trait type " + Enum.GetName(typeof(TraitType), Type)); Log.Error(this, fe); throw fe; } // // Just to point out how this works: only one of them // is going to be valid // switch (Type) { case TraitType.Trait_Const: case TraitType.Trait_Slot: _Data_Slot = ParseSlot(source); break; case TraitType.Trait_Class: _Data_Class = ParseClass(source); break; case TraitType.Trait_Function: _Data_Function = ParseFunction(source); break; case TraitType.Trait_Method: case TraitType.Trait_Getter: case TraitType.Trait_Setter: _Data_Method = ParseMethod(source); break; default: Exception e = new Exception("Internal error: invalid _Type 0x" + Type.ToString("X02") + " reached end of switch"); Log.Error(this, e); throw e; } if (AttribMetadata) { UInt32 metadataCount = VariableLengthInteger.ReadU30(source); _Metadata = new List<UInt32>((int)metadataCount); for (uint i = 0; i < metadataCount; i++) { UInt32 metav = VariableLengthInteger.ReadU30(source); _Metadata.Add(metav); } } }