values.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2010 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.
4
5#include "base/values.h"
6
7#include "base/logging.h"
8#include "base/string_util.h"
9#include "base/utf_string_conversions.h"
10
11namespace {
12
13// Make a deep copy of |node|, but don't include empty lists or dictionaries
14// in the copy. It's possible for this function to return NULL and it
15// expects |node| to always be non-NULL.
16Value* CopyWithoutEmptyChildren(Value* node) {
17  DCHECK(node);
18  switch (node->GetType()) {
19    case Value::TYPE_LIST: {
20      ListValue* list = static_cast<ListValue*>(node);
21      ListValue* copy = new ListValue;
22      for (ListValue::const_iterator it = list->begin(); it != list->end();
23           ++it) {
24        Value* child_copy = CopyWithoutEmptyChildren(*it);
25        if (child_copy)
26          copy->Append(child_copy);
27      }
28      if (!copy->empty())
29        return copy;
30
31      delete copy;
32      return NULL;
33    }
34
35    case Value::TYPE_DICTIONARY: {
36      DictionaryValue* dict = static_cast<DictionaryValue*>(node);
37      DictionaryValue* copy = new DictionaryValue;
38      for (DictionaryValue::key_iterator it = dict->begin_keys();
39           it != dict->end_keys(); ++it) {
40        Value* child = NULL;
41        bool rv = dict->GetWithoutPathExpansion(*it, &child);
42        DCHECK(rv);
43        Value* child_copy = CopyWithoutEmptyChildren(child);
44        if (child_copy)
45          copy->SetWithoutPathExpansion(*it, child_copy);
46      }
47      if (!copy->empty())
48        return copy;
49
50      delete copy;
51      return NULL;
52    }
53
54    default:
55      // For everything else, just make a copy.
56      return node->DeepCopy();
57  }
58}
59
60}  // namespace
61
62///////////////////// Value ////////////////////
63
64Value::~Value() {
65}
66
67// static
68Value* Value::CreateNullValue() {
69  return new Value(TYPE_NULL);
70}
71
72// static
73Value* Value::CreateBooleanValue(bool in_value) {
74  return new FundamentalValue(in_value);
75}
76
77// static
78Value* Value::CreateIntegerValue(int in_value) {
79  return new FundamentalValue(in_value);
80}
81
82// static
83Value* Value::CreateRealValue(double in_value) {
84  return new FundamentalValue(in_value);
85}
86
87// static
88Value* Value::CreateStringValue(const std::string& in_value) {
89  return new StringValue(in_value);
90}
91
92// static
93Value* Value::CreateStringValue(const std::wstring& in_value) {
94  return new StringValue(in_value);
95}
96
97// static
98Value* Value::CreateStringValueFromUTF16(const string16& in_value) {
99  return new StringValue(in_value);
100}
101
102// static
103BinaryValue* Value::CreateBinaryValue(char* buffer, size_t size) {
104  return BinaryValue::Create(buffer, size);
105}
106
107bool Value::GetAsBoolean(bool* in_value) const {
108  return false;
109}
110
111bool Value::GetAsInteger(int* in_value) const {
112  return false;
113}
114
115bool Value::GetAsReal(double* in_value) const {
116  return false;
117}
118
119bool Value::GetAsString(std::string* in_value) const {
120  return false;
121}
122
123bool Value::GetAsString(std::wstring* in_value) const {
124  return false;
125}
126
127bool Value::GetAsUTF16(string16* out_value) const {
128  return false;
129}
130
131Value* Value::DeepCopy() const {
132  // This method should only be getting called for null Values--all subclasses
133  // need to provide their own implementation;.
134  DCHECK(IsType(TYPE_NULL));
135  return CreateNullValue();
136}
137
138bool Value::Equals(const Value* other) const {
139  // This method should only be getting called for null Values--all subclasses
140  // need to provide their own implementation;.
141  DCHECK(IsType(TYPE_NULL));
142  return other->IsType(TYPE_NULL);
143}
144
145Value::Value(ValueType type) : type_(type) {
146}
147
148///////////////////// FundamentalValue ////////////////////
149
150FundamentalValue::FundamentalValue(bool in_value)
151    : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
152}
153
154FundamentalValue::FundamentalValue(int in_value)
155    : Value(TYPE_INTEGER), integer_value_(in_value) {
156}
157
158FundamentalValue::FundamentalValue(double in_value)
159    : Value(TYPE_REAL), real_value_(in_value) {
160}
161
162FundamentalValue::~FundamentalValue() {
163}
164
165bool FundamentalValue::GetAsBoolean(bool* out_value) const {
166  if (out_value && IsType(TYPE_BOOLEAN))
167    *out_value = boolean_value_;
168  return (IsType(TYPE_BOOLEAN));
169}
170
171bool FundamentalValue::GetAsInteger(int* out_value) const {
172  if (out_value && IsType(TYPE_INTEGER))
173    *out_value = integer_value_;
174  return (IsType(TYPE_INTEGER));
175}
176
177bool FundamentalValue::GetAsReal(double* out_value) const {
178  if (out_value && IsType(TYPE_REAL))
179    *out_value = real_value_;
180  return (IsType(TYPE_REAL));
181}
182
183Value* FundamentalValue::DeepCopy() const {
184  switch (GetType()) {
185    case TYPE_BOOLEAN:
186      return CreateBooleanValue(boolean_value_);
187
188    case TYPE_INTEGER:
189      return CreateIntegerValue(integer_value_);
190
191    case TYPE_REAL:
192      return CreateRealValue(real_value_);
193
194    default:
195      NOTREACHED();
196      return NULL;
197  }
198}
199
200bool FundamentalValue::Equals(const Value* other) const {
201  if (other->GetType() != GetType())
202    return false;
203
204  switch (GetType()) {
205    case TYPE_BOOLEAN: {
206      bool lhs, rhs;
207      return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
208    }
209    case TYPE_INTEGER: {
210      int lhs, rhs;
211      return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
212    }
213    case TYPE_REAL: {
214      double lhs, rhs;
215      return GetAsReal(&lhs) && other->GetAsReal(&rhs) && lhs == rhs;
216    }
217    default:
218      NOTREACHED();
219      return false;
220  }
221}
222
223///////////////////// StringValue ////////////////////
224
225StringValue::StringValue(const std::string& in_value)
226    : Value(TYPE_STRING),
227      value_(in_value) {
228  DCHECK(IsStringUTF8(in_value));
229}
230
231StringValue::StringValue(const std::wstring& in_value)
232    : Value(TYPE_STRING),
233      value_(WideToUTF8(in_value)) {
234}
235
236#if !defined(WCHAR_T_IS_UTF16)
237StringValue::StringValue(const string16& in_value)
238    : Value(TYPE_STRING),
239      value_(UTF16ToUTF8(in_value)) {
240}
241#endif
242
243StringValue::~StringValue() {
244}
245
246bool StringValue::GetAsString(std::string* out_value) const {
247  if (out_value)
248    *out_value = value_;
249  return true;
250}
251
252bool StringValue::GetAsString(std::wstring* out_value) const {
253  if (out_value)
254    *out_value = UTF8ToWide(value_);
255  return true;
256}
257
258bool StringValue::GetAsUTF16(string16* out_value) const {
259  if (out_value)
260    *out_value = UTF8ToUTF16(value_);
261  return true;
262}
263
264Value* StringValue::DeepCopy() const {
265  return CreateStringValue(value_);
266}
267
268bool StringValue::Equals(const Value* other) const {
269  if (other->GetType() != GetType())
270    return false;
271  std::string lhs, rhs;
272  return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
273}
274
275///////////////////// BinaryValue ////////////////////
276
277// static
278BinaryValue* BinaryValue::Create(char* buffer, size_t size) {
279  if (!buffer)
280    return NULL;
281
282  return new BinaryValue(buffer, size);
283}
284
285// static
286BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
287                                                 size_t size) {
288  if (!buffer)
289    return NULL;
290
291  char* buffer_copy = new char[size];
292  memcpy(buffer_copy, buffer, size);
293  return new BinaryValue(buffer_copy, size);
294}
295
296
297BinaryValue::BinaryValue(char* buffer, size_t size)
298  : Value(TYPE_BINARY),
299    buffer_(buffer),
300    size_(size) {
301  DCHECK(buffer_);
302}
303
304BinaryValue::~BinaryValue() {
305  DCHECK(buffer_);
306  if (buffer_)
307    delete[] buffer_;
308}
309
310Value* BinaryValue::DeepCopy() const {
311  return CreateWithCopiedBuffer(buffer_, size_);
312}
313
314bool BinaryValue::Equals(const Value* other) const {
315  if (other->GetType() != GetType())
316    return false;
317  const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
318  if (other_binary->size_ != size_)
319    return false;
320  return !memcmp(buffer_, other_binary->buffer_, size_);
321}
322
323///////////////////// DictionaryValue ////////////////////
324
325DictionaryValue::DictionaryValue()
326  : Value(TYPE_DICTIONARY) {
327}
328
329DictionaryValue::~DictionaryValue() {
330  Clear();
331}
332
333Value* DictionaryValue::DeepCopy() const {
334  DictionaryValue* result = new DictionaryValue;
335
336  for (ValueMap::const_iterator current_entry(dictionary_.begin());
337       current_entry != dictionary_.end(); ++current_entry) {
338    result->SetWithoutPathExpansion(current_entry->first,
339                                    current_entry->second->DeepCopy());
340  }
341
342  return result;
343}
344
345bool DictionaryValue::Equals(const Value* other) const {
346  if (other->GetType() != GetType())
347    return false;
348
349  const DictionaryValue* other_dict =
350      static_cast<const DictionaryValue*>(other);
351  key_iterator lhs_it(begin_keys());
352  key_iterator rhs_it(other_dict->begin_keys());
353  while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) {
354    Value* lhs;
355    Value* rhs;
356    if (!GetWithoutPathExpansion(*lhs_it, &lhs) ||
357        !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) ||
358        !lhs->Equals(rhs)) {
359      return false;
360    }
361    ++lhs_it;
362    ++rhs_it;
363  }
364  if (lhs_it != end_keys() || rhs_it != other_dict->end_keys())
365    return false;
366
367  return true;
368}
369
370bool DictionaryValue::HasKey(const std::wstring& key) const {
371  ValueMap::const_iterator current_entry = dictionary_.find(key);
372  DCHECK((current_entry == dictionary_.end()) || current_entry->second);
373  return current_entry != dictionary_.end();
374}
375
376bool DictionaryValue::HasKeyASCII(const std::string& key) const {
377  return HasKey(ASCIIToWide(key));
378}
379
380void DictionaryValue::Clear() {
381  ValueMap::iterator dict_iterator = dictionary_.begin();
382  while (dict_iterator != dictionary_.end()) {
383    delete dict_iterator->second;
384    ++dict_iterator;
385  }
386
387  dictionary_.clear();
388}
389
390void DictionaryValue::Set(const std::wstring& path, Value* in_value) {
391  DCHECK(in_value);
392
393  std::wstring current_path(path);
394  DictionaryValue* current_dictionary = this;
395  for (size_t delimiter_position = current_path.find('.');
396       delimiter_position != std::wstring::npos;
397       delimiter_position = current_path.find('.')) {
398    // Assume that we're indexing into a dictionary.
399    std::wstring key(current_path, 0, delimiter_position);
400    DictionaryValue* child_dictionary = NULL;
401    if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
402      child_dictionary = new DictionaryValue;
403      current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
404    }
405
406    current_dictionary = child_dictionary;
407    current_path.erase(0, delimiter_position + 1);
408  }
409
410  current_dictionary->SetWithoutPathExpansion(current_path, in_value);
411}
412
413void DictionaryValue::SetBoolean(const std::wstring& path, bool in_value) {
414  Set(path, CreateBooleanValue(in_value));
415}
416
417void DictionaryValue::SetInteger(const std::wstring& path, int in_value) {
418  Set(path, CreateIntegerValue(in_value));
419}
420
421void DictionaryValue::SetReal(const std::wstring& path, double in_value) {
422  Set(path, CreateRealValue(in_value));
423}
424
425void DictionaryValue::SetString(const std::wstring& path,
426                                const std::string& in_value) {
427  Set(path, CreateStringValue(in_value));
428}
429
430void DictionaryValue::SetString(const std::wstring& path,
431                                const std::wstring& in_value) {
432  Set(path, CreateStringValue(in_value));
433}
434
435void DictionaryValue::SetStringFromUTF16(const std::wstring& path,
436                                         const string16& in_value) {
437  Set(path, CreateStringValueFromUTF16(in_value));
438}
439
440void DictionaryValue::SetWithoutPathExpansion(const std::wstring& key,
441                                              Value* in_value) {
442  // If there's an existing value here, we need to delete it, because
443  // we own all our children.
444  if (HasKey(key)) {
445    DCHECK(dictionary_[key] != in_value);  // This would be bogus
446    delete dictionary_[key];
447  }
448
449  dictionary_[key] = in_value;
450}
451
452bool DictionaryValue::Get(const std::wstring& path, Value** out_value) const {
453  std::wstring current_path(path);
454  const DictionaryValue* current_dictionary = this;
455  for (size_t delimiter_position = current_path.find('.');
456       delimiter_position != std::wstring::npos;
457       delimiter_position = current_path.find('.')) {
458    DictionaryValue* child_dictionary = NULL;
459    if (!current_dictionary->GetDictionary(
460            current_path.substr(0, delimiter_position), &child_dictionary))
461      return false;
462
463    current_dictionary = child_dictionary;
464    current_path.erase(0, delimiter_position + 1);
465  }
466
467  return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
468}
469
470bool DictionaryValue::GetBoolean(const std::wstring& path,
471                                 bool* bool_value) const {
472  Value* value;
473  if (!Get(path, &value))
474    return false;
475
476  return value->GetAsBoolean(bool_value);
477}
478
479bool DictionaryValue::GetInteger(const std::wstring& path,
480                                 int* out_value) const {
481  Value* value;
482  if (!Get(path, &value))
483    return false;
484
485  return value->GetAsInteger(out_value);
486}
487
488bool DictionaryValue::GetReal(const std::wstring& path,
489                              double* out_value) const {
490  Value* value;
491  if (!Get(path, &value))
492    return false;
493
494  return value->GetAsReal(out_value);
495}
496
497bool DictionaryValue::GetString(const std::string& path,
498                                string16* out_value) const {
499  return GetStringAsUTF16(ASCIIToWide(path), out_value);
500}
501
502bool DictionaryValue::GetStringASCII(const std::string& path,
503                                     std::string* out_value) const {
504  std::string out;
505  if (!GetString(ASCIIToWide(path), &out))
506    return false;
507
508  if (!IsStringASCII(out)) {
509    NOTREACHED();
510    return false;
511  }
512
513  out_value->assign(out);
514  return true;
515}
516
517bool DictionaryValue::GetString(const std::wstring& path,
518                                std::string* out_value) const {
519  Value* value;
520  if (!Get(path, &value))
521    return false;
522
523  return value->GetAsString(out_value);
524}
525
526bool DictionaryValue::GetString(const std::wstring& path,
527                                std::wstring* out_value) const {
528  Value* value;
529  if (!Get(path, &value))
530    return false;
531
532  return value->GetAsString(out_value);
533}
534
535bool DictionaryValue::GetStringAsUTF16(const std::wstring& path,
536                                       string16* out_value) const {
537  Value* value;
538  if (!Get(path, &value))
539    return false;
540
541  return value->GetAsUTF16(out_value);
542}
543
544bool DictionaryValue::GetBinary(const std::wstring& path,
545                                BinaryValue** out_value) const {
546  Value* value;
547  bool result = Get(path, &value);
548  if (!result || !value->IsType(TYPE_BINARY))
549    return false;
550
551  if (out_value)
552    *out_value = static_cast<BinaryValue*>(value);
553
554  return true;
555}
556
557bool DictionaryValue::GetDictionary(const std::wstring& path,
558                                    DictionaryValue** out_value) const {
559  Value* value;
560  bool result = Get(path, &value);
561  if (!result || !value->IsType(TYPE_DICTIONARY))
562    return false;
563
564  if (out_value)
565    *out_value = static_cast<DictionaryValue*>(value);
566
567  return true;
568}
569
570bool DictionaryValue::GetList(const std::wstring& path,
571                              ListValue** out_value) const {
572  Value* value;
573  bool result = Get(path, &value);
574  if (!result || !value->IsType(TYPE_LIST))
575    return false;
576
577  if (out_value)
578    *out_value = static_cast<ListValue*>(value);
579
580  return true;
581}
582
583bool DictionaryValue::GetWithoutPathExpansion(const std::wstring& key,
584                                              Value** out_value) const {
585  ValueMap::const_iterator entry_iterator = dictionary_.find(key);
586  if (entry_iterator == dictionary_.end())
587    return false;
588
589  Value* entry = entry_iterator->second;
590  if (out_value)
591    *out_value = entry;
592  return true;
593}
594
595bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::wstring& path,
596                                                     int* out_value) const {
597  Value* value;
598  if (!GetWithoutPathExpansion(path, &value))
599    return false;
600
601  return value->GetAsInteger(out_value);
602}
603
604bool DictionaryValue::GetStringWithoutPathExpansion(
605    const std::wstring& path,
606    std::string* out_value) const {
607  Value* value;
608  if (!GetWithoutPathExpansion(path, &value))
609    return false;
610
611  return value->GetAsString(out_value);
612}
613
614bool DictionaryValue::GetStringWithoutPathExpansion(
615    const std::wstring& path,
616    std::wstring* out_value) const {
617  Value* value;
618  if (!GetWithoutPathExpansion(path, &value))
619    return false;
620
621  return value->GetAsString(out_value);
622}
623
624bool DictionaryValue::GetStringAsUTF16WithoutPathExpansion(
625    const std::wstring& path,
626    string16* out_value) const {
627  Value* value;
628  if (!GetWithoutPathExpansion(path, &value))
629    return false;
630
631  return value->GetAsUTF16(out_value);
632}
633
634bool DictionaryValue::GetDictionaryWithoutPathExpansion(
635    const std::wstring& path,
636    DictionaryValue** out_value) const {
637  Value* value;
638  bool result = GetWithoutPathExpansion(path, &value);
639  if (!result || !value->IsType(TYPE_DICTIONARY))
640    return false;
641
642  if (out_value)
643    *out_value = static_cast<DictionaryValue*>(value);
644
645  return true;
646}
647
648bool DictionaryValue::GetListWithoutPathExpansion(const std::wstring& path,
649                                                  ListValue** out_value) const {
650  Value* value;
651  bool result = GetWithoutPathExpansion(path, &value);
652  if (!result || !value->IsType(TYPE_LIST))
653    return false;
654
655  if (out_value)
656    *out_value = static_cast<ListValue*>(value);
657
658  return true;
659}
660
661bool DictionaryValue::Remove(const std::wstring& path, Value** out_value) {
662  std::wstring current_path(path);
663  DictionaryValue* current_dictionary = this;
664  size_t delimiter_position = current_path.rfind('.');
665  if (delimiter_position != std::wstring::npos) {
666    if (!GetDictionary(current_path.substr(0, delimiter_position),
667                       &current_dictionary))
668      return false;
669    current_path.erase(0, delimiter_position + 1);
670  }
671
672  return current_dictionary->RemoveWithoutPathExpansion(current_path,
673                                                        out_value);
674}
675
676bool DictionaryValue::RemoveWithoutPathExpansion(const std::wstring& key,
677                                                 Value** out_value) {
678  ValueMap::iterator entry_iterator = dictionary_.find(key);
679  if (entry_iterator == dictionary_.end())
680    return false;
681
682  Value* entry = entry_iterator->second;
683  if (out_value)
684    *out_value = entry;
685  else
686    delete entry;
687  dictionary_.erase(entry_iterator);
688  return true;
689}
690
691DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
692  Value* copy = CopyWithoutEmptyChildren(this);
693  return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
694}
695
696void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
697  for (DictionaryValue::key_iterator key(dictionary->begin_keys());
698       key != dictionary->end_keys(); ++key) {
699    Value* merge_value;
700    if (dictionary->GetWithoutPathExpansion(*key, &merge_value)) {
701      // Check whether we have to merge dictionaries.
702      if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
703        DictionaryValue* sub_dict;
704        if (GetDictionaryWithoutPathExpansion(*key, &sub_dict)) {
705          sub_dict->MergeDictionary(
706              static_cast<const DictionaryValue*>(merge_value));
707          continue;
708        }
709      }
710      // All other cases: Make a copy and hook it up.
711      SetWithoutPathExpansion(*key, merge_value->DeepCopy());
712    }
713  }
714}
715
716///////////////////// ListValue ////////////////////
717
718ListValue::ListValue() : Value(TYPE_LIST) {
719}
720
721ListValue::~ListValue() {
722  Clear();
723}
724
725void ListValue::Clear() {
726  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
727    delete *i;
728  list_.clear();
729}
730
731bool ListValue::Set(size_t index, Value* in_value) {
732  if (!in_value)
733    return false;
734
735  if (index >= list_.size()) {
736    // Pad out any intermediate indexes with null settings
737    while (index > list_.size())
738      Append(CreateNullValue());
739    Append(in_value);
740  } else {
741    DCHECK(list_[index] != in_value);
742    delete list_[index];
743    list_[index] = in_value;
744  }
745  return true;
746}
747
748bool ListValue::Get(size_t index, Value** out_value) const {
749  if (index >= list_.size())
750    return false;
751
752  if (out_value)
753    *out_value = list_[index];
754
755  return true;
756}
757
758bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
759  Value* value;
760  if (!Get(index, &value))
761    return false;
762
763  return value->GetAsBoolean(bool_value);
764}
765
766bool ListValue::GetInteger(size_t index, int* out_value) const {
767  Value* value;
768  if (!Get(index, &value))
769    return false;
770
771  return value->GetAsInteger(out_value);
772}
773
774bool ListValue::GetReal(size_t index, double* out_value) const {
775  Value* value;
776  if (!Get(index, &value))
777    return false;
778
779  return value->GetAsReal(out_value);
780}
781
782bool ListValue::GetString(size_t index, std::string* out_value) const {
783  Value* value;
784  if (!Get(index, &value))
785    return false;
786
787  return value->GetAsString(out_value);
788}
789
790bool ListValue::GetString(size_t index, std::wstring* out_value) const {
791  Value* value;
792  if (!Get(index, &value))
793    return false;
794
795  return value->GetAsString(out_value);
796}
797
798bool ListValue::GetStringAsUTF16(size_t index, string16* out_value) const {
799  Value* value;
800  if (!Get(index, &value))
801    return false;
802
803  return value->GetAsUTF16(out_value);
804}
805
806bool ListValue::GetBinary(size_t index, BinaryValue** out_value) const {
807  Value* value;
808  bool result = Get(index, &value);
809  if (!result || !value->IsType(TYPE_BINARY))
810    return false;
811
812  if (out_value)
813    *out_value = static_cast<BinaryValue*>(value);
814
815  return true;
816}
817
818bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) const {
819  Value* value;
820  bool result = Get(index, &value);
821  if (!result || !value->IsType(TYPE_DICTIONARY))
822    return false;
823
824  if (out_value)
825    *out_value = static_cast<DictionaryValue*>(value);
826
827  return true;
828}
829
830bool ListValue::GetList(size_t index, ListValue** out_value) const {
831  Value* value;
832  bool result = Get(index, &value);
833  if (!result || !value->IsType(TYPE_LIST))
834    return false;
835
836  if (out_value)
837    *out_value = static_cast<ListValue*>(value);
838
839  return true;
840}
841
842bool ListValue::Remove(size_t index, Value** out_value) {
843  if (index >= list_.size())
844    return false;
845
846  if (out_value)
847    *out_value = list_[index];
848  else
849    delete list_[index];
850
851  list_.erase(list_.begin() + index);
852  return true;
853}
854
855int ListValue::Remove(const Value& value) {
856  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
857    if ((*i)->Equals(&value)) {
858      size_t index = i - list_.begin();
859      delete *i;
860      list_.erase(i);
861
862      // TODO(anyone): Returning a signed int type here is just wrong.
863      // Change this interface to return a size_t.
864      DCHECK(index <= INT_MAX);
865      int return_index = static_cast<int>(index);
866      return return_index;
867    }
868  }
869  return -1;
870}
871
872void ListValue::Append(Value* in_value) {
873  DCHECK(in_value);
874  list_.push_back(in_value);
875}
876
877bool ListValue::AppendIfNotPresent(Value* in_value) {
878  DCHECK(in_value);
879  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
880    if ((*i)->Equals(in_value))
881      return false;
882  }
883  list_.push_back(in_value);
884  return true;
885}
886
887bool ListValue::Insert(size_t index, Value* in_value) {
888  DCHECK(in_value);
889  if (index > list_.size())
890    return false;
891
892  list_.insert(list_.begin() + index, in_value);
893  return true;
894}
895
896Value* ListValue::DeepCopy() const {
897  ListValue* result = new ListValue;
898
899  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
900    result->Append((*i)->DeepCopy());
901
902  return result;
903}
904
905bool ListValue::Equals(const Value* other) const {
906  if (other->GetType() != GetType())
907    return false;
908
909  const ListValue* other_list =
910      static_cast<const ListValue*>(other);
911  const_iterator lhs_it, rhs_it;
912  for (lhs_it = begin(), rhs_it = other_list->begin();
913       lhs_it != end() && rhs_it != other_list->end();
914       ++lhs_it, ++rhs_it) {
915    if (!(*lhs_it)->Equals(*rhs_it))
916      return false;
917  }
918  if (lhs_it != end() || rhs_it != other_list->end())
919    return false;
920
921  return true;
922}
923
924ValueSerializer::~ValueSerializer() {
925}
926