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