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 // static 93 FundamentalValue* Value::CreateBooleanValue(bool in_value) { 94 return new FundamentalValue(in_value); 95 } 96 97 // static 98 FundamentalValue* Value::CreateIntegerValue(int in_value) { 99 return new FundamentalValue(in_value); 100 } 101 102 // static 103 FundamentalValue* Value::CreateDoubleValue(double in_value) { 104 return new FundamentalValue(in_value); 105 } 106 107 // static 108 StringValue* Value::CreateStringValue(const std::string& in_value) { 109 return new StringValue(in_value); 110 } 111 112 // static 113 StringValue* Value::CreateStringValue(const string16& in_value) { 114 return new StringValue(in_value); 115 } 116 117 bool Value::GetAsBoolean(bool* out_value) const { 118 return false; 119 } 120 121 bool Value::GetAsInteger(int* out_value) const { 122 return false; 123 } 124 125 bool Value::GetAsDouble(double* out_value) const { 126 return false; 127 } 128 129 bool Value::GetAsString(std::string* out_value) const { 130 return false; 131 } 132 133 bool Value::GetAsString(string16* out_value) const { 134 return false; 135 } 136 137 bool Value::GetAsList(ListValue** out_value) { 138 return false; 139 } 140 141 bool Value::GetAsList(const ListValue** out_value) const { 142 return false; 143 } 144 145 bool Value::GetAsDictionary(DictionaryValue** out_value) { 146 return false; 147 } 148 149 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { 150 return false; 151 } 152 153 Value* Value::DeepCopy() const { 154 // This method should only be getting called for null Values--all subclasses 155 // need to provide their own implementation;. 156 DCHECK(IsType(TYPE_NULL)); 157 return CreateNullValue(); 158 } 159 160 bool Value::Equals(const Value* other) const { 161 // This method should only be getting called for null Values--all subclasses 162 // need to provide their own implementation;. 163 DCHECK(IsType(TYPE_NULL)); 164 return other->IsType(TYPE_NULL); 165 } 166 167 // static 168 bool Value::Equals(const Value* a, const Value* b) { 169 if ((a == NULL) && (b == NULL)) return true; 170 if ((a == NULL) ^ (b == NULL)) return false; 171 return a->Equals(b); 172 } 173 174 Value::Value(Type type) : type_(type) {} 175 176 Value::Value(const Value& that) : type_(that.type_) {} 177 178 Value& Value::operator=(const Value& that) { 179 type_ = that.type_; 180 return *this; 181 } 182 183 ///////////////////// FundamentalValue //////////////////// 184 185 FundamentalValue::FundamentalValue(bool in_value) 186 : Value(TYPE_BOOLEAN), boolean_value_(in_value) { 187 } 188 189 FundamentalValue::FundamentalValue(int in_value) 190 : Value(TYPE_INTEGER), integer_value_(in_value) { 191 } 192 193 FundamentalValue::FundamentalValue(double in_value) 194 : Value(TYPE_DOUBLE), double_value_(in_value) { 195 if (!IsFinite(double_value_)) { 196 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) " 197 << "values cannot be represented in JSON"; 198 double_value_ = 0.0; 199 } 200 } 201 202 FundamentalValue::~FundamentalValue() { 203 } 204 205 bool FundamentalValue::GetAsBoolean(bool* out_value) const { 206 if (out_value && IsType(TYPE_BOOLEAN)) 207 *out_value = boolean_value_; 208 return (IsType(TYPE_BOOLEAN)); 209 } 210 211 bool FundamentalValue::GetAsInteger(int* out_value) const { 212 if (out_value && IsType(TYPE_INTEGER)) 213 *out_value = integer_value_; 214 return (IsType(TYPE_INTEGER)); 215 } 216 217 bool FundamentalValue::GetAsDouble(double* out_value) const { 218 if (out_value && IsType(TYPE_DOUBLE)) 219 *out_value = double_value_; 220 else if (out_value && IsType(TYPE_INTEGER)) 221 *out_value = integer_value_; 222 return (IsType(TYPE_DOUBLE) || IsType(TYPE_INTEGER)); 223 } 224 225 FundamentalValue* FundamentalValue::DeepCopy() const { 226 switch (GetType()) { 227 case TYPE_BOOLEAN: 228 return CreateBooleanValue(boolean_value_); 229 230 case TYPE_INTEGER: 231 return CreateIntegerValue(integer_value_); 232 233 case TYPE_DOUBLE: 234 return CreateDoubleValue(double_value_); 235 236 default: 237 NOTREACHED(); 238 return NULL; 239 } 240 } 241 242 bool FundamentalValue::Equals(const Value* other) const { 243 if (other->GetType() != GetType()) 244 return false; 245 246 switch (GetType()) { 247 case TYPE_BOOLEAN: { 248 bool lhs, rhs; 249 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs; 250 } 251 case TYPE_INTEGER: { 252 int lhs, rhs; 253 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs; 254 } 255 case TYPE_DOUBLE: { 256 double lhs, rhs; 257 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs; 258 } 259 default: 260 NOTREACHED(); 261 return false; 262 } 263 } 264 265 ///////////////////// StringValue //////////////////// 266 267 StringValue::StringValue(const std::string& in_value) 268 : Value(TYPE_STRING), 269 value_(in_value) { 270 DCHECK(IsStringUTF8(in_value)); 271 } 272 273 StringValue::StringValue(const string16& in_value) 274 : Value(TYPE_STRING), 275 value_(UTF16ToUTF8(in_value)) { 276 } 277 278 StringValue::~StringValue() { 279 } 280 281 bool StringValue::GetAsString(std::string* out_value) const { 282 if (out_value) 283 *out_value = value_; 284 return true; 285 } 286 287 bool StringValue::GetAsString(string16* out_value) const { 288 if (out_value) 289 *out_value = UTF8ToUTF16(value_); 290 return true; 291 } 292 293 StringValue* StringValue::DeepCopy() const { 294 return CreateStringValue(value_); 295 } 296 297 bool StringValue::Equals(const Value* other) const { 298 if (other->GetType() != GetType()) 299 return false; 300 std::string lhs, rhs; 301 return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs; 302 } 303 304 ///////////////////// BinaryValue //////////////////// 305 306 BinaryValue::BinaryValue() 307 : Value(TYPE_BINARY), 308 size_(0) { 309 } 310 311 BinaryValue::BinaryValue(scoped_ptr<char[]> buffer, size_t size) 312 : Value(TYPE_BINARY), 313 buffer_(buffer.Pass()), 314 size_(size) { 315 } 316 317 BinaryValue::~BinaryValue() { 318 } 319 320 // static 321 BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer, 322 size_t size) { 323 char* buffer_copy = new char[size]; 324 memcpy(buffer_copy, buffer, size); 325 scoped_ptr<char[]> scoped_buffer_copy(buffer_copy); 326 return new BinaryValue(scoped_buffer_copy.Pass(), size); 327 } 328 329 BinaryValue* BinaryValue::DeepCopy() const { 330 return CreateWithCopiedBuffer(buffer_.get(), size_); 331 } 332 333 bool BinaryValue::Equals(const Value* other) const { 334 if (other->GetType() != GetType()) 335 return false; 336 const BinaryValue* other_binary = static_cast<const BinaryValue*>(other); 337 if (other_binary->size_ != size_) 338 return false; 339 return !memcmp(GetBuffer(), other_binary->GetBuffer(), size_); 340 } 341 342 ///////////////////// DictionaryValue //////////////////// 343 344 DictionaryValue::DictionaryValue() 345 : Value(TYPE_DICTIONARY) { 346 } 347 348 DictionaryValue::~DictionaryValue() { 349 Clear(); 350 } 351 352 bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) { 353 if (out_value) 354 *out_value = this; 355 return true; 356 } 357 358 bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const { 359 if (out_value) 360 *out_value = this; 361 return true; 362 } 363 364 bool DictionaryValue::HasKey(const std::string& key) const { 365 DCHECK(IsStringUTF8(key)); 366 ValueMap::const_iterator current_entry = dictionary_.find(key); 367 DCHECK((current_entry == dictionary_.end()) || current_entry->second); 368 return current_entry != dictionary_.end(); 369 } 370 371 void DictionaryValue::Clear() { 372 ValueMap::iterator dict_iterator = dictionary_.begin(); 373 while (dict_iterator != dictionary_.end()) { 374 delete dict_iterator->second; 375 ++dict_iterator; 376 } 377 378 dictionary_.clear(); 379 } 380 381 void DictionaryValue::Set(const std::string& path, Value* in_value) { 382 DCHECK(IsStringUTF8(path)); 383 DCHECK(in_value); 384 385 std::string current_path(path); 386 DictionaryValue* current_dictionary = this; 387 for (size_t delimiter_position = current_path.find('.'); 388 delimiter_position != std::string::npos; 389 delimiter_position = current_path.find('.')) { 390 // Assume that we're indexing into a dictionary. 391 std::string key(current_path, 0, delimiter_position); 392 DictionaryValue* child_dictionary = NULL; 393 if (!current_dictionary->GetDictionary(key, &child_dictionary)) { 394 child_dictionary = new DictionaryValue; 395 current_dictionary->SetWithoutPathExpansion(key, child_dictionary); 396 } 397 398 current_dictionary = child_dictionary; 399 current_path.erase(0, delimiter_position + 1); 400 } 401 402 current_dictionary->SetWithoutPathExpansion(current_path, in_value); 403 } 404 405 void DictionaryValue::SetBoolean(const std::string& path, bool in_value) { 406 Set(path, CreateBooleanValue(in_value)); 407 } 408 409 void DictionaryValue::SetInteger(const std::string& path, int in_value) { 410 Set(path, CreateIntegerValue(in_value)); 411 } 412 413 void DictionaryValue::SetDouble(const std::string& path, double in_value) { 414 Set(path, CreateDoubleValue(in_value)); 415 } 416 417 void DictionaryValue::SetString(const std::string& path, 418 const std::string& in_value) { 419 Set(path, CreateStringValue(in_value)); 420 } 421 422 void DictionaryValue::SetString(const std::string& path, 423 const string16& in_value) { 424 Set(path, CreateStringValue(in_value)); 425 } 426 427 void DictionaryValue::SetWithoutPathExpansion(const std::string& key, 428 Value* in_value) { 429 // If there's an existing value here, we need to delete it, because 430 // we own all our children. 431 std::pair<ValueMap::iterator, bool> ins_res = 432 dictionary_.insert(std::make_pair(key, in_value)); 433 if (!ins_res.second) { 434 DCHECK_NE(ins_res.first->second, in_value); // This would be bogus 435 delete ins_res.first->second; 436 ins_res.first->second = in_value; 437 } 438 } 439 440 void DictionaryValue::SetBooleanWithoutPathExpansion( 441 const std::string& path, bool in_value) { 442 SetWithoutPathExpansion(path, CreateBooleanValue(in_value)); 443 } 444 445 void DictionaryValue::SetIntegerWithoutPathExpansion( 446 const std::string& path, int in_value) { 447 SetWithoutPathExpansion(path, CreateIntegerValue(in_value)); 448 } 449 450 void DictionaryValue::SetDoubleWithoutPathExpansion( 451 const std::string& path, double in_value) { 452 SetWithoutPathExpansion(path, CreateDoubleValue(in_value)); 453 } 454 455 void DictionaryValue::SetStringWithoutPathExpansion( 456 const std::string& path, const std::string& in_value) { 457 SetWithoutPathExpansion(path, CreateStringValue(in_value)); 458 } 459 460 void DictionaryValue::SetStringWithoutPathExpansion( 461 const std::string& path, const string16& in_value) { 462 SetWithoutPathExpansion(path, CreateStringValue(in_value)); 463 } 464 465 bool DictionaryValue::Get(const std::string& path, 466 const Value** out_value) const { 467 DCHECK(IsStringUTF8(path)); 468 std::string current_path(path); 469 const DictionaryValue* current_dictionary = this; 470 for (size_t delimiter_position = current_path.find('.'); 471 delimiter_position != std::string::npos; 472 delimiter_position = current_path.find('.')) { 473 const DictionaryValue* child_dictionary = NULL; 474 if (!current_dictionary->GetDictionary( 475 current_path.substr(0, delimiter_position), &child_dictionary)) 476 return false; 477 478 current_dictionary = child_dictionary; 479 current_path.erase(0, delimiter_position + 1); 480 } 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 bool DictionaryValue::RemovePath(const std::string& path, 756 scoped_ptr<Value>* out_value) { 757 bool result = false; 758 size_t delimiter_position = path.find('.'); 759 760 if (delimiter_position == std::string::npos) 761 return RemoveWithoutPathExpansion(path, out_value); 762 763 const std::string subdict_path = path.substr(0, delimiter_position); 764 DictionaryValue* subdict = NULL; 765 if (!GetDictionary(subdict_path, &subdict)) 766 return false; 767 result = subdict->RemovePath(path.substr(delimiter_position + 1), 768 out_value); 769 if (result && subdict->empty()) 770 RemoveWithoutPathExpansion(subdict_path, NULL); 771 772 return result; 773 } 774 775 DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() const { 776 Value* copy = CopyWithoutEmptyChildren(this); 777 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue; 778 } 779 780 void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) { 781 for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) { 782 const Value* merge_value = &it.value(); 783 // Check whether we have to merge dictionaries. 784 if (merge_value->IsType(Value::TYPE_DICTIONARY)) { 785 DictionaryValue* sub_dict; 786 if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) { 787 sub_dict->MergeDictionary( 788 static_cast<const DictionaryValue*>(merge_value)); 789 continue; 790 } 791 } 792 // All other cases: Make a copy and hook it up. 793 SetWithoutPathExpansion(it.key(), merge_value->DeepCopy()); 794 } 795 } 796 797 void DictionaryValue::Swap(DictionaryValue* other) { 798 dictionary_.swap(other->dictionary_); 799 } 800 801 DictionaryValue::Iterator::Iterator(const DictionaryValue& target) 802 : target_(target), 803 it_(target.dictionary_.begin()) {} 804 805 DictionaryValue::Iterator::~Iterator() {} 806 807 DictionaryValue* DictionaryValue::DeepCopy() const { 808 DictionaryValue* result = new DictionaryValue; 809 810 for (ValueMap::const_iterator current_entry(dictionary_.begin()); 811 current_entry != dictionary_.end(); ++current_entry) { 812 result->SetWithoutPathExpansion(current_entry->first, 813 current_entry->second->DeepCopy()); 814 } 815 816 return result; 817 } 818 819 bool DictionaryValue::Equals(const Value* other) const { 820 if (other->GetType() != GetType()) 821 return false; 822 823 const DictionaryValue* other_dict = 824 static_cast<const DictionaryValue*>(other); 825 Iterator lhs_it(*this); 826 Iterator rhs_it(*other_dict); 827 while (!lhs_it.IsAtEnd() && !rhs_it.IsAtEnd()) { 828 if (lhs_it.key() != rhs_it.key() || 829 !lhs_it.value().Equals(&rhs_it.value())) { 830 return false; 831 } 832 lhs_it.Advance(); 833 rhs_it.Advance(); 834 } 835 if (!lhs_it.IsAtEnd() || !rhs_it.IsAtEnd()) 836 return false; 837 838 return true; 839 } 840 841 ///////////////////// ListValue //////////////////// 842 843 ListValue::ListValue() : Value(TYPE_LIST) { 844 } 845 846 ListValue::~ListValue() { 847 Clear(); 848 } 849 850 void ListValue::Clear() { 851 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) 852 delete *i; 853 list_.clear(); 854 } 855 856 bool ListValue::Set(size_t index, Value* in_value) { 857 if (!in_value) 858 return false; 859 860 if (index >= list_.size()) { 861 // Pad out any intermediate indexes with null settings 862 while (index > list_.size()) 863 Append(CreateNullValue()); 864 Append(in_value); 865 } else { 866 DCHECK(list_[index] != in_value); 867 delete list_[index]; 868 list_[index] = in_value; 869 } 870 return true; 871 } 872 873 bool ListValue::Get(size_t index, const Value** out_value) const { 874 if (index >= list_.size()) 875 return false; 876 877 if (out_value) 878 *out_value = list_[index]; 879 880 return true; 881 } 882 883 bool ListValue::Get(size_t index, Value** out_value) { 884 return static_cast<const ListValue&>(*this).Get( 885 index, 886 const_cast<const Value**>(out_value)); 887 } 888 889 bool ListValue::GetBoolean(size_t index, bool* bool_value) const { 890 const Value* value; 891 if (!Get(index, &value)) 892 return false; 893 894 return value->GetAsBoolean(bool_value); 895 } 896 897 bool ListValue::GetInteger(size_t index, int* out_value) const { 898 const Value* value; 899 if (!Get(index, &value)) 900 return false; 901 902 return value->GetAsInteger(out_value); 903 } 904 905 bool ListValue::GetDouble(size_t index, double* out_value) const { 906 const Value* value; 907 if (!Get(index, &value)) 908 return false; 909 910 return value->GetAsDouble(out_value); 911 } 912 913 bool ListValue::GetString(size_t index, std::string* out_value) const { 914 const Value* value; 915 if (!Get(index, &value)) 916 return false; 917 918 return value->GetAsString(out_value); 919 } 920 921 bool ListValue::GetString(size_t index, string16* out_value) const { 922 const Value* value; 923 if (!Get(index, &value)) 924 return false; 925 926 return value->GetAsString(out_value); 927 } 928 929 bool ListValue::GetBinary(size_t index, const BinaryValue** out_value) const { 930 const Value* value; 931 bool result = Get(index, &value); 932 if (!result || !value->IsType(TYPE_BINARY)) 933 return false; 934 935 if (out_value) 936 *out_value = static_cast<const BinaryValue*>(value); 937 938 return true; 939 } 940 941 bool ListValue::GetBinary(size_t index, BinaryValue** out_value) { 942 return static_cast<const ListValue&>(*this).GetBinary( 943 index, 944 const_cast<const BinaryValue**>(out_value)); 945 } 946 947 bool ListValue::GetDictionary(size_t index, 948 const DictionaryValue** out_value) const { 949 const Value* value; 950 bool result = Get(index, &value); 951 if (!result || !value->IsType(TYPE_DICTIONARY)) 952 return false; 953 954 if (out_value) 955 *out_value = static_cast<const DictionaryValue*>(value); 956 957 return true; 958 } 959 960 bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) { 961 return static_cast<const ListValue&>(*this).GetDictionary( 962 index, 963 const_cast<const DictionaryValue**>(out_value)); 964 } 965 966 bool ListValue::GetList(size_t index, const ListValue** out_value) const { 967 const Value* value; 968 bool result = Get(index, &value); 969 if (!result || !value->IsType(TYPE_LIST)) 970 return false; 971 972 if (out_value) 973 *out_value = static_cast<const ListValue*>(value); 974 975 return true; 976 } 977 978 bool ListValue::GetList(size_t index, ListValue** out_value) { 979 return static_cast<const ListValue&>(*this).GetList( 980 index, 981 const_cast<const ListValue**>(out_value)); 982 } 983 984 bool ListValue::Remove(size_t index, scoped_ptr<Value>* out_value) { 985 if (index >= list_.size()) 986 return false; 987 988 if (out_value) 989 out_value->reset(list_[index]); 990 else 991 delete list_[index]; 992 993 list_.erase(list_.begin() + index); 994 return true; 995 } 996 997 bool ListValue::Remove(const Value& value, size_t* index) { 998 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) { 999 if ((*i)->Equals(&value)) { 1000 size_t previous_index = i - list_.begin(); 1001 delete *i; 1002 list_.erase(i); 1003 1004 if (index) 1005 *index = previous_index; 1006 return true; 1007 } 1008 } 1009 return false; 1010 } 1011 1012 ListValue::iterator ListValue::Erase(iterator iter, 1013 scoped_ptr<Value>* out_value) { 1014 if (out_value) 1015 out_value->reset(*iter); 1016 else 1017 delete *iter; 1018 1019 return list_.erase(iter); 1020 } 1021 1022 void ListValue::Append(Value* in_value) { 1023 DCHECK(in_value); 1024 list_.push_back(in_value); 1025 } 1026 1027 void ListValue::AppendBoolean(bool in_value) { 1028 Append(CreateBooleanValue(in_value)); 1029 } 1030 1031 void ListValue::AppendInteger(int in_value) { 1032 Append(CreateIntegerValue(in_value)); 1033 } 1034 1035 void ListValue::AppendDouble(double in_value) { 1036 Append(CreateDoubleValue(in_value)); 1037 } 1038 1039 void ListValue::AppendString(const std::string& in_value) { 1040 Append(CreateStringValue(in_value)); 1041 } 1042 1043 void ListValue::AppendString(const string16& in_value) { 1044 Append(CreateStringValue(in_value)); 1045 } 1046 1047 void ListValue::AppendStrings(const std::vector<std::string>& in_values) { 1048 for (std::vector<std::string>::const_iterator it = in_values.begin(); 1049 it != in_values.end(); ++it) { 1050 AppendString(*it); 1051 } 1052 } 1053 1054 void ListValue::AppendStrings(const std::vector<string16>& in_values) { 1055 for (std::vector<string16>::const_iterator it = in_values.begin(); 1056 it != in_values.end(); ++it) { 1057 AppendString(*it); 1058 } 1059 } 1060 1061 bool ListValue::AppendIfNotPresent(Value* in_value) { 1062 DCHECK(in_value); 1063 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) { 1064 if ((*i)->Equals(in_value)) { 1065 delete in_value; 1066 return false; 1067 } 1068 } 1069 list_.push_back(in_value); 1070 return true; 1071 } 1072 1073 bool ListValue::Insert(size_t index, Value* in_value) { 1074 DCHECK(in_value); 1075 if (index > list_.size()) 1076 return false; 1077 1078 list_.insert(list_.begin() + index, in_value); 1079 return true; 1080 } 1081 1082 ListValue::const_iterator ListValue::Find(const Value& value) const { 1083 return std::find_if(list_.begin(), list_.end(), ValueEquals(&value)); 1084 } 1085 1086 void ListValue::Swap(ListValue* other) { 1087 list_.swap(other->list_); 1088 } 1089 1090 bool ListValue::GetAsList(ListValue** out_value) { 1091 if (out_value) 1092 *out_value = this; 1093 return true; 1094 } 1095 1096 bool ListValue::GetAsList(const ListValue** out_value) const { 1097 if (out_value) 1098 *out_value = this; 1099 return true; 1100 } 1101 1102 ListValue* ListValue::DeepCopy() const { 1103 ListValue* result = new ListValue; 1104 1105 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) 1106 result->Append((*i)->DeepCopy()); 1107 1108 return result; 1109 } 1110 1111 bool ListValue::Equals(const Value* other) const { 1112 if (other->GetType() != GetType()) 1113 return false; 1114 1115 const ListValue* other_list = 1116 static_cast<const ListValue*>(other); 1117 const_iterator lhs_it, rhs_it; 1118 for (lhs_it = begin(), rhs_it = other_list->begin(); 1119 lhs_it != end() && rhs_it != other_list->end(); 1120 ++lhs_it, ++rhs_it) { 1121 if (!(*lhs_it)->Equals(*rhs_it)) 1122 return false; 1123 } 1124 if (lhs_it != end() || rhs_it != other_list->end()) 1125 return false; 1126 1127 return true; 1128 } 1129 1130 ValueSerializer::~ValueSerializer() { 1131 } 1132 1133 std::ostream& operator<<(std::ostream& out, const Value& value) { 1134 std::string json; 1135 JSONWriter::WriteWithOptions(&value, 1136 JSONWriter::OPTIONS_PRETTY_PRINT, 1137 &json); 1138 return out << json; 1139 } 1140 1141 } // namespace base 1142