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