public BonDocument GetBonDocument(string name, BonDocument defaultValue = null) { BonElement el; if (elements.TryGetValue(name, out el)) { return(el.value.AsBonDocument); } return(defaultValue); }
public void Encode(BonDocument v) { if (this.format) { sb.Append('{'); int c = v.Count; if (c > 0) { sb.Append('\n'); this.indent += 2; for (int i = 0; i < c; i++) { var elem = v[i]; if (i > 0) { sb.Append(",\n"); } WriteIndent(); sb.Append('\"'); sb.Append(elem.name); sb.Append("\":"); Encode(elem.value); } sb.Append('\n'); this.indent -= 2; WriteIndent(); } sb.Append('}'); } else { sb.Append('{'); int c = v.Count; for (int i = 0; i < c; i++) { var elem = v[i]; if (i > 0) { sb.Append(','); } sb.Append('\"'); sb.Append(elem.name); sb.Append("\":"); Encode(elem.value); } sb.Append('}'); } }
private BonDocument NextDocument() { BonDocument d = new BonDocument(); while (true) { char c = NextToken(); if (c == '}') { break; } if (c != '\"')// && c != '\'') { throw SyntaxError("Document error"); } string k = GetNextString(); if (NextToken() != ':') { throw SyntaxError("Document error"); } BonValue v = NextValue(); d[k] = v; c = NextToken(); if (c == '}') { break; } if (c != ',') { string txt = ""; int ends = myIndex + 20; ends = ends < (mySource.Length - 1) ? ends : mySource.Length - 1; for (int i = myIndex - 1; i < myIndex + 10; i++) { txt += mySource[i]; } throw SyntaxError("Document error token [" + txt + "]"); } } return(d); }
public Enumerator(BonDocument doc) { this.map = doc.elements; this.keys = doc.keys.GetEnumerator(); current = BonElement.Empty; }
internal static object ToObject(this BonValue v, object obj, Type t) { 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 "DateTime": return(v.AsDateTime); } switch (t) { case var _ when t == typeof(object) || t == typeof(BonValue): return(v); case var _ when typeof(BonValue).IsAssignableFrom(t): { if (v.GetType() != t) { return(null); } return(v); } case var _ when typeof(IList).IsAssignableFrom(t) && t.IsGenericType: { BonArray arr = v.AsBonArray; if (arr == null) { return(null); } int num = arr.Count; if (!(obj is IList l)) { l = (IList)Activator.CreateInstance(t, num); } Type t2 = t.GetGenericArguments()[0]; l.Clear(); for (int i = 0; i < num; i++) { l.Add(ToObject(arr[i], null, t2)); } return(l); } case var _ when typeof(IDictionary).IsAssignableFrom(t) && t.IsGenericType: { BonDocument doc = v.AsBonDocument; if (doc == null) { return(null); } int num = doc.Count; if (!(obj is IDictionary d)) { 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 elem = doc[i]; object key = null; switch (tk.Name) { case "UInt32": key = Convert.ToUInt32(elem.name); break; case "Int32": key = Convert.ToInt32(elem.name); break; case "Int64": key = Convert.ToInt64(elem.name); break; case "UInt64": key = Convert.ToUInt64(elem.name); break; case "String": key = elem.name; break; default: { if (tk.IsEnum) { key = Enum.ToObject(tk, Convert.ToInt32(elem.name)); } break; } } if (key != null) { BonValue v2 = elem.value; object vobj = null; if (d.Contains(key)) { vobj = ToObject(v2, d[key], t2); } else { vobj = ToObject(v2, null, t2); } if (vobj == null) { d.Remove(key); } else { d[key] = vobj; } } } return(d); } case var _ when t.IsEnum: { return(Enum.ToObject(t, v.AsInt)); } case var _ when t.IsArray: { BonArray arr = v.AsBonArray; if (arr == null) { return(null); } int num = arr.Count; Type t2 = t.GetElementType(); var a = Array.CreateInstance(t2, num); for (int i = 0; i < num; i++) { a.SetValue(ToObject(arr[i], null, t2), i); } return(a); } default: { if (!v.IsBonDocument) { return(null); } { BonDocument doc = v.AsBonDocument; string _t_ = doc.GetString("_t_"); TypeInfo ti = null; if (_t_ != null) { ti = TypeInfo.Of(_t_); if (ti == null) { Debug.LogError("未找到类型: " + _t_); } } else { ti = TypeInfo.Of(t); } if (ti == null) { return(null); } if (obj != null && obj.GetType() != t) { obj = null; } if (obj == null) { obj = Activator.CreateInstance(t); } bool isValueType = t.IsValueType; int num = doc.Count; for (int i = 0; i < num; i++) { BonElement el = doc[i]; if (!ti.aliasProps.TryGetValue(el.name, out var pi) || !pi.canWrite) { continue; } var oldv = pi.GetValue(obj); var newv = ToObject(el.value, oldv, pi.type); pi.SetValue(obj, newv); } return(obj); } } } }
private static BonValue ToBon(object obj, Type dt, Config cfg, Dictionary <object, BonValue> anti) { if (obj == null) { return(BonNull.value); } Type t = obj.GetType(); switch (obj) { case byte vv: return((int)vv); case sbyte vv: return((int)vv); case short vv: return((int)vv); case ushort vv: return((int)vv); case int vv: return(vv); case uint vv: return((int)vv); case long vv: return(vv); case ulong vv: return((long)vv); case float vv: return(vv); case double vv: return(vv); case bool vv: return(vv); case string vv: return(vv); case byte[] vv: return(vv); case DateTime vv: return(vv); case var _ when obj is Enum: return((int)obj); case BonValue vv: return(vv); case Array vv: { Type et = t.GetElementType(); BonArray arr = new BonArray(); foreach (object i in vv) { BonValue v2 = ToBon(i, et, cfg, anti); arr.Add(v2); } return(arr); } case IList vv when t.IsGenericType: { Type et = t.GenericTypeArguments[0]; BonArray arr = new BonArray(); foreach (object i in vv) { BonValue v2 = ToBon(i, et, cfg, anti); arr.Add(v2); } return(arr); } case IDictionary vv when t.IsGenericType: { Type kt = t.GetGenericArguments()[0]; Type et = t.GetGenericArguments()[1]; BonDocument doc = new BonDocument(); foreach (DictionaryEntry kv in vv) { string name = null; if (kt.IsEnum) { name = ((int)kv.Key).ToString(); } else { name = kv.Key.ToString(); } if (name == null) { continue; } BonValue v2 = ToBon(kv.Value, et, cfg, anti); doc[name] = v2; } return(doc); } default: { if (cfg.debug) { if (anti.TryGetValue(obj, out var bon)) { return(new BonDocument { ["_ref_"] = bon.AsBonDocument["_id_"] }); } } TypeInfo ti = TypeInfo.Of(t); BonDocument doc = new BonDocument(); if (cfg.debug) { doc["_id_"] = Guid.NewGuid().ToString("N"); anti.Add(obj, doc); } if (dt != null && dt != t || cfg.debug) { doc["_t_"] = t.FullName; } foreach (var kv in ti.props) { PropInfo pi = kv.Value; if (!pi.canRead) { continue; } var v = kv.Value.GetValue(obj); if (!cfg.debug && cfg.omitempty) { if (v == null) { continue; } if (pi.type.IsValueType) { if (v.Equals(Activator.CreateInstance(pi.type))) { continue; } } } BonValue v2 = ToBon(v, pi.type, cfg, anti); doc[pi.alias] = v2; } return(doc); } } }
private BonValue Next() { var t = (BonTypes)this.dr.ReadByte(); switch (t) { default: { return(BonNull.value); } case BonTypes.Int: { return(this.dr.ReadInt32()); } case BonTypes.Long: { return(this.dr.ReadInt64()); } case BonTypes.Float: { return(this.dr.ReadSingle()); } case BonTypes.Double: { return(this.dr.ReadDouble()); } case BonTypes.String: { var len = this.dr.Read7BitEncodedInt(); var s = this.dr.ReadUTF(len); this.strArr.Add(s); return(s); } case BonTypes.Boolean: { return(this.dr.ReadBoolean()); } case BonTypes.Binary: { return(this.dr.ReadBytes(this.dr.Read7BitEncodedInt())); } case BonTypes.Document: { var len = this.dr.Read7BitEncodedInt(); var obj = new BonDocument(); for (var i = 0; i < len; i++) { var k = this.Next().ToString(); var v = this.Next(); obj[k] = v; } return(obj); } case BonTypes.Array: { var len = this.dr.Read7BitEncodedInt(); var arr = new BonArray(); for (var i = 0; i < len; i++) { arr.Add(this.Next()); } return(arr); } case BonTypes.DateTime: { return(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(this.dr.ReadInt64())); } case BonTypes.StringRef: { return(this.strArr[this.dr.Read7BitEncodedInt()]); } } }