Mercurial > hg > piper-cpp
diff ext/json11/json11.cpp @ 242:d607ae858682
Update json11 code
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Tue, 13 Jun 2017 17:16:03 +0100 |
parents | bf8e3e7dd7de |
children | de5dc40f1830 |
line wrap: on
line diff
--- a/ext/json11/json11.cpp Tue Jun 13 16:24:24 2017 +0100 +++ b/ext/json11/json11.cpp Tue Jun 13 17:16:03 2017 +0100 @@ -37,11 +37,20 @@ using std::initializer_list; using std::move; +/* Helper for representing null - just a do-nothing struct, plus comparison + * operators so the helpers in JsonValue work. We can't use nullptr_t because + * it may not be orderable. + */ +struct NullStruct { + bool operator==(NullStruct) const { return true; } + bool operator<(NullStruct) const { return false; } +}; + /* * * * * * * * * * * * * * * * * * * * * Serialization */ -static void dump(std::nullptr_t, string &out) { +static void dump(NullStruct, string &out) { out += "null"; } @@ -208,9 +217,9 @@ explicit JsonObject(Json::object &&value) : Value(move(value)) {} }; -class JsonNull final : public Value<Json::NUL, std::nullptr_t> { +class JsonNull final : public Value<Json::NUL, NullStruct> { public: - JsonNull() : Value(nullptr) {} + JsonNull() : Value({}) {} }; /* * * * * * * * * * * * * * * * * * * * @@ -291,6 +300,8 @@ */ bool Json::operator== (const Json &other) const { + if (m_ptr == other.m_ptr) + return true; if (m_ptr->type() != other.m_ptr->type()) return false; @@ -298,6 +309,8 @@ } bool Json::operator< (const Json &other) const { + if (m_ptr == other.m_ptr) + return false; if (m_ptr->type() != other.m_ptr->type()) return m_ptr->type() < other.m_ptr->type(); @@ -326,11 +339,12 @@ return (x >= lower && x <= upper); } +namespace { /* JsonParser * * Object that tracks all state of an in-progress parse. */ -struct JsonParser { +struct JsonParser final { /* State */ @@ -374,38 +388,31 @@ if (str[i] == '/') { i++; if (i == str.size()) - return fail("unexpected end of input inside comment", 0); + return fail("unexpected end of input after start of comment", false); if (str[i] == '/') { // inline comment i++; - if (i == str.size()) - return fail("unexpected end of input inside inline comment", 0); - // advance until next line - while (str[i] != '\n') { + // advance until next line, or end of input + while (i < str.size() && str[i] != '\n') { i++; - if (i == str.size()) - return fail("unexpected end of input inside inline comment", 0); } comment_found = true; } else if (str[i] == '*') { // multiline comment i++; if (i > str.size()-2) - return fail("unexpected end of input inside multi-line comment", 0); + return fail("unexpected end of input inside multi-line comment", false); // advance until closing tokens while (!(str[i] == '*' && str[i+1] == '/')) { i++; if (i > str.size()-2) return fail( - "unexpected end of input inside multi-line comment", 0); + "unexpected end of input inside multi-line comment", false); } i += 2; - if (i == str.size()) - return fail( - "unexpected end of input inside multi-line comment", 0); comment_found = true; } else - return fail("malformed comment", 0); + return fail("malformed comment", false); } return comment_found; } @@ -420,6 +427,7 @@ bool comment_found = false; do { comment_found = consume_comment(); + if (failed) return; consume_whitespace(); } while(comment_found); @@ -433,8 +441,9 @@ */ char get_next_token() { consume_garbage(); + if (failed) return (char)0; if (i == str.size()) - return fail("unexpected end of input", 0); + return fail("unexpected end of input", (char)0); return str[i++]; } @@ -508,7 +517,7 @@ if (esc.length() < 4) { return fail("bad \\u escape: " + esc, ""); } - for (int j = 0; j < 4; j++) { + for (size_t j = 0; j < 4; j++) { if (!in_range(esc[j], 'a', 'f') && !in_range(esc[j], 'A', 'F') && !in_range(esc[j], '0', '9')) return fail("bad \\u escape: " + esc, ""); @@ -718,6 +727,7 @@ return fail("expected value, got " + esc(ch)); } }; +}//namespace { Json Json::parse(const string &in, string &err, JsonParse strategy) { JsonParser parser { in, 0, err, false, strategy }; @@ -725,6 +735,8 @@ // Check for any trailing garbage parser.consume_garbage(); + if (parser.failed) + return Json(); if (parser.i != in.size()) return parser.fail("unexpected trailing " + esc(in[parser.i])); @@ -733,15 +745,22 @@ // Documented in json11.hpp vector<Json> Json::parse_multi(const string &in, + std::string::size_type &parser_stop_pos, string &err, JsonParse strategy) { JsonParser parser { in, 0, err, false, strategy }; - + parser_stop_pos = 0; vector<Json> json_vec; while (parser.i != in.size() && !parser.failed) { json_vec.push_back(parser.parse_json(0)); + if (parser.failed) + break; + // Check for another object parser.consume_garbage(); + if (parser.failed) + break; + parser_stop_pos = parser.i; } return json_vec; }