private SerializedClass DeserializeClass(BinaryReader reader) { var value = new SerializedClass(DeserializeDefaults(reader)); var count = reader.ReadInt32(); for (int i = 0; i < count; i++) { var name = reader.ReadString(); var mode = (ESerializableMode)reader.ReadInt32(); switch (mode) { case ESerializableMode.Primitive: value.Add(name, DeserializePrimitive(reader)); break; case ESerializableMode.Enum: value.Add(name, DeserializeEnum(reader)); break; case ESerializableMode.List: value.Add(name, DeserializeList(reader)); break; case ESerializableMode.Class: value.Add(name, DeserializeClass(reader)); break; default: break; } } return(value); }
private void WriteClass(BinaryWriter writer, SerializedClass obj) { WriteDefaults(writer, obj); writer.Write(obj.Values.Count); foreach (var item in obj.Values) { writer.Write(item.Key); writer.Write((int)item.Value.Mode); switch (item.Value.Mode) { case ESerializableMode.Primitive: WritePrimitive(writer, (SerializedPrimitive)item.Value); break; case ESerializableMode.Enum: WriteEnum(writer, (SerializedEnum)item.Value); break; case ESerializableMode.List: WriteList(writer, (SerializedList)item.Value); break; case ESerializableMode.Class: WriteClass(writer, (SerializedClass)item.Value); break; default: break; } } }
public static byte[] Serialize(SerializedClass obj) { var s = new ByteSerializer(); var stream = new MemoryStream(); var writer = new BinaryWriter(stream); s.WriteClass(writer, obj); writer.Flush(); writer.Close(); var buffer = stream.GetBuffer(); return(buffer); }
private object ReadClass(SerializedClass value) { if (value.IsNull) { return(null); } var type = Type.GetType(value.Type); object instance = null; if (value.IsReference) { if (deserializedObjects.ContainsKey(value.ID)) { return(deserializedObjects[value.ID]); } } try { instance = Activator.CreateInstance(type, true); } catch (MissingMethodException) { // No constructor deserializedObjects.Add(value.ID, null); return(null); } var fields = SerializationHelper.GetFields(type, BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic) .Where(f => (f.IsPublic && f.GetCustomAttributes(typeof(IgnoreSerializationAttribute), false).Length == 0) || (f.IsPrivate && f.GetCustomAttributes(typeof(RequireSerializationAttribute), false).Length == 1)) .OrderBy(f => f.Name).ToList(); var properties = SerializationHelper.GetProperties(type, BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic) .Where(p => p.CanRead && p.CanWrite) .Where(p => p.GetCustomAttributes(typeof(IgnoreSerializationAttribute), false).Length == 0) .OrderBy(p => p.Name).ToList(); foreach (var item in value.Values) { var name = item.Key.Substring(0, item.Key.IndexOf('|')); object tValue = Read(item.Value); var field = fields.Where(f => f.Name == name).FirstOrDefault(); if (field != null) { fields.Remove(field); try { field.SetValue(instance, tValue); } catch (Exception e) { Debug.LogException(e); } continue; } var property = properties.Where(p => p.Name == name).FirstOrDefault(); if (property != null) { properties.Remove(property); try { property.SetValue(instance, tValue, null); } catch (Exception e) { Debug.LogException(e); } continue; } } if (instance is FakeType) { var ft = (FakeType)instance; var v = ft.GetValue(); deserializedObjects.Add(value.ID, v); instance = v; } else { deserializedObjects.Add(value.ID, instance); } return(instance); }
private SerializedClass SerializeClass(object value, Type valueType) { if (value == null) { return(new SerializedClass(GetNextID(), valueType.AssemblyQualifiedName) { IsNull = true }); } if (valueType == typeof(UnityEngine.Texture2D) || valueType == typeof(UnityEngine.GUIStyle) || valueType == typeof(UnityEngine.GUISkin) || valueType == typeof(UnityEngine.GameObject)) { return(new SerializedClass(GetNextID(), valueType.AssemblyQualifiedName) { IsNull = true }); } var obj = new SerializedClass(GetNextID(), valueType.AssemblyQualifiedName); if (Compare(value, valueType, ref obj.ID)) { obj.IsReference = true; return(obj); } else { AddToComparables(obj, value, valueType); } var fields = SerializationHelper.GetFields(valueType, BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic) .Where(f => (f.IsPublic && f.GetCustomAttributes(typeof(IgnoreSerializationAttribute), false).Length == 0) || (f.IsPrivate && f.GetCustomAttributes(typeof(RequireSerializationAttribute), false).Length == 1)) .OrderBy(f => f.Name).ToList(); var properties = SerializationHelper.GetProperties(valueType, BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic) .Where(p => p.CanRead && p.CanWrite) .Where(p => p.GetCustomAttributes(typeof(IgnoreSerializationAttribute), false).Length == 0) .OrderBy(p => p.Name).ToList(); try { for (int i = 0; i < fields.Count; i++) { var field = fields[i]; var type = field.FieldType; var tValue = field.GetValue(value); var fname = string.Format("{0}|{1}", field.Name, i); if (type == typeof(object) && tValue != null) { type = tValue.GetType(); } if ((type.ToString() == "System.MonoType" && tValue != null) || type == typeof(Type)) { var t = (Type)tValue; var v = ""; try { v = t.AssemblyQualifiedName; } catch (Exception) { } obj.Add(fname, SerializeClass(new FakeType(v), typeof(FakeType))); } else if (type.IsArray()) { obj.Add(fname, SerializeList(tValue, type)); } else if (type.IsEnum) { obj.Add(fname, SerializeEnum(tValue, type)); } else if (type.IsValueType && !type.IsPrimitive) { if (type == typeof(decimal)) { obj.Add(fname, SerializePrimitive(tValue, type)); } else { obj.Add(fname, SerializeClass(tValue, type)); } } else if (type.IsValueType) { obj.Add(fname, SerializePrimitive(tValue, type)); } else if (type.IsClass) { if (type == typeof(string)) { obj.Add(fname, SerializePrimitive(tValue, type)); } else if (type.IsList()) { obj.Add(fname, SerializeList(tValue, type)); } else { obj.Add(fname, SerializeClass(tValue, type)); } } } for (int i = 0; i < properties.Count; i++) { var property = properties[i]; var type = property.PropertyType; if (property.GetIndexParameters().Length > 0) { continue; } var tValue = property.GetValue(value, null); var pname = string.Format("{0}|{1}", property.Name, i); if (type == typeof(object) && tValue != null) { type = tValue.GetType(); } if (type.ToString() == "System.MonoType" && tValue != null) { var t = (Type)tValue; var v = ""; try { v = t.AssemblyQualifiedName; } catch (Exception) { } obj.Add(pname, SerializeClass(new FakeType(v), typeof(FakeType))); } else if (type.IsArray()) { obj.Add(pname, SerializeList(tValue, type)); } else if (type.IsEnum) { obj.Add(pname, SerializeEnum(tValue, type)); } else if (type.IsValueType && !type.IsPrimitive) { if (type == typeof(double)) { obj.Add(pname, SerializePrimitive(tValue, type)); } else { obj.Add(pname, SerializeClass(tValue, type)); } } else if (type.IsValueType) { obj.Add(pname, SerializePrimitive(tValue, type)); } else if (type.IsClass) { if (type == typeof(string)) { obj.Add(pname, SerializePrimitive(tValue, type)); } else if (type.IsList()) { obj.Add(pname, SerializeList(tValue, type)); } else { obj.Add(pname, SerializeClass(tValue, type)); } } } } catch (Exception) { // pretty ugly but doing this to prevent MissingReferenceExcpetion which apparently isn't catchable obj.IsNull = true; return(obj); } return(obj); }