1558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// found in the LICENSE file.
4558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/values.h"
6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
7558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include <string.h>
8558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
9558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include <algorithm>
10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include <ostream>
11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
12558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/float_util.h"
13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/json/json_writer.h"
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/logging.h"
15558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/move.h"
16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/strings/string_util.h"
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace base {
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace {
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Make a deep copy of |node|, but don't include empty lists or dictionaries
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// in the copy. It's possible for this function to return NULL and it
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// expects |node| to always be non-NULL.
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)Value* CopyWithoutEmptyChildren(const Value* node) {
27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(node);
28  switch (node->GetType()) {
29    case Value::TYPE_LIST: {
30      const ListValue* list = static_cast<const ListValue*>(node);
31      ListValue* copy = new ListValue;
32      for (ListValue::const_iterator it = list->begin(); it != list->end();
33           ++it) {
34        Value* child_copy = CopyWithoutEmptyChildren(*it);
35        if (child_copy)
36          copy->Append(child_copy);
37      }
38      if (!copy->empty())
39        return copy;
40
41      delete copy;
42      return NULL;
43    }
44
45    case Value::TYPE_DICTIONARY: {
46      const DictionaryValue* dict = static_cast<const DictionaryValue*>(node);
47      DictionaryValue* copy = new DictionaryValue;
48      for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
49        Value* child_copy = CopyWithoutEmptyChildren(&it.value());
50        if (child_copy)
51          copy->SetWithoutPathExpansion(it.key(), child_copy);
52      }
53      if (!copy->empty())
54        return copy;
55
56      delete copy;
57      return NULL;
58    }
59
60    default:
61      // For everything else, just make a copy.
62      return node->DeepCopy();
63  }
64}
65
66// A small functor for comparing Values for std::find_if and similar.
67class ValueEquals {
68 public:
69  // Pass the value against which all consecutive calls of the () operator will
70  // compare their argument to. This Value object must not be destroyed while
71  // the ValueEquals is  in use.
72  explicit ValueEquals(const Value* first) : first_(first) { }
73
74  bool operator ()(const Value* second) const {
75    return first_->Equals(second);
76  }
77
78 private:
79  const Value* first_;
80};
81
82}  // namespace
83
84Value::~Value() {
85}
86
87// static
88Value* Value::CreateNullValue() {
89  return new Value(TYPE_NULL);
90}
91
92// static
93FundamentalValue* Value::CreateBooleanValue(bool in_value) {
94  return new FundamentalValue(in_value);
95}
96
97// static
98FundamentalValue* Value::CreateIntegerValue(int in_value) {
99  return new FundamentalValue(in_value);
100}
101
102// static
103FundamentalValue* Value::CreateDoubleValue(double in_value) {
104  return new FundamentalValue(in_value);
105}
106
107// static
108StringValue* Value::CreateStringValue(const std::string& in_value) {
109  return new StringValue(in_value);
110}
111
112// static
113StringValue* Value::CreateStringValue(const string16& in_value) {
114  return new StringValue(in_value);
115}
116
117bool Value::GetAsBoolean(bool* out_value) const {
118  return false;
119}
120
121bool Value::GetAsInteger(int* out_value) const {
122  return false;
123}
124
125bool Value::GetAsDouble(double* out_value) const {
126  return false;
127}
128
129bool Value::GetAsString(std::string* out_value) const {
130  return false;
131}
132
133bool Value::GetAsString(string16* out_value) const {
134  return false;
135}
136
137bool Value::GetAsString(const StringValue** out_value) const {
138  return false;
139}
140
141bool Value::GetAsList(ListValue** out_value) {
142  return false;
143}
144
145bool Value::GetAsList(const ListValue** out_value) const {
146  return false;
147}
148
149bool Value::GetAsDictionary(DictionaryValue** out_value) {
150  return false;
151}
152
153bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
154  return false;
155}
156
157Value* Value::DeepCopy() const {
158  // This method should only be getting called for null Values--all subclasses
159  // need to provide their own implementation;.
160  DCHECK(IsType(TYPE_NULL));
161  return CreateNullValue();
162}
163
164bool Value::Equals(const Value* other) const {
165  // This method should only be getting called for null Values--all subclasses
166  // need to provide their own implementation;.
167  DCHECK(IsType(TYPE_NULL));
168  return other->IsType(TYPE_NULL);
169}
170
171// static
172bool Value::Equals(const Value* a, const Value* b) {
173  if ((a == NULL) && (b == NULL)) return true;
174  if ((a == NULL) ^  (b == NULL)) return false;
175  return a->Equals(b);
176}
177
178Value::Value(Type type) : type_(type) {}
179
180Value::Value(const Value& that) : type_(that.type_) {}
181
182Value& Value::operator=(const Value& that) {
183  type_ = that.type_;
184  return *this;
185}
186
187///////////////////// FundamentalValue ////////////////////
188
189FundamentalValue::FundamentalValue(bool in_value)
190    : Value(TYPE_BOOLEAN), boolean_value_(in_value) {
191}
192
193FundamentalValue::FundamentalValue(int in_value)
194    : Value(TYPE_INTEGER), integer_value_(in_value) {
195}
196
197FundamentalValue::FundamentalValue(double in_value)
198    : Value(TYPE_DOUBLE), double_value_(in_value) {
199  if (!IsFinite(double_value_)) {
200    NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
201                 << "values cannot be represented in JSON";
202    double_value_ = 0.0;
203  }
204}
205
206FundamentalValue::~FundamentalValue() {
207}
208
209bool FundamentalValue::GetAsBoolean(bool* out_value) const {
210  if (out_value && IsType(TYPE_BOOLEAN))
211    *out_value = boolean_value_;
212  return (IsType(TYPE_BOOLEAN));
213}
214
215bool FundamentalValue::GetAsInteger(int* out_value) const {
216  if (out_value && IsType(TYPE_INTEGER))
217    *out_value = integer_value_;
218  return (IsType(TYPE_INTEGER));
219}
220
221bool FundamentalValue::GetAsDouble(double* out_value) const {
222  if (out_value && IsType(TYPE_DOUBLE))
223    *out_value = double_value_;
224  else if (out_value && IsType(TYPE_INTEGER))
225    *out_value = integer_value_;
226  return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER));
227}
228
229FundamentalValue* FundamentalValue::DeepCopy() const {
230  switch (GetType()) {
231    case TYPE_BOOLEAN:
232      return new FundamentalValue(boolean_value_);
233
234    case TYPE_INTEGER:
235      return new FundamentalValue(integer_value_);
236
237    case TYPE_DOUBLE:
238      return new FundamentalValue(double_value_);
239
240    default:
241      NOTREACHED();
242      return NULL;
243  }
244}
245
246bool FundamentalValue::Equals(const Value* other) const {
247  if (other->GetType() != GetType())
248    return false;
249
250  switch (GetType()) {
251    case TYPE_BOOLEAN: {
252      bool lhs, rhs;
253      return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
254    }
255    case TYPE_INTEGER: {
256      int lhs, rhs;
257      return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
258    }
259    case TYPE_DOUBLE: {
260      double lhs, rhs;
261      return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
262    }
263    default:
264      NOTREACHED();
265      return false;
266  }
267}
268
269///////////////////// StringValue ////////////////////
270
271StringValue::StringValue(const std::string& in_value)
272    : Value(TYPE_STRING),
273      value_(in_value) {
274  DCHECK(IsStringUTF8(in_value));
275}
276
277StringValue::StringValue(const string16& in_value)
278    : Value(TYPE_STRING),
279      value_(UTF16ToUTF8(in_value)) {
280}
281
282StringValue::~StringValue() {
283}
284
285std::string* StringValue::GetString() {
286  return &value_;
287}
288
289const std::string& StringValue::GetString() const {
290  return value_;
291}
292
293bool StringValue::GetAsString(std::string* out_value) const {
294  if (out_value)
295    *out_value = value_;
296  return true;
297}
298
299bool StringValue::GetAsString(string16* out_value) const {
300  if (out_value)
301    *out_value = UTF8ToUTF16(value_);
302  return true;
303}
304
305bool StringValue::GetAsString(const StringValue** out_value) const {
306  if (out_value)
307    *out_value = this;
308  return true;
309}
310
311StringValue* StringValue::DeepCopy() const {
312  return new StringValue(value_);
313}
314
315bool StringValue::Equals(const Value* other) const {
316  if (other->GetType() != GetType())
317    return false;
318  std::string lhs, rhs;
319  return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs;
320}
321
322///////////////////// BinaryValue ////////////////////
323
324BinaryValue::BinaryValue()
325    : Value(TYPE_BINARY),
326      size_(0) {
327}
328
329BinaryValue::BinaryValue(scoped_ptr<char[]> buffer, size_t size)
330    : Value(TYPE_BINARY),
331      buffer_(buffer.Pass()),
332      size_(size) {
333}
334
335BinaryValue::~BinaryValue() {
336}
337
338// static
339BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
340                                                 size_t size) {
341  char* buffer_copy = new char[size];
342  memcpy(buffer_copy, buffer, size);
343  scoped_ptr<char[]> scoped_buffer_copy(buffer_copy);
344  return new BinaryValue(scoped_buffer_copy.Pass(), size);
345}
346
347BinaryValue* BinaryValue::DeepCopy() const {
348  return CreateWithCopiedBuffer(buffer_.get(), size_);
349}
350
351bool BinaryValue::Equals(const Value* other) const {
352  if (other->GetType() != GetType())
353    return false;
354  const BinaryValue* other_binary = static_cast<const BinaryValue*>(other);
355  if (other_binary->size_ != size_)
356    return false;
357  return !memcmp(GetBuffer(), other_binary->GetBuffer(), size_);
358}
359
360///////////////////// DictionaryValue ////////////////////
361
362DictionaryValue::DictionaryValue()
363    : Value(TYPE_DICTIONARY) {
364}
365
366DictionaryValue::~DictionaryValue() {
367  Clear();
368}
369
370bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
371  if (out_value)
372    *out_value = this;
373  return true;
374}
375
376bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
377  if (out_value)
378    *out_value = this;
379  return true;
380}
381
382bool DictionaryValue::HasKey(const std::string& key) const {
383  DCHECK(IsStringUTF8(key));
384  ValueMap::const_iterator current_entry = dictionary_.find(key);
385  DCHECK((current_entry == dictionary_.end()) || current_entry->second);
386  return current_entry != dictionary_.end();
387}
388
389void DictionaryValue::Clear() {
390  ValueMap::iterator dict_iterator = dictionary_.begin();
391  while (dict_iterator != dictionary_.end()) {
392    delete dict_iterator->second;
393    ++dict_iterator;
394  }
395
396  dictionary_.clear();
397}
398
399void DictionaryValue::Set(const std::string& path, Value* in_value) {
400  DCHECK(IsStringUTF8(path));
401  DCHECK(in_value);
402
403  std::string current_path(path);
404  DictionaryValue* current_dictionary = this;
405  for (size_t delimiter_position = current_path.find('.');
406       delimiter_position != std::string::npos;
407       delimiter_position = current_path.find('.')) {
408    // Assume that we're indexing into a dictionary.
409    std::string key(current_path, 0, delimiter_position);
410    DictionaryValue* child_dictionary = NULL;
411    if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
412      child_dictionary = new DictionaryValue;
413      current_dictionary->SetWithoutPathExpansion(key, child_dictionary);
414    }
415
416    current_dictionary = child_dictionary;
417    current_path.erase(0, delimiter_position + 1);
418  }
419
420  current_dictionary->SetWithoutPathExpansion(current_path, in_value);
421}
422
423void DictionaryValue::SetBoolean(const std::string& path, bool in_value) {
424  Set(path, new FundamentalValue(in_value));
425}
426
427void DictionaryValue::SetInteger(const std::string& path, int in_value) {
428  Set(path, new FundamentalValue(in_value));
429}
430
431void DictionaryValue::SetDouble(const std::string& path, double in_value) {
432  Set(path, new FundamentalValue(in_value));
433}
434
435void DictionaryValue::SetString(const std::string& path,
436                                const std::string& in_value) {
437  Set(path, new StringValue(in_value));
438}
439
440void DictionaryValue::SetString(const std::string& path,
441                                const string16& in_value) {
442  Set(path, new StringValue(in_value));
443}
444
445void DictionaryValue::SetWithoutPathExpansion(const std::string& key,
446                                              Value* in_value) {
447  // If there's an existing value here, we need to delete it, because
448  // we own all our children.
449  std::pair<ValueMap::iterator, bool> ins_res =
450      dictionary_.insert(std::make_pair(key, in_value));
451  if (!ins_res.second) {
452    DCHECK_NE(ins_res.first->second, in_value);  // This would be bogus
453    delete ins_res.first->second;
454    ins_res.first->second = in_value;
455  }
456}
457
458void DictionaryValue::SetBooleanWithoutPathExpansion(
459    const std::string& path, bool in_value) {
460  SetWithoutPathExpansion(path, new FundamentalValue(in_value));
461}
462
463void DictionaryValue::SetIntegerWithoutPathExpansion(
464    const std::string& path, int in_value) {
465  SetWithoutPathExpansion(path, new FundamentalValue(in_value));
466}
467
468void DictionaryValue::SetDoubleWithoutPathExpansion(
469    const std::string& path, double in_value) {
470  SetWithoutPathExpansion(path, new FundamentalValue(in_value));
471}
472
473void DictionaryValue::SetStringWithoutPathExpansion(
474    const std::string& path, const std::string& in_value) {
475  SetWithoutPathExpansion(path, new StringValue(in_value));
476}
477
478void DictionaryValue::SetStringWithoutPathExpansion(
479    const std::string& path, const string16& in_value) {
480  SetWithoutPathExpansion(path, new StringValue(in_value));
481}
482
483bool DictionaryValue::Get(const std::string& path,
484                          const Value** out_value) const {
485  DCHECK(IsStringUTF8(path));
486  std::string current_path(path);
487  const DictionaryValue* current_dictionary = this;
488  for (size_t delimiter_position = current_path.find('.');
489       delimiter_position != std::string::npos;
490       delimiter_position = current_path.find('.')) {
491    const DictionaryValue* child_dictionary = NULL;
492    if (!current_dictionary->GetDictionary(
493            current_path.substr(0, delimiter_position), &child_dictionary))
494      return false;
495
496    current_dictionary = child_dictionary;
497    current_path.erase(0, delimiter_position + 1);
498  }
499
500  return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
501}
502
503bool DictionaryValue::Get(const std::string& path, Value** out_value)  {
504  return static_cast<const DictionaryValue&>(*this).Get(
505      path,
506      const_cast<const Value**>(out_value));
507}
508
509bool DictionaryValue::GetBoolean(const std::string& path,
510                                 bool* bool_value) const {
511  const Value* value;
512  if (!Get(path, &value))
513    return false;
514
515  return value->GetAsBoolean(bool_value);
516}
517
518bool DictionaryValue::GetInteger(const std::string& path,
519                                 int* out_value) const {
520  const Value* value;
521  if (!Get(path, &value))
522    return false;
523
524  return value->GetAsInteger(out_value);
525}
526
527bool DictionaryValue::GetDouble(const std::string& path,
528                                double* out_value) const {
529  const Value* value;
530  if (!Get(path, &value))
531    return false;
532
533  return value->GetAsDouble(out_value);
534}
535
536bool DictionaryValue::GetString(const std::string& path,
537                                std::string* out_value) const {
538  const Value* value;
539  if (!Get(path, &value))
540    return false;
541
542  return value->GetAsString(out_value);
543}
544
545bool DictionaryValue::GetString(const std::string& path,
546                                string16* out_value) const {
547  const Value* value;
548  if (!Get(path, &value))
549    return false;
550
551  return value->GetAsString(out_value);
552}
553
554bool DictionaryValue::GetStringASCII(const std::string& path,
555                                     std::string* out_value) const {
556  std::string out;
557  if (!GetString(path, &out))
558    return false;
559
560  if (!IsStringASCII(out)) {
561    NOTREACHED();
562    return false;
563  }
564
565  out_value->assign(out);
566  return true;
567}
568
569bool DictionaryValue::GetBinary(const std::string& path,
570                                const BinaryValue** out_value) const {
571  const Value* value;
572  bool result = Get(path, &value);
573  if (!result || !value->IsType(TYPE_BINARY))
574    return false;
575
576  if (out_value)
577    *out_value = static_cast<const BinaryValue*>(value);
578
579  return true;
580}
581
582bool DictionaryValue::GetBinary(const std::string& path,
583                                BinaryValue** out_value) {
584  return static_cast<const DictionaryValue&>(*this).GetBinary(
585      path,
586      const_cast<const BinaryValue**>(out_value));
587}
588
589bool DictionaryValue::GetDictionary(const std::string& path,
590                                    const DictionaryValue** out_value) const {
591  const Value* value;
592  bool result = Get(path, &value);
593  if (!result || !value->IsType(TYPE_DICTIONARY))
594    return false;
595
596  if (out_value)
597    *out_value = static_cast<const DictionaryValue*>(value);
598
599  return true;
600}
601
602bool DictionaryValue::GetDictionary(const std::string& path,
603                                    DictionaryValue** out_value) {
604  return static_cast<const DictionaryValue&>(*this).GetDictionary(
605      path,
606      const_cast<const DictionaryValue**>(out_value));
607}
608
609bool DictionaryValue::GetList(const std::string& path,
610                              const ListValue** out_value) const {
611  const Value* value;
612  bool result = Get(path, &value);
613  if (!result || !value->IsType(TYPE_LIST))
614    return false;
615
616  if (out_value)
617    *out_value = static_cast<const ListValue*>(value);
618
619  return true;
620}
621
622bool DictionaryValue::GetList(const std::string& path, ListValue** out_value) {
623  return static_cast<const DictionaryValue&>(*this).GetList(
624      path,
625      const_cast<const ListValue**>(out_value));
626}
627
628bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
629                                              const Value** out_value) const {
630  DCHECK(IsStringUTF8(key));
631  ValueMap::const_iterator entry_iterator = dictionary_.find(key);
632  if (entry_iterator == dictionary_.end())
633    return false;
634
635  const Value* entry = entry_iterator->second;
636  if (out_value)
637    *out_value = entry;
638  return true;
639}
640
641bool DictionaryValue::GetWithoutPathExpansion(const std::string& key,
642                                              Value** out_value) {
643  return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
644      key,
645      const_cast<const Value**>(out_value));
646}
647
648bool DictionaryValue::GetBooleanWithoutPathExpansion(const std::string& key,
649                                                     bool* out_value) const {
650  const Value* value;
651  if (!GetWithoutPathExpansion(key, &value))
652    return false;
653
654  return value->GetAsBoolean(out_value);
655}
656
657bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key,
658                                                     int* out_value) const {
659  const Value* value;
660  if (!GetWithoutPathExpansion(key, &value))
661    return false;
662
663  return value->GetAsInteger(out_value);
664}
665
666bool DictionaryValue::GetDoubleWithoutPathExpansion(const std::string& key,
667                                                    double* out_value) const {
668  const Value* value;
669  if (!GetWithoutPathExpansion(key, &value))
670    return false;
671
672  return value->GetAsDouble(out_value);
673}
674
675bool DictionaryValue::GetStringWithoutPathExpansion(
676    const std::string& key,
677    std::string* out_value) const {
678  const Value* value;
679  if (!GetWithoutPathExpansion(key, &value))
680    return false;
681
682  return value->GetAsString(out_value);
683}
684
685bool DictionaryValue::GetStringWithoutPathExpansion(const std::string& key,
686                                                    string16* out_value) const {
687  const Value* value;
688  if (!GetWithoutPathExpansion(key, &value))
689    return false;
690
691  return value->GetAsString(out_value);
692}
693
694bool DictionaryValue::GetDictionaryWithoutPathExpansion(
695    const std::string& key,
696    const DictionaryValue** out_value) const {
697  const Value* value;
698  bool result = GetWithoutPathExpansion(key, &value);
699  if (!result || !value->IsType(TYPE_DICTIONARY))
700    return false;
701
702  if (out_value)
703    *out_value = static_cast<const DictionaryValue*>(value);
704
705  return true;
706}
707
708bool DictionaryValue::GetDictionaryWithoutPathExpansion(
709    const std::string& key,
710    DictionaryValue** out_value) {
711  const DictionaryValue& const_this =
712      static_cast<const DictionaryValue&>(*this);
713  return const_this.GetDictionaryWithoutPathExpansion(
714          key,
715          const_cast<const DictionaryValue**>(out_value));
716}
717
718bool DictionaryValue::GetListWithoutPathExpansion(
719    const std::string& key,
720    const ListValue** out_value) const {
721  const Value* value;
722  bool result = GetWithoutPathExpansion(key, &value);
723  if (!result || !value->IsType(TYPE_LIST))
724    return false;
725
726  if (out_value)
727    *out_value = static_cast<const ListValue*>(value);
728
729  return true;
730}
731
732bool DictionaryValue::GetListWithoutPathExpansion(const std::string& key,
733                                                  ListValue** out_value) {
734  return
735      static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
736          key,
737          const_cast<const ListValue**>(out_value));
738}
739
740bool DictionaryValue::Remove(const std::string& path,
741                             scoped_ptr<Value>* out_value) {
742  DCHECK(IsStringUTF8(path));
743  std::string current_path(path);
744  DictionaryValue* current_dictionary = this;
745  size_t delimiter_position = current_path.rfind('.');
746  if (delimiter_position != std::string::npos) {
747    if (!GetDictionary(current_path.substr(0, delimiter_position),
748                       &current_dictionary))
749      return false;
750    current_path.erase(0, delimiter_position + 1);
751  }
752
753  return current_dictionary->RemoveWithoutPathExpansion(current_path,
754                                                        out_value);
755}
756
757bool DictionaryValue::RemoveWithoutPathExpansion(const std::string& key,
758                                                 scoped_ptr<Value>* out_value) {
759  DCHECK(IsStringUTF8(key));
760  ValueMap::iterator entry_iterator = dictionary_.find(key);
761  if (entry_iterator == dictionary_.end())
762    return false;
763
764  Value* entry = entry_iterator->second;
765  if (out_value)
766    out_value->reset(entry);
767  else
768    delete entry;
769  dictionary_.erase(entry_iterator);
770  return true;
771}
772
773bool DictionaryValue::RemovePath(const std::string& path,
774                                 scoped_ptr<Value>* out_value) {
775  bool result = false;
776  size_t delimiter_position = path.find('.');
777
778  if (delimiter_position == std::string::npos)
779    return RemoveWithoutPathExpansion(path, out_value);
780
781  const std::string subdict_path = path.substr(0, delimiter_position);
782  DictionaryValue* subdict = NULL;
783  if (!GetDictionary(subdict_path, &subdict))
784    return false;
785  result = subdict->RemovePath(path.substr(delimiter_position + 1),
786                               out_value);
787  if (result && subdict->empty())
788    RemoveWithoutPathExpansion(subdict_path, NULL);
789
790  return result;
791}
792
793DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() const {
794  Value* copy = CopyWithoutEmptyChildren(this);
795  return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue;
796}
797
798void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
799  for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) {
800    const Value* merge_value = &it.value();
801    // Check whether we have to merge dictionaries.
802    if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
803      DictionaryValue* sub_dict;
804      if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
805        sub_dict->MergeDictionary(
806            static_cast<const DictionaryValue*>(merge_value));
807        continue;
808      }
809    }
810    // All other cases: Make a copy and hook it up.
811    SetWithoutPathExpansion(it.key(), merge_value->DeepCopy());
812  }
813}
814
815void DictionaryValue::Swap(DictionaryValue* other) {
816  dictionary_.swap(other->dictionary_);
817}
818
819DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
820    : target_(target),
821      it_(target.dictionary_.begin()) {}
822
823DictionaryValue::Iterator::~Iterator() {}
824
825DictionaryValue* DictionaryValue::DeepCopy() const {
826  DictionaryValue* result = new DictionaryValue;
827
828  for (ValueMap::const_iterator current_entry(dictionary_.begin());
829       current_entry != dictionary_.end(); ++current_entry) {
830    result->SetWithoutPathExpansion(current_entry->first,
831                                    current_entry->second->DeepCopy());
832  }
833
834  return result;
835}
836
837bool DictionaryValue::Equals(const Value* other) const {
838  if (other->GetType() != GetType())
839    return false;
840
841  const DictionaryValue* other_dict =
842      static_cast<const DictionaryValue*>(other);
843  Iterator lhs_it(*this);
844  Iterator rhs_it(*other_dict);
845  while (!lhs_it.IsAtEnd() && !rhs_it.IsAtEnd()) {
846    if (lhs_it.key() != rhs_it.key() ||
847        !lhs_it.value().Equals(&rhs_it.value())) {
848      return false;
849    }
850    lhs_it.Advance();
851    rhs_it.Advance();
852  }
853  if (!lhs_it.IsAtEnd() || !rhs_it.IsAtEnd())
854    return false;
855
856  return true;
857}
858
859///////////////////// ListValue ////////////////////
860
861ListValue::ListValue() : Value(TYPE_LIST) {
862}
863
864ListValue::~ListValue() {
865  Clear();
866}
867
868void ListValue::Clear() {
869  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i)
870    delete *i;
871  list_.clear();
872}
873
874bool ListValue::Set(size_t index, Value* in_value) {
875  if (!in_value)
876    return false;
877
878  if (index >= list_.size()) {
879    // Pad out any intermediate indexes with null settings
880    while (index > list_.size())
881      Append(CreateNullValue());
882    Append(in_value);
883  } else {
884    DCHECK(list_[index] != in_value);
885    delete list_[index];
886    list_[index] = in_value;
887  }
888  return true;
889}
890
891bool ListValue::Get(size_t index, const Value** out_value) const {
892  if (index >= list_.size())
893    return false;
894
895  if (out_value)
896    *out_value = list_[index];
897
898  return true;
899}
900
901bool ListValue::Get(size_t index, Value** out_value) {
902  return static_cast<const ListValue&>(*this).Get(
903      index,
904      const_cast<const Value**>(out_value));
905}
906
907bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
908  const Value* value;
909  if (!Get(index, &value))
910    return false;
911
912  return value->GetAsBoolean(bool_value);
913}
914
915bool ListValue::GetInteger(size_t index, int* out_value) const {
916  const Value* value;
917  if (!Get(index, &value))
918    return false;
919
920  return value->GetAsInteger(out_value);
921}
922
923bool ListValue::GetDouble(size_t index, double* out_value) const {
924  const Value* value;
925  if (!Get(index, &value))
926    return false;
927
928  return value->GetAsDouble(out_value);
929}
930
931bool ListValue::GetString(size_t index, std::string* out_value) const {
932  const Value* value;
933  if (!Get(index, &value))
934    return false;
935
936  return value->GetAsString(out_value);
937}
938
939bool ListValue::GetString(size_t index, string16* out_value) const {
940  const Value* value;
941  if (!Get(index, &value))
942    return false;
943
944  return value->GetAsString(out_value);
945}
946
947bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const {
948  const Value* value;
949  bool result = Get(index, &value);
950  if (!result || !value->IsType(TYPE_BINARY))
951    return false;
952
953  if (out_value)
954    *out_value = static_cast<const BinaryValue*>(value);
955
956  return true;
957}
958
959bool ListValue::GetBinary(size_t index, BinaryValue** out_value) {
960  return static_cast<const ListValue&>(*this).GetBinary(
961      index,
962      const_cast<const BinaryValue**>(out_value));
963}
964
965bool ListValue::GetDictionary(size_t index,
966                              const DictionaryValue** out_value) const {
967  const Value* value;
968  bool result = Get(index, &value);
969  if (!result || !value->IsType(TYPE_DICTIONARY))
970    return false;
971
972  if (out_value)
973    *out_value = static_cast<const DictionaryValue*>(value);
974
975  return true;
976}
977
978bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
979  return static_cast<const ListValue&>(*this).GetDictionary(
980      index,
981      const_cast<const DictionaryValue**>(out_value));
982}
983
984bool ListValue::GetList(size_t index, const ListValue** out_value) const {
985  const Value* value;
986  bool result = Get(index, &value);
987  if (!result || !value->IsType(TYPE_LIST))
988    return false;
989
990  if (out_value)
991    *out_value = static_cast<const ListValue*>(value);
992
993  return true;
994}
995
996bool ListValue::GetList(size_t index, ListValue** out_value) {
997  return static_cast<const ListValue&>(*this).GetList(
998      index,
999      const_cast<const ListValue**>(out_value));
1000}
1001
1002bool ListValue::Remove(size_t index, scoped_ptr<Value>* out_value) {
1003  if (index >= list_.size())
1004    return false;
1005
1006  if (out_value)
1007    out_value->reset(list_[index]);
1008  else
1009    delete list_[index];
1010
1011  list_.erase(list_.begin() + index);
1012  return true;
1013}
1014
1015bool ListValue::Remove(const Value& value, size_t* index) {
1016  for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) {
1017    if ((*i)->Equals(&value)) {
1018      size_t previous_index = i - list_.begin();
1019      delete *i;
1020      list_.erase(i);
1021
1022      if (index)
1023        *index = previous_index;
1024      return true;
1025    }
1026  }
1027  return false;
1028}
1029
1030ListValue::iterator ListValue::Erase(iterator iter,
1031                                     scoped_ptr<Value>* out_value) {
1032  if (out_value)
1033    out_value->reset(*iter);
1034  else
1035    delete *iter;
1036
1037  return list_.erase(iter);
1038}
1039
1040void ListValue::Append(Value* in_value) {
1041  DCHECK(in_value);
1042  list_.push_back(in_value);
1043}
1044
1045void ListValue::AppendBoolean(bool in_value) {
1046  Append(new FundamentalValue(in_value));
1047}
1048
1049void ListValue::AppendInteger(int in_value) {
1050  Append(new FundamentalValue(in_value));
1051}
1052
1053void ListValue::AppendDouble(double in_value) {
1054  Append(new FundamentalValue(in_value));
1055}
1056
1057void ListValue::AppendString(const std::string& in_value) {
1058  Append(new StringValue(in_value));
1059}
1060
1061void ListValue::AppendString(const string16& in_value) {
1062  Append(new StringValue(in_value));
1063}
1064
1065void ListValue::AppendStrings(const std::vector<std::string>& in_values) {
1066  for (std::vector<std::string>::const_iterator it = in_values.begin();
1067       it != in_values.end(); ++it) {
1068    AppendString(*it);
1069  }
1070}
1071
1072void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1073  for (std::vector<string16>::const_iterator it = in_values.begin();
1074       it != in_values.end(); ++it) {
1075    AppendString(*it);
1076  }
1077}
1078
1079bool ListValue::AppendIfNotPresent(Value* in_value) {
1080  DCHECK(in_value);
1081  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
1082    if ((*i)->Equals(in_value)) {
1083      delete in_value;
1084      return false;
1085    }
1086  }
1087  list_.push_back(in_value);
1088  return true;
1089}
1090
1091bool ListValue::Insert(size_t index, Value* in_value) {
1092  DCHECK(in_value);
1093  if (index > list_.size())
1094    return false;
1095
1096  list_.insert(list_.begin() + index, in_value);
1097  return true;
1098}
1099
1100ListValue::const_iterator ListValue::Find(const Value& value) const {
1101  return std::find_if(list_.begin(), list_.end(), ValueEquals(&value));
1102}
1103
1104void ListValue::Swap(ListValue* other) {
1105  list_.swap(other->list_);
1106}
1107
1108bool ListValue::GetAsList(ListValue** out_value) {
1109  if (out_value)
1110    *out_value = this;
1111  return true;
1112}
1113
1114bool ListValue::GetAsList(const ListValue** out_value) const {
1115  if (out_value)
1116    *out_value = this;
1117  return true;
1118}
1119
1120ListValue* ListValue::DeepCopy() const {
1121  ListValue* result = new ListValue;
1122
1123  for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i)
1124    result->Append((*i)->DeepCopy());
1125
1126  return result;
1127}
1128
1129bool ListValue::Equals(const Value* other) const {
1130  if (other->GetType() != GetType())
1131    return false;
1132
1133  const ListValue* other_list =
1134      static_cast<const ListValue*>(other);
1135  const_iterator lhs_it, rhs_it;
1136  for (lhs_it = begin(), rhs_it = other_list->begin();
1137       lhs_it != end() && rhs_it != other_list->end();
1138       ++lhs_it, ++rhs_it) {
1139    if (!(*lhs_it)->Equals(*rhs_it))
1140      return false;
1141  }
1142  if (lhs_it != end() || rhs_it != other_list->end())
1143    return false;
1144
1145  return true;
1146}
1147
1148ValueSerializer::~ValueSerializer() {
1149}
1150
1151std::ostream& operator<<(std::ostream& out, const Value& value) {
1152  std::string json;
1153  JSONWriter::WriteWithOptions(&value,
1154                               JSONWriter::OPTIONS_PRETTY_PRINT,
1155                               &json);
1156  return out << json;
1157}
1158
1159}  // namespace base
1160