public static byte[] Serialize(object obj) { MemoryStream ms = new MemoryStream(); using (DataWriter bw = new DataWriter(ms)) { WriteArg arg = new WriteArg(bw); bw.Write(0); WriteObj(obj, true, arg); if (arg.typeRef.Count > basicTypes.Length) { bw.Seek(0, SeekOrigin.Begin); bw.Write((int)bw.BaseStream.Length - sizeof(int)); bw.Seek(0, SeekOrigin.End); bw.Write(arg.typeRef.Count - basicTypes.Length); for (int i = basicTypes.Length; i < arg.typeRef.Count; i++) { bw.Write(arg.typeRef[i].FullName); } } return(ms.ToArray()); } }
private static void WriteObj(object obj, bool writeType, WriteArg arg) { DataWriter bw = arg.bw; if (obj == null) { bw.Write(TYPE_NULL); return; } Type t = obj.GetType(); if (t.IsClass) { int r; if (arg.objRef.TryGetValue(obj, out r)) { bw.Write(TYPE_REF); bw.Write7BitEncodedInt(r); return; } else { arg.objRef[obj] = arg.objRef.Count; } } if (writeType) { bw.Write7BitEncodedInt(arg.AddType(t)); } switch (t.Name) { case "Int32": bw.Write((int)obj); break; case "Int64": bw.Write((long)obj); break; case "Single": bw.Write((float)obj); break; case "Double": bw.Write((double)obj); break; case "String": bw.Write((string)obj); break; case "UInt32": bw.Write((uint)obj); break; case "UInt64": bw.Write((ulong)obj); break; case "Byte": bw.Write((byte)obj); break; case "SByte": bw.Write((sbyte)obj); break; case "Int16": bw.Write((short)obj); break; case "UInt16": bw.Write((ushort)obj); break; case "Boolean": bw.Write((bool)obj); break; case "DateTime": bw.Write(((DateTime)obj).ToBinary()); break; case "Vector2": { Vector2 v2 = (Vector2)obj; bw.Write(v2.x); bw.Write(v2.y); break; } case "Vector3": { Vector3 v3 = (Vector3)obj; bw.Write(v3.x); bw.Write(v3.y); bw.Write(v3.z); break; } default: { if (t.IsEnum) { bw.Write((int)obj); return; } if (t.IsArray) { Array arr = (Array)obj; Type t2 = t.GetElementType(); bw.Write7BitEncodedInt(arr.Length); foreach (object obj2 in arr) { WriteObj(obj2, t2.IsClass, arg); } return; } if (typeof(IList).IsAssignableFrom(t)) { IList list = (IList)obj; Type t2 = null; if (t.IsGenericType) { t2 = t.GetGenericArguments()[0]; } bw.Write7BitEncodedInt(list.Count); bool wt = t2 == null || t2.IsClass; foreach (object obj2 in list) { WriteObj(obj2, wt, arg); } return; } if (typeof(IDictionary).IsAssignableFrom(t)) { Type tk = null; Type tv = null; if (t.IsGenericType) { Type[] ts = t.GetGenericArguments(); tk = ts[0]; tv = ts[1]; } IDictionary dic = (IDictionary)obj; bw.Write7BitEncodedInt(dic.Count); bool wtk = tk == null || tk.IsClass; bool wtv = tv == null || tv.IsClass; foreach (DictionaryEntry kv in dic) { WriteObj(kv.Key, wtk, arg); WriteObj(kv.Value, wtv, arg); } return; } { ClassInfo ci = ClassInfo.Get(t); bw.Write7BitEncodedInt(ci.fields.Count); foreach (FldInfo fi in ci.fields.Values) { WriteObj(fi.name, true, arg); WriteObj(fi.GetValue(obj), true, arg); } } break; } } }