Beispiel #1
0
        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);
        }