protected void AsMessage(Message msg, MessageDescriptor ci) { if (ci.HasOptions) { AsMessageEx(msg, ci); return; } // should be ready to pick up value if parsing into Json data node special class. if (_tlast != JsToken.ObjectStart) Expected("object start"); // parse JSON object into message fields. var comma = false; FieldDescriptor kvfs = null; while (true) { if ((_tlast = Next()) == JsToken.ObjectEnd) { if (kvfs == null) break; kvfs = null; continue; } if (!comma) comma = true; else if (_tlast != JsToken.Comma) Expected("comma"); else _tlast = Next(); if (_tlast != JsToken.String) Expected("name"); _last_name = _sdata; if (Next() != JsToken.Semicolon) Expected(":"); if (GetValue() == JsToken.Null) continue; // when parsing JSON object into map, populate next entry. if (kvfs != null) { msg.Get(kvfs, this); continue; } // find message field descriptor by name. var fs = ci.Find(_last_name); if (fs == null) continue; if (_tlast != JsToken.ArrayStart) // save field desc for extracting kv-map values. if (fs.DataType != WireType.MapEntry) msg.Get(fs, this); else if (_tlast == JsToken.ObjectStart) { kvfs = fs; comma = false; } else Expected("object start"); else AsArray(msg, fs); } }
private void GetMessage(Message msg, MessageDescriptor ci) { // enter next message parsing level. var prev = PushLimit(); while (_storage.Limit > 0) { // read next PB value from the stream. var id = _storage.GetIntPB(); switch (_wirefmt = id & 0x7) { case Pbs.iVarInt: _data = _storage.GetLongPB(); break; case Pbs.iBit64: _data = _storage.GetB64(); break; case Pbs.iString: _fsz = _storage.GetIntPB(); if (_fsz <= _storage.Limit) break; throw new ProtoBufException("nested blob size"); case Pbs.iBit32: _data = _storage.GetB32(); break; default: throw new ProtoBufException("unsupported wire format"); } // match PB field descriptor by id. var fi = ci.Find(id); if (fi != null) if(fi.Id == id) msg.Get(fi, this); else TryReadPacked(fi, msg); else if (_fsz > 0) { _storage.Skip(_fsz); _fsz = 0; } } // exit message segment parsing. if (_storage.Limit < 0) throw new ProtoBufException("message size out of sync"); _level--; PopLimit(prev); }