diff --git a/include/nlohmann/detail/input/json_sax.hpp b/include/nlohmann/detail/input/json_sax.hpp index d1ab4f83a..db95685f0 100644 --- a/include/nlohmann/detail/input/json_sax.hpp +++ b/include/nlohmann/detail/input/json_sax.hpp @@ -569,16 +569,18 @@ class json_sax_dom_parser JSON_ASSERT(frames.back().object == nullptr); const frame f = frames.back(); frames.pop_back(); - enter_enclosing_container(); + reenter_enclosing_container(); if (f.array == nullptr) { - // the elements are on the stack: make them the array + // the elements are the top of the shared elements stack, from + // f.start on (the elements below belong to enclosing arrays that + // are still open): move them into the array and pop them const auto first = elements.begin() + static_cast(f.start); auto* const arr = BasicJsonType::template create(std::make_move_iterator(first), std::make_move_iterator(elements.end())); BasicJsonType value; - value.m_data.m_type = BasicJsonType::value_t::array; value.m_data.m_value.array = arr; + value.m_data.m_type = BasicJsonType::value_t::array; elements.erase(first, elements.end()); place_container(f, frames.empty() ? nullptr : &frames.back(), std::move(value), true); @@ -1033,13 +1035,15 @@ class json_sax_dom_parser return true; } - /// the members of an object that is collected on the stack as an object + /// the members of an object that is collected on the stack as an object; + /// they are the top of the shared member stack, from f.start on (the + /// members below belong to enclosing objects that are still open) object_t* members_to_object(const frame& f, BasicJsonType& value) { const auto first = ordered_data.members.begin() + static_cast(f.start); auto* const obj = BasicJsonType::template create(std::make_move_iterator(first), std::make_move_iterator(ordered_data.members.end())); - value.m_data.m_type = BasicJsonType::value_t::object; value.m_data.m_value.object = obj; + value.m_data.m_type = BasicJsonType::value_t::object; ordered_data.members.erase(first, ordered_data.members.end()); return obj; } @@ -1073,7 +1077,7 @@ class json_sax_dom_parser // the members are on the stack: make them the object const frame f = frames.back(); frames.pop_back(); - enter_enclosing_container(); + reenter_enclosing_container(); BasicJsonType value; members_to_object(f, value); @@ -1098,7 +1102,7 @@ class json_sax_dom_parser release_key_index(frames.back(), std::integral_constant {}); frames.pop_back(); - enter_enclosing_container(); + reenter_enclosing_container(); return true; } @@ -1269,7 +1273,7 @@ class json_sax_dom_parser } /// after a container was closed: the one it was in is the one that gets the next value - void enter_enclosing_container() + void reenter_enclosing_container() { if (frames.empty()) { diff --git a/include/nlohmann/detail/input/parser.hpp b/include/nlohmann/detail/input/parser.hpp index bfa70b01c..3017a29fd 100644 --- a/include/nlohmann/detail/input/parser.hpp +++ b/include/nlohmann/detail/input/parser.hpp @@ -243,13 +243,13 @@ class parser JSON_HEDLEY_NON_NULL(2) bool sax_parse_internal(SAX* sax) { + // value to avoid a goto (see comment where set to true) + bool skip_to_state_evaluation = false; + // stack to remember the hierarchy of structured values we are parsing // true = array; false = object (bytes, not std::vector, whose // push_back() is a call with GCC) std::vector states; - // value to avoid a goto (see comment where set to true) - bool skip_to_state_evaluation = false; - // a document that starts with a container pushes onto the stack at // once: allocate it in one step instead of growing it from 1 byte if (last_token == token_type::begin_object || last_token == token_type::begin_array) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 27f8b8a3c..f2b921cc0 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -15502,16 +15502,18 @@ class json_sax_dom_parser JSON_ASSERT(frames.back().object == nullptr); const frame f = frames.back(); frames.pop_back(); - enter_enclosing_container(); + reenter_enclosing_container(); if (f.array == nullptr) { - // the elements are on the stack: make them the array + // the elements are the top of the shared elements stack, from + // f.start on (the elements below belong to enclosing arrays that + // are still open): move them into the array and pop them const auto first = elements.begin() + static_cast(f.start); auto* const arr = BasicJsonType::template create(std::make_move_iterator(first), std::make_move_iterator(elements.end())); BasicJsonType value; - value.m_data.m_type = BasicJsonType::value_t::array; value.m_data.m_value.array = arr; + value.m_data.m_type = BasicJsonType::value_t::array; elements.erase(first, elements.end()); place_container(f, frames.empty() ? nullptr : &frames.back(), std::move(value), true); @@ -15966,13 +15968,15 @@ class json_sax_dom_parser return true; } - /// the members of an object that is collected on the stack as an object + /// the members of an object that is collected on the stack as an object; + /// they are the top of the shared member stack, from f.start on (the + /// members below belong to enclosing objects that are still open) object_t* members_to_object(const frame& f, BasicJsonType& value) { const auto first = ordered_data.members.begin() + static_cast(f.start); auto* const obj = BasicJsonType::template create(std::make_move_iterator(first), std::make_move_iterator(ordered_data.members.end())); - value.m_data.m_type = BasicJsonType::value_t::object; value.m_data.m_value.object = obj; + value.m_data.m_type = BasicJsonType::value_t::object; ordered_data.members.erase(first, ordered_data.members.end()); return obj; } @@ -16006,7 +16010,7 @@ class json_sax_dom_parser // the members are on the stack: make them the object const frame f = frames.back(); frames.pop_back(); - enter_enclosing_container(); + reenter_enclosing_container(); BasicJsonType value; members_to_object(f, value); @@ -16031,7 +16035,7 @@ class json_sax_dom_parser release_key_index(frames.back(), std::integral_constant {}); frames.pop_back(); - enter_enclosing_container(); + reenter_enclosing_container(); return true; } @@ -16202,7 +16206,7 @@ class json_sax_dom_parser } /// after a container was closed: the one it was in is the one that gets the next value - void enter_enclosing_container() + void reenter_enclosing_container() { if (frames.empty()) { @@ -22007,13 +22011,13 @@ class parser JSON_HEDLEY_NON_NULL(2) bool sax_parse_internal(SAX* sax) { + // value to avoid a goto (see comment where set to true) + bool skip_to_state_evaluation = false; + // stack to remember the hierarchy of structured values we are parsing // true = array; false = object (bytes, not std::vector, whose // push_back() is a call with GCC) std::vector states; - // value to avoid a goto (see comment where set to true) - bool skip_to_state_evaluation = false; - // a document that starts with a container pushes onto the stack at // once: allocate it in one step instead of growing it from 1 byte if (last_token == token_type::begin_object || last_token == token_type::begin_array)