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 |