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