Beispiel #1
0
        public void GetClassCachesInstances()
        {
            ASClass @class = ASClassCache.GetClass("abc", ASClassLayout.Dynamic, EmptyArray <string> .Instance);

            Assert.AreEqual("abc", @class.ClassAlias);
            Assert.AreEqual(ASClassLayout.Dynamic, @class.Layout);
            Assert.AreEqual(0, @class.MemberNames.Count);
            Assert.IsTrue(@class.MemberNames.IsReadOnly);

            Assert.AreSame(@class, ASClassCache.GetClass("abc", ASClassLayout.Dynamic, EmptyArray <string> .Instance));
        }
Beispiel #2
0
        private IASValue ReadTypedObject()
        {
            string classAlias = input.ReadShortString();

            return(ReadObjectWithClass(ASClassCache.GetClass(classAlias, ASClassLayout.Dynamic, EmptyArray <string> .Instance)));
        }
Beispiel #3
0
        private static ActionScriptClassMapping InternalCreateDefaultClassMapping(Type nativeType, string classAliasOverride,
                                                                                  ActionScriptClassAttribute classAttribute)
        {
            // Determine the class alias.
            string classAlias;

            if (classAliasOverride != null)
            {
                classAlias = classAliasOverride;
            }
            else if (classAttribute != null)
            {
                classAlias = classAttribute.ClassAlias;
            }
            else
            {
                classAlias = "";
            }

            // Determine the class layout.
            ASClassLayout classLayout = ASClassLayout.Normal;

            if (typeof(IDynamic).IsAssignableFrom(nativeType))
            {
                classLayout = ASClassLayout.Dynamic;
            }

            if (typeof(IExternalizable).IsAssignableFrom(nativeType))
            {
                if (classAlias.Length == 0)
                {
                    throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture,
                                                                  "Type '{0}' implements IExternalizable but does not have a non-empty class alias name which is required by the externalizable serialization protocol.",
                                                                  nativeType.FullName));
                }

                if (classLayout == ASClassLayout.Dynamic)
                {
                    throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture,
                                                                  "Type '{0}' implements IExternalizable as well as IDynamic which is not supported by the externalizable serialization protocol.",
                                                                  nativeType.FullName));
                }

                classLayout = ASClassLayout.Externalizable;
            }

            // Populate the list of property mappings.
            List <ActionScriptPropertyMapping> propertyMappings = new List <ActionScriptPropertyMapping>();
            List <string> memberNames = new List <string>();

            foreach (PropertyInfo property in nativeType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                AddPropertyMappingIfNeeded(property, propertyMappings, memberNames, ref classLayout);
            }

            foreach (FieldInfo field in nativeType.GetFields(BindingFlags.Instance | BindingFlags.Public))
            {
                AddPropertyMappingIfNeeded(field, propertyMappings, memberNames, ref classLayout);
            }

            // Finish up.
            // Convert the lists to arrays to reduce the memory footprint.
            string[] memberNamesArray = memberNames.Count == 0 ? EmptyArray <string> .Instance : memberNames.ToArray();
            ActionScriptPropertyMapping[] propertyMappingsArray = propertyMappings.Count == 0 ?
                                                                  EmptyArray <ActionScriptPropertyMapping> .Instance : propertyMappings.ToArray();

            ASClass classDefinition = ASClassCache.GetClass(classAlias, classLayout, memberNamesArray);
            ActionScriptClassMapping classMapping = new ActionScriptClassMapping(nativeType, classDefinition, propertyMappingsArray);

            return(classMapping);
        }
Beispiel #4
0
        private IASValue ReadObjectValue()
        {
            int bits = input.ReadVWInt29();

            // Handle cached objects.
            if ((bits & 1) == 0)
            {
                int referenceId = bits >> 1;
                return(GetObjectFromCache(AMF3ObjectTypeCode.Object, referenceId));
            }

            // Handle cached class definitions.
            ASClass classDefinition;

            if ((bits & 2) == 0)
            {
                int referenceId = bits >> 2;

                // Note: Object might be an ASExternalizableObject.
                IASValue obj = GetObjectFromCache(AMF3ObjectTypeCode.Object, referenceId);
                classDefinition = obj.Class;
            }
            else
            {
                // Read the class definition.
                ASClassLayout classLayout = (ASClassLayout)((bits & 0x0c) >> 2);
                if (classLayout > ASClassLayout.Dynamic)
                {
                    throw new AMFException(String.Format(CultureInfo.CurrentCulture,
                                                         ExceptionPrefix + "Encountered Object token with invalid class layout '{0}'.", classLayout));
                }

                int memberCount = bits >> 4;
                if (memberCount < 0)
                {
                    throw new AMFException(String.Format(CultureInfo.CurrentCulture,
                                                         ExceptionPrefix + "Encountered Object token with invalid member count '{0}'.", memberCount));
                }

                if (classLayout == ASClassLayout.Externalizable && memberCount != 0)
                {
                    throw new AMFException(String.Format(CultureInfo.CurrentCulture,
                                                         ExceptionPrefix + "Encountered Object token with Externalizable class layout and non-zero member count '{0}'.", memberCount));
                }

                string classAlias = ReadStringData();

                string[] memberNames;
                if (memberCount != 0)
                {
                    memberNames = new string[memberCount];

                    for (int i = 0; i < memberCount; i++)
                    {
                        memberNames[i] = ReadStringData();
                    }
                }
                else
                {
                    memberNames = EmptyArray <string> .Instance;
                }

                // Look up the class in the cache.
                classDefinition = ASClassCache.GetClass(classAlias, classLayout, memberNames);
            }

            // Read the instance data.
            if (classDefinition.Layout == ASClassLayout.Externalizable)
            {
                // Important: Add the object to the cache before deserializing its properties!
                ASExternalizableObject result = ASExternalizableObject.CreateUninitializedInstance(classDefinition);
                AddObjectToCache(AMF3ObjectTypeCode.Object, result);

                // Use custom serialization for the externalizable object.
                IExternalizable externalizableValue = input.Serializer.CreateExternalizableInstance(classDefinition.ClassAlias);
                externalizableValue.ReadExternal(input);

                result.SetProperties(externalizableValue);
                return(result);
            }
            else
            {
                // Important: Add the object to the cache before deserializing its properties!
                ASObject result = ASObject.CreateUninitializedInstance(classDefinition);
                AddObjectToCache(AMF3ObjectTypeCode.Object, result);

                // Read the member values.
                int        memberCount = classDefinition.MemberNames.Count;
                IASValue[] memberValues;

                if (memberCount != 0)
                {
                    memberValues = new IASValue[memberCount];

                    for (int i = 0; i < memberCount; i++)
                    {
                        memberValues[i] = ReadObject();
                    }
                }
                else
                {
                    memberValues = EmptyArray <IASValue> .Instance;
                }

                // Read the dynamic property values.
                IDictionary <string, IASValue> dynamicProperties;

                if (classDefinition.Layout == ASClassLayout.Dynamic)
                {
                    string key = ReadStringData();
                    if (key.Length != 0)
                    {
                        dynamicProperties = new Dictionary <string, IASValue>();

                        for (; ;)
                        {
                            IASValue value = ReadObject();
                            dynamicProperties.Add(key, value);

                            key = ReadStringData();
                            if (key.Length == 0)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        dynamicProperties = EmptyDictionary <string, IASValue> .Instance;
                    }
                }
                else
                {
                    dynamicProperties = EmptyDictionary <string, IASValue> .Instance;
                }

                result.SetProperties(memberValues, dynamicProperties);
                return(result);
            }
        }