Protect WebURLLoaderImpl::Context while receiving responses.
[chromium-blink-merge.git] / base / values.cc
blob66998853435687b7b2ecf9019458183903378c69
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(const Value* node) {
22 DCHECK(node);
23 switch (node->GetType()) {
24 case Value::TYPE_LIST: {
25 const ListValue* list = static_cast<const 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 const DictionaryValue* dict = static_cast<const DictionaryValue*>(node);
42 DictionaryValue* copy = new DictionaryValue;
43 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
44 Value* child_copy = CopyWithoutEmptyChildren(&it.value());
45 if (child_copy)
46 copy->SetWithoutPathExpansion(it.key(), child_copy);
48 if (!copy->empty())
49 return copy;
51 delete copy;
52 return NULL;
55 default:
56 // For everything else, just make a copy.
57 return node->DeepCopy();
61 // A small functor for comparing Values for std::find_if and similar.
62 class ValueEquals {
63 public:
64 // Pass the value against which all consecutive calls of the () operator will
65 // compare their argument to. This Value object must not be destroyed while
66 // the ValueEquals is in use.
67 explicit ValueEquals(const Value* first) : first_(first) { }
69 bool operator ()(const Value* second) const {
70 return first_->Equals(second);
73 private:
74 const Value* first_;
77 } // namespace
79 namespace base {
81 ///////////////////// Value ////////////////////
83 Value::~Value() {
86 // static
87 Value* Value::CreateNullValue() {
88 return new Value(TYPE_NULL);
91 // static
92 FundamentalValue* Value::CreateBooleanValue(bool in_value) {
93 return new FundamentalValue(in_value);
96 // static
97 FundamentalValue* Value::CreateIntegerValue(int in_value) {
98 return new FundamentalValue(in_value);
101 // static
102 FundamentalValue* Value::CreateDoubleValue(double in_value) {
103 return new FundamentalValue(in_value);
106 // static
107 StringValue* Value::CreateStringValue(const std::string& in_value) {
108 return new StringValue(in_value);
111 // static
112 StringValue* Value::CreateStringValue(const string16& in_value) {
113 return new StringValue(in_value);
116 bool Value::GetAsBoolean(bool* out_value) const {
117 return false;
120 bool Value::GetAsInteger(int* out_value) const {
121 return false;
124 bool Value::GetAsDouble(double* out_value) const {
125 return false;
128 bool Value::GetAsString(std::string* out_value) const {
129 return false;
132 bool Value::GetAsString(string16* out_value) const {
133 return false;
136 bool Value::GetAsList(ListValue** out_value) {
137 return false;
140 bool Value::GetAsList(const ListValue** out_value) const {
141 return false;
144 bool Value::GetAsDictionary(DictionaryValue** out_value) {
145 return false;
148 bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
149 return false;
152 Value* Value::DeepCopy() const {
153 // This method should only be getting called for null Values--all subclasses
154 // need to provide their own implementation;.
155 DCHECK(IsType(TYPE_NULL));
156 return CreateNullValue();
159 bool Value::Equals(const Value* other) const {
160 // This method should only be getting called for null Values--all subclasses
161 // need to provide their own implementation;.
162 DCHECK(IsType(TYPE_NULL));
163 return other->IsType(TYPE_NULL);
166 // static
167 bool Value::Equals(const Value* a, const Value* b) {
168 if ((a == NULL) && (b == NULL)) return true;
169 if ((a == NULL) ^ (b == NULL)) return false;
170 return a->Equals(b);
173 Value::Value(Type type) : type_(type) {}
175 Value::Value(const Value& that) : type_(that.type_) {}
177 Value& Value::operator=(const Value& that) {
178 type_ = that.type_;
179 return *this;
182 ///////////////////// FundamentalValue ////////////////////
184 FundamentalValue::FundamentalValue(bool in_value)
185 : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
188 FundamentalValue::FundamentalValue(int in_value)
189 : Value(TYPE_INTEGER), integer_value_(in_value) {
192 FundamentalValue::FundamentalValue(double in_value)
193 : Value(TYPE_DOUBLE), double_value_(in_value) {
194 if (!IsFinite(double_value_)) {
195 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
196 << "values cannot be represented in JSON";
197 double_value_ = 0.0;
201 FundamentalValue::~FundamentalValue() {
204 bool FundamentalValue::GetAsBoolean(bool* out_value) const {
205 if (out_value && IsType(TYPE_BOOLEAN))
206 *out_value = boolean_value_;
207 return (IsType(TYPE_BOOLEAN));
210 bool FundamentalValue::GetAsInteger(int* out_value) const {
211 if (out_value && IsType(TYPE_INTEGER))
212 *out_value = integer_value_;
213 return (IsType(TYPE_INTEGER));
216 bool FundamentalValue::GetAsDouble(double* out_value) const {
217 if (out_value && IsType(TYPE_DOUBLE))
218 *out_value = double_value_;
219 else if (out_value && IsType(TYPE_INTEGER))
220 *out_value = integer_value_;
221 return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER));
224 FundamentalValue* FundamentalValue::DeepCopy() const {
225 switch (GetType()) {
226 case TYPE_BOOLEAN:
227 return CreateBooleanValue(boolean_value_);
229 case TYPE_INTEGER:
230 return CreateIntegerValue(integer_value_);
232 case TYPE_DOUBLE:
233 return CreateDoubleValue(double_value_);
235 default:
236 NOTREACHED();
237 return NULL;
241 bool FundamentalValue::Equals(const Value* other) const {
242 if (other->GetType() != GetType())
243 return false;
245 switch (GetType()) {
246 case TYPE_BOOLEAN: {
247 bool lhs, rhs;
248 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
250 case TYPE_INTEGER: {
251 int lhs, rhs;
252 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
254 case TYPE_DOUBLE: {
255 double lhs, rhs;
256 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
258 default:
259 NOTREACHED();
260 return false;
264 ///////////////////// StringValue ////////////////////
266 StringValue::StringValue(const std::string& in_value)
267 : Value(TYPE_STRING),
268 value_(in_value) {
269 DCHECK(IsStringUTF8(in_value));
272 StringValue::StringValue(const string16& in_value)
273 : Value(TYPE_STRING),
274 value_(UTF16ToUTF8(in_value)) {
277 StringValue::~StringValue() {
280 bool StringValue::GetAsString(std::string* out_value) const {
281 if (out_value)
282 *out_value = value_;
283 return true;
286 bool StringValue::GetAsString(string16* out_value) const {
287 if (out_value)
288 *out_value = UTF8ToUTF16(value_);
289 return true;
292 StringValue* StringValue::DeepCopy() const {
293 return CreateStringValue(value_);
296 bool StringValue::Equals(const Value* other) const {
297 if (other->GetType() != GetType())
298 return false;
299 std::string lhs, rhs;
300 return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
303 ///////////////////// BinaryValue ////////////////////
305 BinaryValue::BinaryValue()
306 : Value(TYPE_BINARY),
307 size_(0) {
310 BinaryValue::BinaryValue(scoped_ptr<char[]> buffer, size_t size)
311 : Value(TYPE_BINARY),
312 buffer_(buffer.Pass()),
313 size_(size) {
316 BinaryValue::~BinaryValue() {
319 // static
320 BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
321 size_t size) {
322 char* buffer_copy = new char[size];
323 memcpy(buffer_copy, buffer, size);
324 scoped_ptr<char[]> scoped_buffer_copy(buffer_copy);
325 return new BinaryValue(scoped_buffer_copy.Pass(), size);
328 BinaryValue* BinaryValue::DeepCopy() const {
329 return CreateWithCopiedBuffer(buffer_.get(), size_);
332 bool BinaryValue::Equals(const Value* other) const {
333 if (other->GetType() != GetType())
334 return false;
335 const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
336 if (other_binary->size_ != size_)
337 return false;
338 return !memcmp(GetBuffer(), other_binary->GetBuffer(), size_);
341 ///////////////////// DictionaryValue ////////////////////
343 DictionaryValue::DictionaryValue()
344 : Value(TYPE_DICTIONARY) {
347 DictionaryValue::~DictionaryValue() {
348 Clear();
351 bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
352 if (out_value)
353 *out_value = this;
354 return true;
357 bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
358 if (out_value)
359 *out_value = this;
360 return true;
363 bool DictionaryValue::HasKey(const std::string& key) const {
364 DCHECK(IsStringUTF8(key));
365 ValueMap::const_iterator current_entry = dictionary_.find(key);
366 DCHECK((current_entry == dictionary_.end()) || current_entry->second);
367 return current_entry != dictionary_.end();
370 void DictionaryValue::Clear() {
371 ValueMap::iterator dict_iterator = dictionary_.begin();
372 while (dict_iterator != dictionary_.end()) {
373 delete dict_iterator->second;
374 ++dict_iterator;
377 dictionary_.clear();
380 void DictionaryValue::Set(const std::string& path, Value* in_value) {
381 DCHECK(IsStringUTF8(path));
382 DCHECK(in_value);
384 std::string current_path(path);
385 DictionaryValue* current_dictionary = this;
386 for (size_t delimiter_position = current_path.find('.');
387 delimiter_position != std::string::npos;
388 delimiter_position = current_path.find('.')) {
389 // Assume that we're indexing into a dictionary.
390 std::string key(current_path, 0, delimiter_position);
391 DictionaryValue* child_dictionary = NULL;
392 if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
393 child_dictionary = new DictionaryValue;
394 current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
397 current_dictionary = child_dictionary;
398 current_path.erase(0, delimiter_position + 1);
401 current_dictionary->SetWithoutPathExpansion(current_path, in_value);
404 void DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
405 Set(path, CreateBooleanValue(in_value));
408 void DictionaryValue::SetInteger(const std::string& path, int in_value) {
409 Set(path, CreateIntegerValue(in_value));
412 void DictionaryValue::SetDouble(const std::string& path, double in_value) {
413 Set(path, CreateDoubleValue(in_value));
416 void DictionaryValue::SetString(const std::string& path,
417 const std::string& in_value) {
418 Set(path, CreateStringValue(in_value));
421 void DictionaryValue::SetString(const std::string& path,
422 const string16& in_value) {
423 Set(path, CreateStringValue(in_value));
426 void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
427 Value* in_value) {
428 // If there's an existing value here, we need to delete it, because
429 // we own all our children.
430 std::pair<ValueMap::iterator, bool> ins_res =
431 dictionary_.insert(std::make_pair(key, in_value));
432 if (!ins_res.second) {
433 DCHECK_NE(ins_res.first->second, in_value); // This would be bogus
434 delete ins_res.first->second;
435 ins_res.first->second = in_value;
439 void DictionaryValue::SetBooleanWithoutPathExpansion(
440 const std::string& path, bool in_value) {
441 SetWithoutPathExpansion(path, CreateBooleanValue(in_value));
444 void DictionaryValue::SetIntegerWithoutPathExpansion(
445 const std::string& path, int in_value) {
446 SetWithoutPathExpansion(path, CreateIntegerValue(in_value));
449 void DictionaryValue::SetDoubleWithoutPathExpansion(
450 const std::string& path, double in_value) {
451 SetWithoutPathExpansion(path, CreateDoubleValue(in_value));
454 void DictionaryValue::SetStringWithoutPathExpansion(
455 const std::string& path, const std::string& in_value) {
456 SetWithoutPathExpansion(path, CreateStringValue(in_value));
459 void DictionaryValue::SetStringWithoutPathExpansion(
460 const std::string& path, const string16& in_value) {
461 SetWithoutPathExpansion(path, CreateStringValue(in_value));
464 bool DictionaryValue::Get(
465 const std::string& path, const Value** out_value) const {
466 DCHECK(IsStringUTF8(path));
467 // LOG(WARNING) << "\n1\n";
468 std::string current_path(path);
469 const DictionaryValue* current_dictionary = this;
470 // LOG(WARNING) << "\n2\n";
471 for (size_t delimiter_position = current_path.find('.');
472 delimiter_position != std::string::npos;
473 delimiter_position = current_path.find('.')) {
474 const DictionaryValue* child_dictionary = NULL;
475 if (!current_dictionary->GetDictionary(
476 current_path.substr(0, delimiter_position), &child_dictionary))
477 return false;
479 current_dictionary = child_dictionary;
480 current_path.erase(0, delimiter_position + 1);
482 // LOG(WARNING) << "\n3\n";
484 return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
487 bool DictionaryValue::Get(const std::string& path, Value** out_value) {
488 return static_cast<const DictionaryValue&>(*this).Get(
489 path,
490 const_cast<const Value**>(out_value));
493 bool DictionaryValue::GetBoolean(const std::string& path,
494 bool* bool_value) const {
495 const Value* value;
496 if (!Get(path, &value))
497 return false;
499 return value->GetAsBoolean(bool_value);
502 bool DictionaryValue::GetInteger(const std::string& path,
503 int* out_value) const {
504 const Value* value;
505 if (!Get(path, &value))
506 return false;
508 return value->GetAsInteger(out_value);
511 bool DictionaryValue::GetDouble(const std::string& path,
512 double* out_value) const {
513 const Value* value;
514 if (!Get(path, &value))
515 return false;
517 return value->GetAsDouble(out_value);
520 bool DictionaryValue::GetString(const std::string& path,
521 std::string* out_value) const {
522 const Value* value;
523 if (!Get(path, &value))
524 return false;
526 return value->GetAsString(out_value);
529 bool DictionaryValue::GetString(const std::string& path,
530 string16* out_value) const {
531 const Value* value;
532 if (!Get(path, &value))
533 return false;
535 return value->GetAsString(out_value);
538 bool DictionaryValue::GetStringASCII(const std::string& path,
539 std::string* out_value) const {
540 std::string out;
541 if (!GetString(path, &out))
542 return false;
544 if (!IsStringASCII(out)) {
545 NOTREACHED();
546 return false;
549 out_value->assign(out);
550 return true;
553 bool DictionaryValue::GetBinary(const std::string& path,
554 const BinaryValue** out_value) const {
555 const Value* value;
556 bool result = Get(path, &value);
557 if (!result || !value->IsType(TYPE_BINARY))
558 return false;
560 if (out_value)
561 *out_value = static_cast<const BinaryValue*>(value);
563 return true;
566 bool DictionaryValue::GetBinary(const std::string& path,
567 BinaryValue** out_value) {
568 return static_cast<const DictionaryValue&>(*this).GetBinary(
569 path,
570 const_cast<const BinaryValue**>(out_value));
573 bool DictionaryValue::GetDictionary(const std::string& path,
574 const DictionaryValue** out_value) const {
575 const Value* value;
576 bool result = Get(path, &value);
577 if (!result || !value->IsType(TYPE_DICTIONARY))
578 return false;
580 if (out_value)
581 *out_value = static_cast<const DictionaryValue*>(value);
583 return true;
586 bool DictionaryValue::GetDictionary(const std::string& path,
587 DictionaryValue** out_value) {
588 return static_cast<const DictionaryValue&>(*this).GetDictionary(
589 path,
590 const_cast<const DictionaryValue**>(out_value));
593 bool DictionaryValue::GetList(const std::string& path,
594 const ListValue** out_value) const {
595 const Value* value;
596 bool result = Get(path, &value);
597 if (!result || !value->IsType(TYPE_LIST))
598 return false;
600 if (out_value)
601 *out_value = static_cast<const ListValue*>(value);
603 return true;
606 bool DictionaryValue::GetList(const std::string& path, ListValue** out_value) {
607 return static_cast<const DictionaryValue&>(*this).GetList(
608 path,
609 const_cast<const ListValue**>(out_value));
612 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
613 const Value** out_value) const {
614 DCHECK(IsStringUTF8(key));
615 ValueMap::const_iterator entry_iterator = dictionary_.find(key);
616 if (entry_iterator == dictionary_.end())
617 return false;
619 const Value* entry = entry_iterator->second;
620 if (out_value)
621 *out_value = entry;
622 return true;
625 bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
626 Value** out_value) {
627 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
628 key,
629 const_cast<const Value**>(out_value));
632 bool DictionaryValue::GetBooleanWithoutPathExpansion(const std::string& key,
633 bool* out_value) const {
634 const Value* value;
635 if (!GetWithoutPathExpansion(key, &value))
636 return false;
638 return value->GetAsBoolean(out_value);
641 bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
642 int* out_value) const {
643 const Value* value;
644 if (!GetWithoutPathExpansion(key, &value))
645 return false;
647 return value->GetAsInteger(out_value);
650 bool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
651 double* out_value) const {
652 const Value* value;
653 if (!GetWithoutPathExpansion(key, &value))
654 return false;
656 return value->GetAsDouble(out_value);
659 bool DictionaryValue::GetStringWithoutPathExpansion(
660 const std::string& key,
661 std::string* out_value) const {
662 const Value* value;
663 if (!GetWithoutPathExpansion(key, &value))
664 return false;
666 return value->GetAsString(out_value);
669 bool DictionaryValue::GetStringWithoutPathExpansion(const std::string& key,
670 string16* out_value) const {
671 const Value* value;
672 if (!GetWithoutPathExpansion(key, &value))
673 return false;
675 return value->GetAsString(out_value);
678 bool DictionaryValue::GetDictionaryWithoutPathExpansion(
679 const std::string& key,
680 const DictionaryValue** out_value) const {
681 const Value* value;
682 bool result = GetWithoutPathExpansion(key, &value);
683 if (!result || !value->IsType(TYPE_DICTIONARY))
684 return false;
686 if (out_value)
687 *out_value = static_cast<const DictionaryValue*>(value);
689 return true;
692 bool DictionaryValue::GetDictionaryWithoutPathExpansion(
693 const std::string& key,
694 DictionaryValue** out_value) {
695 const DictionaryValue& const_this =
696 static_cast<const DictionaryValue&>(*this);
697 return const_this.GetDictionaryWithoutPathExpansion(
698 key,
699 const_cast<const DictionaryValue**>(out_value));
702 bool DictionaryValue::GetListWithoutPathExpansion(
703 const std::string& key,
704 const ListValue** out_value) const {
705 const Value* value;
706 bool result = GetWithoutPathExpansion(key, &value);
707 if (!result || !value->IsType(TYPE_LIST))
708 return false;
710 if (out_value)
711 *out_value = static_cast<const ListValue*>(value);
713 return true;
716 bool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
717 ListValue** out_value) {
718 return
719 static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
720 key,
721 const_cast<const ListValue**>(out_value));
724 bool DictionaryValue::Remove(const std::string& path, Value** out_value) {
725 DCHECK(IsStringUTF8(path));
726 std::string current_path(path);
727 DictionaryValue* current_dictionary = this;
728 size_t delimiter_position = current_path.rfind('.');
729 if (delimiter_position != std::string::npos) {
730 if (!GetDictionary(current_path.substr(0, delimiter_position),
731 &current_dictionary))
732 return false;
733 current_path.erase(0, delimiter_position + 1);
736 return current_dictionary->RemoveWithoutPathExpansion(current_path,
737 out_value);
740 bool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
741 Value** out_value) {
742 DCHECK(IsStringUTF8(key));
743 ValueMap::iterator entry_iterator = dictionary_.find(key);
744 if (entry_iterator == dictionary_.end())
745 return false;
747 Value* entry = entry_iterator->second;
748 if (out_value)
749 *out_value = entry;
750 else
751 delete entry;
752 dictionary_.erase(entry_iterator);
753 return true;
756 DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
757 Value* copy = CopyWithoutEmptyChildren(this);
758 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
761 void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
762 for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) {
763 const Value* merge_value = &it.value();
764 // Check whether we have to merge dictionaries.
765 if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
766 DictionaryValue* sub_dict;
767 if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
768 sub_dict->MergeDictionary(
769 static_cast<const DictionaryValue*>(merge_value));
770 continue;
773 // All other cases: Make a copy and hook it up.
774 SetWithoutPathExpansion(it.key(), merge_value->DeepCopy());
778 void DictionaryValue::Swap(DictionaryValue* other) {
779 dictionary_.swap(other->dictionary_);
782 DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
783 : target_(target),
784 it_(target.dictionary_.begin()) {}
786 DictionaryValue* DictionaryValue::DeepCopy() const {
787 DictionaryValue* result = new DictionaryValue;
789 for (ValueMap::const_iterator current_entry(dictionary_.begin());
790 current_entry != dictionary_.end(); ++current_entry) {
791 result->SetWithoutPathExpansion(current_entry->first,
792 current_entry->second->DeepCopy());
795 return result;
798 bool DictionaryValue::Equals(const Value* other) const {
799 if (other->GetType() != GetType())
800 return false;
802 const DictionaryValue* other_dict =
803 static_cast<const DictionaryValue*>(other);
804 Iterator lhs_it(*this);
805 Iterator rhs_it(*other_dict);
806 while (!lhs_it.IsAtEnd() && !rhs_it.IsAtEnd()) {
807 if (lhs_it.key() != rhs_it.key() ||
808 !lhs_it.value().Equals(&rhs_it.value())) {
809 return false;
811 lhs_it.Advance();
812 rhs_it.Advance();
814 if (!lhs_it.IsAtEnd() || !rhs_it.IsAtEnd())
815 return false;
817 return true;
820 ///////////////////// ListValue ////////////////////
822 ListValue::ListValue() : Value(TYPE_LIST) {
825 ListValue::~ListValue() {
826 Clear();
829 void ListValue::Clear() {
830 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
831 delete *i;
832 list_.clear();
835 bool ListValue::Set(size_t index, Value* in_value) {
836 if (!in_value)
837 return false;
839 if (index >= list_.size()) {
840 // Pad out any intermediate indexes with null settings
841 while (index > list_.size())
842 Append(CreateNullValue());
843 Append(in_value);
844 } else {
845 DCHECK(list_[index] != in_value);
846 delete list_[index];
847 list_[index] = in_value;
849 return true;
852 bool ListValue::Get(size_t index, const Value** out_value) const {
853 if (index >= list_.size())
854 return false;
856 if (out_value)
857 *out_value = list_[index];
859 return true;
862 bool ListValue::Get(size_t index, Value** out_value) {
863 return static_cast<const ListValue&>(*this).Get(
864 index,
865 const_cast<const Value**>(out_value));
868 bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
869 const Value* value;
870 if (!Get(index, &value))
871 return false;
873 return value->GetAsBoolean(bool_value);
876 bool ListValue::GetInteger(size_t index, int* out_value) const {
877 const Value* value;
878 if (!Get(index, &value))
879 return false;
881 return value->GetAsInteger(out_value);
884 bool ListValue::GetDouble(size_t index, double* out_value) const {
885 const Value* value;
886 if (!Get(index, &value))
887 return false;
889 return value->GetAsDouble(out_value);
892 bool ListValue::GetString(size_t index, std::string* out_value) const {
893 const Value* value;
894 if (!Get(index, &value))
895 return false;
897 return value->GetAsString(out_value);
900 bool ListValue::GetString(size_t index, string16* out_value) const {
901 const Value* value;
902 if (!Get(index, &value))
903 return false;
905 return value->GetAsString(out_value);
908 bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const {
909 const Value* value;
910 bool result = Get(index, &value);
911 if (!result || !value->IsType(TYPE_BINARY))
912 return false;
914 if (out_value)
915 *out_value = static_cast<const BinaryValue*>(value);
917 return true;
920 bool ListValue::GetBinary(size_t index, BinaryValue** out_value) {
921 return static_cast<const ListValue&>(*this).GetBinary(
922 index,
923 const_cast<const BinaryValue**>(out_value));
926 bool ListValue::GetDictionary(size_t index,
927 const DictionaryValue** out_value) const {
928 const Value* value;
929 bool result = Get(index, &value);
930 if (!result || !value->IsType(TYPE_DICTIONARY))
931 return false;
933 if (out_value)
934 *out_value = static_cast<const DictionaryValue*>(value);
936 return true;
939 bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
940 return static_cast<const ListValue&>(*this).GetDictionary(
941 index,
942 const_cast<const DictionaryValue**>(out_value));
945 bool ListValue::GetList(size_t index, const ListValue** out_value) const {
946 const Value* value;
947 bool result = Get(index, &value);
948 if (!result || !value->IsType(TYPE_LIST))
949 return false;
951 if (out_value)
952 *out_value = static_cast<const ListValue*>(value);
954 return true;
957 bool ListValue::GetList(size_t index, ListValue** out_value) {
958 return static_cast<const ListValue&>(*this).GetList(
959 index,
960 const_cast<const ListValue**>(out_value));
963 bool ListValue::Remove(size_t index, Value** out_value) {
964 if (index >= list_.size())
965 return false;
967 if (out_value)
968 *out_value = list_[index];
969 else
970 delete list_[index];
972 list_.erase(list_.begin() + index);
973 return true;
976 bool ListValue::Remove(const Value& value, size_t* index) {
977 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
978 if ((*i)->Equals(&value)) {
979 size_t previous_index = i - list_.begin();
980 delete *i;
981 list_.erase(i);
983 if (index)
984 *index = previous_index;
985 return true;
988 return false;
991 ListValue::iterator ListValue::Erase(iterator iter, Value** out_value) {
992 if (out_value)
993 *out_value = *iter;
994 else
995 delete *iter;
997 return list_.erase(iter);
1000 void ListValue::Append(Value* in_value) {
1001 DCHECK(in_value);
1002 list_.push_back(in_value);
1005 void ListValue::AppendBoolean(bool in_value) {
1006 Append(CreateBooleanValue(in_value));
1009 void ListValue::AppendInteger(int in_value) {
1010 Append(CreateIntegerValue(in_value));
1013 void ListValue::AppendDouble(double in_value) {
1014 Append(CreateDoubleValue(in_value));
1017 void ListValue::AppendString(const std::string& in_value) {
1018 Append(CreateStringValue(in_value));
1021 void ListValue::AppendString(const string16& in_value) {
1022 Append(CreateStringValue(in_value));
1025 void ListValue::AppendStrings(const std::vector<std::string>& in_values) {
1026 for (std::vector<std::string>::const_iterator it = in_values.begin();
1027 it != in_values.end(); ++it) {
1028 AppendString(*it);
1032 void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1033 for (std::vector<string16>::const_iterator it = in_values.begin();
1034 it != in_values.end(); ++it) {
1035 AppendString(*it);
1039 bool ListValue::AppendIfNotPresent(Value* in_value) {
1040 DCHECK(in_value);
1041 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
1042 if ((*i)->Equals(in_value)) {
1043 delete in_value;
1044 return false;
1047 list_.push_back(in_value);
1048 return true;
1051 bool ListValue::Insert(size_t index, Value* in_value) {
1052 DCHECK(in_value);
1053 if (index > list_.size())
1054 return false;
1056 list_.insert(list_.begin() + index, in_value);
1057 return true;
1060 ListValue::const_iterator ListValue::Find(const Value& value) const {
1061 return std::find_if(list_.begin(), list_.end(), ValueEquals(&value));
1064 void ListValue::Swap(ListValue* other) {
1065 list_.swap(other->list_);
1068 bool ListValue::GetAsList(ListValue** out_value) {
1069 if (out_value)
1070 *out_value = this;
1071 return true;
1074 bool ListValue::GetAsList(const ListValue** out_value) const {
1075 if (out_value)
1076 *out_value = this;
1077 return true;
1080 ListValue* ListValue::DeepCopy() const {
1081 ListValue* result = new ListValue;
1083 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
1084 result->Append((*i)->DeepCopy());
1086 return result;
1089 bool ListValue::Equals(const Value* other) const {
1090 if (other->GetType() != GetType())
1091 return false;
1093 const ListValue* other_list =
1094 static_cast<const ListValue*>(other);
1095 const_iterator lhs_it, rhs_it;
1096 for (lhs_it = begin(), rhs_it = other_list->begin();
1097 lhs_it != end() && rhs_it != other_list->end();
1098 ++lhs_it, ++rhs_it) {
1099 if (!(*lhs_it)->Equals(*rhs_it))
1100 return false;
1102 if (lhs_it != end() || rhs_it != other_list->end())
1103 return false;
1105 return true;
1108 ValueSerializer::~ValueSerializer() {
1111 std::ostream& operator<<(std::ostream& out, const Value& value) {
1112 std::string json;
1113 JSONWriter::WriteWithOptions(&value,
1114 JSONWriter::OPTIONS_PRETTY_PRINT,
1115 &json);
1116 return out << json;
1119 } // namespace base