blob: 1063effe3778d9dc644ab5750f4e47fa41f9e77c [file] [log] [blame]
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botf003cfe2008-08-24 09:55:55 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit3f4a7322008-07-27 06:49:38 +09004
tony@chromium.orge4948ab2009-12-02 09:20:32 +09005#include "base/values.h"
6
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +09007#include <algorithm>
kalman@chromium.org829cf752012-09-12 12:39:35 +09008#include <ostream>
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +09009
derat@chromium.orgaf8c8f02011-08-17 17:03:43 +090010#include "base/float_util.h"
kalman@chromium.org829cf752012-09-12 12:39:35 +090011#include "base/json/json_writer.h"
initial.commit3f4a7322008-07-27 06:49:38 +090012#include "base/logging.h"
scherkus@chromium.org2b923e72008-12-11 10:23:17 +090013#include "base/string_util.h"
brettw@chromium.org50c94652009-10-07 11:10:20 +090014#include "base/utf_string_conversions.h"
tony@chromium.orge4948ab2009-12-02 09:20:32 +090015
16namespace {
17
18// Make a deep copy of |node|, but don't include empty lists or dictionaries
19// in the copy. It's possible for this function to return NULL and it
20// expects |node| to always be non-NULL.
21Value* CopyWithoutEmptyChildren(Value* node) {
22 DCHECK(node);
23 switch (node->GetType()) {
24 case Value::TYPE_LIST: {
stevenjb@google.comf4f58272011-08-26 10:54:00 +090025 ListValue* list = static_cast<ListValue*>(node);
tony@chromium.orge4948ab2009-12-02 09:20:32 +090026 ListValue* copy = new ListValue;
27 for (ListValue::const_iterator it = list->begin(); it != list->end();
28 ++it) {
29 Value* child_copy = CopyWithoutEmptyChildren(*it);
30 if (child_copy)
31 copy->Append(child_copy);
32 }
33 if (!copy->empty())
34 return copy;
35
36 delete copy;
37 return NULL;
38 }
39
40 case Value::TYPE_DICTIONARY: {
41 DictionaryValue* dict = static_cast<DictionaryValue*>(node);
42 DictionaryValue* copy = new DictionaryValue;
43 for (DictionaryValue::key_iterator it = dict->begin_keys();
44 it != dict->end_keys(); ++it) {
45 Value* child = NULL;
46 bool rv = dict->GetWithoutPathExpansion(*it, &child);
47 DCHECK(rv);
48 Value* child_copy = CopyWithoutEmptyChildren(child);
49 if (child_copy)
50 copy->SetWithoutPathExpansion(*it, child_copy);
51 }
52 if (!copy->empty())
53 return copy;
54
55 delete copy;
56 return NULL;
57 }
58
59 default:
60 // For everything else, just make a copy.
61 return node->DeepCopy();
62 }
63}
64
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +090065// A small functor for comparing Values for std::find_if and similar.
66class ValueEquals {
67 public:
68 // Pass the value against which all consecutive calls of the () operator will
69 // compare their argument to. This Value object must not be destroyed while
70 // the ValueEquals is in use.
71 ValueEquals(const Value* first) : first_(first) { }
72
73 bool operator ()(const Value* second) const {
74 return first_->Equals(second);
75 }
76
77 private:
78 const Value* first_;
79};
80
tony@chromium.orge4948ab2009-12-02 09:20:32 +090081} // namespace
initial.commit3f4a7322008-07-27 06:49:38 +090082
tfarina@chromium.orgde3ef412011-08-05 08:51:10 +090083namespace base {
84
initial.commit3f4a7322008-07-27 06:49:38 +090085///////////////////// Value ////////////////////
86
87Value::~Value() {
88}
89
90// static
91Value* Value::CreateNullValue() {
92 return new Value(TYPE_NULL);
93}
94
95// static
akalin@chromium.org810f92f2011-01-18 11:16:59 +090096FundamentalValue* Value::CreateBooleanValue(bool in_value) {
initial.commit3f4a7322008-07-27 06:49:38 +090097 return new FundamentalValue(in_value);
98}
99
100// static
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900101FundamentalValue* Value::CreateIntegerValue(int in_value) {
initial.commit3f4a7322008-07-27 06:49:38 +0900102 return new FundamentalValue(in_value);
103}
104
105// static
arv@chromium.org13413eb2011-02-01 10:02:07 +0900106FundamentalValue* Value::CreateDoubleValue(double in_value) {
initial.commit3f4a7322008-07-27 06:49:38 +0900107 return new FundamentalValue(in_value);
108}
109
110// static
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900111StringValue* Value::CreateStringValue(const std::string& in_value) {
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900112 return new StringValue(in_value);
113}
114
115// static
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900116StringValue* Value::CreateStringValue(const string16& in_value) {
scherkus@chromium.org5ad62762008-12-11 07:30:57 +0900117 return new StringValue(in_value);
scherkus@chromium.org92bc0d42008-12-11 07:18:47 +0900118}
119
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900120bool Value::GetAsBoolean(bool* out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900121 return false;
122}
123
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900124bool Value::GetAsInteger(int* out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900125 return false;
126}
127
arv@chromium.org13413eb2011-02-01 10:02:07 +0900128bool Value::GetAsDouble(double* out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900129 return false;
130}
131
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900132bool Value::GetAsString(std::string* out_value) const {
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900133 return false;
134}
135
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900136bool Value::GetAsString(string16* out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900137 return false;
138}
139
scottbyer@google.com673b8762010-12-07 09:35:29 +0900140bool Value::GetAsList(ListValue** out_value) {
141 return false;
142}
143
bauerb@chromium.org6878e502011-07-12 18:04:38 +0900144bool Value::GetAsList(const ListValue** out_value) const {
145 return false;
146}
147
battre@chromium.org29eaa252011-11-26 10:11:44 +0900148bool Value::GetAsDictionary(DictionaryValue** out_value) {
149 return false;
150}
151
152bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
153 return false;
154}
155
initial.commit3f4a7322008-07-27 06:49:38 +0900156Value* Value::DeepCopy() const {
157 // This method should only be getting called for null Values--all subclasses
158 // need to provide their own implementation;.
159 DCHECK(IsType(TYPE_NULL));
160 return CreateNullValue();
161}
162
163bool Value::Equals(const Value* other) const {
164 // This method should only be getting called for null Values--all subclasses
165 // need to provide their own implementation;.
166 DCHECK(IsType(TYPE_NULL));
167 return other->IsType(TYPE_NULL);
168}
169
bauerb@chromium.orgfbd55e12010-12-07 03:13:43 +0900170// static
171bool Value::Equals(const Value* a, const Value* b) {
172 if ((a == NULL) && (b == NULL)) return true;
173 if ((a == NULL) ^ (b == NULL)) return false;
174 return a->Equals(b);
175}
176
sky@chromium.org8d103c72011-08-25 06:17:59 +0900177Value::Value(Type type) : type_(type) {
erg@chromium.org493f5f62010-07-16 06:03:54 +0900178}
179
initial.commit3f4a7322008-07-27 06:49:38 +0900180///////////////////// FundamentalValue ////////////////////
181
erg@chromium.org493f5f62010-07-16 06:03:54 +0900182FundamentalValue::FundamentalValue(bool in_value)
183 : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
184}
185
186FundamentalValue::FundamentalValue(int in_value)
187 : Value(TYPE_INTEGER), integer_value_(in_value) {
188}
189
190FundamentalValue::FundamentalValue(double in_value)
arv@chromium.org13413eb2011-02-01 10:02:07 +0900191 : Value(TYPE_DOUBLE), double_value_(in_value) {
derat@chromium.orga40267d2011-08-23 13:11:22 +0900192 if (!IsFinite(double_value_)) {
193 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
194 << "values cannot be represented in JSON";
195 double_value_ = 0.0;
196 }
erg@chromium.org493f5f62010-07-16 06:03:54 +0900197}
198
initial.commit3f4a7322008-07-27 06:49:38 +0900199FundamentalValue::~FundamentalValue() {
200}
201
202bool FundamentalValue::GetAsBoolean(bool* out_value) const {
203 if (out_value && IsType(TYPE_BOOLEAN))
204 *out_value = boolean_value_;
205 return (IsType(TYPE_BOOLEAN));
206}
207
208bool FundamentalValue::GetAsInteger(int* out_value) const {
209 if (out_value && IsType(TYPE_INTEGER))
210 *out_value = integer_value_;
211 return (IsType(TYPE_INTEGER));
212}
213
arv@chromium.org13413eb2011-02-01 10:02:07 +0900214bool FundamentalValue::GetAsDouble(double* out_value) const {
215 if (out_value && IsType(TYPE_DOUBLE))
216 *out_value = double_value_;
yusukes@google.com0b18b532011-05-02 10:59:21 +0900217 else if (out_value && IsType(TYPE_INTEGER))
218 *out_value = integer_value_;
219 return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER));
initial.commit3f4a7322008-07-27 06:49:38 +0900220}
221
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900222FundamentalValue* FundamentalValue::DeepCopy() const {
initial.commit3f4a7322008-07-27 06:49:38 +0900223 switch (GetType()) {
224 case TYPE_BOOLEAN:
225 return CreateBooleanValue(boolean_value_);
226
227 case TYPE_INTEGER:
228 return CreateIntegerValue(integer_value_);
229
arv@chromium.org13413eb2011-02-01 10:02:07 +0900230 case TYPE_DOUBLE:
231 return CreateDoubleValue(double_value_);
initial.commit3f4a7322008-07-27 06:49:38 +0900232
233 default:
234 NOTREACHED();
235 return NULL;
236 }
237}
238
239bool FundamentalValue::Equals(const Value* other) const {
240 if (other->GetType() != GetType())
241 return false;
242
243 switch (GetType()) {
244 case TYPE_BOOLEAN: {
245 bool lhs, rhs;
246 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
247 }
248 case TYPE_INTEGER: {
249 int lhs, rhs;
250 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
251 }
arv@chromium.org13413eb2011-02-01 10:02:07 +0900252 case TYPE_DOUBLE: {
initial.commit3f4a7322008-07-27 06:49:38 +0900253 double lhs, rhs;
arv@chromium.org13413eb2011-02-01 10:02:07 +0900254 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
initial.commit3f4a7322008-07-27 06:49:38 +0900255 }
256 default:
257 NOTREACHED();
258 return false;
259 }
260}
261
262///////////////////// StringValue ////////////////////
263
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900264StringValue::StringValue(const std::string& in_value)
265 : Value(TYPE_STRING),
266 value_(in_value) {
267 DCHECK(IsStringUTF8(in_value));
268}
269
munjal@chromium.org3b2d3a42010-01-16 05:09:03 +0900270StringValue::StringValue(const string16& in_value)
271 : Value(TYPE_STRING),
272 value_(UTF16ToUTF8(in_value)) {
273}
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900274
initial.commit3f4a7322008-07-27 06:49:38 +0900275StringValue::~StringValue() {
276}
277
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900278bool StringValue::GetAsString(std::string* out_value) const {
279 if (out_value)
280 *out_value = value_;
281 return true;
282}
283
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900284bool StringValue::GetAsString(string16* out_value) const {
285 if (out_value)
286 *out_value = UTF8ToUTF16(value_);
287 return true;
288}
289
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900290StringValue* StringValue::DeepCopy() const {
initial.commit3f4a7322008-07-27 06:49:38 +0900291 return CreateStringValue(value_);
292}
293
294bool StringValue::Equals(const Value* other) const {
295 if (other->GetType() != GetType())
296 return false;
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900297 std::string lhs, rhs;
initial.commit3f4a7322008-07-27 06:49:38 +0900298 return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
299}
300
301///////////////////// BinaryValue ////////////////////
302
mitchellwrosen@chromium.org3897f9b2012-05-20 04:31:16 +0900303BinaryValue::~BinaryValue() {
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900304 DCHECK(buffer_);
305 if (buffer_)
306 delete[] buffer_;
307}
308
309// static
310BinaryValue* BinaryValue::Create(char* buffer, size_t size) {
311 if (!buffer)
312 return NULL;
313
314 return new BinaryValue(buffer, size);
initial.commit3f4a7322008-07-27 06:49:38 +0900315}
316
jcampan@chromium.orgd1105672009-09-15 01:56:12 +0900317// static
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900318BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
319 size_t size) {
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900320 if (!buffer)
321 return NULL;
322
initial.commit3f4a7322008-07-27 06:49:38 +0900323 char* buffer_copy = new char[size];
mmentovai@google.com4a5b6272008-08-07 00:46:59 +0900324 memcpy(buffer_copy, buffer, size);
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900325 return new BinaryValue(buffer_copy, size);
initial.commit3f4a7322008-07-27 06:49:38 +0900326}
327
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900328BinaryValue* BinaryValue::DeepCopy() const {
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900329 return CreateWithCopiedBuffer(buffer_, size_);
initial.commit3f4a7322008-07-27 06:49:38 +0900330}
331
332bool BinaryValue::Equals(const Value* other) const {
333 if (other->GetType() != GetType())
334 return false;
335 const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
336 if (other_binary->size_ != size_)
337 return false;
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900338 return !memcmp(buffer_, other_binary->buffer_, size_);
339}
340
341BinaryValue::BinaryValue(char* buffer, size_t size)
342 : Value(TYPE_BINARY),
343 buffer_(buffer),
344 size_(size) {
345 DCHECK(buffer_);
erg@google.com67a25432011-01-08 05:23:43 +0900346}
347
initial.commit3f4a7322008-07-27 06:49:38 +0900348///////////////////// DictionaryValue ////////////////////
349
erg@chromium.org493f5f62010-07-16 06:03:54 +0900350DictionaryValue::DictionaryValue()
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900351 : Value(TYPE_DICTIONARY) {
erg@chromium.org493f5f62010-07-16 06:03:54 +0900352}
353
initial.commit3f4a7322008-07-27 06:49:38 +0900354DictionaryValue::~DictionaryValue() {
355 Clear();
356}
357
battre@chromium.org29eaa252011-11-26 10:11:44 +0900358bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
359 if (out_value)
360 *out_value = this;
361 return true;
362}
363
364bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
365 if (out_value)
366 *out_value = this;
367 return true;
368}
369
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900370bool DictionaryValue::HasKey(const std::string& key) const {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900371 DCHECK(IsStringUTF8(key));
tony@chromium.orge4948ab2009-12-02 09:20:32 +0900372 ValueMap::const_iterator current_entry = dictionary_.find(key);
373 DCHECK((current_entry == dictionary_.end()) || current_entry->second);
374 return current_entry != dictionary_.end();
375}
376
initial.commit3f4a7322008-07-27 06:49:38 +0900377void DictionaryValue::Clear() {
378 ValueMap::iterator dict_iterator = dictionary_.begin();
379 while (dict_iterator != dictionary_.end()) {
380 delete dict_iterator->second;
381 ++dict_iterator;
382 }
383
384 dictionary_.clear();
385}
386
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900387void DictionaryValue::Set(const std::string& path, Value* in_value) {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900388 DCHECK(IsStringUTF8(path));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900389 DCHECK(in_value);
390
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900391 std::string current_path(path);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900392 DictionaryValue* current_dictionary = this;
393 for (size_t delimiter_position = current_path.find('.');
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900394 delimiter_position != std::string::npos;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900395 delimiter_position = current_path.find('.')) {
396 // Assume that we're indexing into a dictionary.
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900397 std::string key(current_path, 0, delimiter_position);
pkasting@chromium.org8535dc22009-11-26 06:02:24 +0900398 DictionaryValue* child_dictionary = NULL;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900399 if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
400 child_dictionary = new DictionaryValue;
401 current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
402 }
403
404 current_dictionary = child_dictionary;
405 current_path.erase(0, delimiter_position + 1);
406 }
407
408 current_dictionary->SetWithoutPathExpansion(current_path, in_value);
409}
410
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900411void DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
412 Set(path, CreateBooleanValue(in_value));
413}
414
415void DictionaryValue::SetInteger(const std::string& path, int in_value) {
416 Set(path, CreateIntegerValue(in_value));
417}
418
arv@chromium.org13413eb2011-02-01 10:02:07 +0900419void DictionaryValue::SetDouble(const std::string& path, double in_value) {
420 Set(path, CreateDoubleValue(in_value));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900421}
422
423void DictionaryValue::SetString(const std::string& path,
424 const std::string& in_value) {
425 Set(path, CreateStringValue(in_value));
426}
427
viettrungluu@chromium.orgb7b6aa02010-08-05 01:58:12 +0900428void DictionaryValue::SetString(const std::string& path,
429 const string16& in_value) {
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900430 Set(path, CreateStringValue(in_value));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900431}
432
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900433void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900434 Value* in_value) {
initial.commit3f4a7322008-07-27 06:49:38 +0900435 // If there's an existing value here, we need to delete it, because
436 // we own all our children.
grt@chromium.org4c73d402011-10-22 07:58:52 +0900437 std::pair<ValueMap::iterator, bool> ins_res =
438 dictionary_.insert(std::make_pair(key, in_value));
439 if (!ins_res.second) {
440 DCHECK_NE(ins_res.first->second, in_value); // This would be bogus
441 delete ins_res.first->second;
442 ins_res.first->second = in_value;
initial.commit3f4a7322008-07-27 06:49:38 +0900443 }
initial.commit3f4a7322008-07-27 06:49:38 +0900444}
445
vabr@chromium.org74562432012-07-28 07:27:11 +0900446bool DictionaryValue::Get(
447 const std::string& path, const Value** out_value) const {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900448 DCHECK(IsStringUTF8(path));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900449 std::string current_path(path);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900450 const DictionaryValue* current_dictionary = this;
451 for (size_t delimiter_position = current_path.find('.');
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900452 delimiter_position != std::string::npos;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900453 delimiter_position = current_path.find('.')) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900454 const DictionaryValue* child_dictionary = NULL;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900455 if (!current_dictionary->GetDictionary(
456 current_path.substr(0, delimiter_position), &child_dictionary))
457 return false;
initial.commit3f4a7322008-07-27 06:49:38 +0900458
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900459 current_dictionary = child_dictionary;
460 current_path.erase(0, delimiter_position + 1);
initial.commit3f4a7322008-07-27 06:49:38 +0900461 }
462
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900463 return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
initial.commit3f4a7322008-07-27 06:49:38 +0900464}
465
vabr@chromium.org74562432012-07-28 07:27:11 +0900466bool DictionaryValue::Get(const std::string& path, Value** out_value) {
467 return static_cast<const DictionaryValue&>(*this).Get(
468 path,
469 const_cast<const Value**>(out_value));
470}
471
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900472bool DictionaryValue::GetBoolean(const std::string& path,
initial.commit3f4a7322008-07-27 06:49:38 +0900473 bool* bool_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900474 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900475 if (!Get(path, &value))
476 return false;
477
478 return value->GetAsBoolean(bool_value);
479}
480
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900481bool DictionaryValue::GetInteger(const std::string& path,
initial.commit3f4a7322008-07-27 06:49:38 +0900482 int* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900483 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900484 if (!Get(path, &value))
485 return false;
486
487 return value->GetAsInteger(out_value);
488}
489
arv@chromium.org13413eb2011-02-01 10:02:07 +0900490bool DictionaryValue::GetDouble(const std::string& path,
491 double* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900492 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900493 if (!Get(path, &value))
494 return false;
495
arv@chromium.org13413eb2011-02-01 10:02:07 +0900496 return value->GetAsDouble(out_value);
initial.commit3f4a7322008-07-27 06:49:38 +0900497}
498
evan@chromium.orgd9ab8de2010-02-19 22:32:16 +0900499bool DictionaryValue::GetString(const std::string& path,
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900500 std::string* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900501 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900502 if (!Get(path, &value))
503 return false;
504
505 return value->GetAsString(out_value);
506}
507
viettrungluu@chromium.org58767ef2010-08-05 04:35:33 +0900508bool DictionaryValue::GetString(const std::string& path,
509 string16* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900510 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900511 if (!Get(path, &value))
512 return false;
513
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900514 return value->GetAsString(out_value);
evan@chromium.orgd9ab8de2010-02-19 22:32:16 +0900515}
516
517bool DictionaryValue::GetStringASCII(const std::string& path,
518 std::string* out_value) const {
519 std::string out;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900520 if (!GetString(path, &out))
evan@chromium.orgd9ab8de2010-02-19 22:32:16 +0900521 return false;
522
523 if (!IsStringASCII(out)) {
524 NOTREACHED();
525 return false;
526 }
527
528 out_value->assign(out);
529 return true;
530}
531
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900532bool DictionaryValue::GetBinary(const std::string& path,
vabr@chromium.org74562432012-07-28 07:27:11 +0900533 const BinaryValue** out_value) const {
534 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900535 bool result = Get(path, &value);
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900536 if (!result || !value->IsType(TYPE_BINARY))
initial.commit3f4a7322008-07-27 06:49:38 +0900537 return false;
538
539 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900540 *out_value = static_cast<const BinaryValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900541
542 return true;
543}
544
vabr@chromium.org74562432012-07-28 07:27:11 +0900545bool DictionaryValue::GetBinary(const std::string& path,
546 BinaryValue** out_value) {
547 return static_cast<const DictionaryValue&>(*this).GetBinary(
548 path,
549 const_cast<const BinaryValue**>(out_value));
550}
551
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900552bool DictionaryValue::GetDictionary(const std::string& path,
vabr@chromium.org74562432012-07-28 07:27:11 +0900553 const DictionaryValue** out_value) const {
554 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900555 bool result = Get(path, &value);
556 if (!result || !value->IsType(TYPE_DICTIONARY))
557 return false;
558
559 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900560 *out_value = static_cast<const DictionaryValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900561
562 return true;
563}
564
vabr@chromium.org74562432012-07-28 07:27:11 +0900565bool DictionaryValue::GetDictionary(const std::string& path,
566 DictionaryValue** out_value) {
567 return static_cast<const DictionaryValue&>(*this).GetDictionary(
568 path,
569 const_cast<const DictionaryValue**>(out_value));
570}
571
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900572bool DictionaryValue::GetList(const std::string& path,
vabr@chromium.org74562432012-07-28 07:27:11 +0900573 const ListValue** out_value) const {
574 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900575 bool result = Get(path, &value);
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900576 if (!result || !value->IsType(TYPE_LIST))
initial.commit3f4a7322008-07-27 06:49:38 +0900577 return false;
578
579 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900580 *out_value = static_cast<const ListValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900581
582 return true;
583}
584
vabr@chromium.org74562432012-07-28 07:27:11 +0900585bool DictionaryValue::GetList(const std::string& path, ListValue** out_value) {
586 return static_cast<const DictionaryValue&>(*this).GetList(
587 path,
588 const_cast<const ListValue**>(out_value));
589}
590
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900591bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900592 const Value** out_value) const {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900593 DCHECK(IsStringUTF8(key));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900594 ValueMap::const_iterator entry_iterator = dictionary_.find(key);
595 if (entry_iterator == dictionary_.end())
596 return false;
initial.commit3f4a7322008-07-27 06:49:38 +0900597
vabr@chromium.org74562432012-07-28 07:27:11 +0900598 const Value* entry = entry_iterator->second;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900599 if (out_value)
600 *out_value = entry;
601 return true;
602}
603
vabr@chromium.org74562432012-07-28 07:27:11 +0900604bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
605 Value** out_value) {
606 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
607 key,
608 const_cast<const Value**>(out_value));
609}
610
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900611bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900612 int* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900613 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900614 if (!GetWithoutPathExpansion(key, &value))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900615 return false;
616
617 return value->GetAsInteger(out_value);
618}
619
arv@chromium.org13413eb2011-02-01 10:02:07 +0900620bool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
621 double* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900622 const Value* value;
jam@chromium.org5bd53922010-10-01 16:28:25 +0900623 if (!GetWithoutPathExpansion(key, &value))
624 return false;
625
arv@chromium.org13413eb2011-02-01 10:02:07 +0900626 return value->GetAsDouble(out_value);
jam@chromium.org5bd53922010-10-01 16:28:25 +0900627}
628
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900629bool DictionaryValue::GetStringWithoutPathExpansion(
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900630 const std::string& key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900631 std::string* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900632 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900633 if (!GetWithoutPathExpansion(key, &value))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900634 return false;
635
636 return value->GetAsString(out_value);
637}
638
vabr@chromium.org74562432012-07-28 07:27:11 +0900639bool DictionaryValue::GetStringWithoutPathExpansion(const std::string& key,
640 string16* out_value) const {
641 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900642 if (!GetWithoutPathExpansion(key, &value))
munjal@chromium.org3b2d3a42010-01-16 05:09:03 +0900643 return false;
644
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900645 return value->GetAsString(out_value);
munjal@chromium.org3b2d3a42010-01-16 05:09:03 +0900646}
647
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900648bool DictionaryValue::GetDictionaryWithoutPathExpansion(
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900649 const std::string& key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900650 const DictionaryValue** out_value) const {
651 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900652 bool result = GetWithoutPathExpansion(key, &value);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900653 if (!result || !value->IsType(TYPE_DICTIONARY))
654 return false;
655
656 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900657 *out_value = static_cast<const DictionaryValue*>(value);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900658
659 return true;
660}
661
vabr@chromium.org74562432012-07-28 07:27:11 +0900662bool DictionaryValue::GetDictionaryWithoutPathExpansion(
663 const std::string& key,
664 DictionaryValue** out_value) {
665 const DictionaryValue& const_this =
666 static_cast<const DictionaryValue&>(*this);
667 return const_this.GetDictionaryWithoutPathExpansion(
668 key,
669 const_cast<const DictionaryValue**>(out_value));
670}
671
672bool DictionaryValue::GetListWithoutPathExpansion(
673 const std::string& key,
674 const ListValue** out_value) const {
675 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900676 bool result = GetWithoutPathExpansion(key, &value);
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900677 if (!result || !value->IsType(TYPE_LIST))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900678 return false;
679
680 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900681 *out_value = static_cast<const ListValue*>(value);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900682
683 return true;
684}
685
vabr@chromium.org74562432012-07-28 07:27:11 +0900686bool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
687 ListValue** out_value) {
688 return
689 static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
690 key,
691 const_cast<const ListValue**>(out_value));
692}
693
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900694bool DictionaryValue::Remove(const std::string& path, Value** out_value) {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900695 DCHECK(IsStringUTF8(path));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900696 std::string current_path(path);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900697 DictionaryValue* current_dictionary = this;
698 size_t delimiter_position = current_path.rfind('.');
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900699 if (delimiter_position != std::string::npos) {
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900700 if (!GetDictionary(current_path.substr(0, delimiter_position),
701 &current_dictionary))
702 return false;
703 current_path.erase(0, delimiter_position + 1);
initial.commit3f4a7322008-07-27 06:49:38 +0900704 }
705
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900706 return current_dictionary->RemoveWithoutPathExpansion(current_path,
707 out_value);
708}
709
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900710bool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900711 Value** out_value) {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900712 DCHECK(IsStringUTF8(key));
initial.commit3f4a7322008-07-27 06:49:38 +0900713 ValueMap::iterator entry_iterator = dictionary_.find(key);
714 if (entry_iterator == dictionary_.end())
715 return false;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900716
initial.commit3f4a7322008-07-27 06:49:38 +0900717 Value* entry = entry_iterator->second;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900718 if (out_value)
719 *out_value = entry;
720 else
721 delete entry;
722 dictionary_.erase(entry_iterator);
723 return true;
initial.commit3f4a7322008-07-27 06:49:38 +0900724}
725
tony@chromium.orge4948ab2009-12-02 09:20:32 +0900726DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
727 Value* copy = CopyWithoutEmptyChildren(this);
728 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
initial.commit3f4a7322008-07-27 06:49:38 +0900729}
730
mnissler@chromium.org17cee0e2010-05-14 22:17:40 +0900731void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
732 for (DictionaryValue::key_iterator key(dictionary->begin_keys());
733 key != dictionary->end_keys(); ++key) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900734 const Value* merge_value;
mnissler@chromium.org17cee0e2010-05-14 22:17:40 +0900735 if (dictionary->GetWithoutPathExpansion(*key, &merge_value)) {
736 // Check whether we have to merge dictionaries.
737 if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
738 DictionaryValue* sub_dict;
739 if (GetDictionaryWithoutPathExpansion(*key, &sub_dict)) {
740 sub_dict->MergeDictionary(
741 static_cast<const DictionaryValue*>(merge_value));
742 continue;
743 }
744 }
745 // All other cases: Make a copy and hook it up.
746 SetWithoutPathExpansion(*key, merge_value->DeepCopy());
747 }
748 }
749}
750
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +0900751void DictionaryValue::Swap(DictionaryValue* other) {
752 dictionary_.swap(other->dictionary_);
753}
754
hans@chromium.orgd5d38e32012-08-10 21:45:35 +0900755DictionaryValue::key_iterator::key_iterator(ValueMap::const_iterator itr) {
756 itr_ = itr;
757}
758
759DictionaryValue::key_iterator::key_iterator(const key_iterator& rhs) {
760 itr_ = rhs.itr_;
761}
762
763DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
764 : target_(target),
765 it_(target.dictionary_.begin()) {}
766
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900767DictionaryValue* DictionaryValue::DeepCopy() const {
erg@google.com67a25432011-01-08 05:23:43 +0900768 DictionaryValue* result = new DictionaryValue;
769
770 for (ValueMap::const_iterator current_entry(dictionary_.begin());
771 current_entry != dictionary_.end(); ++current_entry) {
772 result->SetWithoutPathExpansion(current_entry->first,
773 current_entry->second->DeepCopy());
774 }
775
776 return result;
777}
778
779bool DictionaryValue::Equals(const Value* other) const {
780 if (other->GetType() != GetType())
781 return false;
782
783 const DictionaryValue* other_dict =
784 static_cast<const DictionaryValue*>(other);
785 key_iterator lhs_it(begin_keys());
786 key_iterator rhs_it(other_dict->begin_keys());
787 while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900788 const Value* lhs;
789 const Value* rhs;
erg@google.com67a25432011-01-08 05:23:43 +0900790 if (*lhs_it != *rhs_it ||
791 !GetWithoutPathExpansion(*lhs_it, &lhs) ||
792 !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) ||
793 !lhs->Equals(rhs)) {
794 return false;
795 }
796 ++lhs_it;
797 ++rhs_it;
798 }
799 if (lhs_it != end_keys() || rhs_it != other_dict->end_keys())
800 return false;
801
802 return true;
803}
804
initial.commit3f4a7322008-07-27 06:49:38 +0900805///////////////////// ListValue ////////////////////
806
erg@chromium.org493f5f62010-07-16 06:03:54 +0900807ListValue::ListValue() : Value(TYPE_LIST) {
808}
809
initial.commit3f4a7322008-07-27 06:49:38 +0900810ListValue::~ListValue() {
811 Clear();
812}
813
814void ListValue::Clear() {
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900815 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
816 delete *i;
initial.commit3f4a7322008-07-27 06:49:38 +0900817 list_.clear();
818}
819
820bool ListValue::Set(size_t index, Value* in_value) {
821 if (!in_value)
822 return false;
823
824 if (index >= list_.size()) {
825 // Pad out any intermediate indexes with null settings
826 while (index > list_.size())
827 Append(CreateNullValue());
828 Append(in_value);
829 } else {
830 DCHECK(list_[index] != in_value);
831 delete list_[index];
832 list_[index] = in_value;
833 }
834 return true;
835}
836
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900837bool ListValue::Get(size_t index, const Value** out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900838 if (index >= list_.size())
839 return false;
840
841 if (out_value)
842 *out_value = list_[index];
843
844 return true;
845}
846
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900847bool ListValue::Get(size_t index, Value** out_value) {
848 return static_cast<const ListValue&>(*this).Get(
849 index,
850 const_cast<const Value**>(out_value));
851}
852
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900853bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900854 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900855 if (!Get(index, &value))
856 return false;
857
858 return value->GetAsBoolean(bool_value);
859}
860
861bool ListValue::GetInteger(size_t index, int* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900862 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900863 if (!Get(index, &value))
864 return false;
865
866 return value->GetAsInteger(out_value);
867}
868
arv@chromium.org13413eb2011-02-01 10:02:07 +0900869bool ListValue::GetDouble(size_t index, double* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900870 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900871 if (!Get(index, &value))
872 return false;
873
arv@chromium.org13413eb2011-02-01 10:02:07 +0900874 return value->GetAsDouble(out_value);
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900875}
876
877bool ListValue::GetString(size_t index, std::string* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900878 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900879 if (!Get(index, &value))
880 return false;
881
882 return value->GetAsString(out_value);
883}
884
viettrungluu@chromium.org58767ef2010-08-05 04:35:33 +0900885bool ListValue::GetString(size_t index, string16* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900886 const Value* value;
viettrungluu@chromium.org58767ef2010-08-05 04:35:33 +0900887 if (!Get(index, &value))
888 return false;
889
890 return value->GetAsString(out_value);
891}
892
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900893bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const {
894 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900895 bool result = Get(index, &value);
896 if (!result || !value->IsType(TYPE_BINARY))
897 return false;
898
899 if (out_value)
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900900 *out_value = static_cast<const BinaryValue*>(value);
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900901
902 return true;
903}
904
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900905bool ListValue::GetBinary(size_t index, BinaryValue** out_value) {
906 return static_cast<const ListValue&>(*this).GetBinary(
907 index,
908 const_cast<const BinaryValue**>(out_value));
909}
910
911bool ListValue::GetDictionary(size_t index,
912 const DictionaryValue** out_value) const {
913 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900914 bool result = Get(index, &value);
915 if (!result || !value->IsType(TYPE_DICTIONARY))
916 return false;
917
918 if (out_value)
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900919 *out_value = static_cast<const DictionaryValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900920
921 return true;
922}
923
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900924bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
925 return static_cast<const ListValue&>(*this).GetDictionary(
926 index,
927 const_cast<const DictionaryValue**>(out_value));
928}
929
930bool ListValue::GetList(size_t index, const ListValue** out_value) const {
931 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900932 bool result = Get(index, &value);
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900933 if (!result || !value->IsType(TYPE_LIST))
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900934 return false;
935
936 if (out_value)
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900937 *out_value = static_cast<const ListValue*>(value);
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900938
939 return true;
940}
941
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900942bool ListValue::GetList(size_t index, ListValue** out_value) {
943 return static_cast<const ListValue&>(*this).GetList(
944 index,
945 const_cast<const ListValue**>(out_value));
946}
947
initial.commit3f4a7322008-07-27 06:49:38 +0900948bool ListValue::Remove(size_t index, Value** out_value) {
949 if (index >= list_.size())
950 return false;
951
952 if (out_value)
953 *out_value = list_[index];
954 else
955 delete list_[index];
956
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900957 list_.erase(list_.begin() + index);
initial.commit3f4a7322008-07-27 06:49:38 +0900958 return true;
959}
960
tfarina@chromium.org09cf4342011-08-14 02:34:31 +0900961bool ListValue::Remove(const Value& value, size_t* index) {
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900962 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
963 if ((*i)->Equals(&value)) {
tfarina@chromium.org09cf4342011-08-14 02:34:31 +0900964 size_t previous_index = i - list_.begin();
pkasting@chromium.orgdfe6a692009-12-01 04:59:11 +0900965 delete *i;
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900966 list_.erase(i);
robertshield@chromium.org9fb9e372010-03-23 05:12:50 +0900967
tfarina@chromium.org09cf4342011-08-14 02:34:31 +0900968 if (index)
969 *index = previous_index;
970 return true;
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900971 }
972 }
tfarina@chromium.org09cf4342011-08-14 02:34:31 +0900973 return false;
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900974}
975
estade@chromium.org52852d52012-07-03 11:51:43 +0900976void ListValue::Erase(iterator iter, Value** out_value) {
977 if (out_value)
978 *out_value = *iter;
979 else
980 delete *iter;
981
982 list_.erase(iter);
983}
984
initial.commit3f4a7322008-07-27 06:49:38 +0900985void ListValue::Append(Value* in_value) {
986 DCHECK(in_value);
987 list_.push_back(in_value);
988}
989
zork@chromium.orgb5f742b2010-04-13 06:48:10 +0900990bool ListValue::AppendIfNotPresent(Value* in_value) {
991 DCHECK(in_value);
ziadh@chromium.org5c7f6312010-07-19 17:00:42 +0900992 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
markusheintz@chromium.org78621872011-03-18 22:56:38 +0900993 if ((*i)->Equals(in_value)) {
994 delete in_value;
zork@chromium.orgb5f742b2010-04-13 06:48:10 +0900995 return false;
markusheintz@chromium.org78621872011-03-18 22:56:38 +0900996 }
zork@chromium.orgb5f742b2010-04-13 06:48:10 +0900997 }
998 list_.push_back(in_value);
999 return true;
1000}
1001
erikkay@chromium.org9034a232009-08-29 05:26:05 +09001002bool ListValue::Insert(size_t index, Value* in_value) {
1003 DCHECK(in_value);
jhawkins@chromium.org33edb6b2009-10-01 06:36:37 +09001004 if (index > list_.size())
erikkay@chromium.org9034a232009-08-29 05:26:05 +09001005 return false;
1006
1007 list_.insert(list_.begin() + index, in_value);
1008 return true;
1009}
1010
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +09001011ListValue::const_iterator ListValue::Find(const Value& value) const {
1012 return std::find_if(list_.begin(), list_.end(), ValueEquals(&value));
1013}
1014
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +09001015void ListValue::Swap(ListValue* other) {
1016 list_.swap(other->list_);
1017}
1018
scottbyer@google.com673b8762010-12-07 09:35:29 +09001019bool ListValue::GetAsList(ListValue** out_value) {
1020 if (out_value)
1021 *out_value = this;
1022 return true;
1023}
1024
bauerb@chromium.org6878e502011-07-12 18:04:38 +09001025bool ListValue::GetAsList(const ListValue** out_value) const {
1026 if (out_value)
1027 *out_value = this;
1028 return true;
1029}
1030
akalin@chromium.org810f92f2011-01-18 11:16:59 +09001031ListValue* ListValue::DeepCopy() const {
initial.commit3f4a7322008-07-27 06:49:38 +09001032 ListValue* result = new ListValue;
1033
pkasting@chromium.org727139c2009-05-09 09:33:04 +09001034 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
1035 result->Append((*i)->DeepCopy());
initial.commit3f4a7322008-07-27 06:49:38 +09001036
1037 return result;
1038}
1039
1040bool ListValue::Equals(const Value* other) const {
1041 if (other->GetType() != GetType())
1042 return false;
1043
1044 const ListValue* other_list =
1045 static_cast<const ListValue*>(other);
1046 const_iterator lhs_it, rhs_it;
1047 for (lhs_it = begin(), rhs_it = other_list->begin();
1048 lhs_it != end() && rhs_it != other_list->end();
1049 ++lhs_it, ++rhs_it) {
1050 if (!(*lhs_it)->Equals(*rhs_it))
1051 return false;
1052 }
1053 if (lhs_it != end() || rhs_it != other_list->end())
1054 return false;
1055
1056 return true;
1057}
erg@chromium.org493f5f62010-07-16 06:03:54 +09001058
1059ValueSerializer::~ValueSerializer() {
1060}
tfarina@chromium.orgde3ef412011-08-05 08:51:10 +09001061
kalman@chromium.org829cf752012-09-12 12:39:35 +09001062std::ostream& operator<<(std::ostream& out, const Value& value) {
1063 std::string json;
1064 JSONWriter::WriteWithOptions(&value,
1065 JSONWriter::OPTIONS_PRETTY_PRINT,
1066 &json);
1067 return out << json;
1068}
1069
tfarina@chromium.orgde3ef412011-08-05 08:51:10 +09001070} // namespace base