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