TerraForge3D  2.3.1
3D Terrain And Landscape Generator

◆ sax_parse_internal()

template<typename BasicJsonType , typename InputAdapterType >
template<typename SAX >
bool nlohmann::detail::parser< BasicJsonType, InputAdapterType >::sax_parse_internal ( SAX *  sax)
inlineprivate

Definition at line 11176 of file json.hpp.

11177 {
11178 // stack to remember the hierarchy of structured values we are parsing
11179 // true = array; false = object
11180 std::vector<bool> states;
11181 // value to avoid a goto (see comment where set to true)
11182 bool skip_to_state_evaluation = false;
11183
11184 while (true)
11185 {
11186 if (!skip_to_state_evaluation)
11187 {
11188 // invariant: get_token() was called before each iteration
11189 switch (last_token)
11190 {
11191 case token_type::begin_object:
11192 {
11193 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11194 {
11195 return false;
11196 }
11197
11198 // closing } -> we are done
11199 if (get_token() == token_type::end_object)
11200 {
11201 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11202 {
11203 return false;
11204 }
11205
11206 break;
11207 }
11208
11209 // parse key
11210 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11211 {
11212 return sax->parse_error(m_lexer.get_position(),
11214 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11215 }
11216
11217 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11218 {
11219 return false;
11220 }
11221
11222 // parse separator (:)
11223 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11224 {
11225 return sax->parse_error(m_lexer.get_position(),
11227 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11228 }
11229
11230 // remember we are now inside an object
11231 states.push_back(false);
11232 // parse values
11233 get_token();
11234 continue;
11235 }
11236
11237 case token_type::begin_array:
11238 {
11239 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11240 {
11241 return false;
11242 }
11243
11244 // closing ] -> we are done
11245 if (get_token() == token_type::end_array)
11246 {
11247 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11248 {
11249 return false;
11250 }
11251
11252 break;
11253 }
11254
11255 // remember we are now inside an array
11256 states.push_back(true);
11257 // parse values (no need to call get_token)
11258 continue;
11259 }
11260
11261 case token_type::value_float:
11262 {
11263 const auto res = m_lexer.get_number_float();
11264
11265 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11266 {
11267 return sax->parse_error(m_lexer.get_position(),
11269 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11270 }
11271
11272 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11273 {
11274 return false;
11275 }
11276
11277 break;
11278 }
11279
11280 case token_type::literal_false:
11281 {
11282 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11283 {
11284 return false;
11285 }
11286
11287 break;
11288 }
11289
11290 case token_type::literal_null:
11291 {
11292 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11293 {
11294 return false;
11295 }
11296
11297 break;
11298 }
11299
11300 case token_type::literal_true:
11301 {
11302 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11303 {
11304 return false;
11305 }
11306
11307 break;
11308 }
11309
11310 case token_type::value_integer:
11311 {
11312 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11313 {
11314 return false;
11315 }
11316
11317 break;
11318 }
11319
11320 case token_type::value_string:
11321 {
11322 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11323 {
11324 return false;
11325 }
11326
11327 break;
11328 }
11329
11330 case token_type::value_unsigned:
11331 {
11332 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11333 {
11334 return false;
11335 }
11336
11337 break;
11338 }
11339
11340 case token_type::parse_error:
11341 {
11342 // using "uninitialized" to avoid "expected" message
11343 return sax->parse_error(m_lexer.get_position(),
11345 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11346 }
11347
11348 case token_type::uninitialized:
11349 case token_type::end_array:
11350 case token_type::end_object:
11351 case token_type::name_separator:
11352 case token_type::value_separator:
11353 case token_type::end_of_input:
11354 case token_type::literal_or_value:
11355 default: // the last token was unexpected
11356 {
11357 return sax->parse_error(m_lexer.get_position(),
11359 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11360 }
11361 }
11362 }
11363
11364 else
11365 {
11366 skip_to_state_evaluation = false;
11367 }
11368
11369 // we reached this line after we successfully parsed a value
11370 if (states.empty())
11371 {
11372 // empty stack: we reached the end of the hierarchy: done
11373 return true;
11374 }
11375
11376 if (states.back()) // array
11377 {
11378 // comma -> next value
11379 if (get_token() == token_type::value_separator)
11380 {
11381 // parse a new value
11382 get_token();
11383 continue;
11384 }
11385
11386 // closing ]
11387 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11388 {
11389 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11390 {
11391 return false;
11392 }
11393
11394 // We are done with this array. Before we can parse a
11395 // new value, we need to evaluate the new state first.
11396 // By setting skip_to_state_evaluation to false, we
11397 // are effectively jumping to the beginning of this if.
11398 JSON_ASSERT(!states.empty());
11399 states.pop_back();
11400 skip_to_state_evaluation = true;
11401 continue;
11402 }
11403
11404 return sax->parse_error(m_lexer.get_position(),
11406 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11407 }
11408
11409 // states.back() is false -> object
11410
11411 // comma -> next value
11412 if (get_token() == token_type::value_separator)
11413 {
11414 // parse key
11415 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11416 {
11417 return sax->parse_error(m_lexer.get_position(),
11419 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11420 }
11421
11422 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11423 {
11424 return false;
11425 }
11426
11427 // parse separator (:)
11428 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11429 {
11430 return sax->parse_error(m_lexer.get_position(),
11432 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11433 }
11434
11435 // parse values
11436 get_token();
11437 continue;
11438 }
11439
11440 // closing }
11441 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11442 {
11443 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11444 {
11445 return false;
11446 }
11447
11448 // We are done with this object. Before we can parse a
11449 // new value, we need to evaluate the new state first.
11450 // By setting skip_to_state_evaluation to false, we
11451 // are effectively jumping to the beginning of this if.
11452 JSON_ASSERT(!states.empty());
11453 states.pop_back();
11454 skip_to_state_evaluation = true;
11455 continue;
11456 }
11457
11458 return sax->parse_error(m_lexer.get_position(),
11460 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11461 }
11462 }
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8035
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8045
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8017
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8023
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8029
std::string get_token_string() const
return the last read token (for errors only).
Definition: json.hpp:8053
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, const BasicJsonType &context)
create a parse error exception
Definition: json.hpp:2800
lexer_t m_lexer
the lexer
Definition: json.hpp:11506
token_type get_token()
get next token from lexer
Definition: json.hpp:11465
token_type last_token
the type of the last read token
Definition: json.hpp:11504