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