예제 #1
0
        public bool Initialzie()
        {
            //get template
            Template = SirenFactory.Create(Attribute.Template) as ISirenTemplate;
            if (Template == null)
            {
                return(false);
            }

            if (Type.IsEnum)
            {
                return(true);
            }

            //get methods
            SerializeMethodInfo   = Type.GetMethod("Serialize", BindingFlags.Public | BindingFlags.Instance);
            DeserializeMethodInfo = Type.GetMethod("Deserialize", BindingFlags.Public | BindingFlags.Instance);
            RegisterMethodInfo    = Type.GetMethod("Register", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
            if (RegisterMethodInfo != null && !Type.ContainsGenericParameters)
            {
                RegisterMethodInfo.Invoke(null, null);
            }


            //get properties
            uint   index      = 0;
            ushort id         = GetBasePropertyCount();
            var    properties = Type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);

            foreach (var propertyInfo in properties)
            {
                SirenPropertyAttribute propertyAttribute = propertyInfo.GetCustomAttribute <SirenPropertyAttribute>();
                if (propertyAttribute != null)
                {
                    SirenProperty property = new SirenProperty(this, propertyInfo, propertyAttribute, index++, id++);
                    Properties.Add(property);
                    PropertyIdDict.Add(property.Id, property);
                    PropertyNameDict.Add(property.Name, property);
                }
            }

            if (Properties.Count == 0)
            {
                if (Type.BaseType == typeof(object) || Type.BaseType.IsValueType)
                {
                    return(false);
                }
            }


            //get include types
            foreach (var property in Properties)
            {
                var type = property.Type;
                if (type.IsGenericType)
                {
                    if (type.Name.StartsWith("List"))
                    {
                        var valueType = type.GenericTypeArguments[0];
                        AddIncludeType(valueType);
                    }
                    else if (type.Name.StartsWith("Dictionary"))
                    {
                        var keyType   = type.GenericTypeArguments[0];
                        var valueType = type.GenericTypeArguments[1];
                        AddIncludeType(keyType);
                        AddIncludeType(valueType);
                    }
                    else
                    {
                        AddIncludeType(type);
                    }
                }
                else
                {
                    AddIncludeType(type);
                }
            }

            if (Type.BaseType != typeof(object) && !Type.BaseType.IsValueType)
            {
                //has base type
                if (!IncludeTypes.Contains(Type.BaseType))
                {
                    IncludeTypes.Add(Type.BaseType);
                }

                BaseSirenClass = SirenFactory.FindClass(Type.BaseType);
                if (BaseSirenClass != null)
                {
                    //add base properties
                    foreach (var sirenProperty in BaseSirenClass.PropertyIdDict)
                    {
                        PropertyIdDict.Add(sirenProperty.Key, sirenProperty.Value);
                    }

                    foreach (var sirenProperty in BaseSirenClass.PropertyNameDict)
                    {
                        PropertyNameDict.Add(sirenProperty.Key, sirenProperty.Value);
                    }
                }
            }


            return(true);
        }
예제 #2
0
        public void DeserializeBase(ref object obj, SirenClass sirenClass)
        {
            if (sirenClass.BaseSirenClass != null)
            {
                DeserializeBase(ref obj, sirenClass.BaseSirenClass);
            }

            foreach (var sirenProperty in sirenClass.Properties)
            {
                while (true)
                {
                    if (Reader.IsEnd())
                    {
                        Console.WriteLine("Reach end of file.Cannot find property {0}.{1}", sirenClass.Name, sirenProperty.Name);
                        Reader.OnError();
                        return;
                    }

                    ushort         outId;
                    SirenFieldType outDataType;
                    int            result = Reader.OnPropertyBegin(sirenProperty.Name, sirenProperty.Id, sirenProperty.DataType, out outId, out outDataType);
                    if (result == 0)
                    {
                        object val = null;

                        switch (sirenProperty.FieldType)
                        {
                        case SirenPropertyFieldType.Value:
                        case SirenPropertyFieldType.String:
                        case SirenPropertyFieldType.Blob:
                            DeserializeHelper(sirenProperty.Type, ref val, sirenProperty.ValueSirenClass);
                            break;

                        case SirenPropertyFieldType.Struct:
                        case SirenPropertyFieldType.Pointer:
                            val = SirenFactory.Create(sirenProperty.Type);
                            DeserializeHelper(sirenProperty.Type, ref val, sirenProperty.ValueSirenClass);
                            break;

                        case SirenPropertyFieldType.List:
                        {
                            val = SirenFactory.Create(sirenProperty.Type);
                            SirenFieldType valueDataType;
                            int            count;
                            Reader.OnListBegin(out valueDataType, out count);        //get count and type
                            var addMethod = sirenProperty.Type.GetMethod("Add");
                            for (int i = 0; i < count; i++)
                            {
                                var listItem = SirenFactory.Create(sirenProperty.ValueType);
                                DeserializeHelper(sirenProperty.ValueType, ref listItem, sirenProperty.ValueSirenClass);
                                addMethod.Invoke(val, new[] { listItem });
                            }
                            Reader.OnListEnd();
                        }

                        break;

                        case SirenPropertyFieldType.Dictionary:
                        {
                            val = SirenFactory.Create(sirenProperty.Type);

                            SirenFieldType keyDataType;
                            SirenFieldType valueDataType;
                            int            count;
                            Reader.OnDictionaryBegin(out keyDataType, out valueDataType, out count);        //get count and type
                            var addMethod = sirenProperty.Type.GetMethod("Add");
                            for (int i = 0; i < count; i++)
                            {
                                var dictKey   = SirenFactory.Create(sirenProperty.KeyType);
                                var dictValue = SirenFactory.Create(sirenProperty.ValueType);

                                DeserializeHelper(sirenProperty.KeyType, ref dictKey, sirenProperty.KeySirenClass);
                                DeserializeHelper(sirenProperty.ValueType, ref dictValue, sirenProperty.ValueSirenClass);
                                addMethod.Invoke(val, new[] { dictKey, dictValue });
                            }

                            Reader.OnDictionaryEnd();
                        }
                        break;
                        }
                        sirenProperty.Info.SetValue(obj, val);
                        Reader.OnPropertyEnd();
                        break;
                    }
                    else if (result < 0)
                    {
                        //Current filed missed
                        if (sirenProperty.Attribute.Modifier == SirenFieldModifier.Required)
                        {
                            //cannot find this property
                            Console.WriteLine("Cannot find property {0}.{1}", sirenClass.Name, sirenProperty.Name);
                            Reader.OnError();
                            return;
                        }
                        else
                        {
                            sirenProperty.SetToDefault(obj);
                            break;
                        }
                    }
                    else
                    {
                        //Read unknown field
                        //skip current field
                        Reader.OnPropertySkip(sirenProperty.DataType);
                        //read next field
                    }
                }
            }
        }