| 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), |
| 137 string_piece_(piece) { | 137 string_piece_(piece) { |
| 138 } | 138 } |
| 139 | 139 |
| 140 // Overridden from base::Value: | 140 // Overridden from Value: |
| 141 bool GetAsString(std::string* out_value) const override { | 141 bool GetAsString(std::string* out_value) const override { |
| 142 string_piece_.CopyToString(out_value); | 142 string_piece_.CopyToString(out_value); |
| 143 return true; | 143 return true; |
| 144 } | 144 } |
| 145 bool GetAsString(string16* out_value) const override { | 145 bool GetAsString(string16* out_value) const override { |
| 146 *out_value = UTF8ToUTF16(string_piece_); | 146 *out_value = UTF8ToUTF16(string_piece_); |
| 147 return true; | 147 return true; |
| 148 } | 148 } |
| 149 Value* DeepCopy() const override { | 149 Value* DeepCopy() const override { |
| 150 return new StringValue(string_piece_.as_string()); | 150 return new StringValue(string_piece_.as_string()); |
| 151 } | 151 } |
| 152 bool Equals(const Value* other) const override { | 152 bool Equals(const Value* other) const override { |
| 153 std::string other_string; | 153 std::string other_string; |
| 154 return other->IsType(TYPE_STRING) && other->GetAsString(&other_string) && | 154 return other->IsType(TYPE_STRING) && other->GetAsString(&other_string) && |
| 155 StringPiece(other_string) == string_piece_; | 155 StringPiece(other_string) == string_piece_; |
| 156 } | 156 } |
| 157 | 157 |
| 158 private: | 158 private: |
| 159 // The location in the original input stream. | 159 // The location in the original input stream. |
| 160 base::StringPiece string_piece_; | 160 StringPiece string_piece_; |
| 161 | 161 |
| 162 DISALLOW_COPY_AND_ASSIGN(JSONStringValue); | 162 DISALLOW_COPY_AND_ASSIGN(JSONStringValue); |
| 163 }; | 163 }; |
| 164 | 164 |
| 165 // Simple class that checks for maximum recursion/"stack overflow." | 165 // Simple class that checks for maximum recursion/"stack overflow." |
| 166 class StackMarker { | 166 class StackMarker { |
| 167 public: | 167 public: |
| 168 explicit StackMarker(int* depth) : depth_(depth) { | 168 explicit StackMarker(int* depth) : depth_(depth) { |
| 169 ++(*depth_); | 169 ++(*depth_); |
| 170 DCHECK_LE(*depth_, kStackMaxDepth); | 170 DCHECK_LE(*depth_, kStackMaxDepth); |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 pos_ = exit_pos; | 865 pos_ = exit_pos; |
| 866 index_ = exit_index; | 866 index_ = exit_index; |
| 867 | 867 |
| 868 StringPiece num_string(num_start, end_index - start_index); | 868 StringPiece num_string(num_start, end_index - start_index); |
| 869 | 869 |
| 870 int num_int; | 870 int num_int; |
| 871 if (StringToInt(num_string, &num_int)) | 871 if (StringToInt(num_string, &num_int)) |
| 872 return new FundamentalValue(num_int); | 872 return new FundamentalValue(num_int); |
| 873 | 873 |
| 874 double num_double; | 874 double num_double; |
| 875 if (base::StringToDouble(num_string.as_string(), &num_double) && | 875 if (StringToDouble(num_string.as_string(), &num_double) && |
| 876 std::isfinite(num_double)) { | 876 std::isfinite(num_double)) { |
| 877 return new FundamentalValue(num_double); | 877 return new FundamentalValue(num_double); |
| 878 } | 878 } |
| 879 | 879 |
| 880 return NULL; | 880 return NULL; |
| 881 } | 881 } |
| 882 | 882 |
| 883 bool JSONParser::ReadInt(bool allow_leading_zeros) { | 883 bool JSONParser::ReadInt(bool allow_leading_zeros) { |
| 884 char first = *pos_; | 884 char first = *pos_; |
| 885 int len = 0; | 885 int len = 0; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 const std::string& description) { | 957 const std::string& description) { |
| 958 if (line || column) { | 958 if (line || column) { |
| 959 return StringPrintf("Line: %i, column: %i, %s", | 959 return StringPrintf("Line: %i, column: %i, %s", |
| 960 line, column, description.c_str()); | 960 line, column, description.c_str()); |
| 961 } | 961 } |
| 962 return description; | 962 return description; |
| 963 } | 963 } |
| 964 | 964 |
| 965 } // namespace internal | 965 } // namespace internal |
| 966 } // namespace base | 966 } // namespace base |
| OLD | NEW |