implement parsing of chunked json
Update: add more tests + use parser.failedpull/5/head
parent
eefbd630ec
commit
33bca8e178
|
@ -733,15 +733,18 @@ Json Json::parse(const string &in, string &err, JsonParse strategy) {
|
||||||
|
|
||||||
// Documented in json11.hpp
|
// Documented in json11.hpp
|
||||||
vector<Json> Json::parse_multi(const string &in,
|
vector<Json> Json::parse_multi(const string &in,
|
||||||
|
std::string::size_type &parser_stop_pos,
|
||||||
string &err,
|
string &err,
|
||||||
JsonParse strategy) {
|
JsonParse strategy) {
|
||||||
JsonParser parser { in, 0, err, false, strategy };
|
JsonParser parser { in, 0, err, false, strategy };
|
||||||
|
parser_stop_pos = 0;
|
||||||
vector<Json> json_vec;
|
vector<Json> json_vec;
|
||||||
while (parser.i != in.size() && !parser.failed) {
|
while (parser.i != in.size() && !parser.failed) {
|
||||||
json_vec.push_back(parser.parse_json(0));
|
json_vec.push_back(parser.parse_json(0));
|
||||||
// Check for another object
|
// Check for another object
|
||||||
parser.consume_garbage();
|
parser.consume_garbage();
|
||||||
|
if (!parser.failed)
|
||||||
|
parser_stop_pos = parser.i;
|
||||||
}
|
}
|
||||||
return json_vec;
|
return json_vec;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,9 +165,18 @@ public:
|
||||||
// Parse multiple objects, concatenated or separated by whitespace
|
// Parse multiple objects, concatenated or separated by whitespace
|
||||||
static std::vector<Json> parse_multi(
|
static std::vector<Json> parse_multi(
|
||||||
const std::string & in,
|
const std::string & in,
|
||||||
|
std::string::size_type & parser_stop_pos,
|
||||||
std::string & err,
|
std::string & err,
|
||||||
JsonParse strategy = JsonParse::STANDARD);
|
JsonParse strategy = JsonParse::STANDARD);
|
||||||
|
|
||||||
|
static inline std::vector<Json> parse_multi(
|
||||||
|
const std::string & in,
|
||||||
|
std::string & err,
|
||||||
|
JsonParse strategy = JsonParse::STANDARD) {
|
||||||
|
std::string::size_type parser_stop_pos;
|
||||||
|
return parse_multi(in, parser_stop_pos, err, strategy);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator== (const Json &rhs) const;
|
bool operator== (const Json &rhs) const;
|
||||||
bool operator< (const Json &rhs) const;
|
bool operator< (const Json &rhs) const;
|
||||||
bool operator!= (const Json &rhs) const { return !(*this == rhs); }
|
bool operator!= (const Json &rhs) const { return !(*this == rhs); }
|
||||||
|
|
36
test.cpp
36
test.cpp
|
@ -1,13 +1,17 @@
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#undef NDEBUG//at now assert will work even in Release build
|
||||||
|
#endif
|
||||||
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "json11.hpp"
|
#include "json11.hpp"
|
||||||
#include <cassert>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace json11;
|
using namespace json11;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
@ -183,6 +187,36 @@ int main(int argc, char **argv) {
|
||||||
assert(nested_array.array_items()[0].is_array());
|
assert(nested_array.array_items()[0].is_array());
|
||||||
assert(nested_array.array_items()[0].array_items().size() == 3);
|
assert(nested_array.array_items()[0].array_items().size() == 3);
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string good_json = R"( {"k1" : "v1"})";
|
||||||
|
const std::string bad_json1 = good_json + " {";
|
||||||
|
const std::string bad_json2 = good_json + R"({"k2":"v2", "k3":[)";
|
||||||
|
struct TestMultiParse {
|
||||||
|
std::string input;
|
||||||
|
std::string::size_type expect_parser_stop_pos;
|
||||||
|
size_t expect_not_empty_elms_count;
|
||||||
|
Json expect_parse_res;
|
||||||
|
} tests[] = {
|
||||||
|
{" {", 0, 0, {}},
|
||||||
|
{good_json, good_json.size(), 1, Json(std::map<string, string>{ { "k1", "v1" } })},
|
||||||
|
{bad_json1, good_json.size() + 1, 1, Json(std::map<string, string>{ { "k1", "v1" } })},
|
||||||
|
{bad_json2, good_json.size(), 1, Json(std::map<string, string>{ { "k1", "v1" } })},
|
||||||
|
{"{}", 2, 1, Json::object{}},
|
||||||
|
};
|
||||||
|
for (const auto &tst : tests) {
|
||||||
|
std::string::size_type parser_stop_pos;
|
||||||
|
std::string err;
|
||||||
|
auto res = Json::parse_multi(tst.input, parser_stop_pos, err);
|
||||||
|
assert(parser_stop_pos == tst.expect_parser_stop_pos);
|
||||||
|
assert(
|
||||||
|
std::count_if(res.begin(), res.end(),
|
||||||
|
[](const Json& j) { return !j.is_null(); })
|
||||||
|
== tst.expect_not_empty_elms_count);
|
||||||
|
if (!res.empty()) {
|
||||||
|
assert(tst.expect_parse_res == res[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Json my_json = Json::object {
|
Json my_json = Json::object {
|
||||||
{ "key1", "value1" },
|
{ "key1", "value1" },
|
||||||
{ "key2", false },
|
{ "key2", false },
|
||||||
|
|
Loading…
Reference in New Issue