OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/json/json_parser.h" | 5 #include "base/json/json_parser.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 } | 460 } |
461 previous_char = next_char; | 461 previous_char = next_char; |
462 } | 462 } |
463 | 463 |
464 // If the comment is unterminated, GetNextToken will report T_END_OF_INPUT. | 464 // If the comment is unterminated, GetNextToken will report T_END_OF_INPUT. |
465 } | 465 } |
466 | 466 |
467 return false; | 467 return false; |
468 } | 468 } |
469 | 469 |
470 Value* JSONParser::ParseNextToken() { | 470 std::unique_ptr<Value> JSONParser::ParseNextToken() { |
471 return ParseToken(GetNextToken()); | 471 return ParseToken(GetNextToken()); |
472 } | 472 } |
473 | 473 |
474 Value* JSONParser::ParseToken(Token token) { | 474 std::unique_ptr<Value> JSONParser::ParseToken(Token token) { |
475 switch (token) { | 475 switch (token) { |
476 case T_OBJECT_BEGIN: | 476 case T_OBJECT_BEGIN: |
477 return ConsumeDictionary(); | 477 return ConsumeDictionary(); |
478 case T_ARRAY_BEGIN: | 478 case T_ARRAY_BEGIN: |
479 return ConsumeList(); | 479 return ConsumeList(); |
480 case T_STRING: | 480 case T_STRING: |
481 return ConsumeString(); | 481 return ConsumeString(); |
482 case T_NUMBER: | 482 case T_NUMBER: |
483 return ConsumeNumber(); | 483 return ConsumeNumber(); |
484 case T_BOOL_TRUE: | 484 case T_BOOL_TRUE: |
485 case T_BOOL_FALSE: | 485 case T_BOOL_FALSE: |
486 case T_NULL: | 486 case T_NULL: |
487 return ConsumeLiteral(); | 487 return ConsumeLiteral(); |
488 default: | 488 default: |
489 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 489 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
490 return nullptr; | 490 return nullptr; |
491 } | 491 } |
492 } | 492 } |
493 | 493 |
494 Value* JSONParser::ConsumeDictionary() { | 494 std::unique_ptr<Value> JSONParser::ConsumeDictionary() { |
495 if (*pos_ != '{') { | 495 if (*pos_ != '{') { |
496 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 496 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
497 return nullptr; | 497 return nullptr; |
498 } | 498 } |
499 | 499 |
500 StackMarker depth_check(&stack_depth_); | 500 StackMarker depth_check(&stack_depth_); |
501 if (depth_check.IsTooDeep()) { | 501 if (depth_check.IsTooDeep()) { |
502 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); | 502 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); |
503 return nullptr; | 503 return nullptr; |
504 } | 504 } |
(...skipping 17 matching lines...) Expand all Loading... |
522 // Read the separator. | 522 // Read the separator. |
523 NextChar(); | 523 NextChar(); |
524 token = GetNextToken(); | 524 token = GetNextToken(); |
525 if (token != T_OBJECT_PAIR_SEPARATOR) { | 525 if (token != T_OBJECT_PAIR_SEPARATOR) { |
526 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 526 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
527 return nullptr; | 527 return nullptr; |
528 } | 528 } |
529 | 529 |
530 // The next token is the value. Ownership transfers to |dict|. | 530 // The next token is the value. Ownership transfers to |dict|. |
531 NextChar(); | 531 NextChar(); |
532 Value* value = ParseNextToken(); | 532 std::unique_ptr<Value> value = ParseNextToken(); |
533 if (!value) { | 533 if (!value) { |
534 // ReportError from deeper level. | 534 // ReportError from deeper level. |
535 return nullptr; | 535 return nullptr; |
536 } | 536 } |
537 | 537 |
538 dict->SetWithoutPathExpansion(key.AsString(), value); | 538 dict->SetWithoutPathExpansion(key.AsString(), std::move(value)); |
539 | 539 |
540 NextChar(); | 540 NextChar(); |
541 token = GetNextToken(); | 541 token = GetNextToken(); |
542 if (token == T_LIST_SEPARATOR) { | 542 if (token == T_LIST_SEPARATOR) { |
543 NextChar(); | 543 NextChar(); |
544 token = GetNextToken(); | 544 token = GetNextToken(); |
545 if (token == T_OBJECT_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) { | 545 if (token == T_OBJECT_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) { |
546 ReportError(JSONReader::JSON_TRAILING_COMMA, 1); | 546 ReportError(JSONReader::JSON_TRAILING_COMMA, 1); |
547 return nullptr; | 547 return nullptr; |
548 } | 548 } |
549 } else if (token != T_OBJECT_END) { | 549 } else if (token != T_OBJECT_END) { |
550 ReportError(JSONReader::JSON_SYNTAX_ERROR, 0); | 550 ReportError(JSONReader::JSON_SYNTAX_ERROR, 0); |
551 return nullptr; | 551 return nullptr; |
552 } | 552 } |
553 } | 553 } |
554 | 554 |
555 return dict.release(); | 555 return std::move(dict); |
556 } | 556 } |
557 | 557 |
558 Value* JSONParser::ConsumeList() { | 558 std::unique_ptr<Value> JSONParser::ConsumeList() { |
559 if (*pos_ != '[') { | 559 if (*pos_ != '[') { |
560 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 560 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
561 return nullptr; | 561 return nullptr; |
562 } | 562 } |
563 | 563 |
564 StackMarker depth_check(&stack_depth_); | 564 StackMarker depth_check(&stack_depth_); |
565 if (depth_check.IsTooDeep()) { | 565 if (depth_check.IsTooDeep()) { |
566 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); | 566 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); |
567 return nullptr; | 567 return nullptr; |
568 } | 568 } |
569 | 569 |
570 std::unique_ptr<ListValue> list(new ListValue); | 570 std::unique_ptr<ListValue> list(new ListValue); |
571 | 571 |
572 NextChar(); | 572 NextChar(); |
573 Token token = GetNextToken(); | 573 Token token = GetNextToken(); |
574 while (token != T_ARRAY_END) { | 574 while (token != T_ARRAY_END) { |
575 Value* item = ParseToken(token); | 575 std::unique_ptr<Value> item = ParseToken(token); |
576 if (!item) { | 576 if (!item) { |
577 // ReportError from deeper level. | 577 // ReportError from deeper level. |
578 return nullptr; | 578 return nullptr; |
579 } | 579 } |
580 | 580 |
581 list->Append(item); | 581 list->Append(std::move(item)); |
582 | 582 |
583 NextChar(); | 583 NextChar(); |
584 token = GetNextToken(); | 584 token = GetNextToken(); |
585 if (token == T_LIST_SEPARATOR) { | 585 if (token == T_LIST_SEPARATOR) { |
586 NextChar(); | 586 NextChar(); |
587 token = GetNextToken(); | 587 token = GetNextToken(); |
588 if (token == T_ARRAY_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) { | 588 if (token == T_ARRAY_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) { |
589 ReportError(JSONReader::JSON_TRAILING_COMMA, 1); | 589 ReportError(JSONReader::JSON_TRAILING_COMMA, 1); |
590 return nullptr; | 590 return nullptr; |
591 } | 591 } |
592 } else if (token != T_ARRAY_END) { | 592 } else if (token != T_ARRAY_END) { |
593 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 593 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
594 return nullptr; | 594 return nullptr; |
595 } | 595 } |
596 } | 596 } |
597 | 597 |
598 return list.release(); | 598 return std::move(list); |
599 } | 599 } |
600 | 600 |
601 Value* JSONParser::ConsumeString() { | 601 std::unique_ptr<Value> JSONParser::ConsumeString() { |
602 StringBuilder string; | 602 StringBuilder string; |
603 if (!ConsumeStringRaw(&string)) | 603 if (!ConsumeStringRaw(&string)) |
604 return nullptr; | 604 return nullptr; |
605 | 605 |
606 // Create the Value representation, using a hidden root, if configured | 606 // Create the Value representation, using a hidden root, if configured |
607 // to do so, and if the string can be represented by StringPiece. | 607 // to do so, and if the string can be represented by StringPiece. |
608 if (string.CanBeStringPiece() && !(options_ & JSON_DETACHABLE_CHILDREN)) | 608 if (string.CanBeStringPiece() && !(options_ & JSON_DETACHABLE_CHILDREN)) |
609 return new JSONStringValue(string.AsStringPiece()); | 609 return base::MakeUnique<JSONStringValue>(string.AsStringPiece()); |
610 | 610 |
611 if (string.CanBeStringPiece()) | 611 if (string.CanBeStringPiece()) |
612 string.Convert(); | 612 string.Convert(); |
613 return new StringValue(string.AsString()); | 613 return base::MakeUnique<StringValue>(string.AsString()); |
614 } | 614 } |
615 | 615 |
616 bool JSONParser::ConsumeStringRaw(StringBuilder* out) { | 616 bool JSONParser::ConsumeStringRaw(StringBuilder* out) { |
617 if (*pos_ != '"') { | 617 if (*pos_ != '"') { |
618 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 618 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
619 return false; | 619 return false; |
620 } | 620 } |
621 | 621 |
622 // StringBuilder will internally build a StringPiece unless a UTF-16 | 622 // StringBuilder will internally build a StringPiece unless a UTF-16 |
623 // conversion occurs, at which point it will perform a copy into a | 623 // conversion occurs, at which point it will perform a copy into a |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 char utf8_units[4] = { 0 }; | 820 char utf8_units[4] = { 0 }; |
821 int offset = 0; | 821 int offset = 0; |
822 CBU8_APPEND_UNSAFE(utf8_units, offset, point); | 822 CBU8_APPEND_UNSAFE(utf8_units, offset, point); |
823 dest->Convert(); | 823 dest->Convert(); |
824 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be | 824 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be |
825 // zero terminated at this point. |offset| contains the correct length. | 825 // zero terminated at this point. |offset| contains the correct length. |
826 dest->AppendString(std::string(utf8_units, offset)); | 826 dest->AppendString(std::string(utf8_units, offset)); |
827 } | 827 } |
828 } | 828 } |
829 | 829 |
830 Value* JSONParser::ConsumeNumber() { | 830 std::unique_ptr<Value> JSONParser::ConsumeNumber() { |
831 const char* num_start = pos_; | 831 const char* num_start = pos_; |
832 const int start_index = index_; | 832 const int start_index = index_; |
833 int end_index = start_index; | 833 int end_index = start_index; |
834 | 834 |
835 if (*pos_ == '-') | 835 if (*pos_ == '-') |
836 NextChar(); | 836 NextChar(); |
837 | 837 |
838 if (!ReadInt(false)) { | 838 if (!ReadInt(false)) { |
839 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 839 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
840 return nullptr; | 840 return nullptr; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 return nullptr; | 885 return nullptr; |
886 } | 886 } |
887 | 887 |
888 pos_ = exit_pos; | 888 pos_ = exit_pos; |
889 index_ = exit_index; | 889 index_ = exit_index; |
890 | 890 |
891 StringPiece num_string(num_start, end_index - start_index); | 891 StringPiece num_string(num_start, end_index - start_index); |
892 | 892 |
893 int num_int; | 893 int num_int; |
894 if (StringToInt(num_string, &num_int)) | 894 if (StringToInt(num_string, &num_int)) |
895 return new FundamentalValue(num_int); | 895 return base::MakeUnique<FundamentalValue>(num_int); |
896 | 896 |
897 double num_double; | 897 double num_double; |
898 if (StringToDouble(num_string.as_string(), &num_double) && | 898 if (StringToDouble(num_string.as_string(), &num_double) && |
899 std::isfinite(num_double)) { | 899 std::isfinite(num_double)) { |
900 return new FundamentalValue(num_double); | 900 return base::MakeUnique<FundamentalValue>(num_double); |
901 } | 901 } |
902 | 902 |
903 return nullptr; | 903 return nullptr; |
904 } | 904 } |
905 | 905 |
906 bool JSONParser::ReadInt(bool allow_leading_zeros) { | 906 bool JSONParser::ReadInt(bool allow_leading_zeros) { |
907 char first = *pos_; | 907 char first = *pos_; |
908 int len = 0; | 908 int len = 0; |
909 | 909 |
910 char c = first; | 910 char c = first; |
911 while (CanConsume(1) && IsAsciiDigit(c)) { | 911 while (CanConsume(1) && IsAsciiDigit(c)) { |
912 c = *NextChar(); | 912 c = *NextChar(); |
913 ++len; | 913 ++len; |
914 } | 914 } |
915 | 915 |
916 if (len == 0) | 916 if (len == 0) |
917 return false; | 917 return false; |
918 | 918 |
919 if (!allow_leading_zeros && len > 1 && first == '0') | 919 if (!allow_leading_zeros && len > 1 && first == '0') |
920 return false; | 920 return false; |
921 | 921 |
922 return true; | 922 return true; |
923 } | 923 } |
924 | 924 |
925 Value* JSONParser::ConsumeLiteral() { | 925 std::unique_ptr<Value> JSONParser::ConsumeLiteral() { |
926 switch (*pos_) { | 926 switch (*pos_) { |
927 case 't': { | 927 case 't': { |
928 const char kTrueLiteral[] = "true"; | 928 const char kTrueLiteral[] = "true"; |
929 const int kTrueLen = static_cast<int>(strlen(kTrueLiteral)); | 929 const int kTrueLen = static_cast<int>(strlen(kTrueLiteral)); |
930 if (!CanConsume(kTrueLen - 1) || | 930 if (!CanConsume(kTrueLen - 1) || |
931 !StringsAreEqual(pos_, kTrueLiteral, kTrueLen)) { | 931 !StringsAreEqual(pos_, kTrueLiteral, kTrueLen)) { |
932 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 932 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
933 return nullptr; | 933 return nullptr; |
934 } | 934 } |
935 NextNChars(kTrueLen - 1); | 935 NextNChars(kTrueLen - 1); |
936 return new FundamentalValue(true); | 936 return base::MakeUnique<FundamentalValue>(true); |
937 } | 937 } |
938 case 'f': { | 938 case 'f': { |
939 const char kFalseLiteral[] = "false"; | 939 const char kFalseLiteral[] = "false"; |
940 const int kFalseLen = static_cast<int>(strlen(kFalseLiteral)); | 940 const int kFalseLen = static_cast<int>(strlen(kFalseLiteral)); |
941 if (!CanConsume(kFalseLen - 1) || | 941 if (!CanConsume(kFalseLen - 1) || |
942 !StringsAreEqual(pos_, kFalseLiteral, kFalseLen)) { | 942 !StringsAreEqual(pos_, kFalseLiteral, kFalseLen)) { |
943 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 943 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
944 return nullptr; | 944 return nullptr; |
945 } | 945 } |
946 NextNChars(kFalseLen - 1); | 946 NextNChars(kFalseLen - 1); |
947 return new FundamentalValue(false); | 947 return base::MakeUnique<FundamentalValue>(false); |
948 } | 948 } |
949 case 'n': { | 949 case 'n': { |
950 const char kNullLiteral[] = "null"; | 950 const char kNullLiteral[] = "null"; |
951 const int kNullLen = static_cast<int>(strlen(kNullLiteral)); | 951 const int kNullLen = static_cast<int>(strlen(kNullLiteral)); |
952 if (!CanConsume(kNullLen - 1) || | 952 if (!CanConsume(kNullLen - 1) || |
953 !StringsAreEqual(pos_, kNullLiteral, kNullLen)) { | 953 !StringsAreEqual(pos_, kNullLiteral, kNullLen)) { |
954 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 954 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
955 return nullptr; | 955 return nullptr; |
956 } | 956 } |
957 NextNChars(kNullLen - 1); | 957 NextNChars(kNullLen - 1); |
958 return Value::CreateNullValue().release(); | 958 return Value::CreateNullValue(); |
959 } | 959 } |
960 default: | 960 default: |
961 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 961 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
962 return nullptr; | 962 return nullptr; |
963 } | 963 } |
964 } | 964 } |
965 | 965 |
966 // static | 966 // static |
967 bool JSONParser::StringsAreEqual(const char* one, const char* two, size_t len) { | 967 bool JSONParser::StringsAreEqual(const char* one, const char* two, size_t len) { |
968 return strncmp(one, two, len) == 0; | 968 return strncmp(one, two, len) == 0; |
(...skipping 11 matching lines...) Expand all Loading... |
980 const std::string& description) { | 980 const std::string& description) { |
981 if (line || column) { | 981 if (line || column) { |
982 return StringPrintf("Line: %i, column: %i, %s", | 982 return StringPrintf("Line: %i, column: %i, %s", |
983 line, column, description.c_str()); | 983 line, column, description.c_str()); |
984 } | 984 } |
985 return description; | 985 return description; |
986 } | 986 } |
987 | 987 |
988 } // namespace internal | 988 } // namespace internal |
989 } // namespace base | 989 } // namespace base |
OLD | NEW |