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)); }
private IASValue ReadTypedObject() { string classAlias = input.ReadShortString(); return(ReadObjectWithClass(ASClassCache.GetClass(classAlias, ASClassLayout.Dynamic, EmptyArray <string> .Instance))); }
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); }
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); } }