public static ArraySegment <byte> Serialize(object obj) { var writer = new CompactBinaryWriter(); Serializer serializer = new Serializer(writer); serializer.SerializeHelper(obj, SirenMachine.GetType(obj.GetType())); return(writer.ToBuffer()); }
public static T Deserialize <T>(ArraySegment <byte> data) where T : class, new() { var reader = new CompactBinaryReader(); reader.Accept(data); Deserializer deserializer = new Deserializer(reader); object obj = new T(); deserializer.DeserializeHelper(typeof(T), ref obj, SirenMachine.GetType(typeof(T))); return((T)obj); }
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 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 } } } }