예제 #1
0
        /// <summary>
        /// Creates the MovieClip class. Or something that looks like it from the outside.
        /// </summary>
        /// <param name="abc">Where to put the namespace</param>
        /// <returns>The MovieClip class.</returns>
        public static AdobeClass CreateFlashDisplayMovieClip(AbcCode abc)
        {
            Namespace nsFlashDisplay = abc.CreateNamespace(Namespace.NamespaceKind.Package, "flash.display");
            Multiname mnMovieClip    = abc.CreateMultiname(Multiname.MultinameKind.QName, "MovieClip", nsFlashDisplay, null);

            return(new AdobeClass()
            {
                Name = mnMovieClip
            });
        }
예제 #2
0
        public ASMultiname(ABCFile abc, FlashReader reader)
            : this(abc)
        {
            var multinameType = (ConstantType)reader.ReadByte();
            switch (multinameType)
            {
            case ConstantType.QName:
            case ConstantType.QNameA:
            {
                var qName = new QName(abc, reader, multinameType);
                ObjNameIndex = qName.ObjNameIndex;
                Data         = qName;
                break;
            }

            case ConstantType.RTQName:
            case ConstantType.RTQNameA:
            {
                var rtqName = new RTQName(abc, reader, multinameType);
                ObjNameIndex = rtqName.ObjNameIndex;
                Data         = rtqName;
                break;
            }

            case ConstantType.RTQNameL:
            case ConstantType.RTQNameLA:
                Data = new RTQNameL(abc, multinameType);
                break;

            case ConstantType.Multiname:
            case ConstantType.MultinameA:
            {
                var multiname = new Multiname(abc, reader, multinameType);
                ObjNameIndex = multiname.ObjNameIndex;
                Data         = multiname;
                break;
            }

            case ConstantType.MultinameL:
            case ConstantType.MultinameLA:
                Data = new MultinameL(abc, reader, multinameType);
                break;

            case ConstantType.Typename:
                Data = new Typename(abc, reader);
                break;

            default:
                throw new Exception("Invalid multiname: " + multinameType);
            }
        }
예제 #3
0
        /// <summary>
        /// Gets an ID for a multiname, ensuring that all other dependencies of the multiname
        /// are themselves registered with IDs.
        /// </summary>
        /// <param name="mn">The multiname</param>
        /// <returns>The ID of the multiname</returns>
        private int MultinameID(Multiname mn)
        {
            this.stringMarshal.Register(mn.Name);

            if (mn.NS != null)
            {
                /*(void)*/ this.NamespaceID(mn.NS);
            }

            if (mn.Set != null)
            {
                /*(void)*/ this.NamespaceSetID(mn.Set);
            }

            return(this.multinameMarshal.GetIDFor(mn));
        }
예제 #4
0
        /// <summary>
        /// If you change this method, please remember to change operator== too.
        /// </summary>
        /// <param name="obj">Other MN for comparison</param>
        /// <returns>true if equals</returns>
        public override bool Equals(object obj)
        {
            if (System.Object.ReferenceEquals(this, obj))
            {
                return(true);
            }

            if (!(obj is Multiname))
            {
                return(false);
            }

            Multiname mn = (Multiname)obj;

            return(this.Kind == mn.Kind && this.Name == mn.Name && this.NS == mn.NS && this.Set == mn.Set);
        }
예제 #5
0
        public void Instantiate(int frameNum, Sprite sprite, Layer.Position layering, Matrix position, string instanceName, string qClassName)
        {
            AS3Class instanceClass = sprite.Class;

            if (this.Class == null)
            {
                throw new SWFModellerException(
                          SWFModellerError.Internal,
                          "Can't instantiate " + instanceName + " on timeline with no code");
            }

            DoABC scriptTag = this.Root.FirstScript;

            if (scriptTag == null)
            {
                /* ISSUE 70: Y'know, we can generate scripts. We should probably do that. */
                throw new SWFModellerException(
                          SWFModellerError.Internal,
                          "Can't instantiate clips in a SWF with no code.");
            }

            if (instanceClass == null)
            {
                DoABC.GenerateDefaultScript(qClassName, sprite);
                instanceClass = sprite.Class;
            }

            /* Create instance variable of type referenced by instanceClass */

            Namespace propNS   = scriptTag.Code.CreateNamespace(Namespace.NamespaceKind.Package, string.Empty);
            Multiname propName = scriptTag.Code.CreateMultiname(Multiname.MultinameKind.QName, instanceName, propNS, NamespaceSet.EmptySet);

            if (this.Class is AS3ClassDef)
            {
                ((AS3ClassDef)this.Class).AddInstanceTrait(new SlotTrait()
                {
                    Kind     = TraitKind.Slot,
                    TypeName = instanceClass.Name,
                    Name     = propName,
                    ValKind  = ConstantKind.ConUndefined
                });
            }

            this.GetFrame(frameNum).AddTag(new PlaceObject(sprite, this.GetFreeLayer(layering), null, position, instanceName, false, null, null, null));
        }
예제 #6
0
        private void RegisterMultiname(Multiname mn)
        {
            this.stringMarshal.Register(mn.Name);

            if (mn.NS != null)
            {
                this.nsMarshal.Register(mn.NS);
            }

            if (!mn.IsEmptySet)
            {
                foreach (Namespace ns in mn.Set)
                {
                    this.nsMarshal.Register(ns);
                }

                this.nsSetMarshal.Register(mn.Set);
            }

            this.multinameMarshal.Register(mn);
        }
예제 #7
0
        public MultinameBase ReadMultiname()
        {
            string word = ReadWord();

            if (word == "null")
            {
                return(null);
            }

            MultinameBase ret;
            ASType        kind = (ASType)Enum.Parse(typeof(ASType), word);

            Expect("(");
            switch (kind)
            {
            case ASType.QName:
            case ASType.QNameA:
                ret             = new QName();
                ((QName)ret).Ns = ReadNamespace();
                Expect(",");
                ((QName)ret).Name = ReadString();
                break;

            case ASType.RTQName:
            case ASType.RTQNameA:
                ret = new RTQName();
                ((RTQName)ret).Name = ReadString();
                break;

            case ASType.RTQNameL:
            case ASType.RTQNameLA:
                ret = new MultinameBase();
                break;

            case ASType.Multiname:
            case ASType.MultinameA:
                ret = new Multiname();
                ((Multiname)ret).Name = ReadString();
                Expect(",");
                ((Multiname)ret).NsSet = ReadNamespaceSet();
                break;

            case ASType.MultinameL:
            case ASType.MultinameLA:
                ret = new Multiname();
                ((MultinameL)ret).NsSet = ReadNamespaceSet();
                break;

            case ASType.TypeName:
                ret = new TypeName();
                ((TypeName)ret).Name   = ReadMultiname();
                ((TypeName)ret).Params = ReadList('<', '>', ReadMultiname, false);
                break;

            default:
                throw new ASParsingException("Cannot handle multiname kind: " + kind.ToString());
            }
            ret.Kind = kind;
            Expect(")");
            return(ret);
        }
예제 #8
0
        /// <summary>
        /// Reads in all the constant values referenced from the bytecode.
        /// </summary>
        private void ReadConstantPool()
        {
            uint intCount = this.abcdtr.ReadU30();

#if DEBUG
            if (this.ReadLog != null)
            {
                this.ReadLog.AppendLine("Constant ints length " + intCount);
            }
#endif
            this.code.SetIntCount(intCount);
            for (int i = 1; i < intCount; i++)
            {
                this.code.IntConsts[i] = this.abcdtr.ReadSI32();
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("int #" + i + ": " + this.code.IntConsts[i]);
                }
#endif
            }

            uint uintCount = this.abcdtr.ReadU30();
#if DEBUG
            if (this.ReadLog != null)
            {
                this.ReadLog.AppendLine("Constant uints length " + uintCount);
            }
#endif
            this.code.SetUintCount(uintCount);
            for (int i = 1; i < uintCount; i++)
            {
                this.code.UIntConsts[i] = this.abcdtr.ReadUI32();
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("uint #" + i + ": " + this.code.UIntConsts[i]);
                }
#endif
            }

            uint double64Count = this.abcdtr.ReadU30();
#if DEBUG
            if (this.ReadLog != null)
            {
                this.ReadLog.AppendLine("Constant d64 length " + double64Count);
            }
#endif
            this.code.SetDoubleCount(double64Count);
            for (int i = 1; i < double64Count; i++)
            {
                /* See the comment on AbcCode.DoubleConsts for the reason for all
                 * of this strange ulong shenanigans. */

                ulong ul = (ulong)this.abcdtr.ReadInt32();
                ul |= ((ulong)this.abcdtr.ReadInt32()) << 32;
                this.code.DoubleConsts[i] = ul;
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("d64 #" + i + ": " + this.code.DoubleConsts[i]);
                }
#endif
            }

            uint stringCount = this.abcdtr.ReadU30();
#if DEBUG
            if (this.ReadLog != null)
            {
                this.ReadLog.AppendLine("Constant string length " + stringCount);
            }
#endif
            this.code.SetStringCount(stringCount);
            for (int i = 1; i < stringCount; i++)
            {
                this.code.StringConsts[i] = this.abcdtr.ReadString();
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("str #" + i + ": " + this.code.StringConsts[i]);
                }
#endif
            }

            uint nspaceCount = this.abcdtr.ReadU30();
#if DEBUG
            if (this.ReadLog != null)
            {
                this.ReadLog.AppendLine("Constant ns length " + nspaceCount);
            }
#endif
            for (int i = 1; i < nspaceCount; i++)
            {
                Namespace.NamespaceKind kind = (Namespace.NamespaceKind) this.abcdtr.ReadUI8();

                Namespace ns = null;
                if (kind == Namespace.NamespaceKind.Private)
                {
                    uint   sidx = this.abcdtr.ReadU30();
                    string name = string.Empty;
                    if (sidx > 0)
                    {
                        name = this.code.StringConsts[sidx];
                    }

                    ns = this.code.CreateNamespace(kind, name);
                }
                else
                {
                    ns = this.code.CreateNamespace(kind, this.ReadString());
                }
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("ns #" + i + ": " + ns);
                }
#endif
            }

            uint nssetCount = this.abcdtr.ReadU30();
#if DEBUG
            if (this.ReadLog != null)
            {
                this.ReadLog.AppendLine("Constant ns set length " + nssetCount);
            }
#endif
            for (int i = 1; i < nssetCount; i++)
            {
                uint        count  = this.abcdtr.ReadU30();
                Namespace[] nsRefs = new Namespace[count];

                for (int j = 0; j < count; j++)
                {
                    nsRefs[j] = this.code.GetNamespace((int)this.abcdtr.ReadU30());
                }

                NamespaceSet nss = this.code.CreateNamespaceSet(nsRefs);
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("nss #" + i + ": " + nss);
                }
#endif
            }

            uint multinameCount = this.abcdtr.ReadU30();
#if DEBUG
            if (this.ReadLog != null)
            {
                this.ReadLog.AppendLine("Constant mname length " + multinameCount);
            }
#endif
            for (int i = 1; i < multinameCount; i++)
            {
                string       name = null;
                Namespace    ns   = null;
                NamespaceSet set  = null;

                Multiname.MultinameKind kind = (Multiname.MultinameKind) this.abcdtr.ReadUI8();
                switch (kind)
                {
                case Multiname.MultinameKind.QName:
                case Multiname.MultinameKind.QNameA:
                    int nsi = (int)this.abcdtr.ReadU30();
                    ns   = this.code.GetNamespace(nsi);
                    name = this.ReadString();
                    break;

                case Multiname.MultinameKind.RTQName:
                case Multiname.MultinameKind.RTQNameA:
                    name = this.ReadString();
                    break;

                case Multiname.MultinameKind.RTQNameL:
                case Multiname.MultinameKind.RTQNameLA:
                    /* No data */
                    break;

                case Multiname.MultinameKind.Multiname:
                case Multiname.MultinameKind.MultinameA:
                    name = this.ReadString();
                    set  = this.code.GetNamespaceSet((int)this.abcdtr.ReadU30());
                    break;

                case Multiname.MultinameKind.MultinameL:
                case Multiname.MultinameKind.MultinameLA:
                    set = this.code.GetNamespaceSet((int)this.abcdtr.ReadU30());
                    break;

                default:
                    throw new SWFModellerException(
                              SWFModellerError.ABCParsing,
                              "Bad multiname kind in ABC data.");
                }

                Multiname mn = this.code.CreateMultiname(kind, name, ns, set);
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("mn #" + i + ": " + mn);
                }
#endif
            }
        }
예제 #9
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);
        }
예제 #10
0
        /// <summary>
        /// Read in the class definitions.
        /// </summary>
        private void ReadClasses()
        {
            uint classCount = this.abcdtr.ReadU30();

            for (int i = 0; i < classCount; i++)
            {
                AS3ClassDef c       = this.code.CreateClass();
                uint        nameIdx = this.abcdtr.ReadU30();
                c.Name = this.code.GetMultiname((int)nameIdx);
                uint superIdx = this.abcdtr.ReadU30();
                c.Supername = this.code.GetMultiname((int)superIdx);
                c.Flags     = this.abcdtr.ReadUI8();
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("Class #" + (i + 1) + " name '" + c.Name + "', super '" + c.Supername + "', flags: " + c.Flags);
                }
#endif
                if (c.IsProtectedNS)
                {
                    c.ProtectedNS = this.code.GetNamespace((int)this.abcdtr.ReadU30());
#if DEBUG
                    if (this.ReadLog != null)
                    {
                        this.ReadLog.AppendLine("  protected ns " + c.ProtectedNS);
                    }
#endif
                }

                uint interfaceCount = this.abcdtr.ReadU30();
                while (interfaceCount-- > 0)
                {
                    Multiname iName = this.code.GetMultiname((int)this.abcdtr.ReadU30());
                    c.AddInterface(iName);
#if DEBUG
                    if (this.ReadLog != null)
                    {
                        this.ReadLog.AppendLine("  implements " + iName);
                    }
#endif
                }

                c.Iinit = this.code.GetMethod((int)this.abcdtr.ReadU30());
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("  iinit " + c.Iinit);
                }
#endif
                uint traitCount = this.abcdtr.ReadU30();
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine("  instance traits: " + traitCount);
                }
#endif
                while (traitCount-- > 0)
                {
                    c.AddInstanceTrait(this.ReadTrait());
                }
            }

            for (int i = 0; i < classCount; i++)
            {
                AS3ClassDef c = this.code.GetClass(i);
                c.Cinit = this.code.GetMethod((int)this.abcdtr.ReadU30());
                uint traitCount = this.abcdtr.ReadU30();
#if DEBUG
                if (this.ReadLog != null)
                {
                    this.ReadLog.AppendLine(" class " + c + " has " + traitCount + " static traits");
                }
#endif
                while (traitCount-- > 0)
                {
                    c.AddClassTrait(this.ReadTrait());
                }
            }
        }
예제 #11
0
 /// <summary>
 /// Add a parameter to this method.
 /// </summary>
 /// <param name="type">The parameter type as a multiname</param>
 public void AddParam(Multiname type)
 {
     this.paramTypes.Add(type);
 }
예제 #12
0
        /// <summary>
        /// Writes out the constants to the SWF file. This will also re-set the tables in the
        /// code object, so be sure you don't have anything in there that you need.
        /// </summary>
        /// <param name="writer">Where to write the constants to.</param>
        /// <param name="code">The code object with the tables in it, that we'll
        /// overwrite.</param>
        private void WriteConstantPool(ABCDataTypeWriter writer, AbcCode code)
        {
            /* Integer constants */
            int[] ints = this.intMarshal.ToArray();
            writer.WriteU30Packed((uint)(ints.Length == 1 ? 0 : ints.Length));
            for (int i = 1; i < ints.Length; i++) /* Omit value at [0] */
            {
#if DEBUG
                this.writeLog.AppendLine("Const int #" + i + ": " + ints[i]);
#endif

                writer.WriteSI32(ints[i]);
            }

            code.IntConsts = ints;

            /* Unsigned integer constants */
            uint[] uints = this.uintMarshal.ToArray();
            writer.WriteU30Packed((uint)(uints.Length == 1 ? 0 : uints.Length));
            for (int i = 1; i < uints.Length; i++) /* Omit value at [0] */
            {
#if DEBUG
                this.writeLog.AppendLine("Const uint #" + i + ": " + uints[i]);
#endif
                writer.WriteUI32(uints[i]);
            }

            code.UIntConsts = uints;

            /* Double constants */
            ulong[] doubles = this.doubleMarshal.ToArray();
            writer.WriteU30Packed((uint)(doubles.Length == 1 ? 0 : doubles.Length));
            for (int i = 1; i < doubles.Length; i++) /* Omit value at [0] */
            {
#if DEBUG
                this.writeLog.AppendLine("Const double (bits) #" + i + ": " + doubles[i]);
#endif

                /* We hack this here instead of having a U64 type, because it's a hack around not
                 * treating double properly. There's no such thing as U64 in SWF. */
                ulong d   = doubles[i];
                uint  low = (uint)(d & 0x00000000FFFFFFFF);
                d >>= 32;
                uint high = (uint)(d & 0x00000000FFFFFFFF);

                writer.WriteUI32(high);
                writer.WriteUI32(low);
            }

            code.DoubleConsts = doubles;

            /* String constants */
            string[] strings = this.stringMarshal.ToArray();
            writer.WriteU30Packed((uint)(strings.Length == 1 ? 0 : strings.Length));
            for (int i = 1; i < strings.Length; i++) /* Omit value at [0] */
            {
#if DEBUG
                this.writeLog.AppendLine("Const string #" + i + ": \"" + strings[i] + "\"");
#endif
                writer.WriteString(strings[i]);
            }

            code.StringConsts = strings;

            /* Namespace constants */
            Namespace[] namespaces = this.nsMarshal.ToArray();
            writer.WriteU30Packed((uint)(namespaces.Length == 1 ? 0 : namespaces.Length));
            for (int i = 1; i < namespaces.Length; i++) /* Omit value at [0] */
            {
#if DEBUG
                this.writeLog.AppendLine("Const ns #" + i + ": " + namespaces[i]);
#endif
                Namespace ns = namespaces[i];
                writer.WriteUI8((uint)ns.Kind);
                writer.WriteU30Packed((uint)this.stringMarshal.GetExistingIDFor(ns.Name));
            }

            code.SetNamespaces(namespaces);

            /* Namespace set constants */
            NamespaceSet[] namespaceSets = this.nsSetMarshal.ToArray();
            writer.WriteU30Packed((uint)(namespaceSets.Length == 1 ? 0 : namespaceSets.Length));
            for (int i = 1; i < namespaceSets.Length; i++) /* Omit value at [0] */
            {
#if DEBUG
                this.writeLog.AppendLine("Const ns set #" + i + ": " + namespaceSets[i]);
#endif
                NamespaceSet nss = namespaceSets[i];

                writer.WriteU30Packed((uint)nss.Count);

                foreach (Namespace ns in nss)
                {
                    writer.WriteU30Packed((uint)this.nsMarshal.GetExistingIDFor(ns));
                }
            }

            code.SetNamespaceSets(namespaceSets);

            /* Multiname constants */
            Multiname[] multinames = this.multinameMarshal.ToArray();
            writer.WriteU30Packed((uint)(multinames.Length == 1 ? 0 : multinames.Length));
            for (int i = 1; i < multinames.Length; i++) /* Omit value at [0] */
            {
#if DEBUG
                this.writeLog.AppendLine("Const mn set #" + i + ": " + multinames[i]);
#endif
                Multiname mn = multinames[i];

                writer.WriteUI8((uint)mn.Kind);

                switch (mn.Kind)
                {
                case Multiname.MultinameKind.QName:
                case Multiname.MultinameKind.QNameA:
                    uint nsIdx   = (uint)this.nsMarshal.GetExistingIDFor(mn.NS);
                    uint nameIdx = (uint)this.stringMarshal.GetExistingIDFor(mn.Name);
                    writer.WriteU30Packed(nsIdx);
                    writer.WriteU30Packed(nameIdx);
                    break;

                case Multiname.MultinameKind.RTQName:
                case Multiname.MultinameKind.RTQNameA:
                    writer.WriteU30Packed((uint)this.stringMarshal.GetExistingIDFor(mn.Name));
                    break;

                case Multiname.MultinameKind.RTQNameL:
                case Multiname.MultinameKind.RTQNameLA:
                    /* No data */
                    break;

                case Multiname.MultinameKind.Multiname:
                case Multiname.MultinameKind.MultinameA:
                    writer.WriteU30Packed((uint)this.stringMarshal.GetExistingIDFor(mn.Name));
                    writer.WriteU30Packed((uint)this.nsSetMarshal.GetExistingIDFor(mn.Set));
                    break;

                case Multiname.MultinameKind.MultinameL:
                case Multiname.MultinameKind.MultinameLA:
                    writer.WriteU30Packed((uint)this.nsSetMarshal.GetExistingIDFor(mn.Set));
                    break;

                default:
                    break;
                }
            }

            code.SetMultinames(multinames);
        }
예제 #13
0
        /// <summary>
        /// Renames the main timeline class.
        /// </summary>
        /// <param name="classQName">New name of the class.</param>
        internal void RenameMainTimelineClass(string classQName)
        {
            if (this.Class == null)
            {
                throw new SWFModellerException(SWFModellerError.Internal, "Can't rename non-existant timeline class.");
            }

            AS3ClassDef classDef = this.Class as AS3ClassDef;

            if (classDef == null)
            {
                throw new SWFModellerException(SWFModellerError.Internal, "MainTimeline class is an in-built class, which is impossible.");
            }

            int splitPos = classQName.LastIndexOf('.');

            string className      = classQName;
            string newPackageName = string.Empty;

            if (splitPos != -1)
            {
                newPackageName = classQName.Substring(0, splitPos);
                className      = classQName.Substring(splitPos + 1);
            }

            /* Class name will be a QName, so won't have a NS set */
            Multiname oldName   = classDef.Name;
            Namespace oldNameNS = oldName.NS;
            Multiname newName   = this.scripts[0].Code.CreateMultiname(
                oldName.Kind,
                className,
                this.scripts[0].Code.CreateNamespace(oldNameNS.Kind, newPackageName),
                null);

            Namespace oldProtectedNS = classDef.ProtectedNS;
            Namespace newProtectedNS = null;

            if (oldProtectedNS != null)
            {
                newProtectedNS = this.scripts[0].Code.CreateNamespace(oldProtectedNS.Kind, newPackageName + ":" + className);
            }

            this.ClassProc(delegate(AS3ClassDef c)
            {
                bool inRenamedClass = false;

                if (c.Name == oldName)
                {
                    inRenamedClass = true;
                    c.Name         = newName;
                }

                if (c.Supername == oldName)
                {
                    c.Supername = newName;
                }

                if (c.ProtectedNS == oldProtectedNS)
                {
                    c.ProtectedNS = newProtectedNS;
                }

                c.TraitProc(delegate(ref Trait t, AbcCode abc)
                {
                    Namespace traitNS = t.Name.NS;
                    if (traitNS == null)
                    {
                        return;
                    }

                    if (!t.Name.IsEmptySet)
                    {
                        /* ISSUE 32: Delete this once confidence is felt. */
                        throw new SWFModellerException(
                            SWFModellerError.UnimplementedFeature,
                            "Trait name has a set. I didn't think that was possible! Following code needs fixed!!!");
                    }

                    switch (traitNS.Kind)
                    {
                    case Namespace.NamespaceKind.PackageInternal:
                    case Namespace.NamespaceKind.Package:
                        if (inRenamedClass && traitNS.Name == oldNameNS.Name)
                        {
                            t.Name = this.scripts[0].Code.CreateMultiname(
                                t.Name.Kind,
                                t.Name.Name,
                                this.scripts[0].Code.CreateNamespace(traitNS.Kind, newPackageName),
                                null);
                        }

                        break;

                    default:
                        /* ISSUE 73 */
                        throw new SWFModellerException(
                            SWFModellerError.UnimplementedFeature,
                            "As yet unsupported namespace (" + traitNS.Kind + ") when remapping a class trait (" + c.Name.Name + "::" + t.Name + ")");
                    }
                });
            });

            this.MethodProc(delegate(Method m, AS3ClassDef c)
            {
                bool inRenamedClass = c.Name == newName;

                m.OpcodeFilter(delegate(ref Opcode op, AbcCode abc)
                {
                    if (op.Args == null)
                    {
                        return;
                    }

                    for (int i = 0; i < op.Args.Length; i++)
                    {
                        object arg = op.Args[i];
                        if (arg is Multiname)
                        {
                            Multiname mn = (Multiname)arg;
                            if (mn == oldName)
                            {
                                op.Args[i] = newName;
                            }
                            else if (inRenamedClass)
                            {
                                bool isMnModified         = false;
                                Namespace multinameNS     = mn.NS;
                                NamespaceSet multinameSet = mn.Set;

                                if (multinameNS != null)
                                {
                                    switch (multinameNS.Kind)
                                    {
                                    case Namespace.NamespaceKind.Package:
                                    case Namespace.NamespaceKind.PackageInternal:
                                        if (inRenamedClass && multinameNS.Name == oldNameNS.Name)
                                        {
                                            multinameNS = this.scripts[0].Code.CreateNamespace(
                                                multinameNS.Kind,
                                                newPackageName);
                                            isMnModified = true;
                                        }

                                        break;

                                    default:
                                        /* ISSUE 73 */
                                        throw new SWFModellerException(
                                            SWFModellerError.UnimplementedFeature,
                                            "As yet unsupported multiname's NS kind (" + multinameNS.Kind.ToString() + ") in op's Multiname arg during MethodProc");
                                    }
                                }

                                if (multinameSet != null)
                                {
                                    List <Namespace> newSet = new List <Namespace>(multinameSet.Count);
                                    bool isSetModified      = false;
                                    foreach (Namespace ns in multinameSet)
                                    {
                                        switch (ns.Kind)
                                        {
                                        case Namespace.NamespaceKind.Protected:
                                        case Namespace.NamespaceKind.StaticProtected:
                                            if (ns.Name == oldProtectedNS.Name)
                                            {
                                                newSet.Add(this.scripts[0].Code.CreateNamespace(
                                                               ns.Kind,
                                                               newProtectedNS.Name));
                                                isSetModified = true;
                                                continue;
                                            }

                                            break;

                                        case Namespace.NamespaceKind.Package:
                                        case Namespace.NamespaceKind.PackageInternal:
                                        case Namespace.NamespaceKind.Private:
                                            if (inRenamedClass && ns.Name == oldNameNS.Name)
                                            {
                                                newSet.Add(this.scripts[0].Code.CreateNamespace(
                                                               ns.Kind,
                                                               newPackageName));
                                                isSetModified = true;
                                                continue;
                                            }

                                            break;

                                        case Namespace.NamespaceKind.Ns:
                                            if (ns.Name == oldNameNS.Name)
                                            {
                                                newSet.Add(this.scripts[0].Code.CreateNamespace(
                                                               ns.Kind,
                                                               newPackageName));
                                                isSetModified = true;
                                                continue;
                                            }

                                            break;

                                        default:
                                            /* ISSUE 73 */
                                            throw new SWFModellerException(
                                                SWFModellerError.UnimplementedFeature,
                                                "As yet unsupported multiname NS set entry kind (" + ns.Kind.ToString() + ") in op's Multiname arg during MethodProc");
                                        }

                                        newSet.Add(ns);
                                    }

                                    if (isSetModified)
                                    {
                                        isMnModified = true;
                                        multinameSet = new NamespaceSet(newSet.ToArray());
                                    }
                                }

                                if (isMnModified)
                                {
                                    op.Args[i] = this.scripts[0].Code.CreateMultiname(
                                        mn.Kind,
                                        mn.Name,
                                        multinameNS,
                                        multinameSet);
                                }
                            }
                        }
                        else if (arg is Namespace)
                        {
                            /* ISSUE 73 */
                            throw new SWFModellerException(
                                SWFModellerError.UnimplementedFeature,
                                "As yet unsupported op arg in MethodProc: Namespace");
                        }
                        else if (arg is AS3Class)
                        {
                            /* ISSUE 73 */
                            throw new SWFModellerException(
                                SWFModellerError.UnimplementedFeature,
                                "As yet unsupported op arg in MethodProc: AS3Class");
                        }
                    }
                });
            });
        }
예제 #14
0
 static Multiname()
 {
     Multiname.GlobalMultiname = new Multiname(MultinameKind.Multiname, "*", null, NamespaceSet.EmptySet);
 }
예제 #15
0
 /// <summary>
 /// Add an interface to this class by name
 /// </summary>
 /// <param name="iface">The name of the interface</param>
 public void AddInterface(Multiname iface)
 {
     this.interfaces.Add(iface);
 }