Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/values.h"
      6 
      7 #include <string.h>
      8 
      9 #include <algorithm>
     10 #include <cmath>
     11 #include <ostream>
     12 #include <utility>
     13 
     14 #include "base/json/json_writer.h"
     15 #include "base/logging.h"
     16 #include "base/memory/ptr_util.h"
     17 #include "base/strings/string_util.h"
     18 #include "base/strings/utf_string_conversions.h"
     19 
     20 namespace base {
     21 
     22 namespace {
     23 
     24 const char* const kTypeNames[] = {"null",   "boolean", "integer",    "double",
     25                                   "string", "binary",  "dictionary", "list"};
     26 static_assert(arraysize(kTypeNames) ==
     27                   static_cast<size_t>(Value::Type::LIST) + 1,
     28               "kTypeNames Has Wrong Size");
     29 
     30 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node);
     31 
     32 // Make a deep copy of |node|, but don't include empty lists or dictionaries
     33 // in the copy. It's possible for this function to return NULL and it
     34 // expects |node| to always be non-NULL.
     35 std::unique_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) {
     36   std::unique_ptr<ListValue> copy;
     37   for (const auto& entry : list) {
     38     std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(*entry);
     39     if (child_copy) {
     40       if (!copy)
     41         copy.reset(new ListValue);
     42       copy->Append(std::move(child_copy));
     43     }
     44   }
     45   return copy;
     46 }
     47 
     48 std::unique_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren(
     49     const DictionaryValue& dict) {
     50   std::unique_ptr<DictionaryValue> copy;
     51   for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
     52     std::unique_ptr<Value> child_copy = CopyWithoutEmptyChildren(it.value());
     53     if (child_copy) {
     54       if (!copy)
     55         copy.reset(new DictionaryValue);
     56       copy->SetWithoutPathExpansion(it.key(), std::move(child_copy));
     57     }
     58   }
     59   return copy;
     60 }
     61 
     62 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) {
     63   switch (node.GetType()) {
     64     case Value::Type::LIST:
     65       return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node));
     66 
     67     case Value::Type::DICTIONARY:
     68       return CopyDictionaryWithoutEmptyChildren(
     69           static_cast<const DictionaryValue&>(node));
     70 
     71     default:
     72       return MakeUnique<Value>(node);
     73   }
     74 }
     75 
     76 }  // namespace
     77 
     78 // static
     79 std::unique_ptr<Value> Value::CreateNullValue() {
     80   return WrapUnique(new Value(Type::NONE));
     81 }
     82 
     83 // static
     84 std::unique_ptr<BinaryValue> BinaryValue::CreateWithCopiedBuffer(
     85     const char* buffer,
     86     size_t size) {
     87   return MakeUnique<BinaryValue>(std::vector<char>(buffer, buffer + size));
     88 }
     89 
     90 Value::Value(const Value& that) {
     91   InternalCopyConstructFrom(that);
     92 }
     93 
     94 Value::Value(Value&& that) noexcept {
     95   InternalMoveConstructFrom(std::move(that));
     96 }
     97 
     98 Value::Value() noexcept : type_(Type::NONE) {}
     99 
    100 Value::Value(Type type) : type_(type) {
    101   // Initialize with the default value.
    102   switch (type_) {
    103     case Type::NONE:
    104       return;
    105 
    106     case Type::BOOLEAN:
    107       bool_value_ = false;
    108       return;
    109     case Type::INTEGER:
    110       int_value_ = 0;
    111       return;
    112     case Type::DOUBLE:
    113       double_value_ = 0.0;
    114       return;
    115     case Type::STRING:
    116       string_value_.Init();
    117       return;
    118     case Type::BINARY:
    119       binary_value_.Init();
    120       return;
    121     case Type::DICTIONARY:
    122       dict_ptr_.Init(MakeUnique<DictStorage>());
    123       return;
    124     case Type::LIST:
    125       list_.Init();
    126       return;
    127   }
    128 }
    129 
    130 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
    131 
    132 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
    133 
    134 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) {
    135   if (!std::isfinite(double_value_)) {
    136     NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
    137                  << "values cannot be represented in JSON";
    138     double_value_ = 0.0;
    139   }
    140 }
    141 
    142 Value::Value(const char* in_string) : type_(Type::STRING) {
    143   string_value_.Init(in_string);
    144   DCHECK(IsStringUTF8(*string_value_));
    145 }
    146 
    147 Value::Value(const std::string& in_string) : type_(Type::STRING) {
    148   string_value_.Init(in_string);
    149   DCHECK(IsStringUTF8(*string_value_));
    150 }
    151 
    152 Value::Value(std::string&& in_string) noexcept : type_(Type::STRING) {
    153   string_value_.Init(std::move(in_string));
    154   DCHECK(IsStringUTF8(*string_value_));
    155 }
    156 
    157 Value::Value(const char16* in_string) : type_(Type::STRING) {
    158   string_value_.Init(UTF16ToUTF8(in_string));
    159 }
    160 
    161 Value::Value(const string16& in_string) : type_(Type::STRING) {
    162   string_value_.Init(UTF16ToUTF8(in_string));
    163 }
    164 
    165 Value::Value(StringPiece in_string) : Value(in_string.as_string()) {}
    166 
    167 Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) {
    168   binary_value_.Init(in_blob);
    169 }
    170 
    171 Value::Value(std::vector<char>&& in_blob) noexcept : type_(Type::BINARY) {
    172   binary_value_.Init(std::move(in_blob));
    173 }
    174 
    175 Value& Value::operator=(const Value& that) {
    176   if (type_ == that.type_) {
    177     InternalCopyAssignFromSameType(that);
    178   } else {
    179     // This is not a self assignment because the type_ doesn't match.
    180     InternalCleanup();
    181     InternalCopyConstructFrom(that);
    182   }
    183 
    184   return *this;
    185 }
    186 
    187 Value& Value::operator=(Value&& that) noexcept {
    188   DCHECK(this != &that) << "attempt to self move assign.";
    189   InternalCleanup();
    190   InternalMoveConstructFrom(std::move(that));
    191 
    192   return *this;
    193 }
    194 
    195 Value::~Value() {
    196   InternalCleanup();
    197 }
    198 
    199 // static
    200 const char* Value::GetTypeName(Value::Type type) {
    201   DCHECK_GE(static_cast<int>(type), 0);
    202   DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames));
    203   return kTypeNames[static_cast<size_t>(type)];
    204 }
    205 
    206 bool Value::GetBool() const {
    207   CHECK(is_bool());
    208   return bool_value_;
    209 }
    210 
    211 int Value::GetInt() const {
    212   CHECK(is_int());
    213   return int_value_;
    214 }
    215 
    216 double Value::GetDouble() const {
    217   if (is_double())
    218     return double_value_;
    219   if (is_int())
    220     return int_value_;
    221   CHECK(false);
    222   return 0.0;
    223 }
    224 
    225 const std::string& Value::GetString() const {
    226   CHECK(is_string());
    227   return *string_value_;
    228 }
    229 
    230 const std::vector<char>& Value::GetBlob() const {
    231   CHECK(is_blob());
    232   return *binary_value_;
    233 }
    234 
    235 size_t Value::GetSize() const {
    236   return GetBlob().size();
    237 }
    238 
    239 const char* Value::GetBuffer() const {
    240   return GetBlob().data();
    241 }
    242 
    243 bool Value::GetAsBoolean(bool* out_value) const {
    244   if (out_value && is_bool()) {
    245     *out_value = bool_value_;
    246     return true;
    247   }
    248   return is_bool();
    249 }
    250 
    251 bool Value::GetAsInteger(int* out_value) const {
    252   if (out_value && is_int()) {
    253     *out_value = int_value_;
    254     return true;
    255   }
    256   return is_int();
    257 }
    258 
    259 bool Value::GetAsDouble(double* out_value) const {
    260   if (out_value && is_double()) {
    261     *out_value = double_value_;
    262     return true;
    263   } else if (out_value && is_int()) {
    264     // Allow promotion from int to double.
    265     *out_value = int_value_;
    266     return true;
    267   }
    268   return is_double() || is_int();
    269 }
    270 
    271 bool Value::GetAsString(std::string* out_value) const {
    272   if (out_value && is_string()) {
    273     *out_value = *string_value_;
    274     return true;
    275   }
    276   return is_string();
    277 }
    278 
    279 bool Value::GetAsString(string16* out_value) const {
    280   if (out_value && is_string()) {
    281     *out_value = UTF8ToUTF16(*string_value_);
    282     return true;
    283   }
    284   return is_string();
    285 }
    286 
    287 bool Value::GetAsString(const Value** out_value) const {
    288   if (out_value && is_string()) {
    289     *out_value = static_cast<const Value*>(this);
    290     return true;
    291   }
    292   return is_string();
    293 }
    294 
    295 bool Value::GetAsString(StringPiece* out_value) const {
    296   if (out_value && is_string()) {
    297     *out_value = *string_value_;
    298     return true;
    299   }
    300   return is_string();
    301 }
    302 
    303 bool Value::GetAsBinary(const BinaryValue** out_value) const {
    304   if (out_value && is_blob()) {
    305     *out_value = this;
    306     return true;
    307   }
    308   return is_blob();
    309 }
    310 
    311 bool Value::GetAsList(ListValue** out_value) {
    312   if (out_value && is_list()) {
    313     *out_value = static_cast<ListValue*>(this);
    314     return true;
    315   }
    316   return is_list();
    317 }
    318 
    319 bool Value::GetAsList(const ListValue** out_value) const {
    320   if (out_value && is_list()) {
    321     *out_value = static_cast<const ListValue*>(this);
    322     return true;
    323   }
    324   return is_list();
    325 }
    326 
    327 bool Value::GetAsDictionary(DictionaryValue** out_value) {
    328   if (out_value && is_dict()) {
    329     *out_value = static_cast<DictionaryValue*>(this);
    330     return true;
    331   }
    332   return is_dict();
    333 }
    334 
    335 bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
    336   if (out_value && is_dict()) {
    337     *out_value = static_cast<const DictionaryValue*>(this);
    338     return true;
    339   }
    340   return is_dict();
    341 }
    342 
    343 Value* Value::DeepCopy() const {
    344   return new Value(*this);
    345 }
    346 
    347 std::unique_ptr<Value> Value::CreateDeepCopy() const {
    348   return MakeUnique<Value>(*this);
    349 }
    350 
    351 bool operator==(const Value& lhs, const Value& rhs) {
    352   if (lhs.type_ != rhs.type_)
    353     return false;
    354 
    355   switch (lhs.type_) {
    356     case Value::Type::NONE:
    357       return true;
    358     case Value::Type::BOOLEAN:
    359       return lhs.bool_value_ == rhs.bool_value_;
    360     case Value::Type::INTEGER:
    361       return lhs.int_value_ == rhs.int_value_;
    362     case Value::Type::DOUBLE:
    363       return lhs.double_value_ == rhs.double_value_;
    364     case Value::Type::STRING:
    365       return *lhs.string_value_ == *rhs.string_value_;
    366     case Value::Type::BINARY:
    367       return *lhs.binary_value_ == *rhs.binary_value_;
    368     // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
    369     // are completely inlined.
    370     case Value::Type::DICTIONARY:
    371       if ((*lhs.dict_ptr_)->size() != (*rhs.dict_ptr_)->size())
    372         return false;
    373       return std::equal(std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_),
    374                         std::begin(**rhs.dict_ptr_),
    375                         [](const Value::DictStorage::value_type& u,
    376                            const Value::DictStorage::value_type& v) {
    377                           return std::tie(u.first, *u.second) ==
    378                                  std::tie(v.first, *v.second);
    379                         });
    380     case Value::Type::LIST:
    381       if (lhs.list_->size() != rhs.list_->size())
    382         return false;
    383       return std::equal(
    384           std::begin(*lhs.list_), std::end(*lhs.list_), std::begin(*rhs.list_),
    385           [](const Value::ListStorage::value_type& u,
    386              const Value::ListStorage::value_type& v) { return *u == *v; });
    387   }
    388 
    389   NOTREACHED();
    390   return false;
    391 }
    392 
    393 bool operator!=(const Value& lhs, const Value& rhs) {
    394   return !(lhs == rhs);
    395 }
    396 
    397 bool operator<(const Value& lhs, const Value& rhs) {
    398   if (lhs.type_ != rhs.type_)
    399     return lhs.type_ < rhs.type_;
    400 
    401   switch (lhs.type_) {
    402     case Value::Type::NONE:
    403       return false;
    404     case Value::Type::BOOLEAN:
    405       return lhs.bool_value_ < rhs.bool_value_;
    406     case Value::Type::INTEGER:
    407       return lhs.int_value_ < rhs.int_value_;
    408     case Value::Type::DOUBLE:
    409       return lhs.double_value_ < rhs.double_value_;
    410     case Value::Type::STRING:
    411       return *lhs.string_value_ < *rhs.string_value_;
    412     case Value::Type::BINARY:
    413       return *lhs.binary_value_ < *rhs.binary_value_;
    414     // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
    415     // are completely inlined.
    416     case Value::Type::DICTIONARY:
    417       return std::lexicographical_compare(
    418           std::begin(**lhs.dict_ptr_), std::end(**lhs.dict_ptr_),
    419           std::begin(**rhs.dict_ptr_), std::end(**rhs.dict_ptr_),
    420           [](const Value::DictStorage::value_type& u,
    421              const Value::DictStorage::value_type& v) {
    422             return std::tie(u.first, *u.second) < std::tie(v.first, *v.second);
    423           });
    424     case Value::Type::LIST:
    425       return std::lexicographical_compare(
    426           std::begin(*lhs.list_), std::end(*lhs.list_), std::begin(*rhs.list_),
    427           std::end(*rhs.list_),
    428           [](const Value::ListStorage::value_type& u,
    429              const Value::ListStorage::value_type& v) { return *u < *v; });
    430   }
    431 
    432   NOTREACHED();
    433   return false;
    434 }
    435 
    436 bool operator>(const Value& lhs, const Value& rhs) {
    437   return rhs < lhs;
    438 }
    439 
    440 bool operator<=(const Value& lhs, const Value& rhs) {
    441   return !(rhs < lhs);
    442 }
    443 
    444 bool operator>=(const Value& lhs, const Value& rhs) {
    445   return !(lhs < rhs);
    446 }
    447 
    448 bool Value::Equals(const Value* other) const {
    449   DCHECK(other);
    450   return *this == *other;
    451 }
    452 
    453 // static
    454 bool Value::Equals(const Value* a, const Value* b) {
    455   if ((a == NULL) && (b == NULL))
    456     return true;
    457   if ((a == NULL) ^ (b == NULL))
    458     return false;
    459   return *a == *b;
    460 }
    461 
    462 void Value::InternalCopyFundamentalValue(const Value& that) {
    463   switch (type_) {
    464     case Type::NONE:
    465       // Nothing to do.
    466       return;
    467 
    468     case Type::BOOLEAN:
    469       bool_value_ = that.bool_value_;
    470       return;
    471     case Type::INTEGER:
    472       int_value_ = that.int_value_;
    473       return;
    474     case Type::DOUBLE:
    475       double_value_ = that.double_value_;
    476       return;
    477 
    478     default:
    479       NOTREACHED();
    480   }
    481 }
    482 
    483 void Value::InternalCopyConstructFrom(const Value& that) {
    484   type_ = that.type_;
    485 
    486   switch (type_) {
    487     case Type::NONE:
    488     case Type::BOOLEAN:
    489     case Type::INTEGER:
    490     case Type::DOUBLE:
    491       InternalCopyFundamentalValue(that);
    492       return;
    493 
    494     case Type::STRING:
    495       string_value_.Init(*that.string_value_);
    496       return;
    497     case Type::BINARY:
    498       binary_value_.Init(*that.binary_value_);
    499       return;
    500     // DictStorage and ListStorage are move-only types due to the presence of
    501     // unique_ptrs. This is why the explicit copy of every element is necessary
    502     // here.
    503     // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage
    504     // can be copied directly.
    505     case Type::DICTIONARY:
    506       dict_ptr_.Init(MakeUnique<DictStorage>());
    507       for (const auto& it : **that.dict_ptr_) {
    508         (*dict_ptr_)
    509             ->emplace_hint((*dict_ptr_)->end(), it.first,
    510                            MakeUnique<Value>(*it.second));
    511       }
    512       return;
    513     case Type::LIST:
    514       list_.Init();
    515       list_->reserve(that.list_->size());
    516       for (const auto& it : *that.list_)
    517         list_->push_back(MakeUnique<Value>(*it));
    518       return;
    519   }
    520 }
    521 
    522 void Value::InternalMoveConstructFrom(Value&& that) {
    523   type_ = that.type_;
    524 
    525   switch (type_) {
    526     case Type::NONE:
    527     case Type::BOOLEAN:
    528     case Type::INTEGER:
    529     case Type::DOUBLE:
    530       InternalCopyFundamentalValue(that);
    531       return;
    532 
    533     case Type::STRING:
    534       string_value_.InitFromMove(std::move(that.string_value_));
    535       return;
    536     case Type::BINARY:
    537       binary_value_.InitFromMove(std::move(that.binary_value_));
    538       return;
    539     case Type::DICTIONARY:
    540       dict_ptr_.InitFromMove(std::move(that.dict_ptr_));
    541       return;
    542     case Type::LIST:
    543       list_.InitFromMove(std::move(that.list_));
    544       return;
    545   }
    546 }
    547 
    548 void Value::InternalCopyAssignFromSameType(const Value& that) {
    549   // TODO(crbug.com/646113): make this a DCHECK once base::Value does not have
    550   // subclasses.
    551   CHECK_EQ(type_, that.type_);
    552 
    553   switch (type_) {
    554     case Type::NONE:
    555     case Type::BOOLEAN:
    556     case Type::INTEGER:
    557     case Type::DOUBLE:
    558       InternalCopyFundamentalValue(that);
    559       return;
    560 
    561     case Type::STRING:
    562       *string_value_ = *that.string_value_;
    563       return;
    564     case Type::BINARY:
    565       *binary_value_ = *that.binary_value_;
    566       return;
    567     // DictStorage and ListStorage are move-only types due to the presence of
    568     // unique_ptrs. This is why the explicit call to the copy constructor is
    569     // necessary here.
    570     // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage
    571     // can be copied directly.
    572     case Type::DICTIONARY:
    573       *dict_ptr_ = std::move(*Value(that).dict_ptr_);
    574       return;
    575     case Type::LIST:
    576       *list_ = std::move(*Value(that).list_);
    577       return;
    578   }
    579 }
    580 
    581 void Value::InternalCleanup() {
    582   switch (type_) {
    583     case Type::NONE:
    584     case Type::BOOLEAN:
    585     case Type::INTEGER:
    586     case Type::DOUBLE:
    587       // Nothing to do
    588       return;
    589 
    590     case Type::STRING:
    591       string_value_.Destroy();
    592       return;
    593     case Type::BINARY:
    594       binary_value_.Destroy();
    595       return;
    596     case Type::DICTIONARY:
    597       dict_ptr_.Destroy();
    598       return;
    599     case Type::LIST:
    600       list_.Destroy();
    601       return;
    602   }
    603 }
    604 
    605 ///////////////////// DictionaryValue ////////////////////
    606 
    607 // static
    608 std::unique_ptr<DictionaryValue> DictionaryValue::From(
    609     std::unique_ptr<Value> value) {
    610   DictionaryValue* out;
    611   if (value && value->GetAsDictionary(&out)) {
    612     ignore_result(value.release());
    613     return WrapUnique(out);
    614   }
    615   return nullptr;
    616 }
    617 
    618 DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {}
    619 
    620 bool DictionaryValue::HasKey(StringPiece key) const {
    621   DCHECK(IsStringUTF8(key));
    622   auto current_entry = (*dict_ptr_)->find(key.as_string());
    623   DCHECK((current_entry == (*dict_ptr_)->end()) || current_entry->second);
    624   return current_entry != (*dict_ptr_)->end();
    625 }
    626 
    627 void DictionaryValue::Clear() {
    628   (*dict_ptr_)->clear();
    629 }
    630 
    631 void DictionaryValue::Set(StringPiece path, std::unique_ptr<Value> in_value) {
    632   DCHECK(IsStringUTF8(path));
    633   DCHECK(in_value);
    634 
    635   StringPiece current_path(path);
    636   DictionaryValue* current_dictionary = this;
    637   for (size_t delimiter_position = current_path.find('.');
    638        delimiter_position != StringPiece::npos;
    639        delimiter_position = current_path.find('.')) {
    640     // Assume that we're indexing into a dictionary.
    641     StringPiece key = current_path.substr(0, delimiter_position);
    642     DictionaryValue* child_dictionary = nullptr;
    643     if (!current_dictionary->GetDictionary(key, &child_dictionary)) {
    644       child_dictionary = new DictionaryValue;
    645       current_dictionary->SetWithoutPathExpansion(
    646           key, base::WrapUnique(child_dictionary));
    647     }
    648 
    649     current_dictionary = child_dictionary;
    650     current_path = current_path.substr(delimiter_position + 1);
    651   }
    652 
    653   current_dictionary->SetWithoutPathExpansion(current_path,
    654                                               std::move(in_value));
    655 }
    656 
    657 void DictionaryValue::Set(StringPiece path, Value* in_value) {
    658   Set(path, WrapUnique(in_value));
    659 }
    660 
    661 void DictionaryValue::SetBoolean(StringPiece path, bool in_value) {
    662   Set(path, new Value(in_value));
    663 }
    664 
    665 void DictionaryValue::SetInteger(StringPiece path, int in_value) {
    666   Set(path, new Value(in_value));
    667 }
    668 
    669 void DictionaryValue::SetDouble(StringPiece path, double in_value) {
    670   Set(path, new Value(in_value));
    671 }
    672 
    673 void DictionaryValue::SetString(StringPiece path, StringPiece in_value) {
    674   Set(path, new Value(in_value));
    675 }
    676 
    677 void DictionaryValue::SetString(StringPiece path, const string16& in_value) {
    678   Set(path, new Value(in_value));
    679 }
    680 
    681 void DictionaryValue::SetWithoutPathExpansion(StringPiece key,
    682                                               std::unique_ptr<Value> in_value) {
    683   (**dict_ptr_)[key.as_string()] = std::move(in_value);
    684 }
    685 
    686 void DictionaryValue::SetWithoutPathExpansion(StringPiece key,
    687                                               Value* in_value) {
    688   SetWithoutPathExpansion(key, WrapUnique(in_value));
    689 }
    690 
    691 void DictionaryValue::SetBooleanWithoutPathExpansion(StringPiece path,
    692                                                      bool in_value) {
    693   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
    694 }
    695 
    696 void DictionaryValue::SetIntegerWithoutPathExpansion(StringPiece path,
    697                                                      int in_value) {
    698   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
    699 }
    700 
    701 void DictionaryValue::SetDoubleWithoutPathExpansion(StringPiece path,
    702                                                     double in_value) {
    703   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
    704 }
    705 
    706 void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path,
    707                                                     StringPiece in_value) {
    708   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
    709 }
    710 
    711 void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path,
    712                                                     const string16& in_value) {
    713   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
    714 }
    715 
    716 bool DictionaryValue::Get(StringPiece path,
    717                           const Value** out_value) const {
    718   DCHECK(IsStringUTF8(path));
    719   StringPiece current_path(path);
    720   const DictionaryValue* current_dictionary = this;
    721   for (size_t delimiter_position = current_path.find('.');
    722        delimiter_position != std::string::npos;
    723        delimiter_position = current_path.find('.')) {
    724     const DictionaryValue* child_dictionary = NULL;
    725     if (!current_dictionary->GetDictionaryWithoutPathExpansion(
    726             current_path.substr(0, delimiter_position), &child_dictionary)) {
    727       return false;
    728     }
    729 
    730     current_dictionary = child_dictionary;
    731     current_path = current_path.substr(delimiter_position + 1);
    732   }
    733 
    734   return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
    735 }
    736 
    737 bool DictionaryValue::Get(StringPiece path, Value** out_value)  {
    738   return static_cast<const DictionaryValue&>(*this).Get(
    739       path,
    740       const_cast<const Value**>(out_value));
    741 }
    742 
    743 bool DictionaryValue::GetBoolean(StringPiece path, bool* bool_value) const {
    744   const Value* value;
    745   if (!Get(path, &value))
    746     return false;
    747 
    748   return value->GetAsBoolean(bool_value);
    749 }
    750 
    751 bool DictionaryValue::GetInteger(StringPiece path, int* out_value) const {
    752   const Value* value;
    753   if (!Get(path, &value))
    754     return false;
    755 
    756   return value->GetAsInteger(out_value);
    757 }
    758 
    759 bool DictionaryValue::GetDouble(StringPiece path, double* out_value) const {
    760   const Value* value;
    761   if (!Get(path, &value))
    762     return false;
    763 
    764   return value->GetAsDouble(out_value);
    765 }
    766 
    767 bool DictionaryValue::GetString(StringPiece path,
    768                                 std::string* out_value) const {
    769   const Value* value;
    770   if (!Get(path, &value))
    771     return false;
    772 
    773   return value->GetAsString(out_value);
    774 }
    775 
    776 bool DictionaryValue::GetString(StringPiece path, string16* out_value) const {
    777   const Value* value;
    778   if (!Get(path, &value))
    779     return false;
    780 
    781   return value->GetAsString(out_value);
    782 }
    783 
    784 bool DictionaryValue::GetStringASCII(StringPiece path,
    785                                      std::string* out_value) const {
    786   std::string out;
    787   if (!GetString(path, &out))
    788     return false;
    789 
    790   if (!IsStringASCII(out)) {
    791     NOTREACHED();
    792     return false;
    793   }
    794 
    795   out_value->assign(out);
    796   return true;
    797 }
    798 
    799 bool DictionaryValue::GetBinary(StringPiece path,
    800                                 const BinaryValue** out_value) const {
    801   const Value* value;
    802   bool result = Get(path, &value);
    803   if (!result || !value->IsType(Type::BINARY))
    804     return false;
    805 
    806   if (out_value)
    807     *out_value = value;
    808 
    809   return true;
    810 }
    811 
    812 bool DictionaryValue::GetBinary(StringPiece path, BinaryValue** out_value) {
    813   return static_cast<const DictionaryValue&>(*this).GetBinary(
    814       path,
    815       const_cast<const BinaryValue**>(out_value));
    816 }
    817 
    818 bool DictionaryValue::GetDictionary(StringPiece path,
    819                                     const DictionaryValue** out_value) const {
    820   const Value* value;
    821   bool result = Get(path, &value);
    822   if (!result || !value->IsType(Type::DICTIONARY))
    823     return false;
    824 
    825   if (out_value)
    826     *out_value = static_cast<const DictionaryValue*>(value);
    827 
    828   return true;
    829 }
    830 
    831 bool DictionaryValue::GetDictionary(StringPiece path,
    832                                     DictionaryValue** out_value) {
    833   return static_cast<const DictionaryValue&>(*this).GetDictionary(
    834       path,
    835       const_cast<const DictionaryValue**>(out_value));
    836 }
    837 
    838 bool DictionaryValue::GetList(StringPiece path,
    839                               const ListValue** out_value) const {
    840   const Value* value;
    841   bool result = Get(path, &value);
    842   if (!result || !value->IsType(Type::LIST))
    843     return false;
    844 
    845   if (out_value)
    846     *out_value = static_cast<const ListValue*>(value);
    847 
    848   return true;
    849 }
    850 
    851 bool DictionaryValue::GetList(StringPiece path, ListValue** out_value) {
    852   return static_cast<const DictionaryValue&>(*this).GetList(
    853       path,
    854       const_cast<const ListValue**>(out_value));
    855 }
    856 
    857 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key,
    858                                               const Value** out_value) const {
    859   DCHECK(IsStringUTF8(key));
    860   auto entry_iterator = (*dict_ptr_)->find(key.as_string());
    861   if (entry_iterator == (*dict_ptr_)->end())
    862     return false;
    863 
    864   if (out_value)
    865     *out_value = entry_iterator->second.get();
    866   return true;
    867 }
    868 
    869 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key,
    870                                               Value** out_value) {
    871   return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
    872       key,
    873       const_cast<const Value**>(out_value));
    874 }
    875 
    876 bool DictionaryValue::GetBooleanWithoutPathExpansion(StringPiece key,
    877                                                      bool* out_value) const {
    878   const Value* value;
    879   if (!GetWithoutPathExpansion(key, &value))
    880     return false;
    881 
    882   return value->GetAsBoolean(out_value);
    883 }
    884 
    885 bool DictionaryValue::GetIntegerWithoutPathExpansion(StringPiece key,
    886                                                      int* out_value) const {
    887   const Value* value;
    888   if (!GetWithoutPathExpansion(key, &value))
    889     return false;
    890 
    891   return value->GetAsInteger(out_value);
    892 }
    893 
    894 bool DictionaryValue::GetDoubleWithoutPathExpansion(StringPiece key,
    895                                                     double* out_value) const {
    896   const Value* value;
    897   if (!GetWithoutPathExpansion(key, &value))
    898     return false;
    899 
    900   return value->GetAsDouble(out_value);
    901 }
    902 
    903 bool DictionaryValue::GetStringWithoutPathExpansion(
    904     StringPiece key,
    905     std::string* out_value) const {
    906   const Value* value;
    907   if (!GetWithoutPathExpansion(key, &value))
    908     return false;
    909 
    910   return value->GetAsString(out_value);
    911 }
    912 
    913 bool DictionaryValue::GetStringWithoutPathExpansion(StringPiece key,
    914                                                     string16* out_value) const {
    915   const Value* value;
    916   if (!GetWithoutPathExpansion(key, &value))
    917     return false;
    918 
    919   return value->GetAsString(out_value);
    920 }
    921 
    922 bool DictionaryValue::GetDictionaryWithoutPathExpansion(
    923     StringPiece key,
    924     const DictionaryValue** out_value) const {
    925   const Value* value;
    926   bool result = GetWithoutPathExpansion(key, &value);
    927   if (!result || !value->IsType(Type::DICTIONARY))
    928     return false;
    929 
    930   if (out_value)
    931     *out_value = static_cast<const DictionaryValue*>(value);
    932 
    933   return true;
    934 }
    935 
    936 bool DictionaryValue::GetDictionaryWithoutPathExpansion(
    937     StringPiece key,
    938     DictionaryValue** out_value) {
    939   const DictionaryValue& const_this =
    940       static_cast<const DictionaryValue&>(*this);
    941   return const_this.GetDictionaryWithoutPathExpansion(
    942           key,
    943           const_cast<const DictionaryValue**>(out_value));
    944 }
    945 
    946 bool DictionaryValue::GetListWithoutPathExpansion(
    947     StringPiece key,
    948     const ListValue** out_value) const {
    949   const Value* value;
    950   bool result = GetWithoutPathExpansion(key, &value);
    951   if (!result || !value->IsType(Type::LIST))
    952     return false;
    953 
    954   if (out_value)
    955     *out_value = static_cast<const ListValue*>(value);
    956 
    957   return true;
    958 }
    959 
    960 bool DictionaryValue::GetListWithoutPathExpansion(StringPiece key,
    961                                                   ListValue** out_value) {
    962   return
    963       static_cast<const DictionaryValue&>(*this).GetListWithoutPathExpansion(
    964           key,
    965           const_cast<const ListValue**>(out_value));
    966 }
    967 
    968 bool DictionaryValue::Remove(StringPiece path,
    969                              std::unique_ptr<Value>* out_value) {
    970   DCHECK(IsStringUTF8(path));
    971   StringPiece current_path(path);
    972   DictionaryValue* current_dictionary = this;
    973   size_t delimiter_position = current_path.rfind('.');
    974   if (delimiter_position != StringPiece::npos) {
    975     if (!GetDictionary(current_path.substr(0, delimiter_position),
    976                        &current_dictionary))
    977       return false;
    978     current_path = current_path.substr(delimiter_position + 1);
    979   }
    980 
    981   return current_dictionary->RemoveWithoutPathExpansion(current_path,
    982                                                         out_value);
    983 }
    984 
    985 bool DictionaryValue::RemoveWithoutPathExpansion(
    986     StringPiece key,
    987     std::unique_ptr<Value>* out_value) {
    988   DCHECK(IsStringUTF8(key));
    989   auto entry_iterator = (*dict_ptr_)->find(key.as_string());
    990   if (entry_iterator == (*dict_ptr_)->end())
    991     return false;
    992 
    993   if (out_value)
    994     *out_value = std::move(entry_iterator->second);
    995   (*dict_ptr_)->erase(entry_iterator);
    996   return true;
    997 }
    998 
    999 bool DictionaryValue::RemovePath(StringPiece path,
   1000                                  std::unique_ptr<Value>* out_value) {
   1001   bool result = false;
   1002   size_t delimiter_position = path.find('.');
   1003 
   1004   if (delimiter_position == std::string::npos)
   1005     return RemoveWithoutPathExpansion(path, out_value);
   1006 
   1007   StringPiece subdict_path = path.substr(0, delimiter_position);
   1008   DictionaryValue* subdict = NULL;
   1009   if (!GetDictionary(subdict_path, &subdict))
   1010     return false;
   1011   result = subdict->RemovePath(path.substr(delimiter_position + 1),
   1012                                out_value);
   1013   if (result && subdict->empty())
   1014     RemoveWithoutPathExpansion(subdict_path, NULL);
   1015 
   1016   return result;
   1017 }
   1018 
   1019 std::unique_ptr<DictionaryValue> DictionaryValue::DeepCopyWithoutEmptyChildren()
   1020     const {
   1021   std::unique_ptr<DictionaryValue> copy =
   1022       CopyDictionaryWithoutEmptyChildren(*this);
   1023   if (!copy)
   1024     copy.reset(new DictionaryValue);
   1025   return copy;
   1026 }
   1027 
   1028 void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
   1029   CHECK(dictionary->is_dict());
   1030   for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) {
   1031     const Value* merge_value = &it.value();
   1032     // Check whether we have to merge dictionaries.
   1033     if (merge_value->IsType(Value::Type::DICTIONARY)) {
   1034       DictionaryValue* sub_dict;
   1035       if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
   1036         sub_dict->MergeDictionary(
   1037             static_cast<const DictionaryValue*>(merge_value));
   1038         continue;
   1039       }
   1040     }
   1041     // All other cases: Make a copy and hook it up.
   1042     SetWithoutPathExpansion(it.key(), MakeUnique<Value>(*merge_value));
   1043   }
   1044 }
   1045 
   1046 void DictionaryValue::Swap(DictionaryValue* other) {
   1047   CHECK(other->is_dict());
   1048   dict_ptr_->swap(*(other->dict_ptr_));
   1049 }
   1050 
   1051 DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
   1052     : target_(target), it_((*target.dict_ptr_)->begin()) {}
   1053 
   1054 DictionaryValue::Iterator::Iterator(const Iterator& other) = default;
   1055 
   1056 DictionaryValue::Iterator::~Iterator() {}
   1057 
   1058 DictionaryValue* DictionaryValue::DeepCopy() const {
   1059   return new DictionaryValue(*this);
   1060 }
   1061 
   1062 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
   1063   return MakeUnique<DictionaryValue>(*this);
   1064 }
   1065 
   1066 ///////////////////// ListValue ////////////////////
   1067 
   1068 // static
   1069 std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) {
   1070   ListValue* out;
   1071   if (value && value->GetAsList(&out)) {
   1072     ignore_result(value.release());
   1073     return WrapUnique(out);
   1074   }
   1075   return nullptr;
   1076 }
   1077 
   1078 ListValue::ListValue() : Value(Type::LIST) {}
   1079 
   1080 void ListValue::Clear() {
   1081   list_->clear();
   1082 }
   1083 
   1084 bool ListValue::Set(size_t index, Value* in_value) {
   1085   return Set(index, WrapUnique(in_value));
   1086 }
   1087 
   1088 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) {
   1089   if (!in_value)
   1090     return false;
   1091 
   1092   if (index >= list_->size()) {
   1093     // Pad out any intermediate indexes with null settings
   1094     while (index > list_->size())
   1095       Append(CreateNullValue());
   1096     Append(std::move(in_value));
   1097   } else {
   1098     // TODO(dcheng): remove this DCHECK once the raw pointer version is removed?
   1099     DCHECK((*list_)[index] != in_value);
   1100     (*list_)[index] = std::move(in_value);
   1101   }
   1102   return true;
   1103 }
   1104 
   1105 bool ListValue::Get(size_t index, const Value** out_value) const {
   1106   if (index >= list_->size())
   1107     return false;
   1108 
   1109   if (out_value)
   1110     *out_value = (*list_)[index].get();
   1111 
   1112   return true;
   1113 }
   1114 
   1115 bool ListValue::Get(size_t index, Value** out_value) {
   1116   return static_cast<const ListValue&>(*this).Get(
   1117       index,
   1118       const_cast<const Value**>(out_value));
   1119 }
   1120 
   1121 bool ListValue::GetBoolean(size_t index, bool* bool_value) const {
   1122   const Value* value;
   1123   if (!Get(index, &value))
   1124     return false;
   1125 
   1126   return value->GetAsBoolean(bool_value);
   1127 }
   1128 
   1129 bool ListValue::GetInteger(size_t index, int* out_value) const {
   1130   const Value* value;
   1131   if (!Get(index, &value))
   1132     return false;
   1133 
   1134   return value->GetAsInteger(out_value);
   1135 }
   1136 
   1137 bool ListValue::GetDouble(size_t index, double* out_value) const {
   1138   const Value* value;
   1139   if (!Get(index, &value))
   1140     return false;
   1141 
   1142   return value->GetAsDouble(out_value);
   1143 }
   1144 
   1145 bool ListValue::GetString(size_t index, std::string* out_value) const {
   1146   const Value* value;
   1147   if (!Get(index, &value))
   1148     return false;
   1149 
   1150   return value->GetAsString(out_value);
   1151 }
   1152 
   1153 bool ListValue::GetString(size_t index, string16* out_value) const {
   1154   const Value* value;
   1155   if (!Get(index, &value))
   1156     return false;
   1157 
   1158   return value->GetAsString(out_value);
   1159 }
   1160 
   1161 bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const {
   1162   const Value* value;
   1163   bool result = Get(index, &value);
   1164   if (!result || !value->IsType(Type::BINARY))
   1165     return false;
   1166 
   1167   if (out_value)
   1168     *out_value = value;
   1169 
   1170   return true;
   1171 }
   1172 
   1173 bool ListValue::GetBinary(size_t index, BinaryValue** out_value) {
   1174   return static_cast<const ListValue&>(*this).GetBinary(
   1175       index,
   1176       const_cast<const BinaryValue**>(out_value));
   1177 }
   1178 
   1179 bool ListValue::GetDictionary(size_t index,
   1180                               const DictionaryValue** out_value) const {
   1181   const Value* value;
   1182   bool result = Get(index, &value);
   1183   if (!result || !value->IsType(Type::DICTIONARY))
   1184     return false;
   1185 
   1186   if (out_value)
   1187     *out_value = static_cast<const DictionaryValue*>(value);
   1188 
   1189   return true;
   1190 }
   1191 
   1192 bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) {
   1193   return static_cast<const ListValue&>(*this).GetDictionary(
   1194       index,
   1195       const_cast<const DictionaryValue**>(out_value));
   1196 }
   1197 
   1198 bool ListValue::GetList(size_t index, const ListValue** out_value) const {
   1199   const Value* value;
   1200   bool result = Get(index, &value);
   1201   if (!result || !value->IsType(Type::LIST))
   1202     return false;
   1203 
   1204   if (out_value)
   1205     *out_value = static_cast<const ListValue*>(value);
   1206 
   1207   return true;
   1208 }
   1209 
   1210 bool ListValue::GetList(size_t index, ListValue** out_value) {
   1211   return static_cast<const ListValue&>(*this).GetList(
   1212       index,
   1213       const_cast<const ListValue**>(out_value));
   1214 }
   1215 
   1216 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) {
   1217   if (index >= list_->size())
   1218     return false;
   1219 
   1220   if (out_value)
   1221     *out_value = std::move((*list_)[index]);
   1222 
   1223   list_->erase(list_->begin() + index);
   1224   return true;
   1225 }
   1226 
   1227 bool ListValue::Remove(const Value& value, size_t* index) {
   1228   for (auto it = list_->begin(); it != list_->end(); ++it) {
   1229     if (**it == value) {
   1230       size_t previous_index = it - list_->begin();
   1231       list_->erase(it);
   1232 
   1233       if (index)
   1234         *index = previous_index;
   1235       return true;
   1236     }
   1237   }
   1238   return false;
   1239 }
   1240 
   1241 ListValue::iterator ListValue::Erase(iterator iter,
   1242                                      std::unique_ptr<Value>* out_value) {
   1243   if (out_value)
   1244     *out_value = std::move(*ListStorage::iterator(iter));
   1245 
   1246   return list_->erase(iter);
   1247 }
   1248 
   1249 void ListValue::Append(std::unique_ptr<Value> in_value) {
   1250   list_->push_back(std::move(in_value));
   1251 }
   1252 
   1253 #if !defined(OS_LINUX)
   1254 void ListValue::Append(Value* in_value) {
   1255   DCHECK(in_value);
   1256   Append(WrapUnique(in_value));
   1257 }
   1258 #endif
   1259 
   1260 void ListValue::AppendBoolean(bool in_value) {
   1261   Append(MakeUnique<Value>(in_value));
   1262 }
   1263 
   1264 void ListValue::AppendInteger(int in_value) {
   1265   Append(MakeUnique<Value>(in_value));
   1266 }
   1267 
   1268 void ListValue::AppendDouble(double in_value) {
   1269   Append(MakeUnique<Value>(in_value));
   1270 }
   1271 
   1272 void ListValue::AppendString(StringPiece in_value) {
   1273   Append(MakeUnique<Value>(in_value));
   1274 }
   1275 
   1276 void ListValue::AppendString(const string16& in_value) {
   1277   Append(MakeUnique<Value>(in_value));
   1278 }
   1279 
   1280 void ListValue::AppendStrings(const std::vector<std::string>& in_values) {
   1281   for (std::vector<std::string>::const_iterator it = in_values.begin();
   1282        it != in_values.end(); ++it) {
   1283     AppendString(*it);
   1284   }
   1285 }
   1286 
   1287 void ListValue::AppendStrings(const std::vector<string16>& in_values) {
   1288   for (std::vector<string16>::const_iterator it = in_values.begin();
   1289        it != in_values.end(); ++it) {
   1290     AppendString(*it);
   1291   }
   1292 }
   1293 
   1294 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) {
   1295   DCHECK(in_value);
   1296   for (const auto& entry : *list_) {
   1297     if (*entry == *in_value)
   1298       return false;
   1299   }
   1300   list_->push_back(std::move(in_value));
   1301   return true;
   1302 }
   1303 
   1304 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) {
   1305   DCHECK(in_value);
   1306   if (index > list_->size())
   1307     return false;
   1308 
   1309   list_->insert(list_->begin() + index, std::move(in_value));
   1310   return true;
   1311 }
   1312 
   1313 ListValue::const_iterator ListValue::Find(const Value& value) const {
   1314   return std::find_if(list_->begin(), list_->end(),
   1315                       [&value](const std::unique_ptr<Value>& entry) {
   1316                         return *entry == value;
   1317                       });
   1318 }
   1319 
   1320 void ListValue::Swap(ListValue* other) {
   1321   CHECK(other->is_list());
   1322   list_->swap(*(other->list_));
   1323 }
   1324 
   1325 ListValue* ListValue::DeepCopy() const {
   1326   return new ListValue(*this);
   1327 }
   1328 
   1329 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const {
   1330   return MakeUnique<ListValue>(*this);
   1331 }
   1332 
   1333 ValueSerializer::~ValueSerializer() {
   1334 }
   1335 
   1336 ValueDeserializer::~ValueDeserializer() {
   1337 }
   1338 
   1339 std::ostream& operator<<(std::ostream& out, const Value& value) {
   1340   std::string json;
   1341   JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json);
   1342   return out << json;
   1343 }
   1344 
   1345 std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
   1346   if (static_cast<int>(type) < 0 ||
   1347       static_cast<size_t>(type) >= arraysize(kTypeNames))
   1348     return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
   1349   return out << Value::GetTypeName(type);
   1350 }
   1351 
   1352 }  // namespace base
   1353