public virtual ClassDefinition GetClassDefinition(object instance) { Type type = instance.GetType(); StringBuilder sb = new StringBuilder(); sb.AppendFormat("Creating class definition for typed {0}", type.FullName); sb.Append("{"); List <string> memberNames = new List <string>(); List <ClassMember> classMemberList = new List <ClassMember>(); PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); for (int i = 0; i < propertyInfos.Length; i++) { PropertyInfo propertyInfo = propertyInfos[i]; string name = propertyInfo.Name; if (propertyInfo.GetGetMethod() == null || propertyInfo.GetSetMethod() == null || propertyInfo.GetGetMethod().GetParameters().Length > 0) { //The gateway will not be able to access this property continue; } if (memberNames.Contains(name)) { continue; } memberNames.Add(name); BindingFlags bf = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; try { PropertyInfo propertyInfoTmp = type.GetProperty(name); Unreferenced.Parameter(propertyInfoTmp); } catch (AmbiguousMatchException) { bf = BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance; } object[] attributes = propertyInfo.GetCustomAttributes(false); ClassMember classMember = new ClassMember(name, bf, propertyInfo.MemberType, attributes); classMemberList.Add(classMember); if (i != 0) { sb.Append(", "); } sb.Append(name); } FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Instance); for (int i = 0; i < fieldInfos.Length; i++) { FieldInfo fieldInfo = fieldInfos[i]; if (fieldInfo.GetCustomAttributes(typeof(NonSerializedAttribute), true).Length > 0) { continue; } string name = fieldInfo.Name; object[] attributes = fieldInfo.GetCustomAttributes(false); ClassMember classMember = new ClassMember(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance, fieldInfo.MemberType, attributes); classMemberList.Add(classMember); if (i != 0 && propertyInfos.Length > 0) { sb.Append(", "); } sb.Append(name); } ClassMember[] classMembers = classMemberList.ToArray(); string customClassName = ObjectFactory.GetCustomClass(type); ClassDefinition classDefinition = new ClassDefinition(customClassName, classMembers, GetIsExternalizable(instance), GetIsDynamic(instance)); return(classDefinition); }
public void WriteAMF3Object(object value) { if (!_objectReferences.ContainsKey(value)) { _objectReferences.Add(value, _objectReferences.Count); ClassDefinition classDefinition = GetClassDefinition(value); if (classDefinition == null) { DebugX.LogError("serializing:{0}", value.GetType().FullName); return; } if (_classDefinitionReferences.ContainsKey(classDefinition)) { //Existing class-def int handle = (int)_classDefinitionReferences[classDefinition];//handle = classRef 0 1 handle = handle << 2; handle = handle | 1; WriteAMF3IntegerData(handle); } else { //inline class-def //classDefinition = CreateClassDefinition(value); _classDefinitionReferences.Add(classDefinition, _classDefinitionReferences.Count); //handle = memberCount dynamic externalizable 1 1 int handle = classDefinition.MemberCount; handle = handle << 1; handle = handle | (classDefinition.IsDynamic ? 1 : 0); handle = handle << 1; handle = handle | (classDefinition.IsExternalizable ? 1 : 0); handle = handle << 2; handle = handle | 3; WriteAMF3IntegerData(handle); WriteAMF3UTF(classDefinition.ClassName); for (int i = 0; i < classDefinition.MemberCount; i++) { string key = classDefinition.Members[i].Name; WriteAMF3UTF(key); } } //write inline object if (classDefinition.IsExternalizable) { if (value is IExternalizable) { IExternalizable externalizable = value as IExternalizable; DataOutput dataOutput = new DataOutput(this); externalizable.WriteExternal(dataOutput); } else { throw new NotImplementedException(classDefinition.ClassName + " must is IExternalizable"); } } else { Type type = value.GetType(); IObjectProxy proxy = ObjectProxyRegistry.GetObjectProxy(type); for (int i = 0; i < classDefinition.MemberCount; i++) { object memberValue = proxy.GetValue(value, classDefinition.Members[i]); WriteAMF3Data(memberValue); } if (classDefinition.IsDynamic) { IDictionary dictionary = value as IDictionary; foreach (DictionaryEntry entry in dictionary) { WriteAMF3UTF(entry.Key.ToString()); WriteAMF3Data(entry.Value); } WriteAMF3UTF(string.Empty); } } } else { //handle = objectRef 0 int handle = (int)_objectReferences[value]; handle = handle << 1; WriteAMF3IntegerData(handle); } }
private object ReadAMF3Object(AMFReader reader, IConfigVODB configVodb) { int handle = reader.ReadAMF3IntegerData(); bool inline = ((handle & 1) != 0); handle = handle >> 1; if (!inline) { //An object reference return(reader.ReadAMF3ObjectReference(handle)); } bool inlineClassDef = ((handle & 1) != 0); handle = handle >> 1; if (inlineClassDef) { //inline class-def string typeIdentifier = reader.ReadAMF3String(); //flags that identify the way the object is serialized/deserialized bool externalizable = ((handle & 1) != 0); handle = handle >> 1; bool dynamic = ((handle & 1) != 0); handle = handle >> 1; ClassMember[] members = null; if (handle > 0) { members = new ClassMember[handle]; for (int i = 0; i < handle; i++) { string name = reader.ReadAMF3String(); ClassMember classMember = new ClassMember(name, BindingFlags.Default, MemberTypes.Custom, null); members[i] = classMember; } } classDefinition = new ClassDefinition(typeIdentifier, members, externalizable, dynamic); reader.AddClassReference(classDefinition); } else { classDefinition = reader.ReadClassReference(handle); } object instance = configVodb.dbInstanceCreater(); reader.AddAMF3ObjectReference(instance); for (int i = 0; i < classDefinition.MemberCount; i++) { string key = classDefinition.Members[i].Name; object value = reader.ReadAMF3Data(); reader.SetMember(instance, key, value); } if (classDefinition.IsDynamic) { string key = reader.ReadAMF3String(); object value; while (key != null && key != string.Empty) { value = reader.ReadAMF3Data(); if (fieldInfosDic.TryGetValue(key, out fieldInfo)) { configVodb.instanceFieldBind(instance, fieldInfo, value); } else if (fieldInfosDic.TryGetValue("__" + key, out fieldInfo)) { configVodb.instanceFieldBind(instance, fieldInfo, value); } else { configVodb.instanceFieldBind(instance, key, value); } key = reader.ReadAMF3String(); } } return(instance); }