示例#1
0
        /// <summary>
        /// Read in a trait, which are like object properties.
        /// </summary>
        /// <returns>A trait.</returns>
        private Trait ReadTrait()
        {
            Trait     t         = null;
            Multiname traitName = this.code.GetMultiname((int)this.abcdtr.ReadU30());
            int       traitCode = this.abcdtr.ReadUI8();
            TraitKind kind      = (TraitKind)(traitCode & 0xF);

            switch (kind)
            {
            case TraitKind.Slot:
            case TraitKind.Const:
                SlotTrait st = new SlotTrait();
                st.Name = traitName;
                st.Kind = kind;

                st.SlotID   = this.abcdtr.ReadU30();
                st.TypeName = this.code.GetMultiname((int)this.abcdtr.ReadU30());

                uint vindex = this.abcdtr.ReadU30();

                if (vindex != 0)
                {
                    st.ValKind = (ConstantKind)this.abcdtr.ReadUI8();
                    switch (st.ValKind)
                    {
                    case ConstantKind.ConInt:
                        st.Val = this.code.IntConsts[vindex];
                        break;

                    case ConstantKind.ConUInt:
                        st.Val = this.code.UIntConsts[vindex];
                        break;

                    case ConstantKind.ConDouble:
                        st.Val = this.code.DoubleConsts[vindex];
                        break;

                    case ConstantKind.ConUtf8:
                        st.Val = this.code.StringConsts[vindex];
                        break;

                    case ConstantKind.ConTrue:
                    case ConstantKind.ConFalse:
                    case ConstantKind.ConNull:
                    case ConstantKind.ConUndefined:
                        break;

                    case ConstantKind.ConNamespace:
                    case ConstantKind.ConPackageNamespace:
                    case ConstantKind.ConPackageInternalNs:
                    case ConstantKind.ConProtectedNamespace:
                    case ConstantKind.ConExplicitNamespace:
                    case ConstantKind.ConStaticProtectedNs:
                    case ConstantKind.ConPrivateNs:
                        st.Val = this.code.GetNamespace((int)vindex);
                        break;

                    default:
                        throw new SWFModellerException(
                                  SWFModellerError.Internal,
                                  "Unsupported constant kind: " + st.ValKind.ToString());
                    }
                }

                t = st;
                break;

            case TraitKind.Class:
                ClassTrait ct = new ClassTrait();
                ct.Name = traitName;
                ct.Kind = kind;

                ct.SlotID = this.abcdtr.ReadU30();
                this.LateResolutions.Add(ct, (int)this.abcdtr.ReadU30());     /* We'll resolve the class ref later. */

                t = ct;
                break;

            case TraitKind.Function:
                FunctionTrait ft = new FunctionTrait();
                ft.Name = traitName;
                ft.Kind = kind;

                ft.SlotID = this.abcdtr.ReadU30();
                ft.Fn     = this.code.GetMethod((int)this.abcdtr.ReadU30());

                t = ft;
                break;

            case TraitKind.Method:
            case TraitKind.Getter:
            case TraitKind.Setter:
            default:
                MethodTrait mt = new MethodTrait();
                mt.Name = traitName;
                mt.Kind = kind;

                uint dispID = this.abcdtr.ReadU30();
                if (dispID != 0)
                {
                    mt.OverriddenMethod = this.code.GetMethod((int)dispID);
                }

                mt.Fn = this.code.GetMethod((int)this.abcdtr.ReadU30());

                t = mt;
                break;
            }

            return(t);
        }
示例#2
0
        public ASTrait(ABCFile abc, FlashReader reader)
            : this(abc)
        {
            TypeIndex = reader.Read7BitEncodedInt();
            byte trueKind = reader.ReadByte();

            var traitType = (TraitType)(trueKind & 0xF);
            Attributes = (TraitAttributes)(trueKind >> 4);
            #region Trait Reading
            switch (traitType)
            {
            case TraitType.Slot:
            case TraitType.Constant:
            {
                Data = new SlotConstantTrait(abc, reader, traitType)
                {
                    ObjName = Type.ObjName
                };
                break;
            }

            case TraitType.Method:
            case TraitType.Getter:
            case TraitType.Setter:
            {
                Data = new MethodGetterSetterTrait(abc, reader, traitType)
                {
                    ObjName = Type.ObjName
                };

                ((MethodGetterSetterTrait)Data).Method.ObjName = ObjName;
                break;
            }

            case TraitType.Class:
            {
                Data = new ClassTrait(abc, reader)
                {
                    ObjName = Type.ObjName
                };
                break;
            }

            case TraitType.Function:
            {
                Data = new FunctionTrait(abc, reader)
                {
                    ObjName = Type.ObjName
                };
                break;
            }

            default:
                throw new Exception($"Invalid {nameof(ASTrait)} type: " + traitType);
            }
            #endregion

            if ((Attributes & TraitAttributes.Metadata) != 0)
            {
                MetadataIndices.Capacity = reader.Read7BitEncodedInt();
            }

            for (int i = 0; i < MetadataIndices.Capacity; i++)
            {
                MetadataIndices.Add(reader.Read7BitEncodedInt());
            }
        }
示例#3
0
        private void WriteTraitInfo(ABCDataTypeWriter writer, Trait t)
        {
            writer.WriteU30Packed((uint)this.MultinameID(t.Name));
            writer.WriteUI8((uint)t.Kind);

            switch (t.Kind)
            {
            case TraitKind.Slot:
            case TraitKind.Const:
                SlotTrait st = (SlotTrait)t;
                writer.WriteU30Packed(st.SlotID);
                writer.WriteU30Packed((uint)this.MultinameID(st.TypeName));

                if (st.Val == null)
                {
                    writer.WriteU30Packed(0);
                }
                else
                {
                    switch (st.ValKind)
                    {
                    case ConstantKind.ConInt:
                        writer.WriteU30Packed((uint)this.intMarshal.GetIDFor((int)st.Val));
                        break;

                    case ConstantKind.ConUInt:
                        writer.WriteU30Packed((uint)this.uintMarshal.GetIDFor((uint)st.Val));
                        break;

                    case ConstantKind.ConDouble:
                        writer.WriteU30Packed((uint)this.doubleMarshal.GetIDFor((ulong)st.Val));
                        break;

                    case ConstantKind.ConUtf8:
                        writer.WriteU30Packed((uint)this.stringMarshal.GetIDFor((string)st.Val));
                        break;

                    case ConstantKind.ConTrue:
                        /* Through observation, this always gets set to 11, I do not know why. It
                         * seems though that it should be any non-zero number. */
                        writer.WriteU30Packed(11);
                        break;

                    case ConstantKind.ConFalse:
                        /* Through observation, this always gets set to 11, I do not know why. It
                         * seems though that it should be any non-zero number. */
                        writer.WriteU30Packed(10);
                        break;

                    case ConstantKind.ConNull:
                        /* Through observation, this always gets set to 11, I do not know why. It
                         * seems though that it should be any non-zero number. */
                        writer.WriteU30Packed(12);
                        break;

                    case ConstantKind.ConUndefined:
                        /* Through observation, true, false and null all seem to have ignored but
                         * specific values. I haven't seen one for undefined, but I'm guessing it's
                         * 13. Really want to know what these number are. The don't seem to relate
                         * the string or multiname tables. */
                        writer.WriteU30Packed(13);
                        break;

                    case ConstantKind.ConNamespace:
                    case ConstantKind.ConPackageNamespace:
                    case ConstantKind.ConPackageInternalNs:
                    case ConstantKind.ConProtectedNamespace:
                    case ConstantKind.ConExplicitNamespace:
                    case ConstantKind.ConStaticProtectedNs:
                    case ConstantKind.ConPrivateNs:
                        writer.WriteU30Packed((uint)this.NamespaceID((Namespace)st.Val));
                        break;

                    default:
                        throw new SWFModellerException(
                                  SWFModellerError.Internal,
                                  "Unsupported constant type: " + st.ValKind.ToString());
                    }

                    writer.WriteUI8((uint)st.ValKind);
                }

                break;

            case TraitKind.Method:
            case TraitKind.Getter:
            case TraitKind.Setter:
                MethodTrait mt = (MethodTrait)t;
                if (mt.OverriddenMethod != null)
                {
                    writer.WriteU30Packed((uint)this.methodMarshal.GetIDFor(mt.OverriddenMethod));
                }
                else
                {
                    writer.WriteU30Packed(0);
                }

                writer.WriteU30Packed((uint)this.methodMarshal.GetIDFor(mt.Fn));
                break;

            case TraitKind.Class:
                ClassTrait ct = (ClassTrait)t;
                writer.WriteU30Packed((uint)ct.SlotID);
                writer.WriteU30Packed((uint)this.classMarshal.GetIDFor(ct.As3class));
                break;

            case TraitKind.Function:
                FunctionTrait ft = (FunctionTrait)t;
                writer.WriteU30Packed((uint)ft.SlotID);
                writer.WriteU30Packed((uint)this.methodMarshal.GetIDFor(ft.Fn));
                break;

            default:
                /* ISSUE 73 */
                throw new SWFModellerException(
                          SWFModellerError.UnimplementedFeature,
                          "Unsupported trait kind: " + t.Kind.ToString());
            }
        }