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); }
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); } } }
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); } } }
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(); } }
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); }
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(); } }
public void SerializeStruct(object obj, SirenCustomClass sirenClass) { Writer.OnStructBegin(); SerializeBase(obj, sirenClass); Writer.OnStructEnd(); }
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 } } } }
public void DeserializeStruct(ref object obj, SirenCustomClass sirenClass) { Reader.OnStructBegin(); DeserializeBase(ref obj, sirenClass); Reader.OnStructEnd(); }