Ejemplo n.º 1
0
        private ASClass GetMessageParser()
        {
            ABCFile    abc      = Class.GetABC();
            ASInstance instance = Class.Instance;

            ASInstance superInstance = abc.GetInstance(instance.Super);

            if (superInstance == null)
            {
                superInstance = instance;
            }

            ASMethod parserGetterMethod = superInstance.GetGetter("parser")?.Method;

            if (parserGetterMethod == null)
            {
                return(null);
            }

            IEnumerable <ASMethod> methods = instance.GetMethods();

            foreach (ASMethod method in methods.Concat(new[] { instance.Constructor }))
            {
                ASCode code = method.Body.ParseCode();
                foreach (ASInstruction instruction in code)
                {
                    ASMultiname multiname = null;
                    if (instruction.OP == OPCode.FindPropStrict)
                    {
                        var findPropStrictIns = (FindPropStrictIns)instruction;
                        multiname = findPropStrictIns.PropertyName;
                    }
                    else if (instruction.OP == OPCode.GetLex)
                    {
                        var getLexIns = (GetLexIns)instruction;
                        multiname = getLexIns.TypeName;
                    }
                    else
                    {
                        continue;
                    }

                    foreach (ASClass refClass in abc.GetClasses(multiname))
                    {
                        ASInstance refInstance = refClass.Instance;
                        if (refInstance.ContainsInterface(parserGetterMethod.ReturnType.Name))
                        {
                            return(refClass);
                        }
                    }
                }
            }
            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns the Incoming message's parser class.
        /// </summary>
        /// <param name="messageClass">The Incoming message class to extract the parser class from.</param>
        /// <returns></returns>
        public ASClass GetIncomingMessageParser(ASClass messageClass)
        {
            if (_messageParsers.ContainsKey(messageClass))
            {
                return(_messageParsers[messageClass]);
            }

            ABCFile    abc = messageClass.ABC;
            ASClass    incomingMsgParserClass = null;
            ASInstance incomingMsgInstance    = messageClass.Instance;

            try
            {
                ASInstance incomingMsgSuperInstance = abc.FindFirstInstanceByName(
                    incomingMsgInstance.SuperType.Name);

                ASMultiname parserReturnType = incomingMsgSuperInstance
                                               .FindFirstGetter("parser", null).ReturnType;

                List <ASMethod> methods =
                    incomingMsgInstance.FindMethodGetterSetterTraits()
                    .Select(mgsTrait => mgsTrait.Method).ToList();

                methods.Add(incomingMsgInstance.Constructor);
                foreach (ASMethod method in methods)
                {
                    var referencedClasses = new List <ASClass>();
                    using (var inCode = new FlashReader(method.Body.Bytecode))
                    {
                        while (inCode.IsDataAvailable)
                        {
                            OPCode   op     = 0;
                            object[] values = inCode.ReadValuesUntilEither(out op, OPCode.FindPropStrict, OPCode.GetLex);
                            if (values == null)
                            {
                                break;
                            }

                            var         typeIndex = (int)values[0];
                            ASMultiname type      = abc.Constants.Multinames[typeIndex];

                            List <ASClass> instances = abc.FindClassesByName(type.Name);
                            referencedClasses.AddRange(instances);
                        }
                    }
                    foreach (ASClass referencedClass in referencedClasses)
                    {
                        ASInstance referencedInstance = referencedClass.Instance;
                        if (referencedInstance.ContainsInterface(parserReturnType.Name))
                        {
                            incomingMsgParserClass = referencedClass;
                            return(incomingMsgParserClass);
                        }
                    }
                }
            }
            finally
            {
                if (incomingMsgParserClass != null)
                {
                    _messageParsers[messageClass] =
                        incomingMsgParserClass;
                }
            }
            return(incomingMsgParserClass);
        }