string Serialize(object data, bool includeType, Type binder) { var pre = data.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(m => m.GetCustomAttribute <PreSerializeAttribute>() != null); foreach (var m in pre) { m.Invoke(data, new object[] { }); } Type type = Bind(ref data, binder); SerializedType stype = new SerializedType(type); StringBuilder sb = new StringBuilder(); if (includeTypes) { if (includeType) { sb.Append(serializationTypes.AddType(type.FullName)); } sb.Append(':'); } if (stype.IsSerializable) { if (stype.IsIEnumerable || stype.IsArray) { var numerable = stype.GetElements(data); bool withType = false; if (includeTypes) { if (!HasDerivedElements((IEnumerable)data)) { withType = true; } } sb.Append(numerable.Count()); Split(sb); if (numerable.Count() > 0) { sb.Append(numerable.Select(e => Serialize(e, withType, null)).ToString("")); } } else if (stype.IsString && ((options & CSOptions.SafeString) != 0)) { sb.Append(((string)data).Length); Split(sb); sb.Append(data.ToString()); Split(sb); } else if (stype.IsComVisible) { sb.Append(data.ToString()); Split(sb); } else { Write(sb, data, stype.GetTypeFields()); } } else { Tuple <Type, VersionAttribute> tv; if (type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic).Select(t => new Tuple <Type, VersionAttribute>(t, t.GetCustomAttribute <VersionAttribute>())) .WithMax(t => t.Item2.version, t => t.Item2 != null, out tv)) { sb.Append(tv.Item2.version.ToString()); Split(sb); sb.Append(Serialize(data, false, tv.Item1)); } else { Write(sb, data, stype.GetTypeAll()); } } return(sb.ToString()); }
object Deserialize(Type ftype, Type binder, StreamReader reader) { if (includeTypes) { string sub; Extract(reader, out sub); if (sub != "") { ftype = GetType(serializationTypes.GetType(int.Parse(sub))); } } if (binder == null) { binder = Bind(ftype); } var stype = new SerializedType(binder); SerializeTemp result = new SerializeTemp(stype); if (stype.IsSerializable) { if (stype.IsIEnumerable || stype.IsArray) { Type elementType = null; if (binder.IsArray) { elementType = binder.GetElementType(); } else { elementType = binder.GetGenericArguments().First(); } string line = ""; Extract(reader, out line); int length = int.Parse(line); for (int i = 0; i < length; i++) { result.AddElement(Deserialize(elementType, null, reader)); } } else if (stype.IsString && ((options & CSOptions.SafeString) != 0)) { string line; Extract(reader, out line); int length = int.Parse(line); Extract(reader, out line, length); result.SetValue(line); } else if (stype.IsComVisible) { string line; Extract(reader, out line); result.SetValue(GetValue(binder, line)); } else { foreach (var sa in stype.GetTypeFields()) { result.AddElement(Deserialize(sa.fieldType, Bind(sa), reader)); } } return(result.GetResult()); } else { var vs = binder.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic).Select(t => new Tuple <Type, VersionAttribute>(t, t.GetCustomAttribute <VersionAttribute>())) .Where(t => t.Item2 != null).ToArray(); if (vs.Length == 0) { foreach (var ca in stype.GetTypeConstructorArgs()) { result.AddArg(Deserialize(Bind(ca), null, reader)); } foreach (var ad in stype.GetTypeFields()) { result.AddElement(Deserialize(Bind(ad), null, reader)); } var value = result.GetResult(); var postSerialize = binder.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) .Where(m => m.GetCustomAttribute <PostDeserializeAttribute>() != null); foreach (var m in postSerialize) { m.Invoke(value, null); } return(value is IBinder ? ((IBinder)value).GetResult() : value); } else { string line; Extract(reader, out line); int v = int.Parse(line); var value = Deserialize(binder, vs.First(t => t.Item2.version == v).Item1, reader); return(value is IBinder ? ((IBinder)value).GetResult() : value); } } }