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