blob: 8d7ca351d1e9cc6db28489f822a9f341906f04b5 [file] [log] [blame]
[email protected]e36eaac2011-03-18 13:56:381// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
[email protected]ec330b52009-12-02 00:20:325#include "base/values.h"
6
[email protected]5fb35372011-09-19 15:23:107#include <algorithm>
8
[email protected]feb0d6b2011-08-17 08:03:439#include "base/float_util.h"
initial.commitd7cae122008-07-26 21:49:3810#include "base/logging.h"
[email protected]4cd5f6a2008-12-11 01:23:1711#include "base/string_util.h"
[email protected]047a03f2009-10-07 02:10:2012#include "base/utf_string_conversions.h"
[email protected]ec330b52009-12-02 00:20:3213
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: {
[email protected]0de764e2011-08-26 01:54:0023 ListValue* list = static_cast<ListValue*>(node);
[email protected]ec330b52009-12-02 00:20:3224 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
[email protected]5fb35372011-09-19 15:23:1063// 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
[email protected]ec330b52009-12-02 00:20:3279} // namespace
initial.commitd7cae122008-07-26 21:49:3880
[email protected]20566c92011-08-04 23:51:1081namespace base {
82
initial.commitd7cae122008-07-26 21:49:3883///////////////////// Value ////////////////////
84
85Value::~Value() {
86}
87
88// static
89Value* Value::CreateNullValue() {
90 return new Value(TYPE_NULL);
91}
92
93// static
[email protected]16f47e082011-01-18 02:16:5994FundamentalValue* Value::CreateBooleanValue(bool in_value) {
initial.commitd7cae122008-07-26 21:49:3895 return new FundamentalValue(in_value);
96}
97
98// static
[email protected]16f47e082011-01-18 02:16:5999FundamentalValue* Value::CreateIntegerValue(int in_value) {
initial.commitd7cae122008-07-26 21:49:38100 return new FundamentalValue(in_value);
101}
102
103// static
[email protected]fb534c92011-02-01 01:02:07104FundamentalValue* Value::CreateDoubleValue(double in_value) {
initial.commitd7cae122008-07-26 21:49:38105 return new FundamentalValue(in_value);
106}
107
108// static
[email protected]16f47e082011-01-18 02:16:59109StringValue* Value::CreateStringValue(const std::string& in_value) {
[email protected]4cd5f6a2008-12-11 01:23:17110 return new StringValue(in_value);
111}
112
113// static
[email protected]16f47e082011-01-18 02:16:59114StringValue* Value::CreateStringValue(const string16& in_value) {
[email protected]e8749c92008-12-10 22:30:57115 return new StringValue(in_value);
[email protected]3e9fe532008-12-10 22:18:47116}
117
[email protected]e2e593d2010-08-03 15:42:58118bool Value::GetAsBoolean(bool* out_value) const {
initial.commitd7cae122008-07-26 21:49:38119 return false;
120}
121
[email protected]e2e593d2010-08-03 15:42:58122bool Value::GetAsInteger(int* out_value) const {
initial.commitd7cae122008-07-26 21:49:38123 return false;
124}
125
[email protected]fb534c92011-02-01 01:02:07126bool Value::GetAsDouble(double* out_value) const {
initial.commitd7cae122008-07-26 21:49:38127 return false;
128}
129
[email protected]e2e593d2010-08-03 15:42:58130bool Value::GetAsString(std::string* out_value) const {
[email protected]4cd5f6a2008-12-11 01:23:17131 return false;
132}
133
[email protected]e2e593d2010-08-03 15:42:58134bool Value::GetAsString(string16* out_value) const {
initial.commitd7cae122008-07-26 21:49:38135 return false;
136}
137
[email protected]81f9fe0b2010-12-07 00:35:29138bool Value::GetAsList(ListValue** out_value) {
139 return false;
140}
141
[email protected]35552dc52011-07-12 09:04:38142bool Value::GetAsList(const ListValue** out_value) const {
143 return false;
144}
145
[email protected]5cf906f82011-11-26 01:11:44146bool Value::GetAsDictionary(DictionaryValue** out_value) {
147 return false;
148}
149
150bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
151 return false;
152}
153
initial.commitd7cae122008-07-26 21:49:38154Value* 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
[email protected]73c47932010-12-06 18:13:43168// 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
[email protected]9b5f56b42011-08-24 21:17:59175Value::Value(Type type) : type_(type) {
[email protected]3a3d47472010-07-15 21:03:54176}
177
initial.commitd7cae122008-07-26 21:49:38178///////////////////// FundamentalValue ////////////////////
179
[email protected]3a3d47472010-07-15 21:03:54180FundamentalValue::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)
[email protected]fb534c92011-02-01 01:02:07189 : Value(TYPE_DOUBLE), double_value_(in_value) {
[email protected]eaa97712011-08-23 04:11:22190 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 }
[email protected]3a3d47472010-07-15 21:03:54195}
196
initial.commitd7cae122008-07-26 21:49:38197FundamentalValue::~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
[email protected]fb534c92011-02-01 01:02:07212bool FundamentalValue::GetAsDouble(double* out_value) const {
213 if (out_value && IsType(TYPE_DOUBLE))
214 *out_value = double_value_;
[email protected]d3accda2011-05-02 01:59:21215 else if (out_value && IsType(TYPE_INTEGER))
216 *out_value = integer_value_;
217 return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER));
initial.commitd7cae122008-07-26 21:49:38218}
219
[email protected]16f47e082011-01-18 02:16:59220FundamentalValue* FundamentalValue::DeepCopy() const {
initial.commitd7cae122008-07-26 21:49:38221 switch (GetType()) {
222 case TYPE_BOOLEAN:
223 return CreateBooleanValue(boolean_value_);
224
225 case TYPE_INTEGER:
226 return CreateIntegerValue(integer_value_);
227
[email protected]fb534c92011-02-01 01:02:07228 case TYPE_DOUBLE:
229 return CreateDoubleValue(double_value_);
initial.commitd7cae122008-07-26 21:49:38230
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 }
[email protected]fb534c92011-02-01 01:02:07250 case TYPE_DOUBLE: {
initial.commitd7cae122008-07-26 21:49:38251 double lhs, rhs;
[email protected]fb534c92011-02-01 01:02:07252 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
initial.commitd7cae122008-07-26 21:49:38253 }
254 default:
255 NOTREACHED();
256 return false;
257 }
258}
259
260///////////////////// StringValue ////////////////////
261
[email protected]4cd5f6a2008-12-11 01:23:17262StringValue::StringValue(const std::string& in_value)
263 : Value(TYPE_STRING),
264 value_(in_value) {
265 DCHECK(IsStringUTF8(in_value));
266}
267
[email protected]9101ef1e2010-01-15 20:09:03268StringValue::StringValue(const string16& in_value)
269 : Value(TYPE_STRING),
270 value_(UTF16ToUTF8(in_value)) {
271}
[email protected]e2e593d2010-08-03 15:42:58272
initial.commitd7cae122008-07-26 21:49:38273StringValue::~StringValue() {
274}
275
[email protected]4cd5f6a2008-12-11 01:23:17276bool StringValue::GetAsString(std::string* out_value) const {
277 if (out_value)
278 *out_value = value_;
279 return true;
280}
281
[email protected]e2e593d2010-08-03 15:42:58282bool StringValue::GetAsString(string16* out_value) const {
283 if (out_value)
284 *out_value = UTF8ToUTF16(value_);
285 return true;
286}
287
[email protected]16f47e082011-01-18 02:16:59288StringValue* StringValue::DeepCopy() const {
initial.commitd7cae122008-07-26 21:49:38289 return CreateStringValue(value_);
290}
291
292bool StringValue::Equals(const Value* other) const {
293 if (other->GetType() != GetType())
294 return false;
[email protected]4cd5f6a2008-12-11 01:23:17295 std::string lhs, rhs;
initial.commitd7cae122008-07-26 21:49:38296 return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
297}
298
299///////////////////// BinaryValue ////////////////////
300
[email protected]9989c9bb2011-01-07 20:23:43301BinaryValue::~BinaryValue() {
302 DCHECK(buffer_);
303 if (buffer_)
304 delete[] buffer_;
305}
306
[email protected]7867cd02009-09-14 16:56:12307// static
initial.commitd7cae122008-07-26 21:49:38308BinaryValue* BinaryValue::Create(char* buffer, size_t size) {
309 if (!buffer)
310 return NULL;
311
312 return new BinaryValue(buffer, size);
313}
314
[email protected]7867cd02009-09-14 16:56:12315// static
[email protected]e4dad9fb2009-10-06 18:15:58316BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
317 size_t size) {
initial.commitd7cae122008-07-26 21:49:38318 if (!buffer)
319 return NULL;
320
321 char* buffer_copy = new char[size];
[email protected]abb9d0c2008-08-06 15:46:59322 memcpy(buffer_copy, buffer, size);
initial.commitd7cae122008-07-26 21:49:38323 return new BinaryValue(buffer_copy, size);
324}
325
[email protected]16f47e082011-01-18 02:16:59326BinaryValue* BinaryValue::DeepCopy() const {
initial.commitd7cae122008-07-26 21:49:38327 return CreateWithCopiedBuffer(buffer_, size_);
328}
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;
336 return !memcmp(buffer_, other_binary->buffer_, size_);
337}
338
[email protected]9989c9bb2011-01-07 20:23:43339BinaryValue::BinaryValue(char* buffer, size_t size)
340 : Value(TYPE_BINARY),
341 buffer_(buffer),
342 size_(size) {
343 DCHECK(buffer_);
344}
345
initial.commitd7cae122008-07-26 21:49:38346///////////////////// DictionaryValue ////////////////////
347
[email protected]3a3d47472010-07-15 21:03:54348DictionaryValue::DictionaryValue()
[email protected]e7b418b2010-07-30 19:47:47349 : Value(TYPE_DICTIONARY) {
[email protected]3a3d47472010-07-15 21:03:54350}
351
initial.commitd7cae122008-07-26 21:49:38352DictionaryValue::~DictionaryValue() {
353 Clear();
354}
355
[email protected]5cf906f82011-11-26 01:11:44356bool 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
[email protected]e7b418b2010-07-30 19:47:47368bool DictionaryValue::HasKey(const std::string& key) const {
[email protected]bc38b2c2010-08-06 06:03:25369 DCHECK(IsStringUTF8(key));
[email protected]ec330b52009-12-02 00:20:32370 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.commitd7cae122008-07-26 21:49:38375void 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
[email protected]e7b418b2010-07-30 19:47:47385void DictionaryValue::Set(const std::string& path, Value* in_value) {
[email protected]bc38b2c2010-08-06 06:03:25386 DCHECK(IsStringUTF8(path));
[email protected]4dad9ad82009-11-25 20:47:52387 DCHECK(in_value);
388
[email protected]e7b418b2010-07-30 19:47:47389 std::string current_path(path);
[email protected]4dad9ad82009-11-25 20:47:52390 DictionaryValue* current_dictionary = this;
391 for (size_t delimiter_position = current_path.find('.');
[email protected]e7b418b2010-07-30 19:47:47392 delimiter_position != std::string::npos;
[email protected]4dad9ad82009-11-25 20:47:52393 delimiter_position = current_path.find('.')) {
394 // Assume that we're indexing into a dictionary.
[email protected]e7b418b2010-07-30 19:47:47395 std::string key(current_path, 0, delimiter_position);
[email protected]37f46b42009-11-25 21:02:24396 DictionaryValue* child_dictionary = NULL;
[email protected]4dad9ad82009-11-25 20:47:52397 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
[email protected]e7b418b2010-07-30 19:47:47409void 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
[email protected]fb534c92011-02-01 01:02:07417void DictionaryValue::SetDouble(const std::string& path, double in_value) {
418 Set(path, CreateDoubleValue(in_value));
[email protected]e7b418b2010-07-30 19:47:47419}
420
421void DictionaryValue::SetString(const std::string& path,
422 const std::string& in_value) {
423 Set(path, CreateStringValue(in_value));
424}
425
[email protected]ff4c1d82010-08-04 16:58:12426void DictionaryValue::SetString(const std::string& path,
427 const string16& in_value) {
[email protected]e2e593d2010-08-03 15:42:58428 Set(path, CreateStringValue(in_value));
[email protected]e7b418b2010-07-30 19:47:47429}
430
[email protected]e7b418b2010-07-30 19:47:47431void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
[email protected]4dad9ad82009-11-25 20:47:52432 Value* in_value) {
initial.commitd7cae122008-07-26 21:49:38433 // If there's an existing value here, we need to delete it, because
434 // we own all our children.
[email protected]18a3df62011-10-21 22:58:52435 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.commitd7cae122008-07-26 21:49:38441 }
initial.commitd7cae122008-07-26 21:49:38442}
443
[email protected]e7b418b2010-07-30 19:47:47444bool DictionaryValue::Get(const std::string& path, Value** out_value) const {
[email protected]bc38b2c2010-08-06 06:03:25445 DCHECK(IsStringUTF8(path));
[email protected]e7b418b2010-07-30 19:47:47446 std::string current_path(path);
[email protected]4dad9ad82009-11-25 20:47:52447 const DictionaryValue* current_dictionary = this;
448 for (size_t delimiter_position = current_path.find('.');
[email protected]e7b418b2010-07-30 19:47:47449 delimiter_position != std::string::npos;
[email protected]4dad9ad82009-11-25 20:47:52450 delimiter_position = current_path.find('.')) {
[email protected]37f46b42009-11-25 21:02:24451 DictionaryValue* child_dictionary = NULL;
[email protected]4dad9ad82009-11-25 20:47:52452 if (!current_dictionary->GetDictionary(
453 current_path.substr(0, delimiter_position), &child_dictionary))
454 return false;
initial.commitd7cae122008-07-26 21:49:38455
[email protected]4dad9ad82009-11-25 20:47:52456 current_dictionary = child_dictionary;
457 current_path.erase(0, delimiter_position + 1);
initial.commitd7cae122008-07-26 21:49:38458 }
459
[email protected]4dad9ad82009-11-25 20:47:52460 return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
initial.commitd7cae122008-07-26 21:49:38461}
462
[email protected]e7b418b2010-07-30 19:47:47463bool DictionaryValue::GetBoolean(const std::string& path,
initial.commitd7cae122008-07-26 21:49:38464 bool* bool_value) const {
465 Value* value;
466 if (!Get(path, &value))
467 return false;
468
469 return value->GetAsBoolean(bool_value);
470}
471
[email protected]e7b418b2010-07-30 19:47:47472bool DictionaryValue::GetInteger(const std::string& path,
initial.commitd7cae122008-07-26 21:49:38473 int* out_value) const {
474 Value* value;
475 if (!Get(path, &value))
476 return false;
477
478 return value->GetAsInteger(out_value);
479}
480
[email protected]fb534c92011-02-01 01:02:07481bool DictionaryValue::GetDouble(const std::string& path,
482 double* out_value) const {
initial.commitd7cae122008-07-26 21:49:38483 Value* value;
484 if (!Get(path, &value))
485 return false;
486
[email protected]fb534c92011-02-01 01:02:07487 return value->GetAsDouble(out_value);
initial.commitd7cae122008-07-26 21:49:38488}
489
[email protected]9430e4b2010-02-19 13:32:16490bool DictionaryValue::GetString(const std::string& path,
[email protected]e7b418b2010-07-30 19:47:47491 std::string* out_value) const {
492 Value* value;
493 if (!Get(path, &value))
494 return false;
495
496 return value->GetAsString(out_value);
497}
498
[email protected]698f7f42010-08-04 19:35:33499bool DictionaryValue::GetString(const std::string& path,
500 string16* out_value) const {
[email protected]e7b418b2010-07-30 19:47:47501 Value* value;
502 if (!Get(path, &value))
503 return false;
504
[email protected]e2e593d2010-08-03 15:42:58505 return value->GetAsString(out_value);
[email protected]9430e4b2010-02-19 13:32:16506}
507
508bool DictionaryValue::GetStringASCII(const std::string& path,
509 std::string* out_value) const {
510 std::string out;
[email protected]e7b418b2010-07-30 19:47:47511 if (!GetString(path, &out))
[email protected]9430e4b2010-02-19 13:32:16512 return false;
513
514 if (!IsStringASCII(out)) {
515 NOTREACHED();
516 return false;
517 }
518
519 out_value->assign(out);
520 return true;
521}
522
[email protected]e7b418b2010-07-30 19:47:47523bool DictionaryValue::GetBinary(const std::string& path,
initial.commitd7cae122008-07-26 21:49:38524 BinaryValue** out_value) const {
525 Value* value;
526 bool result = Get(path, &value);
[email protected]0de764e2011-08-26 01:54:00527 if (!result || !value->IsType(TYPE_BINARY))
initial.commitd7cae122008-07-26 21:49:38528 return false;
529
530 if (out_value)
[email protected]0de764e2011-08-26 01:54:00531 *out_value = static_cast<BinaryValue*>(value);
initial.commitd7cae122008-07-26 21:49:38532
533 return true;
534}
535
[email protected]e7b418b2010-07-30 19:47:47536bool DictionaryValue::GetDictionary(const std::string& path,
initial.commitd7cae122008-07-26 21:49:38537 DictionaryValue** out_value) const {
538 Value* value;
539 bool result = Get(path, &value);
540 if (!result || !value->IsType(TYPE_DICTIONARY))
541 return false;
542
543 if (out_value)
544 *out_value = static_cast<DictionaryValue*>(value);
545
546 return true;
547}
548
[email protected]e7b418b2010-07-30 19:47:47549bool DictionaryValue::GetList(const std::string& path,
initial.commitd7cae122008-07-26 21:49:38550 ListValue** out_value) const {
551 Value* value;
552 bool result = Get(path, &value);
[email protected]0de764e2011-08-26 01:54:00553 if (!result || !value->IsType(TYPE_LIST))
initial.commitd7cae122008-07-26 21:49:38554 return false;
555
556 if (out_value)
[email protected]0de764e2011-08-26 01:54:00557 *out_value = static_cast<ListValue*>(value);
initial.commitd7cae122008-07-26 21:49:38558
559 return true;
560}
561
[email protected]e7b418b2010-07-30 19:47:47562bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
[email protected]4dad9ad82009-11-25 20:47:52563 Value** out_value) const {
[email protected]bc38b2c2010-08-06 06:03:25564 DCHECK(IsStringUTF8(key));
[email protected]4dad9ad82009-11-25 20:47:52565 ValueMap::const_iterator entry_iterator = dictionary_.find(key);
566 if (entry_iterator == dictionary_.end())
567 return false;
initial.commitd7cae122008-07-26 21:49:38568
[email protected]4dad9ad82009-11-25 20:47:52569 Value* entry = entry_iterator->second;
570 if (out_value)
571 *out_value = entry;
572 return true;
573}
574
[email protected]e7b418b2010-07-30 19:47:47575bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
[email protected]4dad9ad82009-11-25 20:47:52576 int* out_value) const {
577 Value* value;
[email protected]e7b418b2010-07-30 19:47:47578 if (!GetWithoutPathExpansion(key, &value))
[email protected]4dad9ad82009-11-25 20:47:52579 return false;
580
581 return value->GetAsInteger(out_value);
582}
583
[email protected]fb534c92011-02-01 01:02:07584bool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
585 double* out_value) const {
[email protected]b75b8292010-10-01 07:28:25586 Value* value;
587 if (!GetWithoutPathExpansion(key, &value))
588 return false;
589
[email protected]fb534c92011-02-01 01:02:07590 return value->GetAsDouble(out_value);
[email protected]b75b8292010-10-01 07:28:25591}
592
[email protected]4dad9ad82009-11-25 20:47:52593bool DictionaryValue::GetStringWithoutPathExpansion(
[email protected]e7b418b2010-07-30 19:47:47594 const std::string& key,
[email protected]4dad9ad82009-11-25 20:47:52595 std::string* out_value) const {
596 Value* value;
[email protected]e7b418b2010-07-30 19:47:47597 if (!GetWithoutPathExpansion(key, &value))
[email protected]4dad9ad82009-11-25 20:47:52598 return false;
599
600 return value->GetAsString(out_value);
601}
602
[email protected]698f7f42010-08-04 19:35:33603bool DictionaryValue::GetStringWithoutPathExpansion(
[email protected]e7b418b2010-07-30 19:47:47604 const std::string& key,
[email protected]9101ef1e2010-01-15 20:09:03605 string16* out_value) const {
606 Value* value;
[email protected]e7b418b2010-07-30 19:47:47607 if (!GetWithoutPathExpansion(key, &value))
[email protected]9101ef1e2010-01-15 20:09:03608 return false;
609
[email protected]e2e593d2010-08-03 15:42:58610 return value->GetAsString(out_value);
[email protected]9101ef1e2010-01-15 20:09:03611}
612
[email protected]4dad9ad82009-11-25 20:47:52613bool DictionaryValue::GetDictionaryWithoutPathExpansion(
[email protected]e7b418b2010-07-30 19:47:47614 const std::string& key,
[email protected]4dad9ad82009-11-25 20:47:52615 DictionaryValue** out_value) const {
616 Value* value;
[email protected]e7b418b2010-07-30 19:47:47617 bool result = GetWithoutPathExpansion(key, &value);
[email protected]4dad9ad82009-11-25 20:47:52618 if (!result || !value->IsType(TYPE_DICTIONARY))
619 return false;
620
621 if (out_value)
622 *out_value = static_cast<DictionaryValue*>(value);
623
624 return true;
625}
626
[email protected]e7b418b2010-07-30 19:47:47627bool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
[email protected]4dad9ad82009-11-25 20:47:52628 ListValue** out_value) const {
629 Value* value;
[email protected]e7b418b2010-07-30 19:47:47630 bool result = GetWithoutPathExpansion(key, &value);
[email protected]0de764e2011-08-26 01:54:00631 if (!result || !value->IsType(TYPE_LIST))
[email protected]4dad9ad82009-11-25 20:47:52632 return false;
633
634 if (out_value)
[email protected]0de764e2011-08-26 01:54:00635 *out_value = static_cast<ListValue*>(value);
[email protected]4dad9ad82009-11-25 20:47:52636
637 return true;
638}
639
[email protected]e7b418b2010-07-30 19:47:47640bool DictionaryValue::Remove(const std::string& path, Value** out_value) {
[email protected]bc38b2c2010-08-06 06:03:25641 DCHECK(IsStringUTF8(path));
[email protected]e7b418b2010-07-30 19:47:47642 std::string current_path(path);
[email protected]4dad9ad82009-11-25 20:47:52643 DictionaryValue* current_dictionary = this;
644 size_t delimiter_position = current_path.rfind('.');
[email protected]e7b418b2010-07-30 19:47:47645 if (delimiter_position != std::string::npos) {
[email protected]4dad9ad82009-11-25 20:47:52646 if (!GetDictionary(current_path.substr(0, delimiter_position),
647 &current_dictionary))
648 return false;
649 current_path.erase(0, delimiter_position + 1);
initial.commitd7cae122008-07-26 21:49:38650 }
651
[email protected]4dad9ad82009-11-25 20:47:52652 return current_dictionary->RemoveWithoutPathExpansion(current_path,
653 out_value);
654}
655
[email protected]e7b418b2010-07-30 19:47:47656bool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
[email protected]4dad9ad82009-11-25 20:47:52657 Value** out_value) {
[email protected]bc38b2c2010-08-06 06:03:25658 DCHECK(IsStringUTF8(key));
initial.commitd7cae122008-07-26 21:49:38659 ValueMap::iterator entry_iterator = dictionary_.find(key);
660 if (entry_iterator == dictionary_.end())
661 return false;
[email protected]4dad9ad82009-11-25 20:47:52662
initial.commitd7cae122008-07-26 21:49:38663 Value* entry = entry_iterator->second;
[email protected]4dad9ad82009-11-25 20:47:52664 if (out_value)
665 *out_value = entry;
666 else
667 delete entry;
668 dictionary_.erase(entry_iterator);
669 return true;
initial.commitd7cae122008-07-26 21:49:38670}
671
[email protected]ec330b52009-12-02 00:20:32672DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
673 Value* copy = CopyWithoutEmptyChildren(this);
674 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
initial.commitd7cae122008-07-26 21:49:38675}
676
[email protected]c378cca2010-05-14 13:17:40677void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
678 for (DictionaryValue::key_iterator key(dictionary->begin_keys());
679 key != dictionary->end_keys(); ++key) {
680 Value* merge_value;
681 if (dictionary->GetWithoutPathExpansion(*key, &merge_value)) {
682 // Check whether we have to merge dictionaries.
683 if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
684 DictionaryValue* sub_dict;
685 if (GetDictionaryWithoutPathExpansion(*key, &sub_dict)) {
686 sub_dict->MergeDictionary(
687 static_cast<const DictionaryValue*>(merge_value));
688 continue;
689 }
690 }
691 // All other cases: Make a copy and hook it up.
692 SetWithoutPathExpansion(*key, merge_value->DeepCopy());
693 }
694 }
695}
696
[email protected]16f47e082011-01-18 02:16:59697DictionaryValue* DictionaryValue::DeepCopy() const {
[email protected]9989c9bb2011-01-07 20:23:43698 DictionaryValue* result = new DictionaryValue;
699
700 for (ValueMap::const_iterator current_entry(dictionary_.begin());
701 current_entry != dictionary_.end(); ++current_entry) {
702 result->SetWithoutPathExpansion(current_entry->first,
703 current_entry->second->DeepCopy());
704 }
705
706 return result;
707}
708
709bool DictionaryValue::Equals(const Value* other) const {
710 if (other->GetType() != GetType())
711 return false;
712
713 const DictionaryValue* other_dict =
714 static_cast<const DictionaryValue*>(other);
715 key_iterator lhs_it(begin_keys());
716 key_iterator rhs_it(other_dict->begin_keys());
717 while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) {
718 Value* lhs;
719 Value* rhs;
720 if (*lhs_it != *rhs_it ||
721 !GetWithoutPathExpansion(*lhs_it, &lhs) ||
722 !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) ||
723 !lhs->Equals(rhs)) {
724 return false;
725 }
726 ++lhs_it;
727 ++rhs_it;
728 }
729 if (lhs_it != end_keys() || rhs_it != other_dict->end_keys())
730 return false;
731
732 return true;
733}
734
initial.commitd7cae122008-07-26 21:49:38735///////////////////// ListValue ////////////////////
736
[email protected]3a3d47472010-07-15 21:03:54737ListValue::ListValue() : Value(TYPE_LIST) {
738}
739
initial.commitd7cae122008-07-26 21:49:38740ListValue::~ListValue() {
741 Clear();
742}
743
744void ListValue::Clear() {
[email protected]e7f5c6f2009-05-09 00:33:04745 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
746 delete *i;
initial.commitd7cae122008-07-26 21:49:38747 list_.clear();
748}
749
750bool ListValue::Set(size_t index, Value* in_value) {
751 if (!in_value)
752 return false;
753
754 if (index >= list_.size()) {
755 // Pad out any intermediate indexes with null settings
756 while (index > list_.size())
757 Append(CreateNullValue());
758 Append(in_value);
759 } else {
760 DCHECK(list_[index] != in_value);
761 delete list_[index];
762 list_[index] = in_value;
763 }
764 return true;
765}
766
767bool ListValue::Get(size_t index, Value** out_value) const {
768 if (index >= list_.size())
769 return false;
770
771 if (out_value)
772 *out_value = list_[index];
773
774 return true;
775}
776
[email protected]f82fb4952009-01-20 21:05:32777bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
778 Value* value;
779 if (!Get(index, &value))
780 return false;
781
782 return value->GetAsBoolean(bool_value);
783}
784
785bool ListValue::GetInteger(size_t index, int* out_value) const {
786 Value* value;
787 if (!Get(index, &value))
788 return false;
789
790 return value->GetAsInteger(out_value);
791}
792
[email protected]fb534c92011-02-01 01:02:07793bool ListValue::GetDouble(size_t index, double* out_value) const {
[email protected]f82fb4952009-01-20 21:05:32794 Value* value;
795 if (!Get(index, &value))
796 return false;
797
[email protected]fb534c92011-02-01 01:02:07798 return value->GetAsDouble(out_value);
[email protected]f82fb4952009-01-20 21:05:32799}
800
801bool ListValue::GetString(size_t index, std::string* out_value) const {
802 Value* value;
803 if (!Get(index, &value))
804 return false;
805
806 return value->GetAsString(out_value);
807}
808
[email protected]698f7f42010-08-04 19:35:33809bool ListValue::GetString(size_t index, string16* out_value) const {
810 Value* value;
811 if (!Get(index, &value))
812 return false;
813
814 return value->GetAsString(out_value);
815}
816
[email protected]f82fb4952009-01-20 21:05:32817bool ListValue::GetBinary(size_t index, BinaryValue** out_value) const {
818 Value* value;
819 bool result = Get(index, &value);
820 if (!result || !value->IsType(TYPE_BINARY))
821 return false;
822
823 if (out_value)
824 *out_value = static_cast<BinaryValue*>(value);
825
826 return true;
827}
828
829bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) const {
initial.commitd7cae122008-07-26 21:49:38830 Value* value;
831 bool result = Get(index, &value);
832 if (!result || !value->IsType(TYPE_DICTIONARY))
833 return false;
834
835 if (out_value)
836 *out_value = static_cast<DictionaryValue*>(value);
837
838 return true;
839}
840
[email protected]f82fb4952009-01-20 21:05:32841bool ListValue::GetList(size_t index, ListValue** out_value) const {
842 Value* value;
843 bool result = Get(index, &value);
[email protected]0de764e2011-08-26 01:54:00844 if (!result || !value->IsType(TYPE_LIST))
[email protected]f82fb4952009-01-20 21:05:32845 return false;
846
847 if (out_value)
[email protected]0de764e2011-08-26 01:54:00848 *out_value = static_cast<ListValue*>(value);
[email protected]f82fb4952009-01-20 21:05:32849
850 return true;
851}
852
initial.commitd7cae122008-07-26 21:49:38853bool ListValue::Remove(size_t index, Value** out_value) {
854 if (index >= list_.size())
855 return false;
856
857 if (out_value)
858 *out_value = list_[index];
859 else
860 delete list_[index];
861
[email protected]e7f5c6f2009-05-09 00:33:04862 list_.erase(list_.begin() + index);
initial.commitd7cae122008-07-26 21:49:38863 return true;
864}
865
[email protected]4fc3c5642011-08-13 17:34:31866bool ListValue::Remove(const Value& value, size_t* index) {
[email protected]e7f5c6f2009-05-09 00:33:04867 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
868 if ((*i)->Equals(&value)) {
[email protected]4fc3c5642011-08-13 17:34:31869 size_t previous_index = i - list_.begin();
[email protected]6832cbe2009-11-30 19:59:11870 delete *i;
[email protected]e7f5c6f2009-05-09 00:33:04871 list_.erase(i);
[email protected]c604a552010-03-22 20:12:50872
[email protected]4fc3c5642011-08-13 17:34:31873 if (index)
874 *index = previous_index;
875 return true;
[email protected]e7f5c6f2009-05-09 00:33:04876 }
877 }
[email protected]4fc3c5642011-08-13 17:34:31878 return false;
[email protected]e7f5c6f2009-05-09 00:33:04879}
880
initial.commitd7cae122008-07-26 21:49:38881void ListValue::Append(Value* in_value) {
882 DCHECK(in_value);
883 list_.push_back(in_value);
884}
885
[email protected]840642202010-04-12 21:48:10886bool ListValue::AppendIfNotPresent(Value* in_value) {
887 DCHECK(in_value);
[email protected]46f89e142010-07-19 08:00:42888 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
[email protected]e36eaac2011-03-18 13:56:38889 if ((*i)->Equals(in_value)) {
890 delete in_value;
[email protected]840642202010-04-12 21:48:10891 return false;
[email protected]e36eaac2011-03-18 13:56:38892 }
[email protected]840642202010-04-12 21:48:10893 }
894 list_.push_back(in_value);
895 return true;
896}
897
[email protected]86c008e82009-08-28 20:26:05898bool ListValue::Insert(size_t index, Value* in_value) {
899 DCHECK(in_value);
[email protected]2b9d4582009-09-30 21:36:37900 if (index > list_.size())
[email protected]86c008e82009-08-28 20:26:05901 return false;
902
903 list_.insert(list_.begin() + index, in_value);
904 return true;
905}
906
[email protected]5fb35372011-09-19 15:23:10907ListValue::const_iterator ListValue::Find(const Value& value) const {
908 return std::find_if(list_.begin(), list_.end(), ValueEquals(&value));
909}
910
[email protected]81f9fe0b2010-12-07 00:35:29911bool ListValue::GetAsList(ListValue** out_value) {
912 if (out_value)
913 *out_value = this;
914 return true;
915}
916
[email protected]35552dc52011-07-12 09:04:38917bool ListValue::GetAsList(const ListValue** out_value) const {
918 if (out_value)
919 *out_value = this;
920 return true;
921}
922
[email protected]16f47e082011-01-18 02:16:59923ListValue* ListValue::DeepCopy() const {
initial.commitd7cae122008-07-26 21:49:38924 ListValue* result = new ListValue;
925
[email protected]e7f5c6f2009-05-09 00:33:04926 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
927 result->Append((*i)->DeepCopy());
initial.commitd7cae122008-07-26 21:49:38928
929 return result;
930}
931
932bool ListValue::Equals(const Value* other) const {
933 if (other->GetType() != GetType())
934 return false;
935
936 const ListValue* other_list =
937 static_cast<const ListValue*>(other);
938 const_iterator lhs_it, rhs_it;
939 for (lhs_it = begin(), rhs_it = other_list->begin();
940 lhs_it != end() && rhs_it != other_list->end();
941 ++lhs_it, ++rhs_it) {
942 if (!(*lhs_it)->Equals(*rhs_it))
943 return false;
944 }
945 if (lhs_it != end() || rhs_it != other_list->end())
946 return false;
947
948 return true;
949}
[email protected]3a3d47472010-07-15 21:03:54950
951ValueSerializer::~ValueSerializer() {
952}
[email protected]20566c92011-08-04 23:51:10953
954} // namespace base