| 7377 | } |
| 7378 | |
| 7379 | token_type scan() |
| 7380 | { |
| 7381 | // initially, skip the BOM |
| 7382 | if (position.chars_read_total == 0 && !skip_bom()) |
| 7383 | { |
| 7384 | error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; |
| 7385 | return token_type::parse_error; |
| 7386 | } |
| 7387 | |
| 7388 | // read next character and ignore whitespace |
| 7389 | skip_whitespace(); |
| 7390 | |
| 7391 | // ignore comments |
| 7392 | while (ignore_comments && current == '/') |
| 7393 | { |
| 7394 | if (!scan_comment()) |
| 7395 | { |
| 7396 | return token_type::parse_error; |
| 7397 | } |
| 7398 | |
| 7399 | // skip following whitespace |
| 7400 | skip_whitespace(); |
| 7401 | } |
| 7402 | |
| 7403 | switch (current) |
| 7404 | { |
| 7405 | // structural characters |
| 7406 | case '[': |
| 7407 | return token_type::begin_array; |
| 7408 | case ']': |
| 7409 | return token_type::end_array; |
| 7410 | case '{': |
| 7411 | return token_type::begin_object; |
| 7412 | case '}': |
| 7413 | return token_type::end_object; |
| 7414 | case ':': |
| 7415 | return token_type::name_separator; |
| 7416 | case ',': |
| 7417 | return token_type::value_separator; |
| 7418 | |
| 7419 | // literals |
| 7420 | case 't': |
| 7421 | { |
| 7422 | std::array<char_type, 4> true_literal = { {'t', 'r', 'u', 'e'} }; |
| 7423 | return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); |
| 7424 | } |
| 7425 | case 'f': |
| 7426 | { |
| 7427 | std::array<char_type, 5> false_literal = { {'f', 'a', 'l', 's', 'e'} }; |
| 7428 | return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); |
| 7429 | } |
| 7430 | case 'n': |
| 7431 | { |
| 7432 | std::array<char_type, 4> null_literal = { {'n', 'u', 'l', 'l'} }; |
| 7433 | return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); |
| 7434 | } |
| 7435 | |
| 7436 | // string |
nothing calls this directly
no test coverage detected