我正在使用JsonCpp在 C++ 中解析 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“部分验证器”,该状态机在输入字符串的每一步都考虑哪些字符是“有效的”?我宁愿不重新发明轮子...