예제 #1
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="source"></param>
 /// <returns></returns>
 private TraitsData_Method ParseMethod(Stream source)
 {
     TraitsData_Method m = new TraitsData_Method();
     m.DispID = VariableLengthInteger.ReadU30(source);
     m.Method = VariableLengthInteger.ReadU30(source);
     return m;
 }
예제 #2
0
        /// <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);
                }
            }
        }