• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
CopyListWithoutEmptyChildren(const ListValue & list)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 
CopyDictionaryWithoutEmptyChildren(const DictionaryValue & dict)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 
CopyWithoutEmptyChildren(const Value & node)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
CreateNullValue()79 std::unique_ptr<Value> Value::CreateNullValue() {
80   return WrapUnique(new Value(Type::NONE));
81 }
82 
83 // static
CreateWithCopiedBuffer(const char * buffer,size_t size)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 
Value(const Value & that)90 Value::Value(const Value& that) {
91   InternalCopyConstructFrom(that);
92 }
93 
Value(Value && that)94 Value::Value(Value&& that) noexcept {
95   InternalMoveConstructFrom(std::move(that));
96 }
97 
Value()98 Value::Value() noexcept : type_(Type::NONE) {}
99 
Value(Type type)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 
Value(bool in_bool)130 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
131 
Value(int in_int)132 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
133 
Value(double in_double)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 
Value(const char * in_string)142 Value::Value(const char* in_string) : type_(Type::STRING) {
143   string_value_.Init(in_string);
144   DCHECK(IsStringUTF8(*string_value_));
145 }
146 
Value(const std::string & in_string)147 Value::Value(const std::string& in_string) : type_(Type::STRING) {
148   string_value_.Init(in_string);
149   DCHECK(IsStringUTF8(*string_value_));
150 }
151 
Value(std::string && in_string)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 
Value(const char16 * in_string)157 Value::Value(const char16* in_string) : type_(Type::STRING) {
158   string_value_.Init(UTF16ToUTF8(in_string));
159 }
160 
Value(const string16 & in_string)161 Value::Value(const string16& in_string) : type_(Type::STRING) {
162   string_value_.Init(UTF16ToUTF8(in_string));
163 }
164 
Value(StringPiece in_string)165 Value::Value(StringPiece in_string) : Value(in_string.as_string()) {}
166 
Value(const std::vector<char> & in_blob)167 Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) {
168   binary_value_.Init(in_blob);
169 }
170 
Value(std::vector<char> && in_blob)171 Value::Value(std::vector<char>&& in_blob) noexcept : type_(Type::BINARY) {
172   binary_value_.Init(std::move(in_blob));
173 }
174 
operator =(const Value & that)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 
operator =(Value && that)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 
~Value()195 Value::~Value() {
196   InternalCleanup();
197 }
198 
199 // static
GetTypeName(Value::Type type)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 
GetBool() const206 bool Value::GetBool() const {
207   CHECK(is_bool());
208   return bool_value_;
209 }
210 
GetInt() const211 int Value::GetInt() const {
212   CHECK(is_int());
213   return int_value_;
214 }
215 
GetDouble() const216 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 
GetString() const225 const std::string& Value::GetString() const {
226   CHECK(is_string());
227   return *string_value_;
228 }
229 
GetBlob() const230 const std::vector<char>& Value::GetBlob() const {
231   CHECK(is_blob());
232   return *binary_value_;
233 }
234 
GetSize() const235 size_t Value::GetSize() const {
236   return GetBlob().size();
237 }
238 
GetBuffer() const239 const char* Value::GetBuffer() const {
240   return GetBlob().data();
241 }
242 
GetAsBoolean(bool * out_value) const243 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 
GetAsInteger(int * out_value) const251 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 
GetAsDouble(double * out_value) const259 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 
GetAsString(std::string * out_value) const271 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 
GetAsString(string16 * out_value) const279 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 
GetAsString(const Value ** out_value) const287 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 
GetAsString(StringPiece * out_value) const295 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 
GetAsBinary(const BinaryValue ** out_value) const303 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 
GetAsList(ListValue ** out_value)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 
GetAsList(const ListValue ** out_value) const319 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 
GetAsDictionary(DictionaryValue ** out_value)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 
GetAsDictionary(const DictionaryValue ** out_value) const335 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 
DeepCopy() const343 Value* Value::DeepCopy() const {
344   return new Value(*this);
345 }
346 
CreateDeepCopy() const347 std::unique_ptr<Value> Value::CreateDeepCopy() const {
348   return MakeUnique<Value>(*this);
349 }
350 
operator ==(const Value & lhs,const Value & rhs)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 
operator !=(const Value & lhs,const Value & rhs)393 bool operator!=(const Value& lhs, const Value& rhs) {
394   return !(lhs == rhs);
395 }
396 
operator <(const Value & lhs,const Value & rhs)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 
operator >(const Value & lhs,const Value & rhs)436 bool operator>(const Value& lhs, const Value& rhs) {
437   return rhs < lhs;
438 }
439 
operator <=(const Value & lhs,const Value & rhs)440 bool operator<=(const Value& lhs, const Value& rhs) {
441   return !(rhs < lhs);
442 }
443 
operator >=(const Value & lhs,const Value & rhs)444 bool operator>=(const Value& lhs, const Value& rhs) {
445   return !(lhs < rhs);
446 }
447 
Equals(const Value * other) const448 bool Value::Equals(const Value* other) const {
449   DCHECK(other);
450   return *this == *other;
451 }
452 
453 // static
Equals(const Value * a,const Value * b)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 
InternalCopyFundamentalValue(const Value & that)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 
InternalCopyConstructFrom(const Value & that)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 
InternalMoveConstructFrom(Value && that)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 
InternalCopyAssignFromSameType(const Value & that)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 
InternalCleanup()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
From(std::unique_ptr<Value> value)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 
DictionaryValue()618 DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {}
619 
HasKey(StringPiece key) const620 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 
Clear()627 void DictionaryValue::Clear() {
628   (*dict_ptr_)->clear();
629 }
630 
Set(StringPiece path,std::unique_ptr<Value> in_value)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 
Set(StringPiece path,Value * in_value)657 void DictionaryValue::Set(StringPiece path, Value* in_value) {
658   Set(path, WrapUnique(in_value));
659 }
660 
SetBoolean(StringPiece path,bool in_value)661 void DictionaryValue::SetBoolean(StringPiece path, bool in_value) {
662   Set(path, new Value(in_value));
663 }
664 
SetInteger(StringPiece path,int in_value)665 void DictionaryValue::SetInteger(StringPiece path, int in_value) {
666   Set(path, new Value(in_value));
667 }
668 
SetDouble(StringPiece path,double in_value)669 void DictionaryValue::SetDouble(StringPiece path, double in_value) {
670   Set(path, new Value(in_value));
671 }
672 
SetString(StringPiece path,StringPiece in_value)673 void DictionaryValue::SetString(StringPiece path, StringPiece in_value) {
674   Set(path, new Value(in_value));
675 }
676 
SetString(StringPiece path,const string16 & in_value)677 void DictionaryValue::SetString(StringPiece path, const string16& in_value) {
678   Set(path, new Value(in_value));
679 }
680 
SetWithoutPathExpansion(StringPiece key,std::unique_ptr<Value> in_value)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 
SetWithoutPathExpansion(StringPiece key,Value * in_value)686 void DictionaryValue::SetWithoutPathExpansion(StringPiece key,
687                                               Value* in_value) {
688   SetWithoutPathExpansion(key, WrapUnique(in_value));
689 }
690 
SetBooleanWithoutPathExpansion(StringPiece path,bool in_value)691 void DictionaryValue::SetBooleanWithoutPathExpansion(StringPiece path,
692                                                      bool in_value) {
693   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
694 }
695 
SetIntegerWithoutPathExpansion(StringPiece path,int in_value)696 void DictionaryValue::SetIntegerWithoutPathExpansion(StringPiece path,
697                                                      int in_value) {
698   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
699 }
700 
SetDoubleWithoutPathExpansion(StringPiece path,double in_value)701 void DictionaryValue::SetDoubleWithoutPathExpansion(StringPiece path,
702                                                     double in_value) {
703   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
704 }
705 
SetStringWithoutPathExpansion(StringPiece path,StringPiece in_value)706 void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path,
707                                                     StringPiece in_value) {
708   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
709 }
710 
SetStringWithoutPathExpansion(StringPiece path,const string16 & in_value)711 void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path,
712                                                     const string16& in_value) {
713   SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
714 }
715 
Get(StringPiece path,const Value ** out_value) const716 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 
Get(StringPiece path,Value ** out_value)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 
GetBoolean(StringPiece path,bool * bool_value) const743 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 
GetInteger(StringPiece path,int * out_value) const751 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 
GetDouble(StringPiece path,double * out_value) const759 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 
GetString(StringPiece path,std::string * out_value) const767 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 
GetString(StringPiece path,string16 * out_value) const776 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 
GetStringASCII(StringPiece path,std::string * out_value) const784 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 
GetBinary(StringPiece path,const BinaryValue ** out_value) const799 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 
GetBinary(StringPiece path,BinaryValue ** out_value)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 
GetDictionary(StringPiece path,const DictionaryValue ** out_value) const818 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 
GetDictionary(StringPiece path,DictionaryValue ** out_value)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 
GetList(StringPiece path,const ListValue ** out_value) const838 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 
GetList(StringPiece path,ListValue ** out_value)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 
GetWithoutPathExpansion(StringPiece key,const Value ** out_value) const857 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 
GetWithoutPathExpansion(StringPiece key,Value ** out_value)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 
GetBooleanWithoutPathExpansion(StringPiece key,bool * out_value) const876 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 
GetIntegerWithoutPathExpansion(StringPiece key,int * out_value) const885 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 
GetDoubleWithoutPathExpansion(StringPiece key,double * out_value) const894 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 
GetStringWithoutPathExpansion(StringPiece key,std::string * out_value) const903 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 
GetStringWithoutPathExpansion(StringPiece key,string16 * out_value) const913 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 
GetDictionaryWithoutPathExpansion(StringPiece key,const DictionaryValue ** out_value) const922 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 
GetDictionaryWithoutPathExpansion(StringPiece key,DictionaryValue ** out_value)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 
GetListWithoutPathExpansion(StringPiece key,const ListValue ** out_value) const946 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 
GetListWithoutPathExpansion(StringPiece key,ListValue ** out_value)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 
Remove(StringPiece path,std::unique_ptr<Value> * out_value)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 
RemoveWithoutPathExpansion(StringPiece key,std::unique_ptr<Value> * out_value)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 
RemovePath(StringPiece path,std::unique_ptr<Value> * out_value)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 
DeepCopyWithoutEmptyChildren() const1019 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 
MergeDictionary(const DictionaryValue * dictionary)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 
Swap(DictionaryValue * other)1046 void DictionaryValue::Swap(DictionaryValue* other) {
1047   CHECK(other->is_dict());
1048   dict_ptr_->swap(*(other->dict_ptr_));
1049 }
1050 
Iterator(const DictionaryValue & target)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 
~Iterator()1056 DictionaryValue::Iterator::~Iterator() {}
1057 
DeepCopy() const1058 DictionaryValue* DictionaryValue::DeepCopy() const {
1059   return new DictionaryValue(*this);
1060 }
1061 
CreateDeepCopy() const1062 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
1063   return MakeUnique<DictionaryValue>(*this);
1064 }
1065 
1066 ///////////////////// ListValue ////////////////////
1067 
1068 // static
From(std::unique_ptr<Value> value)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 
ListValue()1078 ListValue::ListValue() : Value(Type::LIST) {}
1079 
Clear()1080 void ListValue::Clear() {
1081   list_->clear();
1082 }
1083 
Set(size_t index,Value * in_value)1084 bool ListValue::Set(size_t index, Value* in_value) {
1085   return Set(index, WrapUnique(in_value));
1086 }
1087 
Set(size_t index,std::unique_ptr<Value> in_value)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 
Get(size_t index,const Value ** out_value) const1105 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 
Get(size_t index,Value ** out_value)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 
GetBoolean(size_t index,bool * bool_value) const1121 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 
GetInteger(size_t index,int * out_value) const1129 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 
GetDouble(size_t index,double * out_value) const1137 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 
GetString(size_t index,std::string * out_value) const1145 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 
GetString(size_t index,string16 * out_value) const1153 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 
GetBinary(size_t index,const BinaryValue ** out_value) const1161 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 
GetBinary(size_t index,BinaryValue ** out_value)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 
GetDictionary(size_t index,const DictionaryValue ** out_value) const1179 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 
GetDictionary(size_t index,DictionaryValue ** out_value)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 
GetList(size_t index,const ListValue ** out_value) const1198 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 
GetList(size_t index,ListValue ** out_value)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 
Remove(size_t index,std::unique_ptr<Value> * out_value)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 
Remove(const Value & value,size_t * index)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 
Erase(iterator iter,std::unique_ptr<Value> * out_value)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 
Append(std::unique_ptr<Value> in_value)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)
Append(Value * in_value)1254 void ListValue::Append(Value* in_value) {
1255   DCHECK(in_value);
1256   Append(WrapUnique(in_value));
1257 }
1258 #endif
1259 
AppendBoolean(bool in_value)1260 void ListValue::AppendBoolean(bool in_value) {
1261   Append(MakeUnique<Value>(in_value));
1262 }
1263 
AppendInteger(int in_value)1264 void ListValue::AppendInteger(int in_value) {
1265   Append(MakeUnique<Value>(in_value));
1266 }
1267 
AppendDouble(double in_value)1268 void ListValue::AppendDouble(double in_value) {
1269   Append(MakeUnique<Value>(in_value));
1270 }
1271 
AppendString(StringPiece in_value)1272 void ListValue::AppendString(StringPiece in_value) {
1273   Append(MakeUnique<Value>(in_value));
1274 }
1275 
AppendString(const string16 & in_value)1276 void ListValue::AppendString(const string16& in_value) {
1277   Append(MakeUnique<Value>(in_value));
1278 }
1279 
AppendStrings(const std::vector<std::string> & in_values)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 
AppendStrings(const std::vector<string16> & in_values)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 
AppendIfNotPresent(std::unique_ptr<Value> in_value)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 
Insert(size_t index,std::unique_ptr<Value> in_value)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 
Find(const Value & value) const1313 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 
Swap(ListValue * other)1320 void ListValue::Swap(ListValue* other) {
1321   CHECK(other->is_list());
1322   list_->swap(*(other->list_));
1323 }
1324 
DeepCopy() const1325 ListValue* ListValue::DeepCopy() const {
1326   return new ListValue(*this);
1327 }
1328 
CreateDeepCopy() const1329 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const {
1330   return MakeUnique<ListValue>(*this);
1331 }
1332 
~ValueSerializer()1333 ValueSerializer::~ValueSerializer() {
1334 }
1335 
~ValueDeserializer()1336 ValueDeserializer::~ValueDeserializer() {
1337 }
1338 
operator <<(std::ostream & out,const Value & value)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 
operator <<(std::ostream & out,const Value::Type & type)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