public static BonValue ToBon(object obj, HashSet <string> fields = null, Type declareType = null) { if (obj == null) { return(BonNull.value); } Type t = obj.GetType(); switch (t.Name) { case "Byte": return((int)(byte)obj); case "SByte": return((int)(sbyte)obj); case "Int16": return((int)(short)obj); case "UInt16": return((int)(ushort)obj); case "Int32": return((int)obj); case "UInt32": return((int)(uint)obj); case "Int64": return((long)obj); case "UInt64": return((long)(ulong)obj); case "Single": return((float)obj); case "Double": return((double)obj); case "Boolean": return((bool)obj); case "String": return((string)obj); case "Byte[]": return((byte[])obj); default: { if (t.IsEnum) { return((int)obj); } break; } } switch (t.Name) { case "List`1": { Type et = t.GetGenericArguments()[0]; BonArray arr = null; arr = new BonArray(); IList list = (IList)obj; int num = list.Count; for (int i = 0; i < num; i++) { arr.Add(ToBon(list[i], fields, et)); } return(arr); } case "Dictionary`2": { Type et = t.GetGenericArguments()[1]; BonDocument doc = null; doc = new BonDocument(); foreach (DictionaryEntry kv in (IDictionary)obj) { if (kv.Key.GetType().IsEnum) { doc[((int)kv.Key).ToString()] = ToBon(kv.Value, fields, et); } else { doc[kv.Key.ToString()] = ToBon(kv.Value, fields, et); } } return(doc); } default: { if (t.IsArray) { Type et = t.GetElementType(); BonArray arr = null; arr = new BonArray(); Array list = (Array)obj; int num = list.Length; for (int i = 0; i < num; i++) { arr.Add(ToBon(list.GetValue(i), fields, et)); } return(arr); } { if (obj is IBon) { return(((IBon)obj).ToBon()); } ClassInfo ci = ClassInfo.Get(t); BonDocument doc = new BonDocument(); if (declareType != null && declareType != t) { doc["_t_"] = t.FullName; } FldInfo[] fis = ci.fields.Values; for (int i = fis.Length; --i >= 0;) { FldInfo fi = fis[i]; if (fields != null && !fields.Contains(fi.name)) { continue; } doc[fi.name] = ToBon(fi.GetValue(obj), fi.subFields); } return(doc); } } } }
private static object ReadObj(Type t, ReadArg arg) { DataReader br = arg.br; if (t == null) { int ti = br.Read7BitEncodedInt(); switch (ti) { case TYPE_NULL: return(null); case TYPE_REF: return(arg.objRef[br.Read7BitEncodedInt()]); } t = arg.typeRef[ti]; } switch (t.Name) { case "Int32": return(br.ReadInt32()); case "Int64": return(br.ReadInt64()); case "Single": return(br.ReadSingle()); case "Double": return(br.ReadDouble()); case "String": string s = br.ReadString(); arg.objRef.Add(s); return(s); case "UInt32": return(br.ReadUInt32()); case "UInt64": return(br.ReadUInt64()); case "Byte": return(br.ReadByte()); case "SByte": return(br.ReadSByte()); case "Int16": return(br.ReadInt16()); case "UInt16": return(br.ReadUInt16()); case "Boolean": return(br.ReadBoolean()); case "DateTime": return(DateTime.FromBinary(br.ReadInt64())); case "Vector2": return(new Vector2(br.ReadSingle(), br.ReadSingle())); case "Vector3": return(new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle())); default: { if (t.IsEnum) { return(Enum.ToObject(t, br.ReadInt32())); } if (t.IsArray) { Type t2 = t.GetElementType(); int num = br.Read7BitEncodedInt(); Array arr = Array.CreateInstance(t2, num); arg.objRef.Add(arr); Type rt = t2.IsClass ? null : t2; for (int i = 0; i < num; i++) { arr.SetValue(ReadObj(rt, arg), i); } return(arr); } if (typeof(IList).IsAssignableFrom(t)) { IList list = (IList)Activator.CreateInstance(t); arg.objRef.Add(list); Type t2 = null; if (t.IsGenericType) { t2 = t.GetGenericArguments()[0]; if (t2.IsClass) { t2 = null; } } int num = br.Read7BitEncodedInt(); for (int i = 0; i < num; i++) { list.Add(ReadObj(t2, arg)); } return(list); } if (typeof(IDictionary).IsAssignableFrom(t)) { IDictionary dic = (IDictionary)Activator.CreateInstance(t); arg.objRef.Add(dic); Type tk = null; Type tv = null; if (t.IsGenericType) { Type[] ts = t.GetGenericArguments(); tk = ts[0]; tv = ts[1]; if (tk.IsClass) { tk = null; } if (tv.IsClass) { tv = null; } } int num = br.Read7BitEncodedInt(); for (int i = 0; i < num; i++) { object key = ReadObj(tk, arg); object value = ReadObj(tv, arg); dic[key] = value; } return(dic); } { object obj = Activator.CreateInstance(t); if (t.IsClass) { arg.objRef.Add(obj); } ClassInfo ci = ClassInfo.Get(t); int num = br.Read7BitEncodedInt(); for (int i = 0; i < num; i++) { string name = (string)ReadObj(null, arg); object v = ReadObj(null, arg); FldInfo fi; if (ci.fields.TryGetValue(name, out fi)) { if (v == null) { if (fi.type.IsClass) { fi.SetValue(obj, null); } } else { Type vt = v.GetType(); if (fi.type.IsEnum && vt == typeof(int) || fi.type.IsAssignableFrom(vt)) { fi.SetValue(obj, v); } } } } return(obj); } } } }
public static object ToObj(BonValue v, Type t, object old, HashSet <string> fields = null) { if (v == null) { return(null); } switch (t.Name) { case "Byte": return((byte)v.AsInt); case "SByte": return((sbyte)v.AsInt); case "Int16": return((short)v.AsInt); case "UInt16": return((ushort)v.AsInt); case "Int32": return(v.AsInt); case "UInt32": return((uint)v.AsInt); case "Int64": return(v.AsLong); case "UInt64": return((ulong)v.AsLong); case "Single": return(v.AsFloat); case "Double": return(v.AsDouble); case "Boolean": return(v.AsBoolean); case "String": return(v.AsString); case "Byte[]": return(v.AsBinary); case "List`1": { BonArray arr = v.AsBonArray; if (arr == null) { return(null); } int num = arr.Count; IList l = null; if (old != null) { l = (IList)old; } else { l = (IList)Activator.CreateInstance(t, num); } Type t2 = t.GetGenericArguments()[0]; l.Clear(); for (int i = 0; i < num; i++) { l.Add(ToObj(arr[i], t2, null, fields)); } return(l); } case "Dictionary`2": { BonDocument doc = v.AsBonDocument; if (doc == null) { return(null); } int num = doc.Count; IDictionary d = null; if (old != null) { d = (IDictionary)old; } else { d = (IDictionary)Activator.CreateInstance(t, num); } Type[] t2s = t.GetGenericArguments(); Type tk = t2s[0]; Type t2 = t2s[1]; for (int i = 0; i < num; i++) { BonElement el = doc[i]; object key = null; switch (tk.Name) { case "Int32": key = Convert.ToInt32(el.name); break; case "Int64": key = Convert.ToInt64(el.name); break; case "String": key = el.name; break; default: { if (tk.IsEnum) { key = Enum.ToObject(tk, Convert.ToInt32(el.name)); } break; } } if (key != null) { BonValue v2 = el.value; object obj = null; if (d.Contains(key)) { obj = ToObj(v2, t2, d[key], fields); } else { obj = ToObj(v2, t2, null, fields); } if (obj == null) { d.Remove(key); } else { d[key] = obj; } } } return(d); } default: { if (t.IsEnum) { return(Enum.ToObject(t, v.AsInt)); } if (t.IsArray) { BonArray arr = v.AsBonArray; if (arr == null) { return(null); } int num = arr.Count; Type t2 = t.GetElementType(); var obj = Array.CreateInstance(t2, num); for (int i = 0; i < num; i++) { obj.SetValue(ToObj(arr[i], t2, null, fields), i); } return(obj); } if (!v.IsBonDocument) { return(null); } { BonDocument doc = v.AsBonDocument; string _t_ = doc.GetString("_t_"); if (_t_ != null) { try { t = Type.GetType(_t_); } catch (Exception) { Debug.LogWarning("δÕÒµ½ÀàÐÍ: " + doc["_t_"].AsString); return(null); } } ClassInfo ci = ClassInfo.Get(t); object obj = old; Dictionary <string, List <DataMonitor> > dataMonitors = null; bool monitorObj = false; if (old != null) { monitorObj = dataMonitor.TryGetValue(old, out dataMonitors); } if (obj == null) { obj = Activator.CreateInstance(t); } if (obj is IBon) { ((IBon)obj).FromBon(doc); return(obj); } CachedDictionary <string, FldInfo> fis = ci.fields; bool isValueType = t.IsValueType; int num = doc.Count; for (int i = 0; i < num; i++) { BonElement el = doc[i]; if (fields != null && !fields.Contains(el.name)) { continue; } FldInfo fi; if (fis.TryGetValue(el.name, out fi)) { List <DataMonitor> fieldMonitors = null; bool monitorField = monitorObj && dataMonitors.TryGetValue(fi.name, out fieldMonitors) && fieldMonitors.Count > 0; if ((fi.type.IsValueType || fi.type == typeof(string) || fi.type.IsEnum) && !monitorField) { fi.SetValue(obj, ToObj(el.value, fi.type, null, fi.subFields)); } else { object oldv = fi.GetValue(obj); object newv = ToObj(el.value, fi.type, oldv, fi.subFields); fi.SetValue(obj, newv); if (monitorField && (fi.type.IsClass || oldv != newv)) { dataChanged.AddRange(fieldMonitors); } } } } return(obj); } } } }
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; } } }