Tab Audio Mirroring: WebContentsAudioInputStream is a new implementation which repres...
[chromium-blink-merge.git] / base / values.cc
blob4c8968f9795f419f5e16e45dfc09949114f078a6
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 explicit 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 : Value(TYPE_BINARY),
311 buffer_(NULL),
312 size_(0) {
315 BinaryValue::BinaryValue(scoped_ptr<char[]> buffer, size_t size)
316 : Value(TYPE_BINARY),
317 buffer_(buffer.Pass()),
318 size_(size) {
321 BinaryValue::~BinaryValue() {
324 // static
325 BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
326 size_t size) {
327 char* buffer_copy = new char[size];
328 memcpy(buffer_copy, buffer, size);
329 scoped_ptr<char[]> scoped_buffer_copy(buffer_copy);
330 return new BinaryValue(scoped_buffer_copy.Pass(), size);
333 BinaryValue* BinaryValue::DeepCopy() const {
334 return CreateWithCopiedBuffer(buffer_.get(), size_);
337 bool BinaryValue::Equals(const Value* other) const {
338 if (other->GetType() != GetType())
339 return false;
340 const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
341 if (other_binary->size_ != size_)
342 return false;
343 return !memcmp(GetBuffer(), other_binary->GetBuffer(), size_);
346 ///////////////////// DictionaryValue ////////////////////
348 DictionaryValue::DictionaryValue()
349 : Value(TYPE_DICTIONARY) {
352 DictionaryValue::~DictionaryValue() {
353 Clear();
356 bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
357 if (out_value)
358 *out_value = this;
359 return true;
362 bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
363 if (out_value)
364 *out_value = this;
365 return true;
368 bool DictionaryValue::HasKey(const std::string& key) const {
369 DCHECK(IsStringUTF8(key));
370 ValueMap::const_iterator current_entry = dictionary_.find(key);
371 DCHECK((current_entry == dictionary_.end()) || current_entry->second);
372 return current_entry != dictionary_.end();
375 void DictionaryValue::Clear() {
376 ValueMap::iterator dict_iterator = dictionary_.begin();
377 while (dict_iterator != dictionary_.end()) {
378 delete dict_iterator->second;
379 ++dict_iterator;
382 dictionary_.clear();
385 void DictionaryValue::Set(const std::string& path, Value* in_value) {
386 DCHECK(IsStringUTF8(path));
387 DCHECK(in_value);
389 std::string current_path(path);
390 DictionaryValue* current_dictionary = this;
391 for (size_t delimiter_position = current_path.find('.');
392 delimiter_position != std::string::npos;
393 delimiter_position = current_path.find('.')) {
394 // Assume that we're indexing into a dictionary.
395 std::string key(current_path, 0, delimiter_position);
396 DictionaryValue* child_dictionary = NULL;
397 if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
398 child_dictionary = new DictionaryValue;
399 current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
402 current_dictionary = child_dictionary;
403 current_path.erase(0, delimiter_position + 1);
406 current_dictionary->SetWithoutPathExpansion(current_path, in_value);
409 void DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
410 Set(path, CreateBooleanValue(in_value));
413 void DictionaryValue::SetInteger(const std::string& path, int in_value) {
414 Set(path, CreateIntegerValue(in_value));
417 void DictionaryValue::SetDouble(const std::string& path, double in_value) {
418 Set(path, CreateDoubleValue(in_value));
421 void DictionaryValue::SetString(const std::string& path,
422 const std::string& in_value) {
423 Set(path, CreateStringValue(in_value));
426 void DictionaryValue::SetString(const std::string& path,
427 const string16& in_value) {
428 Set(path, CreateStringValue(in_value));
431 void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
432 Value* in_value) {
433 // If there's an existing value here, we need to delete it, because
434 // we own all our children.
435 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;
444 void DictionaryValue::SetBooleanWithoutPathExpansion(
445 const std::string& path, bool in_value) {
446 SetWithoutPathExpansion(path, CreateBooleanValue(in_value));
449 void DictionaryValue::SetIntegerWithoutPathExpansion(
450 const std::string& path, int in_value) {
451 SetWithoutPathExpansion(path, CreateIntegerValue(in_value));
454 void DictionaryValue::SetDoubleWithoutPathExpansion(
455 const std::string& path, double in_value) {
456 SetWithoutPathExpansion(path, CreateDoubleValue(in_value));
459 void DictionaryValue::SetStringWithoutPathExpansion(
460 const std::string& path, const std::string& in_value) {
461 SetWithoutPathExpansion(path, CreateStringValue(in_value));
464 void DictionaryValue::SetStringWithoutPathExpansion(
465 const std::string& path, const string16& in_value) {
466 SetWithoutPathExpansion(path, CreateStringValue(in_value));
469 bool DictionaryValue::Get(
470 const std::string& path, const Value** out_value) const {
471 DCHECK(IsStringUTF8(path));
472 std::string current_path(path);
473 const DictionaryValue* current_dictionary = this;
474 for (size_t delimiter_position = current_path.find('.');
475 delimiter_position != std::string::npos;
476 delimiter_position = current_path.find('.')) {
477 const DictionaryValue* child_dictionary = NULL;
478 if (!current_dictionary->GetDictionary(
479 current_path.substr(0, delimiter_position), &child_dictionary))
480 return false;
482 current_dictionary = child_dictionary;
483 current_path.erase(0, delimiter_position + 1);
486 return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
489 bool DictionaryValue::Get(const std::string& path, Value** out_value) {
490 return static_cast<const DictionaryValue&>(*this).Get(
491 path,
492 const_cast<const Value**>(out_value));
495 bool DictionaryValue::GetBoolean(const std::string& path,
496 bool* bool_value) const {
497 const Value* value;
498 if (!Get(path, &value))
499 return false;
501 return value->GetAsBoolean(bool_value);
504 bool DictionaryValue::GetInteger(const std::string& path,
505 int* out_value) const {
506 const Value* value;
507 if (!Get(path, &value))
508 return false;
510 return value->GetAsInteger(out_value);
513 bool DictionaryValue::GetDouble(const std::string& path,
514 double* out_value) const {
515 const Value* value;
516 if (!Get(path, &value))
517 return false;
519 return value->GetAsDouble(out_value);
522 bool DictionaryValue::GetString(const std::string& path,
523 std::string* out_value) const {
524 const Value* value;
525 if (!Get(path, &value))
526 return false;
528 return value->GetAsString(out_value);
531 bool DictionaryValue::GetString(const std::string& path,
532 string16* out_value) const {
533 const Value* value;
534 if (!Get(path, &value))
535 return false;
537 return value->GetAsString(out_value);
540 bool DictionaryValue::GetStringASCII(const std::string& path,
541 std::string* out_value) const {
542 std::string out;
543 if (!GetString(path, &out))
544 return false;
546 if (!IsStringASCII(out)) {
547 NOTREACHED();
548 return false;
551 out_value->assign(out);
552 return true;
555 bool DictionaryValue::GetBinary(const std::string& path,
556 const BinaryValue** out_value) const {
557 const Value* value;
558 bool result = Get(path, &value);
559 if (!result || !value->IsType(TYPE_BINARY))
560 return false;
562 if (out_value)
563 *out_value = static_cast<const BinaryValue*>(value);
565 return true;
568 bool DictionaryValue::GetBinary(const std::string& path,
569 BinaryValue** out_value) {
570 return static_cast<const DictionaryValue&>(*this).GetBinary(
571 path,
572 const_cast<const BinaryValue**>(out_value));
575 bool DictionaryValue::GetDictionary(const std::string& path,
576 const DictionaryValue** out_value) const {
577 const Value* value;
578 bool result = Get(path, &value);
579 if (!result || !value->IsType(TYPE_DICTIONARY))
580 return false;
582 if (out_value)
583 *out_value = static_cast<const DictionaryValue*>(value);
585 return true;
588 bool DictionaryValue::GetDictionary(const std::string& path,
589 DictionaryValue** out_value) {
590 return static_cast<const DictionaryValue&>(*this).GetDictionary(
591 path,
592 const_cast<const DictionaryValue**>(out_value));
595 bool DictionaryValue::GetList(const std::string& path,
596 const ListValue** out_value) const {
597 const Value* value;
598 bool result = Get(path, &value);
599 if (!result || !value->IsType(TYPE_LIST))
600 return false;
602 if (out_value)
603 *out_value = static_cast<const ListValue*>(value);
605 return true;
608 bool DictionaryValue::GetList(const std::string& path, ListValue** out_value) {
609 return static_cast<const DictionaryValue&>(*this).GetList(
610 path,
611 const_cast<const ListValue**>(out_value));
614 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
615 const Value** out_value) const {
616 DCHECK(IsStringUTF8(key));
617 ValueMap::const_iterator entry_iterator = dictionary_.find(key);
618 if (entry_iterator == dictionary_.end())
619 return false;
621 const Value* entry = entry_iterator->second;
622 if (out_value)
623 *out_value = entry;
624 return true;
627 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
628 Value** out_value) {
629 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
630 key,
631 const_cast<const Value**>(out_value));
634 bool DictionaryValue::GetBooleanWithoutPathExpansion(const std::string& key,
635 bool* out_value) const {
636 const Value* value;
637 if (!GetWithoutPathExpansion(key, &value))
638 return false;
640 return value->GetAsBoolean(out_value);
643 bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
644 int* out_value) const {
645 const Value* value;
646 if (!GetWithoutPathExpansion(key, &value))
647 return false;
649 return value->GetAsInteger(out_value);
652 bool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
653 double* out_value) const {
654 const Value* value;
655 if (!GetWithoutPathExpansion(key, &value))
656 return false;
658 return value->GetAsDouble(out_value);
661 bool DictionaryValue::GetStringWithoutPathExpansion(
662 const std::string& key,
663 std::string* out_value) const {
664 const Value* value;
665 if (!GetWithoutPathExpansion(key, &value))
666 return false;
668 return value->GetAsString(out_value);
671 bool DictionaryValue::GetStringWithoutPathExpansion(const std::string& key,
672 string16* out_value) const {
673 const Value* value;
674 if (!GetWithoutPathExpansion(key, &value))
675 return false;
677 return value->GetAsString(out_value);
680 bool DictionaryValue::GetDictionaryWithoutPathExpansion(
681 const std::string& key,
682 const DictionaryValue** out_value) const {
683 const Value* value;
684 bool result = GetWithoutPathExpansion(key, &value);
685 if (!result || !value->IsType(TYPE_DICTIONARY))
686 return false;
688 if (out_value)
689 *out_value = static_cast<const DictionaryValue*>(value);
691 return true;
694 bool DictionaryValue::GetDictionaryWithoutPathExpansion(
695 const std::string& key,
696 DictionaryValue** out_value) {
697 const DictionaryValue& const_this =
698 static_cast<const DictionaryValue&>(*this);
699 return const_this.GetDictionaryWithoutPathExpansion(
700 key,
701 const_cast<const DictionaryValue**>(out_value));
704 bool DictionaryValue::GetListWithoutPathExpansion(
705 const std::string& key,
706 const ListValue** out_value) const {
707 const Value* value;
708 bool result = GetWithoutPathExpansion(key, &value);
709 if (!result || !value->IsType(TYPE_LIST))
710 return false;
712 if (out_value)
713 *out_value = static_cast<const ListValue*>(value);
715 return true;
718 bool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
719 ListValue** out_value) {
720 return
721 static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
722 key,
723 const_cast<const ListValue**>(out_value));
726 bool DictionaryValue::Remove(const std::string& path, Value** out_value) {
727 DCHECK(IsStringUTF8(path));
728 std::string current_path(path);
729 DictionaryValue* current_dictionary = this;
730 size_t delimiter_position = current_path.rfind('.');
731 if (delimiter_position != std::string::npos) {
732 if (!GetDictionary(current_path.substr(0, delimiter_position),
733 &current_dictionary))
734 return false;
735 current_path.erase(0, delimiter_position + 1);
738 return current_dictionary->RemoveWithoutPathExpansion(current_path,
739 out_value);
742 bool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
743 Value** out_value) {
744 DCHECK(IsStringUTF8(key));
745 ValueMap::iterator entry_iterator = dictionary_.find(key);
746 if (entry_iterator == dictionary_.end())
747 return false;
749 Value* entry = entry_iterator->second;
750 if (out_value)
751 *out_value = entry;
752 else
753 delete entry;
754 dictionary_.erase(entry_iterator);
755 return true;
758 DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
759 Value* copy = CopyWithoutEmptyChildren(this);
760 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
763 void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
764 for (DictionaryValue::key_iterator key(dictionary->begin_keys());
765 key != dictionary->end_keys(); ++key) {
766 const Value* merge_value;
767 if (dictionary->GetWithoutPathExpansion(*key, &merge_value)) {
768 // Check whether we have to merge dictionaries.
769 if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
770 DictionaryValue* sub_dict;
771 if (GetDictionaryWithoutPathExpansion(*key, &sub_dict)) {
772 sub_dict->MergeDictionary(
773 static_cast<const DictionaryValue*>(merge_value));
774 continue;
777 // All other cases: Make a copy and hook it up.
778 SetWithoutPathExpansion(*key, merge_value->DeepCopy());
783 void DictionaryValue::Swap(DictionaryValue* other) {
784 dictionary_.swap(other->dictionary_);
787 DictionaryValue::key_iterator::key_iterator(ValueMap::const_iterator itr) {
788 itr_ = itr;
791 DictionaryValue::key_iterator::key_iterator(const key_iterator& rhs) {
792 itr_ = rhs.itr_;
795 DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
796 : target_(target),
797 it_(target.dictionary_.begin()) {}
799 DictionaryValue* DictionaryValue::DeepCopy() const {
800 DictionaryValue* result = new DictionaryValue;
802 for (ValueMap::const_iterator current_entry(dictionary_.begin());
803 current_entry != dictionary_.end(); ++current_entry) {
804 result->SetWithoutPathExpansion(current_entry->first,
805 current_entry->second->DeepCopy());
808 return result;
811 bool DictionaryValue::Equals(const Value* other) const {
812 if (other->GetType() != GetType())
813 return false;
815 const DictionaryValue* other_dict =
816 static_cast<const DictionaryValue*>(other);
817 key_iterator lhs_it(begin_keys());
818 key_iterator rhs_it(other_dict->begin_keys());
819 while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) {
820 const Value* lhs;
821 const Value* rhs;
822 if (*lhs_it != *rhs_it ||
823 !GetWithoutPathExpansion(*lhs_it, &lhs) ||
824 !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) ||
825 !lhs->Equals(rhs)) {
826 return false;
828 ++lhs_it;
829 ++rhs_it;
831 if (lhs_it != end_keys() || rhs_it != other_dict->end_keys())
832 return false;
834 return true;
837 ///////////////////// ListValue ////////////////////
839 ListValue::ListValue() : Value(TYPE_LIST) {
842 ListValue::~ListValue() {
843 Clear();
846 void ListValue::Clear() {
847 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
848 delete *i;
849 list_.clear();
852 bool ListValue::Set(size_t index, Value* in_value) {
853 if (!in_value)
854 return false;
856 if (index >= list_.size()) {
857 // Pad out any intermediate indexes with null settings
858 while (index > list_.size())
859 Append(CreateNullValue());
860 Append(in_value);
861 } else {
862 DCHECK(list_[index] != in_value);
863 delete list_[index];
864 list_[index] = in_value;
866 return true;
869 bool ListValue::Get(size_t index, const Value** out_value) const {
870 if (index >= list_.size())
871 return false;
873 if (out_value)
874 *out_value = list_[index];
876 return true;
879 bool ListValue::Get(size_t index, Value** out_value) {
880 return static_cast<const ListValue&>(*this).Get(
881 index,
882 const_cast<const Value**>(out_value));
885 bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
886 const Value* value;
887 if (!Get(index, &value))
888 return false;
890 return value->GetAsBoolean(bool_value);
893 bool ListValue::GetInteger(size_t index, int* out_value) const {
894 const Value* value;
895 if (!Get(index, &value))
896 return false;
898 return value->GetAsInteger(out_value);
901 bool ListValue::GetDouble(size_t index, double* out_value) const {
902 const Value* value;
903 if (!Get(index, &value))
904 return false;
906 return value->GetAsDouble(out_value);
909 bool ListValue::GetString(size_t index, std::string* out_value) const {
910 const Value* value;
911 if (!Get(index, &value))
912 return false;
914 return value->GetAsString(out_value);
917 bool ListValue::GetString(size_t index, string16* out_value) const {
918 const Value* value;
919 if (!Get(index, &value))
920 return false;
922 return value->GetAsString(out_value);
925 bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const {
926 const Value* value;
927 bool result = Get(index, &value);
928 if (!result || !value->IsType(TYPE_BINARY))
929 return false;
931 if (out_value)
932 *out_value = static_cast<const BinaryValue*>(value);
934 return true;
937 bool ListValue::GetBinary(size_t index, BinaryValue** out_value) {
938 return static_cast<const ListValue&>(*this).GetBinary(
939 index,
940 const_cast<const BinaryValue**>(out_value));
943 bool ListValue::GetDictionary(size_t index,
944 const DictionaryValue** out_value) const {
945 const Value* value;
946 bool result = Get(index, &value);
947 if (!result || !value->IsType(TYPE_DICTIONARY))
948 return false;
950 if (out_value)
951 *out_value = static_cast<const DictionaryValue*>(value);
953 return true;
956 bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
957 return static_cast<const ListValue&>(*this).GetDictionary(
958 index,
959 const_cast<const DictionaryValue**>(out_value));
962 bool ListValue::GetList(size_t index, const ListValue** out_value) const {
963 const Value* value;
964 bool result = Get(index, &value);
965 if (!result || !value->IsType(TYPE_LIST))
966 return false;
968 if (out_value)
969 *out_value = static_cast<const ListValue*>(value);
971 return true;
974 bool ListValue::GetList(size_t index, ListValue** out_value) {
975 return static_cast<const ListValue&>(*this).GetList(
976 index,
977 const_cast<const ListValue**>(out_value));
980 bool ListValue::Remove(size_t index, Value** out_value) {
981 if (index >= list_.size())
982 return false;
984 if (out_value)
985 *out_value = list_[index];
986 else
987 delete list_[index];
989 list_.erase(list_.begin() + index);
990 return true;
993 bool ListValue::Remove(const Value& value, size_t* index) {
994 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
995 if ((*i)->Equals(&value)) {
996 size_t previous_index = i - list_.begin();
997 delete *i;
998 list_.erase(i);
1000 if (index)
1001 *index = previous_index;
1002 return true;
1005 return false;
1008 void ListValue::Erase(iterator iter, Value** out_value) {
1009 if (out_value)
1010 *out_value = *iter;
1011 else
1012 delete *iter;
1014 list_.erase(iter);
1017 void ListValue::Append(Value* in_value) {
1018 DCHECK(in_value);
1019 list_.push_back(in_value);
1022 void ListValue::AppendBoolean(bool in_value) {
1023 Append(CreateBooleanValue(in_value));
1026 void ListValue::AppendInteger(int in_value) {
1027 Append(CreateIntegerValue(in_value));
1030 void ListValue::AppendDouble(double in_value) {
1031 Append(CreateDoubleValue(in_value));
1034 void ListValue::AppendString(const std::string& in_value) {
1035 Append(CreateStringValue(in_value));
1038 void ListValue::AppendString(const string16& in_value) {
1039 Append(CreateStringValue(in_value));
1042 void ListValue::AppendStrings(const std::vector<std::string>& in_values) {
1043 for (std::vector<std::string>::const_iterator it = in_values.begin();
1044 it != in_values.end(); ++it) {
1045 AppendString(*it);
1049 void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1050 for (std::vector<string16>::const_iterator it = in_values.begin();
1051 it != in_values.end(); ++it) {
1052 AppendString(*it);
1056 bool ListValue::AppendIfNotPresent(Value* in_value) {
1057 DCHECK(in_value);
1058 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
1059 if ((*i)->Equals(in_value)) {
1060 delete in_value;
1061 return false;
1064 list_.push_back(in_value);
1065 return true;
1068 bool ListValue::Insert(size_t index, Value* in_value) {
1069 DCHECK(in_value);
1070 if (index > list_.size())
1071 return false;
1073 list_.insert(list_.begin() + index, in_value);
1074 return true;
1077 ListValue::const_iterator ListValue::Find(const Value& value) const {
1078 return std::find_if(list_.begin(), list_.end(), ValueEquals(&value));
1081 void ListValue::Swap(ListValue* other) {
1082 list_.swap(other->list_);
1085 bool ListValue::GetAsList(ListValue** out_value) {
1086 if (out_value)
1087 *out_value = this;
1088 return true;
1091 bool ListValue::GetAsList(const ListValue** out_value) const {
1092 if (out_value)
1093 *out_value = this;
1094 return true;
1097 ListValue* ListValue::DeepCopy() const {
1098 ListValue* result = new ListValue;
1100 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
1101 result->Append((*i)->DeepCopy());
1103 return result;
1106 bool ListValue::Equals(const Value* other) const {
1107 if (other->GetType() != GetType())
1108 return false;
1110 const ListValue* other_list =
1111 static_cast<const ListValue*>(other);
1112 const_iterator lhs_it, rhs_it;
1113 for (lhs_it = begin(), rhs_it = other_list->begin();
1114 lhs_it != end() && rhs_it != other_list->end();
1115 ++lhs_it, ++rhs_it) {
1116 if (!(*lhs_it)->Equals(*rhs_it))
1117 return false;
1119 if (lhs_it != end() || rhs_it != other_list->end())
1120 return false;
1122 return true;
1125 ValueSerializer::~ValueSerializer() {
1128 std::ostream& operator<<(std::ostream& out, const Value& value) {
1129 std::string json;
1130 JSONWriter::WriteWithOptions(&value,
1131 JSONWriter::OPTIONS_PRETTY_PRINT,
1132 &json);
1133 return out << json;
1136 } // namespace base