Я использую JsonCpp для анализа JSON в C++.Могу ли я использовать JsonCpp для частичного подтверждения ввода JSON?
например.
Json::Reader r;
std::stringstream ss;
ss << "{\"name\": \"sample\"}";
Json::Value v;
assert(r.parse(ss, v)); // OK
assert(v["name"] == "sample"); // OK
Но мой фактический ввод целый поток сообщений JSON, которые могут прийти на куски любого размера; все, что я могу сделать, чтобы получить JsonCpp попытаться разобрать мой вход, посимвольно, съедает полные сообщения в формате JSON, как мы открываем их:
Json::Reader r;
std::string input = "{\"name\": \"sample\"}{\"name\": \"aardvark\"}";
for (size_t cursor = 0; cursor < input.size(); cursor++) {
std::stringstream ss;
ss << input.substr(0, cursor);
Json::Value v;
if (r.parse(ss, v)) {
std::cout << v["name"] << " ";
input.erase(0, cursor);
}
} // Output: sample aardvark
Это уже немного противно, но это еще хуже. Я также должен иметь возможность повторной синхронизации, когда часть ввода отсутствует (по какой-либо причине).
Теперь он не должен быть без потерь, но я хочу, чтобы предотвратить ввод, например, как вытекающее из потенциально нарушая парсер навсегда:
{"name": "samp{"name": "aardvark"}
Проходя этот вход в JsonCpp потерпит неудачу, но эта проблема не исчезнет, поскольку мы получим больше символов в буфере; что второй name
просто недействителен непосредственно после предшествующего ему "
; буфер не может быть завершен, чтобы представить действительный JSON.
Однако, если мне скажут, что фрагмент, безусловно, становится недействительным со второго символа n
, я мог бы отбросить все в буфере до этой точки, а затем просто подождать следующего {
, чтобы рассмотреть начало новый объект, как рестайлинг с наилучшими усилиями.
Итак, есть ли способ, что я могу попросить JsonCpp сказать мне ли неполный фрагмент JSON уже гарантировано, что полный «объект» будет синтаксически недействительным?
То есть:
{"name": "sample"} Valid (Json::Reader::parse == true)
{"name": "sam Incomplete (Json::Reader::parse == false)
{"name": "sam"LOL Invalid (Json::Reader::parse == false)
Я хотел бы различать два состояния не в состоянии.
Могу ли я использовать JsonCpp для этого, или мне придется написать собственный JSON-частичный валидатор, построив конечный автомат, который считает, какие символы «действительны» на каждом шаге через входную строку? Я бы предпочел не изобретать колесо ...
Производитель знает только полный объект JSON. Сегментация сводится к тому, что можно было передать по сети. –
(Я действительно хочу, чтобы у нашего протокола было поле длины сообщения. В начале каждого сообщения JSON у нас есть дозорный сигнал, который выглядит как «PIGEON: JSON:', поэтому мы могли бы построить его в этом. в следующей версии: D) –
I _was_ в состоянии настроить формат в конце, создавая сверхсовременную версию нашего протокола, которая включает в себя заголовок длины; однако мне все еще нужно было решить эту проблему для существующего формата по соображениям обратной совместимости. –