Пример #1
0
        public static SirenCustomClass FindClass(Type type)
        {
            if (type.IsPrimitive || type == typeof(string) || type == typeof(byte[]))
            {
                return(null);
            }

            SirenCustomClass sirenClass;

            if (AllSirenClasses.TryGetValue(type, out sirenClass))
            {
                return(sirenClass);
            }

            if (GenerictSirenClasses.TryGetValue(type, out sirenClass))
            {
                return(sirenClass);
            }

            if (type.IsGenericType)
            {
                Type testType = null;
                foreach (var temp in AllSirenClasses)
                {
                    var oldType = temp.Key;
                    if (oldType.IsGenericTypeDefinition)
                    {
                        testType = oldType.MakeGenericType(type.GetGenericArguments());
                        if (testType == type)
                        {
                            var attr2 = type.GetCustomAttributes(typeof(SirenClassAttribute), false);
                            if (attr2.Length <= 0)
                            {
                                return(null);
                            }


                            sirenClass = new SirenCustomClass(type, attr2[0] as SirenClassAttribute);
                            sirenClass.Initialize();
                            break;
                        }
                        testType = null;
                    }
                }

                if (testType != null)
                {
                    GenerictSirenClasses.Add(testType, sirenClass);
                }
            }

            return(sirenClass);
        }
Пример #2
0
        public void SerializeHelper(object obj, SirenType sirenType)
        {
            if (sirenType.IsBuildIn)
            {
                switch (sirenType.Id)
                {
                case SirenTypeId.List:
                    break;

                case SirenTypeId.Dictionary:
                    break;

                case SirenTypeId.String:
                    Writer.OnString(obj as string);
                    break;

                case SirenTypeId.Blob:
                    Writer.OnMemoryData(obj as byte[]);
                    break;

                default:
                    Writer.OnValue(obj);
                    break;
                }
            }
            else
            {
                if (sirenType.IsCustomClass)
                {
                    SirenCustomClass sirenClass = sirenType as SirenCustomClass;
                    if (sirenClass.SerializeMethodInfo != null)
                    {
                        sirenClass.SerializeMethodInfo.Invoke(obj, new object[] { Writer });
                    }
                    else
                    {
                        SerializeStruct(obj, sirenClass);
                    }
                }
                else
                {
                    SerializeEnum(obj, sirenType as SirenCustomEnum);
                }
            }
        }
Пример #3
0
        public void DeserializeHelper(Type type, ref object obj, SirenType sirenType)
        {
            if (sirenType.IsBuildIn)
            {
                switch (sirenType.Id)
                {
                case SirenTypeId.List:
                    break;

                case SirenTypeId.Dictionary:
                    break;

                case SirenTypeId.String:
                    obj = Reader.OnString();
                    break;

                case SirenTypeId.Blob:
                    obj = Reader.OnMemoryData();
                    break;

                default:
                    obj = Reader.OnValue(type);
                    break;
                }
            }
            else
            {
                if (sirenType.IsCustomClass)
                {
                    SirenCustomClass sirenClass = sirenType as SirenCustomClass;
                    if (sirenClass.DeserializeMethodInfo != null)
                    {
                        sirenClass.DeserializeMethodInfo.Invoke(obj, new object[] { Reader });
                    }
                    else
                    {
                        DeserializeStruct(ref obj, sirenClass);
                    }
                }
                else
                {
                    obj = DeserializeEnum(sirenType as SirenCustomEnum);
                }
            }
        }
Пример #4
0
        static SirenMachine()
        {
            BuildinTypes.Add(Bool.Name, Bool);
            BuildinTypes.Add(Int8.Name, Int8);
            BuildinTypes.Add(UInt8.Name, UInt8);
            BuildinTypes.Add(Int16.Name, Int16);
            BuildinTypes.Add(UInt16.Name, UInt16);
            BuildinTypes.Add(Int32.Name, Int32);
            BuildinTypes.Add(UInt32.Name, UInt32);
            BuildinTypes.Add(Int64.Name, Int64);
            BuildinTypes.Add(UInt64.Name, UInt64);
            BuildinTypes.Add(Float.Name, Float);
            BuildinTypes.Add(Double.Name, Double);
            BuildinTypes.Add(String.Name, String);
            BuildinTypes.Add(Blob.Name, Blob);
            BuildinTypes.Add(List.Name, List);
            BuildinTypes.Add(Dictionary.Name, Dictionary);

            //alias
            BuildinTypes.Add("int8", Int8);
            BuildinTypes.Add("uint8", UInt8);
            BuildinTypes.Add("int16", Int16);
            BuildinTypes.Add("uint16", UInt16);
            BuildinTypes.Add("int32", Int32);
            BuildinTypes.Add("uint32", UInt32);
            BuildinTypes.Add("long", Int64);
            BuildinTypes.Add("ulong", UInt64);
            BuildinTypes.Add("string", String);
            BuildinTypes.Add("String", String);
            BuildinTypes.Add("blob", Blob);

            //register types
            var allAssemblies = GetAllAssemblies();

            foreach (var assemblyName in allAssemblies)
            {
                var assembly = Assembly.Load(assemblyName.Value);
                var types    = assembly.GetTypes();
                foreach (var type in types)
                {
                    var attr2 = type.GetCustomAttributes(typeof(SirenClassAttribute), false);
                    if (attr2.Length > 0)
                    {
                        SirenCustomClass sirenClass = new SirenCustomClass(type, attr2[0] as SirenClassAttribute);
                        AllSirenClasses.Add(type, sirenClass);
                    }

                    var attr3 = type.GetCustomAttributes(typeof(SirenEnumAttribute), false);
                    if (attr3.Length > 0)
                    {
                        SirenCustomEnum sirenEnum = new SirenCustomEnum(type, attr3[0] as SirenEnumAttribute);
                        AllSirenEnums.Add(type, sirenEnum);
                    }
                }
            }

            foreach (var sirenClass in AllSirenClasses)
            {
                sirenClass.Value.Initialize();
            }

            foreach (var sirenClass in AllSirenEnums)
            {
                sirenClass.Value.Initialize();
            }
        }
Пример #5
0
        public static SirenType FindType(Type type)
        {
            if (type.IsGenericType)
            {
                if (type.Name.StartsWith("List"))
                {
                    return(new SirenBuildinList(type));
                }
                if (type.Name.StartsWith("Dictionary"))
                {
                    return(new SirenBuildinDictionary(type));
                }
            }
            else
            {
                if (type.IsValueType)
                {
                    if (type == typeof(bool))
                    {
                        return(Bool);
                    }
                    if (type == typeof(char))
                    {
                        return(Int8);
                    }
                    if (type == typeof(short))
                    {
                        return(Int16);
                    }
                    if (type == typeof(int))
                    {
                        return(Int32);
                    }
                    if (type == typeof(Int64))
                    {
                        return(Int64);
                    }
                    if (type == typeof(byte))
                    {
                        return(UInt8);
                    }
                    if (type == typeof(ushort))
                    {
                        return(UInt16);
                    }
                    if (type == typeof(uint))
                    {
                        return(UInt32);
                    }
                    if (type == typeof(UInt64))
                    {
                        return(UInt64);
                    }
                    if (type == typeof(float))
                    {
                        return(Float);
                    }
                    if (type == typeof(double))
                    {
                        return(Double);
                    }
                }
                else
                {
                    if (type == typeof(string))
                    {
                        return(String);
                    }
                    if (type == typeof(byte[]))
                    {
                        return(Blob);
                    }
                }
            }


            SirenCustomClass sirenClass;

            if (AllSirenClasses.TryGetValue(type, out sirenClass))
            {
                return(sirenClass);
            }

            if (GenerictSirenClasses.TryGetValue(type, out sirenClass))
            {
                return(sirenClass);
            }

            SirenCustomEnum sirenEnum;

            if (AllSirenEnums.TryGetValue(type, out sirenEnum))
            {
                return(sirenEnum);
            }

            if (type.IsGenericType)
            {
                Type testType = null;
                foreach (var temp in AllSirenClasses)
                {
                    var oldType = temp.Key;
                    if (oldType.IsGenericTypeDefinition)
                    {
                        testType = oldType.MakeGenericType(type.GetGenericArguments());
                        if (testType == type)
                        {
                            var attr2 = type.GetCustomAttributes(typeof(SirenClassAttribute), false);
                            if (attr2.Length <= 0)
                            {
                                return(null);
                            }


                            sirenClass = new SirenCustomClass(type, attr2[0] as SirenClassAttribute);
                            sirenClass.Initialize();
                            break;
                        }
                        testType = null;
                    }
                }

                if (testType != null)
                {
                    GenerictSirenClasses.Add(testType, sirenClass);
                }
            }

            return(sirenClass);
        }
Пример #6
0
        public void SerializeBase(object obj, SirenCustomClass sirenClass)
        {
            if (sirenClass.BaseType != null)
            {
                SerializeBase(obj, sirenClass.BaseType);
            }

            foreach (var sirenField in sirenClass.Fields)
            {
                if (sirenField.Attribute.Mode != SirenFieldGenerateMode.Optional)
                {
                    if (!sirenField.HasValue(obj))
                    {
                        Logger.ErrorLine("Forget to set {0}.{1}", sirenClass.Name, sirenField.Name);
                        Writer.OnError();
                        return;
                    }
                }
                else
                {
                    if (!sirenField.HasValue(obj))
                    {
                        //skip
                        return;
                    }
                }

                Writer.OnFieldBegin(sirenField.Name, sirenField.Id, sirenField.DataType);

                switch (sirenField.FieldType)
                {
                case SirenPropertyFieldType.Value:
                    Writer.OnValue(sirenField.Info.GetValue(obj, null));
                    break;

                case SirenPropertyFieldType.String:
                    Writer.OnString(sirenField.Info.GetValue(obj, null) as string);
                    break;

                case SirenPropertyFieldType.Blob:
                    Writer.OnMemoryData(sirenField.Info.GetValue(obj, null) as byte[]);
                    break;

                case SirenPropertyFieldType.List:
                {
                    object items    = sirenField.Info.GetValue(obj, null);
                    var    listType = sirenField.Type;
                    int    count    = Convert.ToInt32(listType.Type.GetProperty("Count").GetValue(items, null));

                    var         itemType     = sirenField.Type.Type.GetGenericArguments()[0];
                    SirenTypeId itemDataType = SirenMachine.GetTypeId(itemType);
                    Writer.OnListBegin(itemDataType, count);
                    var itemsProperty = listType.Type.GetProperty("Item");
                    for (int i = 0; i < count; i++)
                    {
                        object listItem = itemsProperty.GetValue(items, new object[] { i });
                        SerializeHelper(listItem, sirenField.ValueType);
                    }
                    Writer.OnListEnd();
                }

                break;

                case SirenPropertyFieldType.Dictionary:
                {
                    object items    = sirenField.Info.GetValue(obj, null);
                    var    dictType = sirenField.Type;
                    int    count    = Convert.ToInt32(dictType.Type.GetProperty("Count").GetValue(items, null));

                    var keyType   = sirenField.Type.Type.GetGenericArguments()[0];
                    var valueType = sirenField.Type.Type.GetGenericArguments()[1];

                    SirenTypeId keyDataType   = SirenMachine.GetTypeId(keyType);
                    SirenTypeId valueDataType = SirenMachine.GetTypeId(valueType);


                    Writer.OnDictionaryBegin(keyDataType, valueDataType, count);

                    foreach (var o in (items as IEnumerable))
                    {
                        var itemKey = o.GetType().GetProperty("Key").GetValue(o, null);
                        SerializeHelper(itemKey, sirenField.KeyType);
                        var itemValue = o.GetType().GetProperty("Value").GetValue(o, null);
                        SerializeHelper(itemValue, sirenField.ValueType);
                    }

                    Writer.OnDictionaryEnd();
                }
                break;

                case SirenPropertyFieldType.Struct:
                {
                    object val = sirenField.Info.GetValue(obj, null);
                    SerializeHelper(val, sirenField.ValueType);
                }

                break;
                }

                Writer.OnFieldEnd();
            }
        }
Пример #7
0
 public void SerializeStruct(object obj, SirenCustomClass sirenClass)
 {
     Writer.OnStructBegin();
     SerializeBase(obj, sirenClass);
     Writer.OnStructEnd();
 }
Пример #8
0
        public void DeserializeBase(ref object obj, SirenCustomClass sirenClass)
        {
            if (sirenClass.BaseType != null)
            {
                DeserializeBase(ref obj, sirenClass.BaseType);
            }

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

                    ushort      outId;
                    SirenTypeId outDataType;
                    int         result = Reader.OnFieldBegin(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.Type, ref val, sirenProperty.Type);
                            break;

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

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

                        break;

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

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

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

                            Reader.OnDictionaryEnd();
                        }
                        break;
                        }

                        if (sirenProperty.DataType == SirenTypeId.Enum)
                        {
                            var enumObj = Enum.ToObject(sirenProperty.Info.PropertyType, val);
                            sirenProperty.Info.SetValue(obj, enumObj, null);
                        }
                        else
                        {
                            sirenProperty.Info.SetValue(obj, val, null);
                        }
                        Reader.OnFieldEnd();
                        break;
                    }
                    else if (result < 0)
                    {
                        //Current filed missed
                        if (sirenProperty.Attribute.Mode != SirenFieldGenerateMode.Optional)
                        {
                            //cannot find this property
                            Logger.ErrorLine("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.OnFieldSkip(sirenProperty.DataType);
                        //read next field
                    }
                }
            }
        }
Пример #9
0
 public void DeserializeStruct(ref object obj, SirenCustomClass sirenClass)
 {
     Reader.OnStructBegin();
     DeserializeBase(ref obj, sirenClass);
     Reader.OnStructEnd();
 }