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 <memory> |
8 | 9 |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "base/macros.h" | 11 #include "base/macros.h" |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
13 #include "base/strings/string_piece.h" | 13 #include "base/strings/string_piece.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "base/strings/utf_string_conversion_utils.h" | 16 #include "base/strings/utf_string_conversion_utils.h" |
17 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
18 #include "base/third_party/icu/icu_utf.h" | 18 #include "base/third_party/icu/icu_utf.h" |
19 #include "base/values.h" | 19 #include "base/values.h" |
20 | 20 |
21 namespace base { | 21 namespace base { |
(...skipping 15 matching lines...) Expand all Loading... |
37 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { | 37 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { |
38 DCHECK(root->IsType(Value::TYPE_DICTIONARY)); | 38 DCHECK(root->IsType(Value::TYPE_DICTIONARY)); |
39 DictionaryValue::Swap(static_cast<DictionaryValue*>(root)); | 39 DictionaryValue::Swap(static_cast<DictionaryValue*>(root)); |
40 } | 40 } |
41 | 41 |
42 void Swap(DictionaryValue* other) override { | 42 void Swap(DictionaryValue* other) override { |
43 DVLOG(1) << "Swap()ing a DictionaryValue inefficiently."; | 43 DVLOG(1) << "Swap()ing a DictionaryValue inefficiently."; |
44 | 44 |
45 // First deep copy to convert JSONStringValue to std::string and swap that | 45 // First deep copy to convert JSONStringValue to std::string and swap that |
46 // copy with |other|, which contains the new contents of |this|. | 46 // copy with |other|, which contains the new contents of |this|. |
47 scoped_ptr<DictionaryValue> copy(DeepCopy()); | 47 std::unique_ptr<DictionaryValue> copy(DeepCopy()); |
48 copy->Swap(other); | 48 copy->Swap(other); |
49 | 49 |
50 // Then erase the contents of the current dictionary and swap in the | 50 // Then erase the contents of the current dictionary and swap in the |
51 // new contents, originally from |other|. | 51 // new contents, originally from |other|. |
52 Clear(); | 52 Clear(); |
53 json_.reset(); | 53 json_.reset(); |
54 DictionaryValue::Swap(copy.get()); | 54 DictionaryValue::Swap(copy.get()); |
55 } | 55 } |
56 | 56 |
57 // Not overriding DictionaryValue::Remove because it just calls through to | 57 // Not overriding DictionaryValue::Remove because it just calls through to |
58 // the method below. | 58 // the method below. |
59 | 59 |
60 bool RemoveWithoutPathExpansion(const std::string& key, | 60 bool RemoveWithoutPathExpansion(const std::string& key, |
61 scoped_ptr<Value>* out) override { | 61 std::unique_ptr<Value>* out) override { |
62 // If the caller won't take ownership of the removed value, just call up. | 62 // If the caller won't take ownership of the removed value, just call up. |
63 if (!out) | 63 if (!out) |
64 return DictionaryValue::RemoveWithoutPathExpansion(key, out); | 64 return DictionaryValue::RemoveWithoutPathExpansion(key, out); |
65 | 65 |
66 DVLOG(1) << "Remove()ing from a DictionaryValue inefficiently."; | 66 DVLOG(1) << "Remove()ing from a DictionaryValue inefficiently."; |
67 | 67 |
68 // Otherwise, remove the value while its still "owned" by this and copy it | 68 // Otherwise, remove the value while its still "owned" by this and copy it |
69 // to convert any JSONStringValues to std::string. | 69 // to convert any JSONStringValues to std::string. |
70 scoped_ptr<Value> out_owned; | 70 std::unique_ptr<Value> out_owned; |
71 if (!DictionaryValue::RemoveWithoutPathExpansion(key, &out_owned)) | 71 if (!DictionaryValue::RemoveWithoutPathExpansion(key, &out_owned)) |
72 return false; | 72 return false; |
73 | 73 |
74 out->reset(out_owned->DeepCopy()); | 74 out->reset(out_owned->DeepCopy()); |
75 | 75 |
76 return true; | 76 return true; |
77 } | 77 } |
78 | 78 |
79 private: | 79 private: |
80 scoped_ptr<std::string> json_; | 80 std::unique_ptr<std::string> json_; |
81 | 81 |
82 DISALLOW_COPY_AND_ASSIGN(DictionaryHiddenRootValue); | 82 DISALLOW_COPY_AND_ASSIGN(DictionaryHiddenRootValue); |
83 }; | 83 }; |
84 | 84 |
85 class ListHiddenRootValue : public ListValue { | 85 class ListHiddenRootValue : public ListValue { |
86 public: | 86 public: |
87 ListHiddenRootValue(std::string* json, Value* root) : json_(json) { | 87 ListHiddenRootValue(std::string* json, Value* root) : json_(json) { |
88 DCHECK(root->IsType(Value::TYPE_LIST)); | 88 DCHECK(root->IsType(Value::TYPE_LIST)); |
89 ListValue::Swap(static_cast<ListValue*>(root)); | 89 ListValue::Swap(static_cast<ListValue*>(root)); |
90 } | 90 } |
91 | 91 |
92 void Swap(ListValue* other) override { | 92 void Swap(ListValue* other) override { |
93 DVLOG(1) << "Swap()ing a ListValue inefficiently."; | 93 DVLOG(1) << "Swap()ing a ListValue inefficiently."; |
94 | 94 |
95 // First deep copy to convert JSONStringValue to std::string and swap that | 95 // First deep copy to convert JSONStringValue to std::string and swap that |
96 // copy with |other|, which contains the new contents of |this|. | 96 // copy with |other|, which contains the new contents of |this|. |
97 scoped_ptr<ListValue> copy(DeepCopy()); | 97 std::unique_ptr<ListValue> copy(DeepCopy()); |
98 copy->Swap(other); | 98 copy->Swap(other); |
99 | 99 |
100 // Then erase the contents of the current list and swap in the new contents, | 100 // Then erase the contents of the current list and swap in the new contents, |
101 // originally from |other|. | 101 // originally from |other|. |
102 Clear(); | 102 Clear(); |
103 json_.reset(); | 103 json_.reset(); |
104 ListValue::Swap(copy.get()); | 104 ListValue::Swap(copy.get()); |
105 } | 105 } |
106 | 106 |
107 bool Remove(size_t index, scoped_ptr<Value>* out) override { | 107 bool Remove(size_t index, std::unique_ptr<Value>* out) override { |
108 // If the caller won't take ownership of the removed value, just call up. | 108 // If the caller won't take ownership of the removed value, just call up. |
109 if (!out) | 109 if (!out) |
110 return ListValue::Remove(index, out); | 110 return ListValue::Remove(index, out); |
111 | 111 |
112 DVLOG(1) << "Remove()ing from a ListValue inefficiently."; | 112 DVLOG(1) << "Remove()ing from a ListValue inefficiently."; |
113 | 113 |
114 // Otherwise, remove the value while its still "owned" by this and copy it | 114 // Otherwise, remove the value while its still "owned" by this and copy it |
115 // to convert any JSONStringValues to std::string. | 115 // to convert any JSONStringValues to std::string. |
116 scoped_ptr<Value> out_owned; | 116 std::unique_ptr<Value> out_owned; |
117 if (!ListValue::Remove(index, &out_owned)) | 117 if (!ListValue::Remove(index, &out_owned)) |
118 return false; | 118 return false; |
119 | 119 |
120 out->reset(out_owned->DeepCopy()); | 120 out->reset(out_owned->DeepCopy()); |
121 | 121 |
122 return true; | 122 return true; |
123 } | 123 } |
124 | 124 |
125 private: | 125 private: |
126 scoped_ptr<std::string> json_; | 126 std::unique_ptr<std::string> json_; |
127 | 127 |
128 DISALLOW_COPY_AND_ASSIGN(ListHiddenRootValue); | 128 DISALLOW_COPY_AND_ASSIGN(ListHiddenRootValue); |
129 }; | 129 }; |
130 | 130 |
131 // A variant on StringValue that uses StringPiece instead of copying the string | 131 // A variant on StringValue that uses StringPiece instead of copying the string |
132 // into the Value. This can only be stored in a child of hidden root (above), | 132 // into the Value. This can only be stored in a child of hidden root (above), |
133 // otherwise the referenced string will not be guaranteed to outlive it. | 133 // otherwise the referenced string will not be guaranteed to outlive it. |
134 class JSONStringValue : public Value { | 134 class JSONStringValue : public Value { |
135 public: | 135 public: |
136 explicit JSONStringValue(const StringPiece& piece) | 136 explicit JSONStringValue(const StringPiece& piece) |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 index_last_line_(0), | 197 index_last_line_(0), |
198 error_code_(JSONReader::JSON_NO_ERROR), | 198 error_code_(JSONReader::JSON_NO_ERROR), |
199 error_line_(0), | 199 error_line_(0), |
200 error_column_(0) { | 200 error_column_(0) { |
201 } | 201 } |
202 | 202 |
203 JSONParser::~JSONParser() { | 203 JSONParser::~JSONParser() { |
204 } | 204 } |
205 | 205 |
206 Value* JSONParser::Parse(const StringPiece& input) { | 206 Value* JSONParser::Parse(const StringPiece& input) { |
207 scoped_ptr<std::string> input_copy; | 207 std::unique_ptr<std::string> input_copy; |
208 // If the children of a JSON root can be detached, then hidden roots cannot | 208 // If the children of a JSON root can be detached, then hidden roots cannot |
209 // be used, so do not bother copying the input because StringPiece will not | 209 // be used, so do not bother copying the input because StringPiece will not |
210 // be used anywhere. | 210 // be used anywhere. |
211 if (!(options_ & JSON_DETACHABLE_CHILDREN)) { | 211 if (!(options_ & JSON_DETACHABLE_CHILDREN)) { |
212 input_copy.reset(new std::string(input.as_string())); | 212 input_copy.reset(new std::string(input.as_string())); |
213 start_pos_ = input_copy->data(); | 213 start_pos_ = input_copy->data(); |
214 } else { | 214 } else { |
215 start_pos_ = input.data(); | 215 start_pos_ = input.data(); |
216 } | 216 } |
217 pos_ = start_pos_; | 217 pos_ = start_pos_; |
(...skipping 10 matching lines...) Expand all Loading... |
228 // <0xEF 0xBB 0xBF>, advance the start position to avoid the | 228 // <0xEF 0xBB 0xBF>, advance the start position to avoid the |
229 // ParseNextToken function mis-treating a Unicode BOM as an invalid | 229 // ParseNextToken function mis-treating a Unicode BOM as an invalid |
230 // character and returning NULL. | 230 // character and returning NULL. |
231 if (CanConsume(3) && static_cast<uint8_t>(*pos_) == 0xEF && | 231 if (CanConsume(3) && static_cast<uint8_t>(*pos_) == 0xEF && |
232 static_cast<uint8_t>(*(pos_ + 1)) == 0xBB && | 232 static_cast<uint8_t>(*(pos_ + 1)) == 0xBB && |
233 static_cast<uint8_t>(*(pos_ + 2)) == 0xBF) { | 233 static_cast<uint8_t>(*(pos_ + 2)) == 0xBF) { |
234 NextNChars(3); | 234 NextNChars(3); |
235 } | 235 } |
236 | 236 |
237 // Parse the first and any nested tokens. | 237 // Parse the first and any nested tokens. |
238 scoped_ptr<Value> root(ParseNextToken()); | 238 std::unique_ptr<Value> root(ParseNextToken()); |
239 if (!root.get()) | 239 if (!root.get()) |
240 return NULL; | 240 return NULL; |
241 | 241 |
242 // Make sure the input stream is at an end. | 242 // Make sure the input stream is at an end. |
243 if (GetNextToken() != T_END_OF_INPUT) { | 243 if (GetNextToken() != T_END_OF_INPUT) { |
244 if (!CanConsume(1) || (NextChar() && GetNextToken() != T_END_OF_INPUT)) { | 244 if (!CanConsume(1) || (NextChar() && GetNextToken() != T_END_OF_INPUT)) { |
245 ReportError(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, 1); | 245 ReportError(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, 1); |
246 return NULL; | 246 return NULL; |
247 } | 247 } |
248 } | 248 } |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 492 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
493 return NULL; | 493 return NULL; |
494 } | 494 } |
495 | 495 |
496 StackMarker depth_check(&stack_depth_); | 496 StackMarker depth_check(&stack_depth_); |
497 if (depth_check.IsTooDeep()) { | 497 if (depth_check.IsTooDeep()) { |
498 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); | 498 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); |
499 return NULL; | 499 return NULL; |
500 } | 500 } |
501 | 501 |
502 scoped_ptr<DictionaryValue> dict(new DictionaryValue); | 502 std::unique_ptr<DictionaryValue> dict(new DictionaryValue); |
503 | 503 |
504 NextChar(); | 504 NextChar(); |
505 Token token = GetNextToken(); | 505 Token token = GetNextToken(); |
506 while (token != T_OBJECT_END) { | 506 while (token != T_OBJECT_END) { |
507 if (token != T_STRING) { | 507 if (token != T_STRING) { |
508 ReportError(JSONReader::JSON_UNQUOTED_DICTIONARY_KEY, 1); | 508 ReportError(JSONReader::JSON_UNQUOTED_DICTIONARY_KEY, 1); |
509 return NULL; | 509 return NULL; |
510 } | 510 } |
511 | 511 |
512 // First consume the key. | 512 // First consume the key. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 556 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
557 return NULL; | 557 return NULL; |
558 } | 558 } |
559 | 559 |
560 StackMarker depth_check(&stack_depth_); | 560 StackMarker depth_check(&stack_depth_); |
561 if (depth_check.IsTooDeep()) { | 561 if (depth_check.IsTooDeep()) { |
562 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); | 562 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); |
563 return NULL; | 563 return NULL; |
564 } | 564 } |
565 | 565 |
566 scoped_ptr<ListValue> list(new ListValue); | 566 std::unique_ptr<ListValue> list(new ListValue); |
567 | 567 |
568 NextChar(); | 568 NextChar(); |
569 Token token = GetNextToken(); | 569 Token token = GetNextToken(); |
570 while (token != T_ARRAY_END) { | 570 while (token != T_ARRAY_END) { |
571 Value* item = ParseToken(token); | 571 Value* item = ParseToken(token); |
572 if (!item) { | 572 if (!item) { |
573 // ReportError from deeper level. | 573 // ReportError from deeper level. |
574 return NULL; | 574 return NULL; |
575 } | 575 } |
576 | 576 |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 const std::string& description) { | 974 const std::string& description) { |
975 if (line || column) { | 975 if (line || column) { |
976 return StringPrintf("Line: %i, column: %i, %s", | 976 return StringPrintf("Line: %i, column: %i, %s", |
977 line, column, description.c_str()); | 977 line, column, description.c_str()); |
978 } | 978 } |
979 return description; | 979 return description; |
980 } | 980 } |
981 | 981 |
982 } // namespace internal | 982 } // namespace internal |
983 } // namespace base | 983 } // namespace base |
OLD | NEW |