From 7ed92d18a4404d12119b3ace116d3df7f19d48f1 Mon Sep 17 00:00:00 2001 From: Damien Merenne Date: Thu, 29 Dec 2016 15:58:44 +0100 Subject: [PATCH] Store builded object on the stack. For partial building, we need to temporary store the object being build as we maybe interrupted. This commits change object and array parsing to use the values stack has a temporary place for storing the object being build. --- json11.cpp | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/json11.cpp b/json11.cpp index ab7a069..0e4f0d1 100644 --- a/json11.cpp +++ b/json11.cpp @@ -808,21 +808,23 @@ struct JsonParserPriv final { void parse_object() { assert(states.top() >= VALUE_OBJECT && states.top() <= OBJECT_VALUE); - map data; + values.push(map()); set_state(OBJECT_KEY_OR_END); char ch = get_next_token(); if (ch == '}') { pop_state(); - return values.push(data); + return; } while (1) { if (need_data) return; - if (ch != '"') + if (ch != '"') { + values.pop(); return fail("expected '\"' in object, got " + esc(ch)); + } set_state(OBJECT_KEY); push_state(VALUE_STRING); @@ -833,16 +835,20 @@ struct JsonParserPriv final { string key = values.top().string_value(); values.pop(); - if (failed) + if (failed) { + values.pop(); return values.push(Json()); + } set_state(OBJECT_COLON); ch = get_next_token(); if (need_data) return; - if (ch != ':') + if (ch != ':') { + values.pop(); return fail("expected ':' in object, got " + esc(ch)); + } set_state(OBJECT_VALUE); push_state(EXPECT_VALUE); @@ -853,10 +859,15 @@ struct JsonParserPriv final { Json value = values.top(); values.pop(); - if (failed) + if (failed) { + values.pop(); return values.push(Json()); + } + map data = values.top().object_items(); data[std::move(key)] = value; + values.pop(); + values.push(data); set_state(OBJECT_COMMA_OR_END); ch = get_next_token(); @@ -864,14 +875,14 @@ struct JsonParserPriv final { return; if (ch == '}') { - values.push(data); pop_state(); break; } - if (ch != ',') + if (ch != ',') { + values.pop(); return fail("expected ',' in object, got " + esc(ch)); - + } ch = get_next_token(); } } @@ -883,14 +894,14 @@ struct JsonParserPriv final { void parse_array() { assert(states.top() >= VALUE_ARRAY && states.top() <= ARRAY_VALUE); - vector data; + values.push(vector()); set_state(ARRAY_VALUE_OR_END); char ch = get_next_token(); if (ch == ']') { pop_state(); - return values.push(data); + return; } while (1) { @@ -909,9 +920,15 @@ struct JsonParserPriv final { Json value = values.top(); values.pop(); - if (failed) + if (failed) { + values.pop(); return values.push(Json()); + } + + vector data = values.top().array_items(); data.push_back(value); + values.pop(); + values.push(data); set_state(ARRAY_COMMA_OR_END); ch = get_next_token(); @@ -919,13 +936,14 @@ struct JsonParserPriv final { return; if (ch == ']') { - values.push(data); pop_state(); break; } - if (ch != ',') + if (ch != ',') { + values.pop(); return fail("expected ',' in list, got " + esc(ch)); + } ch = get_next_token(); (void)ch;