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