| 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/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 const int kStackMaxDepth = 100; | 25 const int kStackMaxDepth = 100; |
| 26 | 26 |
| 27 const int32 kExtendedASCIIStart = 0x80; | 27 const int32 kExtendedASCIIStart = 0x80; |
| 28 | 28 |
| 29 // This and the class below are used to own the JSON input string for when | 29 // 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 | 30 // string tokens are stored as StringPiece instead of std::string. This |
| 31 // optimization avoids about 2/3rds of string memory copies. The constructor | 31 // 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 | 32 // takes ownership of the input string. The real root value is Swap()ed into |
| 33 // the new instance. | 33 // the new instance. |
| 34 class DictionaryHiddenRootValue : public base::DictionaryValue { | 34 class DictionaryHiddenRootValue : public DictionaryValue { |
| 35 public: | 35 public: |
| 36 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { | 36 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { |
| 37 DCHECK(root->IsType(Value::TYPE_DICTIONARY)); | 37 DCHECK(root->IsType(Value::TYPE_DICTIONARY)); |
| 38 DictionaryValue::Swap(static_cast<DictionaryValue*>(root)); | 38 DictionaryValue::Swap(static_cast<DictionaryValue*>(root)); |
| 39 } | 39 } |
| 40 | 40 |
| 41 void Swap(DictionaryValue* other) override { | 41 void Swap(DictionaryValue* other) override { |
| 42 DVLOG(1) << "Swap()ing a DictionaryValue inefficiently."; | 42 DVLOG(1) << "Swap()ing a DictionaryValue inefficiently."; |
| 43 | 43 |
| 44 // First deep copy to convert JSONStringValue to std::string and swap that | 44 // First deep copy to convert JSONStringValue to std::string and swap that |
| 45 // copy with |other|, which contains the new contents of |this|. | 45 // copy with |other|, which contains the new contents of |this|. |
| 46 scoped_ptr<base::DictionaryValue> copy(DeepCopy()); | 46 scoped_ptr<DictionaryValue> copy(DeepCopy()); |
| 47 copy->Swap(other); | 47 copy->Swap(other); |
| 48 | 48 |
| 49 // Then erase the contents of the current dictionary and swap in the | 49 // Then erase the contents of the current dictionary and swap in the |
| 50 // new contents, originally from |other|. | 50 // new contents, originally from |other|. |
| 51 Clear(); | 51 Clear(); |
| 52 json_.reset(); | 52 json_.reset(); |
| 53 DictionaryValue::Swap(copy.get()); | 53 DictionaryValue::Swap(copy.get()); |
| 54 } | 54 } |
| 55 | 55 |
| 56 // Not overriding DictionaryValue::Remove because it just calls through to | 56 // Not overriding DictionaryValue::Remove because it just calls through to |
| (...skipping 17 matching lines...) Expand all Loading... |
| 74 | 74 |
| 75 return true; | 75 return true; |
| 76 } | 76 } |
| 77 | 77 |
| 78 private: | 78 private: |
| 79 scoped_ptr<std::string> json_; | 79 scoped_ptr<std::string> json_; |
| 80 | 80 |
| 81 DISALLOW_COPY_AND_ASSIGN(DictionaryHiddenRootValue); | 81 DISALLOW_COPY_AND_ASSIGN(DictionaryHiddenRootValue); |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 class ListHiddenRootValue : public base::ListValue { | 84 class ListHiddenRootValue : public ListValue { |
| 85 public: | 85 public: |
| 86 ListHiddenRootValue(std::string* json, Value* root) : json_(json) { | 86 ListHiddenRootValue(std::string* json, Value* root) : json_(json) { |
| 87 DCHECK(root->IsType(Value::TYPE_LIST)); | 87 DCHECK(root->IsType(Value::TYPE_LIST)); |
| 88 ListValue::Swap(static_cast<ListValue*>(root)); | 88 ListValue::Swap(static_cast<ListValue*>(root)); |
| 89 } | 89 } |
| 90 | 90 |
| 91 void Swap(ListValue* other) override { | 91 void Swap(ListValue* other) override { |
| 92 DVLOG(1) << "Swap()ing a ListValue inefficiently."; | 92 DVLOG(1) << "Swap()ing a ListValue inefficiently."; |
| 93 | 93 |
| 94 // First deep copy to convert JSONStringValue to std::string and swap that | 94 // First deep copy to convert JSONStringValue to std::string and swap that |
| 95 // copy with |other|, which contains the new contents of |this|. | 95 // copy with |other|, which contains the new contents of |this|. |
| 96 scoped_ptr<base::ListValue> copy(DeepCopy()); | 96 scoped_ptr<ListValue> copy(DeepCopy()); |
| 97 copy->Swap(other); | 97 copy->Swap(other); |
| 98 | 98 |
| 99 // Then erase the contents of the current list and swap in the new contents, | 99 // Then erase the contents of the current list and swap in the new contents, |
| 100 // originally from |other|. | 100 // originally from |other|. |
| 101 Clear(); | 101 Clear(); |
| 102 json_.reset(); | 102 json_.reset(); |
| 103 ListValue::Swap(copy.get()); | 103 ListValue::Swap(copy.get()); |
| 104 } | 104 } |
| 105 | 105 |
| 106 bool Remove(size_t index, scoped_ptr<Value>* out) override { | 106 bool Remove(size_t index, scoped_ptr<Value>* out) override { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 123 | 123 |
| 124 private: | 124 private: |
| 125 scoped_ptr<std::string> json_; | 125 scoped_ptr<std::string> json_; |
| 126 | 126 |
| 127 DISALLOW_COPY_AND_ASSIGN(ListHiddenRootValue); | 127 DISALLOW_COPY_AND_ASSIGN(ListHiddenRootValue); |
| 128 }; | 128 }; |
| 129 | 129 |
| 130 // A variant on StringValue that uses StringPiece instead of copying the string | 130 // A variant on StringValue that uses StringPiece instead of copying the string |
| 131 // into the Value. This can only be stored in a child of hidden root (above), | 131 // into the Value. This can only be stored in a child of hidden root (above), |
| 132 // otherwise the referenced string will not be guaranteed to outlive it. | 132 // otherwise the referenced string will not be guaranteed to outlive it. |
| 133 class JSONStringValue : public base::Value { | 133 class JSONStringValue : public Value { |
| 134 public: | 134 public: |
| 135 explicit JSONStringValue(const base::StringPiece& piece) | 135 explicit JSONStringValue(const StringPiece& piece) |
| 136 : Value(TYPE_STRING), | 136 : Value(TYPE_STRING), string_piece_(piece) {} |
| 137 string_piece_(piece) { | |
| 138 } | |
| 139 | 137 |
| 140 // Overridden from base::Value: | 138 // Overridden from Value: |
| 141 bool GetAsString(std::string* out_value) const override { | 139 bool GetAsString(std::string* out_value) const override { |
| 142 string_piece_.CopyToString(out_value); | 140 string_piece_.CopyToString(out_value); |
| 143 return true; | 141 return true; |
| 144 } | 142 } |
| 145 bool GetAsString(string16* out_value) const override { | 143 bool GetAsString(string16* out_value) const override { |
| 146 *out_value = UTF8ToUTF16(string_piece_); | 144 *out_value = UTF8ToUTF16(string_piece_); |
| 147 return true; | 145 return true; |
| 148 } | 146 } |
| 149 Value* DeepCopy() const override { | 147 Value* DeepCopy() const override { |
| 150 return new StringValue(string_piece_.as_string()); | 148 return new StringValue(string_piece_.as_string()); |
| 151 } | 149 } |
| 152 bool Equals(const Value* other) const override { | 150 bool Equals(const Value* other) const override { |
| 153 std::string other_string; | 151 std::string other_string; |
| 154 return other->IsType(TYPE_STRING) && other->GetAsString(&other_string) && | 152 return other->IsType(TYPE_STRING) && other->GetAsString(&other_string) && |
| 155 StringPiece(other_string) == string_piece_; | 153 StringPiece(other_string) == string_piece_; |
| 156 } | 154 } |
| 157 | 155 |
| 158 private: | 156 private: |
| 159 // The location in the original input stream. | 157 // The location in the original input stream. |
| 160 base::StringPiece string_piece_; | 158 StringPiece string_piece_; |
| 161 | 159 |
| 162 DISALLOW_COPY_AND_ASSIGN(JSONStringValue); | 160 DISALLOW_COPY_AND_ASSIGN(JSONStringValue); |
| 163 }; | 161 }; |
| 164 | 162 |
| 165 // Simple class that checks for maximum recursion/"stack overflow." | 163 // Simple class that checks for maximum recursion/"stack overflow." |
| 166 class StackMarker { | 164 class StackMarker { |
| 167 public: | 165 public: |
| 168 explicit StackMarker(int* depth) : depth_(depth) { | 166 explicit StackMarker(int* depth) : depth_(depth) { |
| 169 ++(*depth_); | 167 ++(*depth_); |
| 170 DCHECK_LE(*depth_, kStackMaxDepth); | 168 DCHECK_LE(*depth_, kStackMaxDepth); |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 return false; | 767 return false; |
| 770 | 768 |
| 771 NextNChars(3); | 769 NextNChars(3); |
| 772 | 770 |
| 773 if (!CBU16_IS_TRAIL(code_unit16_low)) { | 771 if (!CBU16_IS_TRAIL(code_unit16_low)) { |
| 774 return false; | 772 return false; |
| 775 } | 773 } |
| 776 | 774 |
| 777 uint32 code_point = CBU16_GET_SUPPLEMENTARY(code_unit16_high, | 775 uint32 code_point = CBU16_GET_SUPPLEMENTARY(code_unit16_high, |
| 778 code_unit16_low); | 776 code_unit16_low); |
| 777 if (!IsValidCharacter(code_point)) |
| 778 return false; |
| 779 |
| 779 offset = 0; | 780 offset = 0; |
| 780 CBU8_APPEND_UNSAFE(code_unit8, offset, code_point); | 781 CBU8_APPEND_UNSAFE(code_unit8, offset, code_point); |
| 781 } else { | 782 } else { |
| 782 // Not a surrogate. | 783 // Not a surrogate. |
| 783 DCHECK(CBU16_IS_SINGLE(code_unit16_high)); | 784 DCHECK(CBU16_IS_SINGLE(code_unit16_high)); |
| 785 if (!IsValidCharacter(code_unit16_high)) |
| 786 return false; |
| 787 |
| 784 CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high); | 788 CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high); |
| 785 } | 789 } |
| 786 | 790 |
| 787 dest_string->append(code_unit8); | 791 dest_string->append(code_unit8); |
| 788 return true; | 792 return true; |
| 789 } | 793 } |
| 790 | 794 |
| 791 void JSONParser::DecodeUTF8(const int32& point, StringBuilder* dest) { | 795 void JSONParser::DecodeUTF8(const int32& point, StringBuilder* dest) { |
| 796 DCHECK(IsValidCharacter(point)); |
| 797 |
| 792 // Anything outside of the basic ASCII plane will need to be decoded from | 798 // Anything outside of the basic ASCII plane will need to be decoded from |
| 793 // int32 to a multi-byte sequence. | 799 // int32 to a multi-byte sequence. |
| 794 if (point < kExtendedASCIIStart) { | 800 if (point < kExtendedASCIIStart) { |
| 795 dest->Append(static_cast<char>(point)); | 801 dest->Append(static_cast<char>(point)); |
| 796 } else { | 802 } else { |
| 797 char utf8_units[4] = { 0 }; | 803 char utf8_units[4] = { 0 }; |
| 798 int offset = 0; | 804 int offset = 0; |
| 799 CBU8_APPEND_UNSAFE(utf8_units, offset, point); | 805 CBU8_APPEND_UNSAFE(utf8_units, offset, point); |
| 800 dest->Convert(); | 806 dest->Convert(); |
| 801 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be | 807 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 pos_ = exit_pos; | 871 pos_ = exit_pos; |
| 866 index_ = exit_index; | 872 index_ = exit_index; |
| 867 | 873 |
| 868 StringPiece num_string(num_start, end_index - start_index); | 874 StringPiece num_string(num_start, end_index - start_index); |
| 869 | 875 |
| 870 int num_int; | 876 int num_int; |
| 871 if (StringToInt(num_string, &num_int)) | 877 if (StringToInt(num_string, &num_int)) |
| 872 return new FundamentalValue(num_int); | 878 return new FundamentalValue(num_int); |
| 873 | 879 |
| 874 double num_double; | 880 double num_double; |
| 875 if (base::StringToDouble(num_string.as_string(), &num_double) && | 881 if (StringToDouble(num_string.as_string(), &num_double) && |
| 876 std::isfinite(num_double)) { | 882 std::isfinite(num_double)) { |
| 877 return new FundamentalValue(num_double); | 883 return new FundamentalValue(num_double); |
| 878 } | 884 } |
| 879 | 885 |
| 880 return NULL; | 886 return NULL; |
| 881 } | 887 } |
| 882 | 888 |
| 883 bool JSONParser::ReadInt(bool allow_leading_zeros) { | 889 bool JSONParser::ReadInt(bool allow_leading_zeros) { |
| 884 char first = *pos_; | 890 char first = *pos_; |
| 885 int len = 0; | 891 int len = 0; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 const std::string& description) { | 963 const std::string& description) { |
| 958 if (line || column) { | 964 if (line || column) { |
| 959 return StringPrintf("Line: %i, column: %i, %s", | 965 return StringPrintf("Line: %i, column: %i, %s", |
| 960 line, column, description.c_str()); | 966 line, column, description.c_str()); |
| 961 } | 967 } |
| 962 return description; | 968 return description; |
| 963 } | 969 } |
| 964 | 970 |
| 965 } // namespace internal | 971 } // namespace internal |
| 966 } // namespace base | 972 } // namespace base |
| OLD | NEW |