values.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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.
4
5#include "base/values.h"
6
7#include <algorithm>
8#include <ostream>
9
10#include "base/float_util.h"
11#include "base/json/json_writer.h"
12#include "base/logging.h"
13#include "base/strings/string_util.h"
14#include "base/strings/utf_string_conversions.h"
15
16namespace {
17
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.
21Value* 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);
32      }
33      if (!copy->empty())
34        return copy;
35
36      delete copy;
37      return NULL;
38    }
39
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);
47      }
48      if (!copy->empty())
49        return copy;
50
51      delete copy;
52      return NULL;
53    }
54
55    default:
56      // For everything else, just make a copy.
57      return node->DeepCopy();
58  }
59}
60
61// A small functor for comparing Values for std::find_if and similar.
62class 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) { }
68
69  bool operator ()(const Value* second) const {
70    return first_->Equals(second);
71  }
72
73 private:
74  const Value* first_;
75};
76
77}  // namespace
78
79namespace base {
80
81///////////////////// Value ////////////////////
82
83Value::~Value() {
84}
85
86// static
87Value* Value::CreateNullValue() {
88  return new Value(TYPE_NULL);
89}
90
91// static
92FundamentalValue* Value::CreateBooleanValue(bool in_value) {
93  return new FundamentalValue(in_value);
94}
95
96// static
97FundamentalValue* Value::CreateIntegerValue(int in_value) {
98  return new FundamentalValue(in_value);
99}
100
101// static
102FundamentalValue* Value::CreateDoubleValue(double in_value) {
103  return new FundamentalValue(in_value);
104}
105
106// static
107StringValue* Value::CreateStringValue(const std::string& in_value) {
108  return new StringValue(in_value);
109}
110
111// static
112StringValue* Value::CreateStringValue(const string16& in_value) {
113  return new StringValue(in_value);
114}
115
116bool Value::GetAsBoolean(bool* out_value) const {
117  return false;
118}
119
120bool Value::GetAsInteger(int* out_value) const {
121  return false;
122}
123
124bool Value::GetAsDouble(double* out_value) const {
125  return false;
126}
127
128bool Value::GetAsString(std::string* out_value) const {
129  return false;
130}
131
132bool Value::GetAsString(string16* out_value) const {
133  return false;
134}
135
136bool Value::GetAsList(ListValue** out_value) {
137  return false;
138}
139
140bool Value::GetAsList(const ListValue** out_value) const {
141  return false;
142}
143
144bool Value::GetAsDictionary(DictionaryValue** out_value) {
145  return false;
146}
147
148bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
149  return false;
150}
151
152Value* 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();
157}
158
159bool 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);
164}
165
166// static
167bool 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);
171}
172
173Value::Value(Type type) : type_(type) {}
174
175Value::Value(const Value& that) : type_(that.type_) {}
176
177Value& Value::operator=(const Value& that) {
178  type_ = that.type_;
179  return *this;
180}
181
182///////////////////// FundamentalValue ////////////////////
183
184FundamentalValue::FundamentalValue(bool in_value)
185    : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
186}
187
188FundamentalValue::FundamentalValue(int in_value)
189    : Value(TYPE_INTEGER), integer_value_(in_value) {
190}
191
192FundamentalValue::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;
198  }
199}
200
201FundamentalValue::~FundamentalValue() {
202}
203
204bool FundamentalValue::GetAsBoolean(bool* out_value) const {
205  if (out_value && IsType(TYPE_BOOLEAN))
206    *out_value = boolean_value_;
207  return (IsType(TYPE_BOOLEAN));
208}
209
210bool FundamentalValue::GetAsInteger(int* out_value) const {
211  if (out_value && IsType(TYPE_INTEGER))
212    *out_value = integer_value_;
213  return (IsType(TYPE_INTEGER));
214}
215
216bool 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));
222}
223
224FundamentalValue* FundamentalValue::DeepCopy() const {
225  switch (GetType()) {
226    case TYPE_BOOLEAN:
227      return CreateBooleanValue(boolean_value_);
228
229    case TYPE_INTEGER:
230      return CreateIntegerValue(integer_value_);
231
232    case TYPE_DOUBLE:
233      return CreateDoubleValue(double_value_);
234
235    default:
236      NOTREACHED();
237      return NULL;
238  }
239}
240
241bool FundamentalValue::Equals(const Value* other) const {
242  if (other->GetType() != GetType())
243    return false;
244
245  switch (GetType()) {
246    case TYPE_BOOLEAN: {
247      bool lhs, rhs;
248      return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
249    }
250    case TYPE_INTEGER: {
251      int lhs, rhs;
252      return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
253    }
254    case TYPE_DOUBLE: {
255      double lhs, rhs;
256      return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
257    }
258    default:
259      NOTREACHED();
260      return false;
261  }
262}
263
264///////////////////// StringValue ////////////////////
265
266StringValue::StringValue(const std::string& in_value)
267    : Value(TYPE_STRING),
268      value_(in_value) {
269  DCHECK(IsStringUTF8(in_value));
270}
271
272StringValue::StringValue(const string16& in_value)
273    : Value(TYPE_STRING),
274      value_(UTF16ToUTF8(in_value)) {
275}
276
277StringValue::~StringValue() {
278}
279
280bool StringValue::GetAsString(std::string* out_value) const {
281  if (out_value)
282    *out_value = value_;
283  return true;
284}
285
286bool StringValue::GetAsString(string16* out_value) const {
287  if (out_value)
288    *out_value = UTF8ToUTF16(value_);
289  return true;
290}
291
292StringValue* StringValue::DeepCopy() const {
293  return CreateStringValue(value_);
294}
295
296bool 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;
301}
302
303///////////////////// BinaryValue ////////////////////
304
305BinaryValue::BinaryValue()
306    : Value(TYPE_BINARY),
307      size_(0) {
308}
309
310BinaryValue::BinaryValue(scoped_ptr<char[]> buffer, size_t size)
311    : Value(TYPE_BINARY),
312      buffer_(buffer.Pass()),
313      size_(size) {
314}
315
316BinaryValue::~BinaryValue() {
317}
318
319// static
320BinaryValue* 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);
326}
327
328BinaryValue* BinaryValue::DeepCopy() const {
329  return CreateWithCopiedBuffer(buffer_.get(), size_);
330}
331
332bool 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_);
339}
340
341///////////////////// DictionaryValue ////////////////////
342
343DictionaryValue::DictionaryValue()
344    : Value(TYPE_DICTIONARY) {
345}
346
347DictionaryValue::~DictionaryValue() {
348  Clear();
349}
350
351bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
352  if (out_value)
353    *out_value = this;
354  return true;
355}
356
357bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
358  if (out_value)
359    *out_value = this;
360  return true;
361}
362
363bool 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();
368}
369
370void DictionaryValue::Clear() {
371  ValueMap::iterator dict_iterator = dictionary_.begin();
372  while (dict_iterator != dictionary_.end()) {
373    delete dict_iterator->second;
374    ++dict_iterator;
375  }
376
377  dictionary_.clear();
378}
379
380void DictionaryValue::Set(const std::string& path, Value* in_value) {
381  DCHECK(IsStringUTF8(path));
382  DCHECK(in_value);
383
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);
395    }
396
397    current_dictionary = child_dictionary;
398    current_path.erase(0, delimiter_position + 1);
399  }
400
401  current_dictionary->SetWithoutPathExpansion(current_path, in_value);
402}
403
404void DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
405  Set(path, CreateBooleanValue(in_value));
406}
407
408void DictionaryValue::SetInteger(const std::string& path, int in_value) {
409  Set(path, CreateIntegerValue(in_value));
410}
411
412void DictionaryValue::SetDouble(const std::string& path, double in_value) {
413  Set(path, CreateDoubleValue(in_value));
414}
415
416void DictionaryValue::SetString(const std::string& path,
417                                const std::string& in_value) {
418  Set(path, CreateStringValue(in_value));
419}
420
421void DictionaryValue::SetString(const std::string& path,
422                                const string16& in_value) {
423  Set(path, CreateStringValue(in_value));
424}
425
426void 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;
436  }
437}
438
439void DictionaryValue::SetBooleanWithoutPathExpansion(
440    const std::string& path, bool in_value) {
441  SetWithoutPathExpansion(path, CreateBooleanValue(in_value));
442}
443
444void DictionaryValue::SetIntegerWithoutPathExpansion(
445    const std::string& path, int in_value) {
446  SetWithoutPathExpansion(path, CreateIntegerValue(in_value));
447}
448
449void DictionaryValue::SetDoubleWithoutPathExpansion(
450    const std::string& path, double in_value) {
451  SetWithoutPathExpansion(path, CreateDoubleValue(in_value));
452}
453
454void DictionaryValue::SetStringWithoutPathExpansion(
455    const std::string& path, const std::string& in_value) {
456  SetWithoutPathExpansion(path, CreateStringValue(in_value));
457}
458
459void DictionaryValue::SetStringWithoutPathExpansion(
460    const std::string& path, const string16& in_value) {
461  SetWithoutPathExpansion(path, CreateStringValue(in_value));
462}
463
464bool 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;
478
479    current_dictionary = child_dictionary;
480    current_path.erase(0, delimiter_position + 1);
481  }
482//  LOG(WARNING) << "\n3\n";
483
484  return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
485}
486
487bool 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));
491}
492
493bool DictionaryValue::GetBoolean(const std::string& path,
494                                 bool* bool_value) const {
495  const Value* value;
496  if (!Get(path, &value))
497    return false;
498
499  return value->GetAsBoolean(bool_value);
500}
501
502bool DictionaryValue::GetInteger(const std::string& path,
503                                 int* out_value) const {
504  const Value* value;
505  if (!Get(path, &value))
506    return false;
507
508  return value->GetAsInteger(out_value);
509}
510
511bool DictionaryValue::GetDouble(const std::string& path,
512                                double* out_value) const {
513  const Value* value;
514  if (!Get(path, &value))
515    return false;
516
517  return value->GetAsDouble(out_value);
518}
519
520bool DictionaryValue::GetString(const std::string& path,
521                                std::string* out_value) const {
522  const Value* value;
523  if (!Get(path, &value))
524    return false;
525
526  return value->GetAsString(out_value);
527}
528
529bool DictionaryValue::GetString(const std::string& path,
530                                string16* out_value) const {
531  const Value* value;
532  if (!Get(path, &value))
533    return false;
534
535  return value->GetAsString(out_value);
536}
537
538bool DictionaryValue::GetStringASCII(const std::string& path,
539                                     std::string* out_value) const {
540  std::string out;
541  if (!GetString(path, &out))
542    return false;
543
544  if (!IsStringASCII(out)) {
545    NOTREACHED();
546    return false;
547  }
548
549  out_value->assign(out);
550  return true;
551}
552
553bool 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;
559
560  if (out_value)
561    *out_value = static_cast<const BinaryValue*>(value);
562
563  return true;
564}
565
566bool 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));
571}
572
573bool 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;
579
580  if (out_value)
581    *out_value = static_cast<const DictionaryValue*>(value);
582
583  return true;
584}
585
586bool 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));
591}
592
593bool 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;
599
600  if (out_value)
601    *out_value = static_cast<const ListValue*>(value);
602
603  return true;
604}
605
606bool 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));
610}
611
612bool 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;
618
619  const Value* entry = entry_iterator->second;
620  if (out_value)
621    *out_value = entry;
622  return true;
623}
624
625bool 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));
630}
631
632bool DictionaryValue::GetBooleanWithoutPathExpansion(const std::string& key,
633                                                     bool* out_value) const {
634  const Value* value;
635  if (!GetWithoutPathExpansion(key, &value))
636    return false;
637
638  return value->GetAsBoolean(out_value);
639}
640
641bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
642                                                     int* out_value) const {
643  const Value* value;
644  if (!GetWithoutPathExpansion(key, &value))
645    return false;
646
647  return value->GetAsInteger(out_value);
648}
649
650bool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
651                                                    double* out_value) const {
652  const Value* value;
653  if (!GetWithoutPathExpansion(key, &value))
654    return false;
655
656  return value->GetAsDouble(out_value);
657}
658
659bool 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;
665
666  return value->GetAsString(out_value);
667}
668
669bool DictionaryValue::GetStringWithoutPathExpansion(const std::string& key,
670                                                    string16* out_value) const {
671  const Value* value;
672  if (!GetWithoutPathExpansion(key, &value))
673    return false;
674
675  return value->GetAsString(out_value);
676}
677
678bool 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;
685
686  if (out_value)
687    *out_value = static_cast<const DictionaryValue*>(value);
688
689  return true;
690}
691
692bool 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));
700}
701
702bool 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;
709
710  if (out_value)
711    *out_value = static_cast<const ListValue*>(value);
712
713  return true;
714}
715
716bool 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));
722}
723
724bool 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);
734  }
735
736  return current_dictionary->RemoveWithoutPathExpansion(current_path,
737                                                        out_value);
738}
739
740bool 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;
746
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;
754}
755
756DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() {
757  Value* copy = CopyWithoutEmptyChildren(this);
758  return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
759}
760
761void 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;
771      }
772    }
773    // All other cases: Make a copy and hook it up.
774    SetWithoutPathExpansion(it.key(), merge_value->DeepCopy());
775  }
776}
777
778void DictionaryValue::Swap(DictionaryValue* other) {
779  dictionary_.swap(other->dictionary_);
780}
781
782DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
783    : target_(target),
784      it_(target.dictionary_.begin()) {}
785
786DictionaryValue* DictionaryValue::DeepCopy() const {
787  DictionaryValue* result = new DictionaryValue;
788
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());
793  }
794
795  return result;
796}
797
798bool DictionaryValue::Equals(const Value* other) const {
799  if (other->GetType() != GetType())
800    return false;
801
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;
810    }
811    lhs_it.Advance();
812    rhs_it.Advance();
813  }
814  if (!lhs_it.IsAtEnd() || !rhs_it.IsAtEnd())
815    return false;
816
817  return true;
818}
819
820///////////////////// ListValue ////////////////////
821
822ListValue::ListValue() : Value(TYPE_LIST) {
823}
824
825ListValue::~ListValue() {
826  Clear();
827}
828
829void ListValue::Clear() {
830  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
831    delete *i;
832  list_.clear();
833}
834
835bool ListValue::Set(size_t index, Value* in_value) {
836  if (!in_value)
837    return false;
838
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;
848  }
849  return true;
850}
851
852bool ListValue::Get(size_t index, const Value** out_value) const {
853  if (index >= list_.size())
854    return false;
855
856  if (out_value)
857    *out_value = list_[index];
858
859  return true;
860}
861
862bool 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));
866}
867
868bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
869  const Value* value;
870  if (!Get(index, &value))
871    return false;
872
873  return value->GetAsBoolean(bool_value);
874}
875
876bool ListValue::GetInteger(size_t index, int* out_value) const {
877  const Value* value;
878  if (!Get(index, &value))
879    return false;
880
881  return value->GetAsInteger(out_value);
882}
883
884bool ListValue::GetDouble(size_t index, double* out_value) const {
885  const Value* value;
886  if (!Get(index, &value))
887    return false;
888
889  return value->GetAsDouble(out_value);
890}
891
892bool ListValue::GetString(size_t index, std::string* out_value) const {
893  const Value* value;
894  if (!Get(index, &value))
895    return false;
896
897  return value->GetAsString(out_value);
898}
899
900bool ListValue::GetString(size_t index, string16* out_value) const {
901  const Value* value;
902  if (!Get(index, &value))
903    return false;
904
905  return value->GetAsString(out_value);
906}
907
908bool 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;
913
914  if (out_value)
915    *out_value = static_cast<const BinaryValue*>(value);
916
917  return true;
918}
919
920bool 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));
924}
925
926bool 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;
932
933  if (out_value)
934    *out_value = static_cast<const DictionaryValue*>(value);
935
936  return true;
937}
938
939bool 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));
943}
944
945bool 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;
950
951  if (out_value)
952    *out_value = static_cast<const ListValue*>(value);
953
954  return true;
955}
956
957bool 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));
961}
962
963bool ListValue::Remove(size_t index, Value** out_value) {
964  if (index >= list_.size())
965    return false;
966
967  if (out_value)
968    *out_value = list_[index];
969  else
970    delete list_[index];
971
972  list_.erase(list_.begin() + index);
973  return true;
974}
975
976bool 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);
982
983      if (index)
984        *index = previous_index;
985      return true;
986    }
987  }
988  return false;
989}
990
991ListValue::iterator ListValue::Erase(iterator iter, Value** out_value) {
992  if (out_value)
993    *out_value = *iter;
994  else
995    delete *iter;
996
997  return list_.erase(iter);
998}
999
1000void ListValue::Append(Value* in_value) {
1001  DCHECK(in_value);
1002  list_.push_back(in_value);
1003}
1004
1005void ListValue::AppendBoolean(bool in_value) {
1006  Append(CreateBooleanValue(in_value));
1007}
1008
1009void ListValue::AppendInteger(int in_value) {
1010  Append(CreateIntegerValue(in_value));
1011}
1012
1013void ListValue::AppendDouble(double in_value) {
1014  Append(CreateDoubleValue(in_value));
1015}
1016
1017void ListValue::AppendString(const std::string& in_value) {
1018  Append(CreateStringValue(in_value));
1019}
1020
1021void ListValue::AppendString(const string16& in_value) {
1022  Append(CreateStringValue(in_value));
1023}
1024
1025void 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);
1029  }
1030}
1031
1032void 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);
1036  }
1037}
1038
1039bool 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;
1045    }
1046  }
1047  list_.push_back(in_value);
1048  return true;
1049}
1050
1051bool ListValue::Insert(size_t index, Value* in_value) {
1052  DCHECK(in_value);
1053  if (index > list_.size())
1054    return false;
1055
1056  list_.insert(list_.begin() + index, in_value);
1057  return true;
1058}
1059
1060ListValue::const_iterator ListValue::Find(const Value& value) const {
1061  return std::find_if(list_.begin(), list_.end(), ValueEquals(&value));
1062}
1063
1064void ListValue::Swap(ListValue* other) {
1065  list_.swap(other->list_);
1066}
1067
1068bool ListValue::GetAsList(ListValue** out_value) {
1069  if (out_value)
1070    *out_value = this;
1071  return true;
1072}
1073
1074bool ListValue::GetAsList(const ListValue** out_value) const {
1075  if (out_value)
1076    *out_value = this;
1077  return true;
1078}
1079
1080ListValue* ListValue::DeepCopy() const {
1081  ListValue* result = new ListValue;
1082
1083  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
1084    result->Append((*i)->DeepCopy());
1085
1086  return result;
1087}
1088
1089bool ListValue::Equals(const Value* other) const {
1090  if (other->GetType() != GetType())
1091    return false;
1092
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;
1101  }
1102  if (lhs_it != end() || rhs_it != other_list->end())
1103    return false;
1104
1105  return true;
1106}
1107
1108ValueSerializer::~ValueSerializer() {
1109}
1110
1111std::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;
1117}
1118
1119}  // namespace base
1120