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