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