private BonArray NextArray() { BonArray b = new BonArray(); while (true) { char c = NextToken(); if (c == ']') { break; } myIndex--; BonValue v = NextValue(); b.Add(v); c = NextToken(); if (c == ']') { break; } if (c != ',') { throw SyntaxError("Array error"); } } return(b); }
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()]); } } }