blob: 1ccc9ec4a13755fab4115b20303be9872896f9b0 [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>
8
derat@chromium.orgaf8c8f02011-08-17 17:03:43 +09009#include "base/float_util.h"
initial.commit3f4a7322008-07-27 06:49:38 +090010#include "base/logging.h"
scherkus@chromium.org2b923e72008-12-11 10:23:17 +090011#include "base/string_util.h"
brettw@chromium.org50c94652009-10-07 11:10:20 +090012#include "base/utf_string_conversions.h"
tony@chromium.orge4948ab2009-12-02 09:20:32 +090013
14namespace {
15
16// Make a deep copy of |node|, but don't include empty lists or dictionaries
17// in the copy. It's possible for this function to return NULL and it
18// expects |node| to always be non-NULL.
19Value* CopyWithoutEmptyChildren(Value* node) {
20 DCHECK(node);
21 switch (node->GetType()) {
22 case Value::TYPE_LIST: {
stevenjb@google.comf4f58272011-08-26 10:54:00 +090023 ListValue* list = static_cast<ListValue*>(node);
tony@chromium.orge4948ab2009-12-02 09:20:32 +090024 ListValue* copy = new ListValue;
25 for (ListValue::const_iterator it = list->begin(); it != list->end();
26 ++it) {
27 Value* child_copy = CopyWithoutEmptyChildren(*it);
28 if (child_copy)
29 copy->Append(child_copy);
30 }
31 if (!copy->empty())
32 return copy;
33
34 delete copy;
35 return NULL;
36 }
37
38 case Value::TYPE_DICTIONARY: {
39 DictionaryValue* dict = static_cast<DictionaryValue*>(node);
40 DictionaryValue* copy = new DictionaryValue;
41 for (DictionaryValue::key_iterator it = dict->begin_keys();
42 it != dict->end_keys(); ++it) {
43 Value* child = NULL;
44 bool rv = dict->GetWithoutPathExpansion(*it, &child);
45 DCHECK(rv);
46 Value* child_copy = CopyWithoutEmptyChildren(child);
47 if (child_copy)
48 copy->SetWithoutPathExpansion(*it, child_copy);
49 }
50 if (!copy->empty())
51 return copy;
52
53 delete copy;
54 return NULL;
55 }
56
57 default:
58 // For everything else, just make a copy.
59 return node->DeepCopy();
60 }
61}
62
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +090063// A small functor for comparing Values for std::find_if and similar.
64class ValueEquals {
65 public:
66 // Pass the value against which all consecutive calls of the () operator will
67 // compare their argument to. This Value object must not be destroyed while
68 // the ValueEquals is in use.
69 ValueEquals(const Value* first) : first_(first) { }
70
71 bool operator ()(const Value* second) const {
72 return first_->Equals(second);
73 }
74
75 private:
76 const Value* first_;
77};
78
tony@chromium.orge4948ab2009-12-02 09:20:32 +090079} // namespace
initial.commit3f4a7322008-07-27 06:49:38 +090080
tfarina@chromium.orgde3ef412011-08-05 08:51:10 +090081namespace base {
82
initial.commit3f4a7322008-07-27 06:49:38 +090083///////////////////// Value ////////////////////
84
85Value::~Value() {
86}
87
88// static
89Value* Value::CreateNullValue() {
90 return new Value(TYPE_NULL);
91}
92
93// static
akalin@chromium.org810f92f2011-01-18 11:16:59 +090094FundamentalValue* Value::CreateBooleanValue(bool in_value) {
initial.commit3f4a7322008-07-27 06:49:38 +090095 return new FundamentalValue(in_value);
96}
97
98// static
akalin@chromium.org810f92f2011-01-18 11:16:59 +090099FundamentalValue* Value::CreateIntegerValue(int in_value) {
initial.commit3f4a7322008-07-27 06:49:38 +0900100 return new FundamentalValue(in_value);
101}
102
103// static
arv@chromium.org13413eb2011-02-01 10:02:07 +0900104FundamentalValue* Value::CreateDoubleValue(double in_value) {
initial.commit3f4a7322008-07-27 06:49:38 +0900105 return new FundamentalValue(in_value);
106}
107
108// static
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900109StringValue* Value::CreateStringValue(const std::string& in_value) {
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900110 return new StringValue(in_value);
111}
112
113// static
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900114StringValue* Value::CreateStringValue(const string16& in_value) {
scherkus@chromium.org5ad62762008-12-11 07:30:57 +0900115 return new StringValue(in_value);
scherkus@chromium.org92bc0d42008-12-11 07:18:47 +0900116}
117
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900118bool Value::GetAsBoolean(bool* out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900119 return false;
120}
121
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900122bool Value::GetAsInteger(int* out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900123 return false;
124}
125
arv@chromium.org13413eb2011-02-01 10:02:07 +0900126bool Value::GetAsDouble(double* out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900127 return false;
128}
129
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900130bool Value::GetAsString(std::string* out_value) const {
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900131 return false;
132}
133
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900134bool Value::GetAsString(string16* out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900135 return false;
136}
137
scottbyer@google.com673b8762010-12-07 09:35:29 +0900138bool Value::GetAsList(ListValue** out_value) {
139 return false;
140}
141
bauerb@chromium.org6878e502011-07-12 18:04:38 +0900142bool Value::GetAsList(const ListValue** out_value) const {
143 return false;
144}
145
battre@chromium.org29eaa252011-11-26 10:11:44 +0900146bool Value::GetAsDictionary(DictionaryValue** out_value) {
147 return false;
148}
149
150bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
151 return false;
152}
153
initial.commit3f4a7322008-07-27 06:49:38 +0900154Value* Value::DeepCopy() const {
155 // This method should only be getting called for null Values--all subclasses
156 // need to provide their own implementation;.
157 DCHECK(IsType(TYPE_NULL));
158 return CreateNullValue();
159}
160
161bool Value::Equals(const Value* other) const {
162 // This method should only be getting called for null Values--all subclasses
163 // need to provide their own implementation;.
164 DCHECK(IsType(TYPE_NULL));
165 return other->IsType(TYPE_NULL);
166}
167
bauerb@chromium.orgfbd55e12010-12-07 03:13:43 +0900168// static
169bool Value::Equals(const Value* a, const Value* b) {
170 if ((a == NULL) && (b == NULL)) return true;
171 if ((a == NULL) ^ (b == NULL)) return false;
172 return a->Equals(b);
173}
174
sky@chromium.org8d103c72011-08-25 06:17:59 +0900175Value::Value(Type type) : type_(type) {
erg@chromium.org493f5f62010-07-16 06:03:54 +0900176}
177
initial.commit3f4a7322008-07-27 06:49:38 +0900178///////////////////// FundamentalValue ////////////////////
179
erg@chromium.org493f5f62010-07-16 06:03:54 +0900180FundamentalValue::FundamentalValue(bool in_value)
181 : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
182}
183
184FundamentalValue::FundamentalValue(int in_value)
185 : Value(TYPE_INTEGER), integer_value_(in_value) {
186}
187
188FundamentalValue::FundamentalValue(double in_value)
arv@chromium.org13413eb2011-02-01 10:02:07 +0900189 : Value(TYPE_DOUBLE), double_value_(in_value) {
derat@chromium.orga40267d2011-08-23 13:11:22 +0900190 if (!IsFinite(double_value_)) {
191 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
192 << "values cannot be represented in JSON";
193 double_value_ = 0.0;
194 }
erg@chromium.org493f5f62010-07-16 06:03:54 +0900195}
196
initial.commit3f4a7322008-07-27 06:49:38 +0900197FundamentalValue::~FundamentalValue() {
198}
199
200bool FundamentalValue::GetAsBoolean(bool* out_value) const {
201 if (out_value && IsType(TYPE_BOOLEAN))
202 *out_value = boolean_value_;
203 return (IsType(TYPE_BOOLEAN));
204}
205
206bool FundamentalValue::GetAsInteger(int* out_value) const {
207 if (out_value && IsType(TYPE_INTEGER))
208 *out_value = integer_value_;
209 return (IsType(TYPE_INTEGER));
210}
211
arv@chromium.org13413eb2011-02-01 10:02:07 +0900212bool FundamentalValue::GetAsDouble(double* out_value) const {
213 if (out_value && IsType(TYPE_DOUBLE))
214 *out_value = double_value_;
yusukes@google.com0b18b532011-05-02 10:59:21 +0900215 else if (out_value && IsType(TYPE_INTEGER))
216 *out_value = integer_value_;
217 return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER));
initial.commit3f4a7322008-07-27 06:49:38 +0900218}
219
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900220FundamentalValue* FundamentalValue::DeepCopy() const {
initial.commit3f4a7322008-07-27 06:49:38 +0900221 switch (GetType()) {
222 case TYPE_BOOLEAN:
223 return CreateBooleanValue(boolean_value_);
224
225 case TYPE_INTEGER:
226 return CreateIntegerValue(integer_value_);
227
arv@chromium.org13413eb2011-02-01 10:02:07 +0900228 case TYPE_DOUBLE:
229 return CreateDoubleValue(double_value_);
initial.commit3f4a7322008-07-27 06:49:38 +0900230
231 default:
232 NOTREACHED();
233 return NULL;
234 }
235}
236
237bool FundamentalValue::Equals(const Value* other) const {
238 if (other->GetType() != GetType())
239 return false;
240
241 switch (GetType()) {
242 case TYPE_BOOLEAN: {
243 bool lhs, rhs;
244 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
245 }
246 case TYPE_INTEGER: {
247 int lhs, rhs;
248 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
249 }
arv@chromium.org13413eb2011-02-01 10:02:07 +0900250 case TYPE_DOUBLE: {
initial.commit3f4a7322008-07-27 06:49:38 +0900251 double lhs, rhs;
arv@chromium.org13413eb2011-02-01 10:02:07 +0900252 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
initial.commit3f4a7322008-07-27 06:49:38 +0900253 }
254 default:
255 NOTREACHED();
256 return false;
257 }
258}
259
260///////////////////// StringValue ////////////////////
261
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900262StringValue::StringValue(const std::string& in_value)
263 : Value(TYPE_STRING),
264 value_(in_value) {
265 DCHECK(IsStringUTF8(in_value));
266}
267
munjal@chromium.org3b2d3a42010-01-16 05:09:03 +0900268StringValue::StringValue(const string16& in_value)
269 : Value(TYPE_STRING),
270 value_(UTF16ToUTF8(in_value)) {
271}
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900272
initial.commit3f4a7322008-07-27 06:49:38 +0900273StringValue::~StringValue() {
274}
275
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900276bool StringValue::GetAsString(std::string* out_value) const {
277 if (out_value)
278 *out_value = value_;
279 return true;
280}
281
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900282bool StringValue::GetAsString(string16* out_value) const {
283 if (out_value)
284 *out_value = UTF8ToUTF16(value_);
285 return true;
286}
287
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900288StringValue* StringValue::DeepCopy() const {
initial.commit3f4a7322008-07-27 06:49:38 +0900289 return CreateStringValue(value_);
290}
291
292bool StringValue::Equals(const Value* other) const {
293 if (other->GetType() != GetType())
294 return false;
scherkus@chromium.org2b923e72008-12-11 10:23:17 +0900295 std::string lhs, rhs;
initial.commit3f4a7322008-07-27 06:49:38 +0900296 return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
297}
298
299///////////////////// BinaryValue ////////////////////
300
mitchellwrosen@chromium.org3897f9b2012-05-20 04:31:16 +0900301BinaryValue::~BinaryValue() {
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900302 DCHECK(buffer_);
303 if (buffer_)
304 delete[] buffer_;
305}
306
307// static
308BinaryValue* BinaryValue::Create(char* buffer, size_t size) {
309 if (!buffer)
310 return NULL;
311
312 return new BinaryValue(buffer, size);
initial.commit3f4a7322008-07-27 06:49:38 +0900313}
314
jcampan@chromium.orgd1105672009-09-15 01:56:12 +0900315// static
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900316BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
317 size_t size) {
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900318 if (!buffer)
319 return NULL;
320
initial.commit3f4a7322008-07-27 06:49:38 +0900321 char* buffer_copy = new char[size];
mmentovai@google.com4a5b6272008-08-07 00:46:59 +0900322 memcpy(buffer_copy, buffer, size);
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900323 return new BinaryValue(buffer_copy, size);
initial.commit3f4a7322008-07-27 06:49:38 +0900324}
325
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900326BinaryValue* BinaryValue::DeepCopy() const {
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900327 return CreateWithCopiedBuffer(buffer_, size_);
initial.commit3f4a7322008-07-27 06:49:38 +0900328}
329
330bool BinaryValue::Equals(const Value* other) const {
331 if (other->GetType() != GetType())
332 return false;
333 const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
334 if (other_binary->size_ != size_)
335 return false;
jhawkins@chromium.org592520e2012-05-20 11:34:57 +0900336 return !memcmp(buffer_, other_binary->buffer_, size_);
337}
338
339BinaryValue::BinaryValue(char* buffer, size_t size)
340 : Value(TYPE_BINARY),
341 buffer_(buffer),
342 size_(size) {
343 DCHECK(buffer_);
erg@google.com67a25432011-01-08 05:23:43 +0900344}
345
initial.commit3f4a7322008-07-27 06:49:38 +0900346///////////////////// DictionaryValue ////////////////////
347
erg@chromium.org493f5f62010-07-16 06:03:54 +0900348DictionaryValue::DictionaryValue()
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900349 : Value(TYPE_DICTIONARY) {
erg@chromium.org493f5f62010-07-16 06:03:54 +0900350}
351
initial.commit3f4a7322008-07-27 06:49:38 +0900352DictionaryValue::~DictionaryValue() {
353 Clear();
354}
355
battre@chromium.org29eaa252011-11-26 10:11:44 +0900356bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
357 if (out_value)
358 *out_value = this;
359 return true;
360}
361
362bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
363 if (out_value)
364 *out_value = this;
365 return true;
366}
367
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900368bool DictionaryValue::HasKey(const std::string& key) const {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900369 DCHECK(IsStringUTF8(key));
tony@chromium.orge4948ab2009-12-02 09:20:32 +0900370 ValueMap::const_iterator current_entry = dictionary_.find(key);
371 DCHECK((current_entry == dictionary_.end()) || current_entry->second);
372 return current_entry != dictionary_.end();
373}
374
initial.commit3f4a7322008-07-27 06:49:38 +0900375void DictionaryValue::Clear() {
376 ValueMap::iterator dict_iterator = dictionary_.begin();
377 while (dict_iterator != dictionary_.end()) {
378 delete dict_iterator->second;
379 ++dict_iterator;
380 }
381
382 dictionary_.clear();
383}
384
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900385void DictionaryValue::Set(const std::string& path, Value* in_value) {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900386 DCHECK(IsStringUTF8(path));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900387 DCHECK(in_value);
388
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900389 std::string current_path(path);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900390 DictionaryValue* current_dictionary = this;
391 for (size_t delimiter_position = current_path.find('.');
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900392 delimiter_position != std::string::npos;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900393 delimiter_position = current_path.find('.')) {
394 // Assume that we're indexing into a dictionary.
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900395 std::string key(current_path, 0, delimiter_position);
pkasting@chromium.org8535dc22009-11-26 06:02:24 +0900396 DictionaryValue* child_dictionary = NULL;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900397 if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
398 child_dictionary = new DictionaryValue;
399 current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
400 }
401
402 current_dictionary = child_dictionary;
403 current_path.erase(0, delimiter_position + 1);
404 }
405
406 current_dictionary->SetWithoutPathExpansion(current_path, in_value);
407}
408
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900409void DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
410 Set(path, CreateBooleanValue(in_value));
411}
412
413void DictionaryValue::SetInteger(const std::string& path, int in_value) {
414 Set(path, CreateIntegerValue(in_value));
415}
416
arv@chromium.org13413eb2011-02-01 10:02:07 +0900417void DictionaryValue::SetDouble(const std::string& path, double in_value) {
418 Set(path, CreateDoubleValue(in_value));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900419}
420
421void DictionaryValue::SetString(const std::string& path,
422 const std::string& in_value) {
423 Set(path, CreateStringValue(in_value));
424}
425
viettrungluu@chromium.orgb7b6aa02010-08-05 01:58:12 +0900426void DictionaryValue::SetString(const std::string& path,
427 const string16& in_value) {
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900428 Set(path, CreateStringValue(in_value));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900429}
430
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900431void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900432 Value* in_value) {
initial.commit3f4a7322008-07-27 06:49:38 +0900433 // If there's an existing value here, we need to delete it, because
434 // we own all our children.
grt@chromium.org4c73d402011-10-22 07:58:52 +0900435 std::pair<ValueMap::iterator, bool> ins_res =
436 dictionary_.insert(std::make_pair(key, in_value));
437 if (!ins_res.second) {
438 DCHECK_NE(ins_res.first->second, in_value); // This would be bogus
439 delete ins_res.first->second;
440 ins_res.first->second = in_value;
initial.commit3f4a7322008-07-27 06:49:38 +0900441 }
initial.commit3f4a7322008-07-27 06:49:38 +0900442}
443
vabr@chromium.org74562432012-07-28 07:27:11 +0900444bool DictionaryValue::Get(
445 const std::string& path, const Value** out_value) const {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900446 DCHECK(IsStringUTF8(path));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900447 std::string current_path(path);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900448 const DictionaryValue* current_dictionary = this;
449 for (size_t delimiter_position = current_path.find('.');
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900450 delimiter_position != std::string::npos;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900451 delimiter_position = current_path.find('.')) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900452 const DictionaryValue* child_dictionary = NULL;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900453 if (!current_dictionary->GetDictionary(
454 current_path.substr(0, delimiter_position), &child_dictionary))
455 return false;
initial.commit3f4a7322008-07-27 06:49:38 +0900456
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900457 current_dictionary = child_dictionary;
458 current_path.erase(0, delimiter_position + 1);
initial.commit3f4a7322008-07-27 06:49:38 +0900459 }
460
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900461 return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
initial.commit3f4a7322008-07-27 06:49:38 +0900462}
463
vabr@chromium.org74562432012-07-28 07:27:11 +0900464bool DictionaryValue::Get(const std::string& path, Value** out_value) {
465 return static_cast<const DictionaryValue&>(*this).Get(
466 path,
467 const_cast<const Value**>(out_value));
468}
469
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900470bool DictionaryValue::GetBoolean(const std::string& path,
initial.commit3f4a7322008-07-27 06:49:38 +0900471 bool* bool_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900472 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900473 if (!Get(path, &value))
474 return false;
475
476 return value->GetAsBoolean(bool_value);
477}
478
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900479bool DictionaryValue::GetInteger(const std::string& path,
initial.commit3f4a7322008-07-27 06:49:38 +0900480 int* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900481 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900482 if (!Get(path, &value))
483 return false;
484
485 return value->GetAsInteger(out_value);
486}
487
arv@chromium.org13413eb2011-02-01 10:02:07 +0900488bool DictionaryValue::GetDouble(const std::string& path,
489 double* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900490 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900491 if (!Get(path, &value))
492 return false;
493
arv@chromium.org13413eb2011-02-01 10:02:07 +0900494 return value->GetAsDouble(out_value);
initial.commit3f4a7322008-07-27 06:49:38 +0900495}
496
evan@chromium.orgd9ab8de2010-02-19 22:32:16 +0900497bool DictionaryValue::GetString(const std::string& path,
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900498 std::string* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900499 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900500 if (!Get(path, &value))
501 return false;
502
503 return value->GetAsString(out_value);
504}
505
viettrungluu@chromium.org58767ef2010-08-05 04:35:33 +0900506bool DictionaryValue::GetString(const std::string& path,
507 string16* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900508 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900509 if (!Get(path, &value))
510 return false;
511
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900512 return value->GetAsString(out_value);
evan@chromium.orgd9ab8de2010-02-19 22:32:16 +0900513}
514
515bool DictionaryValue::GetStringASCII(const std::string& path,
516 std::string* out_value) const {
517 std::string out;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900518 if (!GetString(path, &out))
evan@chromium.orgd9ab8de2010-02-19 22:32:16 +0900519 return false;
520
521 if (!IsStringASCII(out)) {
522 NOTREACHED();
523 return false;
524 }
525
526 out_value->assign(out);
527 return true;
528}
529
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900530bool DictionaryValue::GetBinary(const std::string& path,
vabr@chromium.org74562432012-07-28 07:27:11 +0900531 const BinaryValue** out_value) const {
532 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900533 bool result = Get(path, &value);
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900534 if (!result || !value->IsType(TYPE_BINARY))
initial.commit3f4a7322008-07-27 06:49:38 +0900535 return false;
536
537 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900538 *out_value = static_cast<const BinaryValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900539
540 return true;
541}
542
vabr@chromium.org74562432012-07-28 07:27:11 +0900543bool DictionaryValue::GetBinary(const std::string& path,
544 BinaryValue** out_value) {
545 return static_cast<const DictionaryValue&>(*this).GetBinary(
546 path,
547 const_cast<const BinaryValue**>(out_value));
548}
549
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900550bool DictionaryValue::GetDictionary(const std::string& path,
vabr@chromium.org74562432012-07-28 07:27:11 +0900551 const DictionaryValue** out_value) const {
552 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900553 bool result = Get(path, &value);
554 if (!result || !value->IsType(TYPE_DICTIONARY))
555 return false;
556
557 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900558 *out_value = static_cast<const DictionaryValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900559
560 return true;
561}
562
vabr@chromium.org74562432012-07-28 07:27:11 +0900563bool DictionaryValue::GetDictionary(const std::string& path,
564 DictionaryValue** out_value) {
565 return static_cast<const DictionaryValue&>(*this).GetDictionary(
566 path,
567 const_cast<const DictionaryValue**>(out_value));
568}
569
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900570bool DictionaryValue::GetList(const std::string& path,
vabr@chromium.org74562432012-07-28 07:27:11 +0900571 const ListValue** out_value) const {
572 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900573 bool result = Get(path, &value);
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900574 if (!result || !value->IsType(TYPE_LIST))
initial.commit3f4a7322008-07-27 06:49:38 +0900575 return false;
576
577 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900578 *out_value = static_cast<const ListValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900579
580 return true;
581}
582
vabr@chromium.org74562432012-07-28 07:27:11 +0900583bool DictionaryValue::GetList(const std::string& path, ListValue** out_value) {
584 return static_cast<const DictionaryValue&>(*this).GetList(
585 path,
586 const_cast<const ListValue**>(out_value));
587}
588
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900589bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900590 const Value** out_value) const {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900591 DCHECK(IsStringUTF8(key));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900592 ValueMap::const_iterator entry_iterator = dictionary_.find(key);
593 if (entry_iterator == dictionary_.end())
594 return false;
initial.commit3f4a7322008-07-27 06:49:38 +0900595
vabr@chromium.org74562432012-07-28 07:27:11 +0900596 const Value* entry = entry_iterator->second;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900597 if (out_value)
598 *out_value = entry;
599 return true;
600}
601
vabr@chromium.org74562432012-07-28 07:27:11 +0900602bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
603 Value** out_value) {
604 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
605 key,
606 const_cast<const Value**>(out_value));
607}
608
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900609bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900610 int* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900611 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900612 if (!GetWithoutPathExpansion(key, &value))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900613 return false;
614
615 return value->GetAsInteger(out_value);
616}
617
arv@chromium.org13413eb2011-02-01 10:02:07 +0900618bool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
619 double* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900620 const Value* value;
jam@chromium.org5bd53922010-10-01 16:28:25 +0900621 if (!GetWithoutPathExpansion(key, &value))
622 return false;
623
arv@chromium.org13413eb2011-02-01 10:02:07 +0900624 return value->GetAsDouble(out_value);
jam@chromium.org5bd53922010-10-01 16:28:25 +0900625}
626
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900627bool DictionaryValue::GetStringWithoutPathExpansion(
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900628 const std::string& key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900629 std::string* out_value) const {
vabr@chromium.org74562432012-07-28 07:27:11 +0900630 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900631 if (!GetWithoutPathExpansion(key, &value))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900632 return false;
633
634 return value->GetAsString(out_value);
635}
636
vabr@chromium.org74562432012-07-28 07:27:11 +0900637bool DictionaryValue::GetStringWithoutPathExpansion(const std::string& key,
638 string16* out_value) const {
639 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900640 if (!GetWithoutPathExpansion(key, &value))
munjal@chromium.org3b2d3a42010-01-16 05:09:03 +0900641 return false;
642
viettrungluu@chromium.org31b80ba2010-08-04 00:42:58 +0900643 return value->GetAsString(out_value);
munjal@chromium.org3b2d3a42010-01-16 05:09:03 +0900644}
645
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900646bool DictionaryValue::GetDictionaryWithoutPathExpansion(
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900647 const std::string& key,
vabr@chromium.org74562432012-07-28 07:27:11 +0900648 const DictionaryValue** out_value) const {
649 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900650 bool result = GetWithoutPathExpansion(key, &value);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900651 if (!result || !value->IsType(TYPE_DICTIONARY))
652 return false;
653
654 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900655 *out_value = static_cast<const DictionaryValue*>(value);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900656
657 return true;
658}
659
vabr@chromium.org74562432012-07-28 07:27:11 +0900660bool DictionaryValue::GetDictionaryWithoutPathExpansion(
661 const std::string& key,
662 DictionaryValue** out_value) {
663 const DictionaryValue& const_this =
664 static_cast<const DictionaryValue&>(*this);
665 return const_this.GetDictionaryWithoutPathExpansion(
666 key,
667 const_cast<const DictionaryValue**>(out_value));
668}
669
670bool DictionaryValue::GetListWithoutPathExpansion(
671 const std::string& key,
672 const ListValue** out_value) const {
673 const Value* value;
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900674 bool result = GetWithoutPathExpansion(key, &value);
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900675 if (!result || !value->IsType(TYPE_LIST))
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900676 return false;
677
678 if (out_value)
vabr@chromium.org74562432012-07-28 07:27:11 +0900679 *out_value = static_cast<const ListValue*>(value);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900680
681 return true;
682}
683
vabr@chromium.org74562432012-07-28 07:27:11 +0900684bool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
685 ListValue** out_value) {
686 return
687 static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
688 key,
689 const_cast<const ListValue**>(out_value));
690}
691
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900692bool DictionaryValue::Remove(const std::string& path, Value** out_value) {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900693 DCHECK(IsStringUTF8(path));
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900694 std::string current_path(path);
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900695 DictionaryValue* current_dictionary = this;
696 size_t delimiter_position = current_path.rfind('.');
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900697 if (delimiter_position != std::string::npos) {
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900698 if (!GetDictionary(current_path.substr(0, delimiter_position),
699 &current_dictionary))
700 return false;
701 current_path.erase(0, delimiter_position + 1);
initial.commit3f4a7322008-07-27 06:49:38 +0900702 }
703
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900704 return current_dictionary->RemoveWithoutPathExpansion(current_path,
705 out_value);
706}
707
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900708bool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900709 Value** out_value) {
viettrungluu@chromium.org4c86b852010-08-06 15:03:25 +0900710 DCHECK(IsStringUTF8(key));
initial.commit3f4a7322008-07-27 06:49:38 +0900711 ValueMap::iterator entry_iterator = dictionary_.find(key);
712 if (entry_iterator == dictionary_.end())
713 return false;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900714
initial.commit3f4a7322008-07-27 06:49:38 +0900715 Value* entry = entry_iterator->second;
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900716 if (out_value)
717 *out_value = entry;
718 else
719 delete entry;
720 dictionary_.erase(entry_iterator);
721 return true;
initial.commit3f4a7322008-07-27 06:49:38 +0900722}
723
tony@chromium.orge4948ab2009-12-02 09:20:32 +0900724DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
725 Value* copy = CopyWithoutEmptyChildren(this);
726 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
initial.commit3f4a7322008-07-27 06:49:38 +0900727}
728
mnissler@chromium.org17cee0e2010-05-14 22:17:40 +0900729void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
730 for (DictionaryValue::key_iterator key(dictionary->begin_keys());
731 key != dictionary->end_keys(); ++key) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900732 const Value* merge_value;
mnissler@chromium.org17cee0e2010-05-14 22:17:40 +0900733 if (dictionary->GetWithoutPathExpansion(*key, &merge_value)) {
734 // Check whether we have to merge dictionaries.
735 if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
736 DictionaryValue* sub_dict;
737 if (GetDictionaryWithoutPathExpansion(*key, &sub_dict)) {
738 sub_dict->MergeDictionary(
739 static_cast<const DictionaryValue*>(merge_value));
740 continue;
741 }
742 }
743 // All other cases: Make a copy and hook it up.
744 SetWithoutPathExpansion(*key, merge_value->DeepCopy());
745 }
746 }
747}
748
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +0900749void DictionaryValue::Swap(DictionaryValue* other) {
750 dictionary_.swap(other->dictionary_);
751}
752
akalin@chromium.org810f92f2011-01-18 11:16:59 +0900753DictionaryValue* DictionaryValue::DeepCopy() const {
erg@google.com67a25432011-01-08 05:23:43 +0900754 DictionaryValue* result = new DictionaryValue;
755
756 for (ValueMap::const_iterator current_entry(dictionary_.begin());
757 current_entry != dictionary_.end(); ++current_entry) {
758 result->SetWithoutPathExpansion(current_entry->first,
759 current_entry->second->DeepCopy());
760 }
761
762 return result;
763}
764
765bool DictionaryValue::Equals(const Value* other) const {
766 if (other->GetType() != GetType())
767 return false;
768
769 const DictionaryValue* other_dict =
770 static_cast<const DictionaryValue*>(other);
771 key_iterator lhs_it(begin_keys());
772 key_iterator rhs_it(other_dict->begin_keys());
773 while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) {
vabr@chromium.org74562432012-07-28 07:27:11 +0900774 const Value* lhs;
775 const Value* rhs;
erg@google.com67a25432011-01-08 05:23:43 +0900776 if (*lhs_it != *rhs_it ||
777 !GetWithoutPathExpansion(*lhs_it, &lhs) ||
778 !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) ||
779 !lhs->Equals(rhs)) {
780 return false;
781 }
782 ++lhs_it;
783 ++rhs_it;
784 }
785 if (lhs_it != end_keys() || rhs_it != other_dict->end_keys())
786 return false;
787
788 return true;
789}
790
initial.commit3f4a7322008-07-27 06:49:38 +0900791///////////////////// ListValue ////////////////////
792
erg@chromium.org493f5f62010-07-16 06:03:54 +0900793ListValue::ListValue() : Value(TYPE_LIST) {
794}
795
initial.commit3f4a7322008-07-27 06:49:38 +0900796ListValue::~ListValue() {
797 Clear();
798}
799
800void ListValue::Clear() {
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900801 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
802 delete *i;
initial.commit3f4a7322008-07-27 06:49:38 +0900803 list_.clear();
804}
805
806bool ListValue::Set(size_t index, Value* in_value) {
807 if (!in_value)
808 return false;
809
810 if (index >= list_.size()) {
811 // Pad out any intermediate indexes with null settings
812 while (index > list_.size())
813 Append(CreateNullValue());
814 Append(in_value);
815 } else {
816 DCHECK(list_[index] != in_value);
817 delete list_[index];
818 list_[index] = in_value;
819 }
820 return true;
821}
822
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900823bool ListValue::Get(size_t index, const Value** out_value) const {
initial.commit3f4a7322008-07-27 06:49:38 +0900824 if (index >= list_.size())
825 return false;
826
827 if (out_value)
828 *out_value = list_[index];
829
830 return true;
831}
832
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900833bool ListValue::Get(size_t index, Value** out_value) {
834 return static_cast<const ListValue&>(*this).Get(
835 index,
836 const_cast<const Value**>(out_value));
837}
838
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900839bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900840 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900841 if (!Get(index, &value))
842 return false;
843
844 return value->GetAsBoolean(bool_value);
845}
846
847bool ListValue::GetInteger(size_t index, int* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900848 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900849 if (!Get(index, &value))
850 return false;
851
852 return value->GetAsInteger(out_value);
853}
854
arv@chromium.org13413eb2011-02-01 10:02:07 +0900855bool ListValue::GetDouble(size_t index, double* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900856 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900857 if (!Get(index, &value))
858 return false;
859
arv@chromium.org13413eb2011-02-01 10:02:07 +0900860 return value->GetAsDouble(out_value);
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900861}
862
863bool ListValue::GetString(size_t index, std::string* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900864 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900865 if (!Get(index, &value))
866 return false;
867
868 return value->GetAsString(out_value);
869}
870
viettrungluu@chromium.org58767ef2010-08-05 04:35:33 +0900871bool ListValue::GetString(size_t index, string16* out_value) const {
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900872 const Value* value;
viettrungluu@chromium.org58767ef2010-08-05 04:35:33 +0900873 if (!Get(index, &value))
874 return false;
875
876 return value->GetAsString(out_value);
877}
878
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900879bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const {
880 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900881 bool result = Get(index, &value);
882 if (!result || !value->IsType(TYPE_BINARY))
883 return false;
884
885 if (out_value)
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900886 *out_value = static_cast<const BinaryValue*>(value);
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900887
888 return true;
889}
890
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900891bool ListValue::GetBinary(size_t index, BinaryValue** out_value) {
892 return static_cast<const ListValue&>(*this).GetBinary(
893 index,
894 const_cast<const BinaryValue**>(out_value));
895}
896
897bool ListValue::GetDictionary(size_t index,
898 const DictionaryValue** out_value) const {
899 const Value* value;
initial.commit3f4a7322008-07-27 06:49:38 +0900900 bool result = Get(index, &value);
901 if (!result || !value->IsType(TYPE_DICTIONARY))
902 return false;
903
904 if (out_value)
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900905 *out_value = static_cast<const DictionaryValue*>(value);
initial.commit3f4a7322008-07-27 06:49:38 +0900906
907 return true;
908}
909
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900910bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
911 return static_cast<const ListValue&>(*this).GetDictionary(
912 index,
913 const_cast<const DictionaryValue**>(out_value));
914}
915
916bool ListValue::GetList(size_t index, const ListValue** out_value) const {
917 const Value* value;
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900918 bool result = Get(index, &value);
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900919 if (!result || !value->IsType(TYPE_LIST))
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900920 return false;
921
922 if (out_value)
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900923 *out_value = static_cast<const ListValue*>(value);
aa@chromium.orgc93b02f2009-01-21 06:05:32 +0900924
925 return true;
926}
927
vabr@chromium.orga8ca4fd2012-08-03 17:43:37 +0900928bool ListValue::GetList(size_t index, ListValue** out_value) {
929 return static_cast<const ListValue&>(*this).GetList(
930 index,
931 const_cast<const ListValue**>(out_value));
932}
933
initial.commit3f4a7322008-07-27 06:49:38 +0900934bool ListValue::Remove(size_t index, Value** out_value) {
935 if (index >= list_.size())
936 return false;
937
938 if (out_value)
939 *out_value = list_[index];
940 else
941 delete list_[index];
942
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900943 list_.erase(list_.begin() + index);
initial.commit3f4a7322008-07-27 06:49:38 +0900944 return true;
945}
946
tfarina@chromium.org09cf4342011-08-14 02:34:31 +0900947bool ListValue::Remove(const Value& value, size_t* index) {
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900948 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
949 if ((*i)->Equals(&value)) {
tfarina@chromium.org09cf4342011-08-14 02:34:31 +0900950 size_t previous_index = i - list_.begin();
pkasting@chromium.orgdfe6a692009-12-01 04:59:11 +0900951 delete *i;
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900952 list_.erase(i);
robertshield@chromium.org9fb9e372010-03-23 05:12:50 +0900953
tfarina@chromium.org09cf4342011-08-14 02:34:31 +0900954 if (index)
955 *index = previous_index;
956 return true;
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900957 }
958 }
tfarina@chromium.org09cf4342011-08-14 02:34:31 +0900959 return false;
pkasting@chromium.org727139c2009-05-09 09:33:04 +0900960}
961
estade@chromium.org52852d52012-07-03 11:51:43 +0900962void ListValue::Erase(iterator iter, Value** out_value) {
963 if (out_value)
964 *out_value = *iter;
965 else
966 delete *iter;
967
968 list_.erase(iter);
969}
970
initial.commit3f4a7322008-07-27 06:49:38 +0900971void ListValue::Append(Value* in_value) {
972 DCHECK(in_value);
973 list_.push_back(in_value);
974}
975
zork@chromium.orgb5f742b2010-04-13 06:48:10 +0900976bool ListValue::AppendIfNotPresent(Value* in_value) {
977 DCHECK(in_value);
ziadh@chromium.org5c7f6312010-07-19 17:00:42 +0900978 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
markusheintz@chromium.org78621872011-03-18 22:56:38 +0900979 if ((*i)->Equals(in_value)) {
980 delete in_value;
zork@chromium.orgb5f742b2010-04-13 06:48:10 +0900981 return false;
markusheintz@chromium.org78621872011-03-18 22:56:38 +0900982 }
zork@chromium.orgb5f742b2010-04-13 06:48:10 +0900983 }
984 list_.push_back(in_value);
985 return true;
986}
987
erikkay@chromium.org9034a232009-08-29 05:26:05 +0900988bool ListValue::Insert(size_t index, Value* in_value) {
989 DCHECK(in_value);
jhawkins@chromium.org33edb6b2009-10-01 06:36:37 +0900990 if (index > list_.size())
erikkay@chromium.org9034a232009-08-29 05:26:05 +0900991 return false;
992
993 list_.insert(list_.begin() + index, in_value);
994 return true;
995}
996
pastarmovj@chromium.org1602a472011-09-20 00:23:10 +0900997ListValue::const_iterator ListValue::Find(const Value& value) const {
998 return std::find_if(list_.begin(), list_.end(), ValueEquals(&value));
999}
1000
rsesek@chromium.orgc2d2b202012-05-17 00:23:30 +09001001void ListValue::Swap(ListValue* other) {
1002 list_.swap(other->list_);
1003}
1004
scottbyer@google.com673b8762010-12-07 09:35:29 +09001005bool ListValue::GetAsList(ListValue** out_value) {
1006 if (out_value)
1007 *out_value = this;
1008 return true;
1009}
1010
bauerb@chromium.org6878e502011-07-12 18:04:38 +09001011bool ListValue::GetAsList(const ListValue** out_value) const {
1012 if (out_value)
1013 *out_value = this;
1014 return true;
1015}
1016
akalin@chromium.org810f92f2011-01-18 11:16:59 +09001017ListValue* ListValue::DeepCopy() const {
initial.commit3f4a7322008-07-27 06:49:38 +09001018 ListValue* result = new ListValue;
1019
pkasting@chromium.org727139c2009-05-09 09:33:04 +09001020 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
1021 result->Append((*i)->DeepCopy());
initial.commit3f4a7322008-07-27 06:49:38 +09001022
1023 return result;
1024}
1025
1026bool ListValue::Equals(const Value* other) const {
1027 if (other->GetType() != GetType())
1028 return false;
1029
1030 const ListValue* other_list =
1031 static_cast<const ListValue*>(other);
1032 const_iterator lhs_it, rhs_it;
1033 for (lhs_it = begin(), rhs_it = other_list->begin();
1034 lhs_it != end() && rhs_it != other_list->end();
1035 ++lhs_it, ++rhs_it) {
1036 if (!(*lhs_it)->Equals(*rhs_it))
1037 return false;
1038 }
1039 if (lhs_it != end() || rhs_it != other_list->end())
1040 return false;
1041
1042 return true;
1043}
erg@chromium.org493f5f62010-07-16 06:03:54 +09001044
1045ValueSerializer::~ValueSerializer() {
1046}
tfarina@chromium.orgde3ef412011-08-05 08:51:10 +09001047
1048} // namespace base