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