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