[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / base / values.cc
blob459d56fa0222fa2ea98503ece9dd755022908725
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/values.h"
7 #include <algorithm>
8 #include <ostream>
10 #include "base/float_util.h"
11 #include "base/json/json_writer.h"
12 #include "base/logging.h"
13 #include "base/string_util.h"
14 #include "base/utf_string_conversions.h"
16 namespace {
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.
21 Value* CopyWithoutEmptyChildren(Value* node) {
22 DCHECK(node);
23 switch (node->GetType()) {
24 case Value::TYPE_LIST: {
25 ListValue* list = static_cast<ListValue*>(node);
26 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);
33 if (!copy->empty())
34 return copy;
36 delete copy;
37 return NULL;
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);
52 if (!copy->empty())
53 return copy;
55 delete copy;
56 return NULL;
59 default:
60 // For everything else, just make a copy.
61 return node->DeepCopy();
65 // A small functor for comparing Values for std::find_if and similar.
66 class 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) { }
73 bool operator ()(const Value* second) const {
74 return first_->Equals(second);
77 private:
78 const Value* first_;
81 } // namespace
83 namespace base {
85 ///////////////////// Value ////////////////////
87 Value::~Value() {
90 // static
91 Value* Value::CreateNullValue() {
92 return new Value(TYPE_NULL);
95 // static
96 FundamentalValue* Value::CreateBooleanValue(bool in_value) {
97 return new FundamentalValue(in_value);
100 // static
101 FundamentalValue* Value::CreateIntegerValue(int in_value) {
102 return new FundamentalValue(in_value);
105 // static
106 FundamentalValue* Value::CreateDoubleValue(double in_value) {
107 return new FundamentalValue(in_value);
110 // static
111 StringValue* Value::CreateStringValue(const std::string& in_value) {
112 return new StringValue(in_value);
115 // static
116 StringValue* Value::CreateStringValue(const string16& in_value) {
117 return new StringValue(in_value);
120 bool Value::GetAsBoolean(bool* out_value) const {
121 return false;
124 bool Value::GetAsInteger(int* out_value) const {
125 return false;
128 bool Value::GetAsDouble(double* out_value) const {
129 return false;
132 bool Value::GetAsString(std::string* out_value) const {
133 return false;
136 bool Value::GetAsString(string16* out_value) const {
137 return false;
140 bool Value::GetAsList(ListValue** out_value) {
141 return false;
144 bool Value::GetAsList(const ListValue** out_value) const {
145 return false;
148 bool Value::GetAsDictionary(DictionaryValue** out_value) {
149 return false;
152 bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
153 return false;
156 Value* 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();
163 bool 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);
170 // static
171 bool 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);
177 Value::Value(Type type) : type_(type) {}
179 Value::Value(const Value& that) : type_(that.type_) {}
181 Value& Value::operator=(const Value& that) {
182 type_ = that.type_;
183 return *this;
186 ///////////////////// FundamentalValue ////////////////////
188 FundamentalValue::FundamentalValue(bool in_value)
189 : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
192 FundamentalValue::FundamentalValue(int in_value)
193 : Value(TYPE_INTEGER), integer_value_(in_value) {
196 FundamentalValue::FundamentalValue(double in_value)
197 : Value(TYPE_DOUBLE), double_value_(in_value) {
198 if (!IsFinite(double_value_)) {
199 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
200 << "values cannot be represented in JSON";
201 double_value_ = 0.0;
205 FundamentalValue::~FundamentalValue() {
208 bool FundamentalValue::GetAsBoolean(bool* out_value) const {
209 if (out_value && IsType(TYPE_BOOLEAN))
210 *out_value = boolean_value_;
211 return (IsType(TYPE_BOOLEAN));
214 bool FundamentalValue::GetAsInteger(int* out_value) const {
215 if (out_value && IsType(TYPE_INTEGER))
216 *out_value = integer_value_;
217 return (IsType(TYPE_INTEGER));
220 bool FundamentalValue::GetAsDouble(double* out_value) const {
221 if (out_value && IsType(TYPE_DOUBLE))
222 *out_value = double_value_;
223 else if (out_value && IsType(TYPE_INTEGER))
224 *out_value = integer_value_;
225 return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER));
228 FundamentalValue* FundamentalValue::DeepCopy() const {
229 switch (GetType()) {
230 case TYPE_BOOLEAN:
231 return CreateBooleanValue(boolean_value_);
233 case TYPE_INTEGER:
234 return CreateIntegerValue(integer_value_);
236 case TYPE_DOUBLE:
237 return CreateDoubleValue(double_value_);
239 default:
240 NOTREACHED();
241 return NULL;
245 bool FundamentalValue::Equals(const Value* other) const {
246 if (other->GetType() != GetType())
247 return false;
249 switch (GetType()) {
250 case TYPE_BOOLEAN: {
251 bool lhs, rhs;
252 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
254 case TYPE_INTEGER: {
255 int lhs, rhs;
256 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
258 case TYPE_DOUBLE: {
259 double lhs, rhs;
260 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
262 default:
263 NOTREACHED();
264 return false;
268 ///////////////////// StringValue ////////////////////
270 StringValue::StringValue(const std::string& in_value)
271 : Value(TYPE_STRING),
272 value_(in_value) {
273 DCHECK(IsStringUTF8(in_value));
276 StringValue::StringValue(const string16& in_value)
277 : Value(TYPE_STRING),
278 value_(UTF16ToUTF8(in_value)) {
281 StringValue::~StringValue() {
284 bool StringValue::GetAsString(std::string* out_value) const {
285 if (out_value)
286 *out_value = value_;
287 return true;
290 bool StringValue::GetAsString(string16* out_value) const {
291 if (out_value)
292 *out_value = UTF8ToUTF16(value_);
293 return true;
296 StringValue* StringValue::DeepCopy() const {
297 return CreateStringValue(value_);
300 bool StringValue::Equals(const Value* other) const {
301 if (other->GetType() != GetType())
302 return false;
303 std::string lhs, rhs;
304 return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
307 ///////////////////// BinaryValue ////////////////////
309 BinaryValue::~BinaryValue() {
310 DCHECK(buffer_);
311 if (buffer_)
312 delete[] buffer_;
315 // static
316 BinaryValue* BinaryValue::Create(char* buffer, size_t size) {
317 if (!buffer)
318 return NULL;
320 return new BinaryValue(buffer, size);
323 // static
324 BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
325 size_t size) {
326 if (!buffer)
327 return NULL;
329 char* buffer_copy = new char[size];
330 memcpy(buffer_copy, buffer, size);
331 return new BinaryValue(buffer_copy, size);
334 BinaryValue* BinaryValue::DeepCopy() const {
335 return CreateWithCopiedBuffer(buffer_, size_);
338 bool BinaryValue::Equals(const Value* other) const {
339 if (other->GetType() != GetType())
340 return false;
341 const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
342 if (other_binary->size_ != size_)
343 return false;
344 return !memcmp(buffer_, other_binary->buffer_, size_);
347 BinaryValue::BinaryValue(char* buffer, size_t size)
348 : Value(TYPE_BINARY),
349 buffer_(buffer),
350 size_(size) {
351 DCHECK(buffer_);
354 ///////////////////// DictionaryValue ////////////////////
356 DictionaryValue::DictionaryValue()
357 : Value(TYPE_DICTIONARY) {
360 DictionaryValue::~DictionaryValue() {
361 Clear();
364 bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
365 if (out_value)
366 *out_value = this;
367 return true;
370 bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
371 if (out_value)
372 *out_value = this;
373 return true;
376 bool DictionaryValue::HasKey(const std::string& key) const {
377 DCHECK(IsStringUTF8(key));
378 ValueMap::const_iterator current_entry = dictionary_.find(key);
379 DCHECK((current_entry == dictionary_.end()) || current_entry->second);
380 return current_entry != dictionary_.end();
383 void DictionaryValue::Clear() {
384 ValueMap::iterator dict_iterator = dictionary_.begin();
385 while (dict_iterator != dictionary_.end()) {
386 delete dict_iterator->second;
387 ++dict_iterator;
390 dictionary_.clear();
393 void DictionaryValue::Set(const std::string& path, Value* in_value) {
394 DCHECK(IsStringUTF8(path));
395 DCHECK(in_value);
397 std::string current_path(path);
398 DictionaryValue* current_dictionary = this;
399 for (size_t delimiter_position = current_path.find('.');
400 delimiter_position != std::string::npos;
401 delimiter_position = current_path.find('.')) {
402 // Assume that we're indexing into a dictionary.
403 std::string key(current_path, 0, delimiter_position);
404 DictionaryValue* child_dictionary = NULL;
405 if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
406 child_dictionary = new DictionaryValue;
407 current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
410 current_dictionary = child_dictionary;
411 current_path.erase(0, delimiter_position + 1);
414 current_dictionary->SetWithoutPathExpansion(current_path, in_value);
417 void DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
418 Set(path, CreateBooleanValue(in_value));
421 void DictionaryValue::SetInteger(const std::string& path, int in_value) {
422 Set(path, CreateIntegerValue(in_value));
425 void DictionaryValue::SetDouble(const std::string& path, double in_value) {
426 Set(path, CreateDoubleValue(in_value));
429 void DictionaryValue::SetString(const std::string& path,
430 const std::string& in_value) {
431 Set(path, CreateStringValue(in_value));
434 void DictionaryValue::SetString(const std::string& path,
435 const string16& in_value) {
436 Set(path, CreateStringValue(in_value));
439 void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
440 Value* in_value) {
441 // If there's an existing value here, we need to delete it, because
442 // we own all our children.
443 std::pair<ValueMap::iterator, bool> ins_res =
444 dictionary_.insert(std::make_pair(key, in_value));
445 if (!ins_res.second) {
446 DCHECK_NE(ins_res.first->second, in_value); // This would be bogus
447 delete ins_res.first->second;
448 ins_res.first->second = in_value;
452 void DictionaryValue::SetBooleanWithoutPathExpansion(
453 const std::string& path, bool in_value) {
454 SetWithoutPathExpansion(path, CreateBooleanValue(in_value));
457 void DictionaryValue::SetIntegerWithoutPathExpansion(
458 const std::string& path, int in_value) {
459 SetWithoutPathExpansion(path, CreateIntegerValue(in_value));
462 void DictionaryValue::SetDoubleWithoutPathExpansion(
463 const std::string& path, double in_value) {
464 SetWithoutPathExpansion(path, CreateDoubleValue(in_value));
467 void DictionaryValue::SetStringWithoutPathExpansion(
468 const std::string& path, const std::string& in_value) {
469 SetWithoutPathExpansion(path, CreateStringValue(in_value));
472 void DictionaryValue::SetStringWithoutPathExpansion(
473 const std::string& path, const string16& in_value) {
474 SetWithoutPathExpansion(path, CreateStringValue(in_value));
477 bool DictionaryValue::Get(
478 const std::string& path, const Value** out_value) const {
479 DCHECK(IsStringUTF8(path));
480 std::string current_path(path);
481 const DictionaryValue* current_dictionary = this;
482 for (size_t delimiter_position = current_path.find('.');
483 delimiter_position != std::string::npos;
484 delimiter_position = current_path.find('.')) {
485 const DictionaryValue* child_dictionary = NULL;
486 if (!current_dictionary->GetDictionary(
487 current_path.substr(0, delimiter_position), &child_dictionary))
488 return false;
490 current_dictionary = child_dictionary;
491 current_path.erase(0, delimiter_position + 1);
494 return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
497 bool DictionaryValue::Get(const std::string& path, Value** out_value) {
498 return static_cast<const DictionaryValue&>(*this).Get(
499 path,
500 const_cast<const Value**>(out_value));
503 bool DictionaryValue::GetBoolean(const std::string& path,
504 bool* bool_value) const {
505 const Value* value;
506 if (!Get(path, &value))
507 return false;
509 return value->GetAsBoolean(bool_value);
512 bool DictionaryValue::GetInteger(const std::string& path,
513 int* out_value) const {
514 const Value* value;
515 if (!Get(path, &value))
516 return false;
518 return value->GetAsInteger(out_value);
521 bool DictionaryValue::GetDouble(const std::string& path,
522 double* out_value) const {
523 const Value* value;
524 if (!Get(path, &value))
525 return false;
527 return value->GetAsDouble(out_value);
530 bool DictionaryValue::GetString(const std::string& path,
531 std::string* out_value) const {
532 const Value* value;
533 if (!Get(path, &value))
534 return false;
536 return value->GetAsString(out_value);
539 bool DictionaryValue::GetString(const std::string& path,
540 string16* out_value) const {
541 const Value* value;
542 if (!Get(path, &value))
543 return false;
545 return value->GetAsString(out_value);
548 bool DictionaryValue::GetStringASCII(const std::string& path,
549 std::string* out_value) const {
550 std::string out;
551 if (!GetString(path, &out))
552 return false;
554 if (!IsStringASCII(out)) {
555 NOTREACHED();
556 return false;
559 out_value->assign(out);
560 return true;
563 bool DictionaryValue::GetBinary(const std::string& path,
564 const BinaryValue** out_value) const {
565 const Value* value;
566 bool result = Get(path, &value);
567 if (!result || !value->IsType(TYPE_BINARY))
568 return false;
570 if (out_value)
571 *out_value = static_cast<const BinaryValue*>(value);
573 return true;
576 bool DictionaryValue::GetBinary(const std::string& path,
577 BinaryValue** out_value) {
578 return static_cast<const DictionaryValue&>(*this).GetBinary(
579 path,
580 const_cast<const BinaryValue**>(out_value));
583 bool DictionaryValue::GetDictionary(const std::string& path,
584 const DictionaryValue** out_value) const {
585 const Value* value;
586 bool result = Get(path, &value);
587 if (!result || !value->IsType(TYPE_DICTIONARY))
588 return false;
590 if (out_value)
591 *out_value = static_cast<const DictionaryValue*>(value);
593 return true;
596 bool DictionaryValue::GetDictionary(const std::string& path,
597 DictionaryValue** out_value) {
598 return static_cast<const DictionaryValue&>(*this).GetDictionary(
599 path,
600 const_cast<const DictionaryValue**>(out_value));
603 bool DictionaryValue::GetList(const std::string& path,
604 const ListValue** out_value) const {
605 const Value* value;
606 bool result = Get(path, &value);
607 if (!result || !value->IsType(TYPE_LIST))
608 return false;
610 if (out_value)
611 *out_value = static_cast<const ListValue*>(value);
613 return true;
616 bool DictionaryValue::GetList(const std::string& path, ListValue** out_value) {
617 return static_cast<const DictionaryValue&>(*this).GetList(
618 path,
619 const_cast<const ListValue**>(out_value));
622 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
623 const Value** out_value) const {
624 DCHECK(IsStringUTF8(key));
625 ValueMap::const_iterator entry_iterator = dictionary_.find(key);
626 if (entry_iterator == dictionary_.end())
627 return false;
629 const Value* entry = entry_iterator->second;
630 if (out_value)
631 *out_value = entry;
632 return true;
635 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
636 Value** out_value) {
637 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
638 key,
639 const_cast<const Value**>(out_value));
642 bool DictionaryValue::GetBooleanWithoutPathExpansion(const std::string& key,
643 bool* out_value) const {
644 const Value* value;
645 if (!GetWithoutPathExpansion(key, &value))
646 return false;
648 return value->GetAsBoolean(out_value);
651 bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
652 int* out_value) const {
653 const Value* value;
654 if (!GetWithoutPathExpansion(key, &value))
655 return false;
657 return value->GetAsInteger(out_value);
660 bool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
661 double* out_value) const {
662 const Value* value;
663 if (!GetWithoutPathExpansion(key, &value))
664 return false;
666 return value->GetAsDouble(out_value);
669 bool DictionaryValue::GetStringWithoutPathExpansion(
670 const std::string& key,
671 std::string* out_value) const {
672 const Value* value;
673 if (!GetWithoutPathExpansion(key, &value))
674 return false;
676 return value->GetAsString(out_value);
679 bool DictionaryValue::GetStringWithoutPathExpansion(const std::string& key,
680 string16* out_value) const {
681 const Value* value;
682 if (!GetWithoutPathExpansion(key, &value))
683 return false;
685 return value->GetAsString(out_value);
688 bool DictionaryValue::GetDictionaryWithoutPathExpansion(
689 const std::string& key,
690 const DictionaryValue** out_value) const {
691 const Value* value;
692 bool result = GetWithoutPathExpansion(key, &value);
693 if (!result || !value->IsType(TYPE_DICTIONARY))
694 return false;
696 if (out_value)
697 *out_value = static_cast<const DictionaryValue*>(value);
699 return true;
702 bool DictionaryValue::GetDictionaryWithoutPathExpansion(
703 const std::string& key,
704 DictionaryValue** out_value) {
705 const DictionaryValue& const_this =
706 static_cast<const DictionaryValue&>(*this);
707 return const_this.GetDictionaryWithoutPathExpansion(
708 key,
709 const_cast<const DictionaryValue**>(out_value));
712 bool DictionaryValue::GetListWithoutPathExpansion(
713 const std::string& key,
714 const ListValue** out_value) const {
715 const Value* value;
716 bool result = GetWithoutPathExpansion(key, &value);
717 if (!result || !value->IsType(TYPE_LIST))
718 return false;
720 if (out_value)
721 *out_value = static_cast<const ListValue*>(value);
723 return true;
726 bool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
727 ListValue** out_value) {
728 return
729 static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
730 key,
731 const_cast<const ListValue**>(out_value));
734 bool DictionaryValue::Remove(const std::string& path, Value** out_value) {
735 DCHECK(IsStringUTF8(path));
736 std::string current_path(path);
737 DictionaryValue* current_dictionary = this;
738 size_t delimiter_position = current_path.rfind('.');
739 if (delimiter_position != std::string::npos) {
740 if (!GetDictionary(current_path.substr(0, delimiter_position),
741 &current_dictionary))
742 return false;
743 current_path.erase(0, delimiter_position + 1);
746 return current_dictionary->RemoveWithoutPathExpansion(current_path,
747 out_value);
750 bool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
751 Value** out_value) {
752 DCHECK(IsStringUTF8(key));
753 ValueMap::iterator entry_iterator = dictionary_.find(key);
754 if (entry_iterator == dictionary_.end())
755 return false;
757 Value* entry = entry_iterator->second;
758 if (out_value)
759 *out_value = entry;
760 else
761 delete entry;
762 dictionary_.erase(entry_iterator);
763 return true;
766 DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
767 Value* copy = CopyWithoutEmptyChildren(this);
768 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
771 void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
772 for (DictionaryValue::key_iterator key(dictionary->begin_keys());
773 key != dictionary->end_keys(); ++key) {
774 const Value* merge_value;
775 if (dictionary->GetWithoutPathExpansion(*key, &merge_value)) {
776 // Check whether we have to merge dictionaries.
777 if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
778 DictionaryValue* sub_dict;
779 if (GetDictionaryWithoutPathExpansion(*key, &sub_dict)) {
780 sub_dict->MergeDictionary(
781 static_cast<const DictionaryValue*>(merge_value));
782 continue;
785 // All other cases: Make a copy and hook it up.
786 SetWithoutPathExpansion(*key, merge_value->DeepCopy());
791 void DictionaryValue::Swap(DictionaryValue* other) {
792 dictionary_.swap(other->dictionary_);
795 DictionaryValue::key_iterator::key_iterator(ValueMap::const_iterator itr) {
796 itr_ = itr;
799 DictionaryValue::key_iterator::key_iterator(const key_iterator& rhs) {
800 itr_ = rhs.itr_;
803 DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
804 : target_(target),
805 it_(target.dictionary_.begin()) {}
807 DictionaryValue* DictionaryValue::DeepCopy() const {
808 DictionaryValue* result = new DictionaryValue;
810 for (ValueMap::const_iterator current_entry(dictionary_.begin());
811 current_entry != dictionary_.end(); ++current_entry) {
812 result->SetWithoutPathExpansion(current_entry->first,
813 current_entry->second->DeepCopy());
816 return result;
819 bool DictionaryValue::Equals(const Value* other) const {
820 if (other->GetType() != GetType())
821 return false;
823 const DictionaryValue* other_dict =
824 static_cast<const DictionaryValue*>(other);
825 key_iterator lhs_it(begin_keys());
826 key_iterator rhs_it(other_dict->begin_keys());
827 while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) {
828 const Value* lhs;
829 const Value* rhs;
830 if (*lhs_it != *rhs_it ||
831 !GetWithoutPathExpansion(*lhs_it, &lhs) ||
832 !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) ||
833 !lhs->Equals(rhs)) {
834 return false;
836 ++lhs_it;
837 ++rhs_it;
839 if (lhs_it != end_keys() || rhs_it != other_dict->end_keys())
840 return false;
842 return true;
845 ///////////////////// ListValue ////////////////////
847 ListValue::ListValue() : Value(TYPE_LIST) {
850 ListValue::~ListValue() {
851 Clear();
854 void ListValue::Clear() {
855 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
856 delete *i;
857 list_.clear();
860 bool ListValue::Set(size_t index, Value* in_value) {
861 if (!in_value)
862 return false;
864 if (index >= list_.size()) {
865 // Pad out any intermediate indexes with null settings
866 while (index > list_.size())
867 Append(CreateNullValue());
868 Append(in_value);
869 } else {
870 DCHECK(list_[index] != in_value);
871 delete list_[index];
872 list_[index] = in_value;
874 return true;
877 bool ListValue::Get(size_t index, const Value** out_value) const {
878 if (index >= list_.size())
879 return false;
881 if (out_value)
882 *out_value = list_[index];
884 return true;
887 bool ListValue::Get(size_t index, Value** out_value) {
888 return static_cast<const ListValue&>(*this).Get(
889 index,
890 const_cast<const Value**>(out_value));
893 bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
894 const Value* value;
895 if (!Get(index, &value))
896 return false;
898 return value->GetAsBoolean(bool_value);
901 bool ListValue::GetInteger(size_t index, int* out_value) const {
902 const Value* value;
903 if (!Get(index, &value))
904 return false;
906 return value->GetAsInteger(out_value);
909 bool ListValue::GetDouble(size_t index, double* out_value) const {
910 const Value* value;
911 if (!Get(index, &value))
912 return false;
914 return value->GetAsDouble(out_value);
917 bool ListValue::GetString(size_t index, std::string* out_value) const {
918 const Value* value;
919 if (!Get(index, &value))
920 return false;
922 return value->GetAsString(out_value);
925 bool ListValue::GetString(size_t index, string16* out_value) const {
926 const Value* value;
927 if (!Get(index, &value))
928 return false;
930 return value->GetAsString(out_value);
933 bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const {
934 const Value* value;
935 bool result = Get(index, &value);
936 if (!result || !value->IsType(TYPE_BINARY))
937 return false;
939 if (out_value)
940 *out_value = static_cast<const BinaryValue*>(value);
942 return true;
945 bool ListValue::GetBinary(size_t index, BinaryValue** out_value) {
946 return static_cast<const ListValue&>(*this).GetBinary(
947 index,
948 const_cast<const BinaryValue**>(out_value));
951 bool ListValue::GetDictionary(size_t index,
952 const DictionaryValue** out_value) const {
953 const Value* value;
954 bool result = Get(index, &value);
955 if (!result || !value->IsType(TYPE_DICTIONARY))
956 return false;
958 if (out_value)
959 *out_value = static_cast<const DictionaryValue*>(value);
961 return true;
964 bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
965 return static_cast<const ListValue&>(*this).GetDictionary(
966 index,
967 const_cast<const DictionaryValue**>(out_value));
970 bool ListValue::GetList(size_t index, const ListValue** out_value) const {
971 const Value* value;
972 bool result = Get(index, &value);
973 if (!result || !value->IsType(TYPE_LIST))
974 return false;
976 if (out_value)
977 *out_value = static_cast<const ListValue*>(value);
979 return true;
982 bool ListValue::GetList(size_t index, ListValue** out_value) {
983 return static_cast<const ListValue&>(*this).GetList(
984 index,
985 const_cast<const ListValue**>(out_value));
988 bool ListValue::Remove(size_t index, Value** out_value) {
989 if (index >= list_.size())
990 return false;
992 if (out_value)
993 *out_value = list_[index];
994 else
995 delete list_[index];
997 list_.erase(list_.begin() + index);
998 return true;
1001 bool ListValue::Remove(const Value& value, size_t* index) {
1002 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
1003 if ((*i)->Equals(&value)) {
1004 size_t previous_index = i - list_.begin();
1005 delete *i;
1006 list_.erase(i);
1008 if (index)
1009 *index = previous_index;
1010 return true;
1013 return false;
1016 void ListValue::Erase(iterator iter, Value** out_value) {
1017 if (out_value)
1018 *out_value = *iter;
1019 else
1020 delete *iter;
1022 list_.erase(iter);
1025 void ListValue::Append(Value* in_value) {
1026 DCHECK(in_value);
1027 list_.push_back(in_value);
1030 void ListValue::AppendBoolean(bool in_value) {
1031 Append(CreateBooleanValue(in_value));
1034 void ListValue::AppendInteger(int in_value) {
1035 Append(CreateIntegerValue(in_value));
1038 void ListValue::AppendDouble(double in_value) {
1039 Append(CreateDoubleValue(in_value));
1042 void ListValue::AppendString(const std::string& in_value) {
1043 Append(CreateStringValue(in_value));
1046 void ListValue::AppendString(const string16& in_value) {
1047 Append(CreateStringValue(in_value));
1050 void ListValue::AppendStrings(const std::vector<std::string>& in_values) {
1051 for (std::vector<std::string>::const_iterator it = in_values.begin();
1052 it != in_values.end(); ++it) {
1053 AppendString(*it);
1057 void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1058 for (std::vector<string16>::const_iterator it = in_values.begin();
1059 it != in_values.end(); ++it) {
1060 AppendString(*it);
1064 bool ListValue::AppendIfNotPresent(Value* in_value) {
1065 DCHECK(in_value);
1066 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
1067 if ((*i)->Equals(in_value)) {
1068 delete in_value;
1069 return false;
1072 list_.push_back(in_value);
1073 return true;
1076 bool ListValue::Insert(size_t index, Value* in_value) {
1077 DCHECK(in_value);
1078 if (index > list_.size())
1079 return false;
1081 list_.insert(list_.begin() + index, in_value);
1082 return true;
1085 ListValue::const_iterator ListValue::Find(const Value& value) const {
1086 return std::find_if(list_.begin(), list_.end(), ValueEquals(&value));
1089 void ListValue::Swap(ListValue* other) {
1090 list_.swap(other->list_);
1093 bool ListValue::GetAsList(ListValue** out_value) {
1094 if (out_value)
1095 *out_value = this;
1096 return true;
1099 bool ListValue::GetAsList(const ListValue** out_value) const {
1100 if (out_value)
1101 *out_value = this;
1102 return true;
1105 ListValue* ListValue::DeepCopy() const {
1106 ListValue* result = new ListValue;
1108 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
1109 result->Append((*i)->DeepCopy());
1111 return result;
1114 bool ListValue::Equals(const Value* other) const {
1115 if (other->GetType() != GetType())
1116 return false;
1118 const ListValue* other_list =
1119 static_cast<const ListValue*>(other);
1120 const_iterator lhs_it, rhs_it;
1121 for (lhs_it = begin(), rhs_it = other_list->begin();
1122 lhs_it != end() && rhs_it != other_list->end();
1123 ++lhs_it, ++rhs_it) {
1124 if (!(*lhs_it)->Equals(*rhs_it))
1125 return false;
1127 if (lhs_it != end() || rhs_it != other_list->end())
1128 return false;
1130 return true;
1133 ValueSerializer::~ValueSerializer() {
1136 std::ostream& operator<<(std::ostream& out, const Value& value) {
1137 std::string json;
1138 JSONWriter::WriteWithOptions(&value,
1139 JSONWriter::OPTIONS_PRETTY_PRINT,
1140 &json);
1141 return out << json;
1144 } // namespace base