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 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" |
10 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
11 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/string_piece.h" | 13 #include "base/strings/string_piece.h" |
13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
15 #include "base/strings/utf_string_conversion_utils.h" | 16 #include "base/strings/utf_string_conversion_utils.h" |
16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
17 #include "base/third_party/icu/icu_utf.h" | 18 #include "base/third_party/icu/icu_utf.h" |
18 #include "base/values.h" | 19 #include "base/values.h" |
19 | 20 |
20 namespace base { | 21 namespace base { |
21 namespace internal { | 22 namespace internal { |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 const int kStackMaxDepth = 100; | 26 const int kStackMaxDepth = 100; |
26 | 27 |
27 const int32 kExtendedASCIIStart = 0x80; | 28 const int32_t kExtendedASCIIStart = 0x80; |
28 | 29 |
29 // This and the class below are used to own the JSON input string for when | 30 // This and the class below are used to own the JSON input string for when |
30 // string tokens are stored as StringPiece instead of std::string. This | 31 // string tokens are stored as StringPiece instead of std::string. This |
31 // optimization avoids about 2/3rds of string memory copies. The constructor | 32 // optimization avoids about 2/3rds of string memory copies. The constructor |
32 // takes ownership of the input string. The real root value is Swap()ed into | 33 // takes ownership of the input string. The real root value is Swap()ed into |
33 // the new instance. | 34 // the new instance. |
34 class DictionaryHiddenRootValue : public DictionaryValue { | 35 class DictionaryHiddenRootValue : public DictionaryValue { |
35 public: | 36 public: |
36 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { | 37 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { |
37 DCHECK(root->IsType(Value::TYPE_DICTIONARY)); | 38 DCHECK(root->IsType(Value::TYPE_DICTIONARY)); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 index_last_line_ = 0; | 221 index_last_line_ = 0; |
221 | 222 |
222 error_code_ = JSONReader::JSON_NO_ERROR; | 223 error_code_ = JSONReader::JSON_NO_ERROR; |
223 error_line_ = 0; | 224 error_line_ = 0; |
224 error_column_ = 0; | 225 error_column_ = 0; |
225 | 226 |
226 // When the input JSON string starts with a UTF-8 Byte-Order-Mark | 227 // When the input JSON string starts with a UTF-8 Byte-Order-Mark |
227 // <0xEF 0xBB 0xBF>, advance the start position to avoid the | 228 // <0xEF 0xBB 0xBF>, advance the start position to avoid the |
228 // ParseNextToken function mis-treating a Unicode BOM as an invalid | 229 // ParseNextToken function mis-treating a Unicode BOM as an invalid |
229 // character and returning NULL. | 230 // character and returning NULL. |
230 if (CanConsume(3) && static_cast<uint8>(*pos_) == 0xEF && | 231 if (CanConsume(3) && static_cast<uint8_t>(*pos_) == 0xEF && |
231 static_cast<uint8>(*(pos_ + 1)) == 0xBB && | 232 static_cast<uint8_t>(*(pos_ + 1)) == 0xBB && |
232 static_cast<uint8>(*(pos_ + 2)) == 0xBF) { | 233 static_cast<uint8_t>(*(pos_ + 2)) == 0xBF) { |
233 NextNChars(3); | 234 NextNChars(3); |
234 } | 235 } |
235 | 236 |
236 // Parse the first and any nested tokens. | 237 // Parse the first and any nested tokens. |
237 scoped_ptr<Value> root(ParseNextToken()); | 238 scoped_ptr<Value> root(ParseNextToken()); |
238 if (!root.get()) | 239 if (!root.get()) |
239 return NULL; | 240 return NULL; |
240 | 241 |
241 // Make sure the input stream is at an end. | 242 // Make sure the input stream is at an end. |
242 if (GetNextToken() != T_END_OF_INPUT) { | 243 if (GetNextToken() != T_END_OF_INPUT) { |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 607 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
607 return false; | 608 return false; |
608 } | 609 } |
609 | 610 |
610 // StringBuilder will internally build a StringPiece unless a UTF-16 | 611 // StringBuilder will internally build a StringPiece unless a UTF-16 |
611 // conversion occurs, at which point it will perform a copy into a | 612 // conversion occurs, at which point it will perform a copy into a |
612 // std::string. | 613 // std::string. |
613 StringBuilder string(NextChar()); | 614 StringBuilder string(NextChar()); |
614 | 615 |
615 int length = end_pos_ - start_pos_; | 616 int length = end_pos_ - start_pos_; |
616 int32 next_char = 0; | 617 int32_t next_char = 0; |
617 | 618 |
618 while (CanConsume(1)) { | 619 while (CanConsume(1)) { |
619 pos_ = start_pos_ + index_; // CBU8_NEXT is postcrement. | 620 pos_ = start_pos_ + index_; // CBU8_NEXT is postcrement. |
620 CBU8_NEXT(start_pos_, index_, length, next_char); | 621 CBU8_NEXT(start_pos_, index_, length, next_char); |
621 if (next_char < 0 || !IsValidCharacter(next_char)) { | 622 if (next_char < 0 || !IsValidCharacter(next_char)) { |
622 ReportError(JSONReader::JSON_UNSUPPORTED_ENCODING, 1); | 623 ReportError(JSONReader::JSON_UNSUPPORTED_ENCODING, 1); |
623 return false; | 624 return false; |
624 } | 625 } |
625 | 626 |
626 // If this character is an escape sequence... | 627 // If this character is an escape sequence... |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 int code_unit16_low = 0; | 768 int code_unit16_low = 0; |
768 if (!HexStringToInt(StringPiece(pos_, 4), &code_unit16_low)) | 769 if (!HexStringToInt(StringPiece(pos_, 4), &code_unit16_low)) |
769 return false; | 770 return false; |
770 | 771 |
771 NextNChars(3); | 772 NextNChars(3); |
772 | 773 |
773 if (!CBU16_IS_TRAIL(code_unit16_low)) { | 774 if (!CBU16_IS_TRAIL(code_unit16_low)) { |
774 return false; | 775 return false; |
775 } | 776 } |
776 | 777 |
777 uint32 code_point = CBU16_GET_SUPPLEMENTARY(code_unit16_high, | 778 uint32_t code_point = |
778 code_unit16_low); | 779 CBU16_GET_SUPPLEMENTARY(code_unit16_high, code_unit16_low); |
779 if (!IsValidCharacter(code_point)) | 780 if (!IsValidCharacter(code_point)) |
780 return false; | 781 return false; |
781 | 782 |
782 offset = 0; | 783 offset = 0; |
783 CBU8_APPEND_UNSAFE(code_unit8, offset, code_point); | 784 CBU8_APPEND_UNSAFE(code_unit8, offset, code_point); |
784 } else { | 785 } else { |
785 // Not a surrogate. | 786 // Not a surrogate. |
786 DCHECK(CBU16_IS_SINGLE(code_unit16_high)); | 787 DCHECK(CBU16_IS_SINGLE(code_unit16_high)); |
787 if (!IsValidCharacter(code_unit16_high)) | 788 if (!IsValidCharacter(code_unit16_high)) |
788 return false; | 789 return false; |
789 | 790 |
790 CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high); | 791 CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high); |
791 } | 792 } |
792 | 793 |
793 dest_string->append(code_unit8); | 794 dest_string->append(code_unit8); |
794 return true; | 795 return true; |
795 } | 796 } |
796 | 797 |
797 void JSONParser::DecodeUTF8(const int32& point, StringBuilder* dest) { | 798 void JSONParser::DecodeUTF8(const int32_t& point, StringBuilder* dest) { |
798 DCHECK(IsValidCharacter(point)); | 799 DCHECK(IsValidCharacter(point)); |
799 | 800 |
800 // Anything outside of the basic ASCII plane will need to be decoded from | 801 // Anything outside of the basic ASCII plane will need to be decoded from |
801 // int32 to a multi-byte sequence. | 802 // int32_t to a multi-byte sequence. |
802 if (point < kExtendedASCIIStart) { | 803 if (point < kExtendedASCIIStart) { |
803 dest->Append(static_cast<char>(point)); | 804 dest->Append(static_cast<char>(point)); |
804 } else { | 805 } else { |
805 char utf8_units[4] = { 0 }; | 806 char utf8_units[4] = { 0 }; |
806 int offset = 0; | 807 int offset = 0; |
807 CBU8_APPEND_UNSAFE(utf8_units, offset, point); | 808 CBU8_APPEND_UNSAFE(utf8_units, offset, point); |
808 dest->Convert(); | 809 dest->Convert(); |
809 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be | 810 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be |
810 // zero terminated at this point. |offset| contains the correct length. | 811 // zero terminated at this point. |offset| contains the correct length. |
811 dest->AppendString(std::string(utf8_units, offset)); | 812 dest->AppendString(std::string(utf8_units, offset)); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 const std::string& description) { | 966 const std::string& description) { |
966 if (line || column) { | 967 if (line || column) { |
967 return StringPrintf("Line: %i, column: %i, %s", | 968 return StringPrintf("Line: %i, column: %i, %s", |
968 line, column, description.c_str()); | 969 line, column, description.c_str()); |
969 } | 970 } |
970 return description; | 971 return description; |
971 } | 972 } |
972 | 973 |
973 } // namespace internal | 974 } // namespace internal |
974 } // namespace base | 975 } // namespace base |
OLD | NEW |