values.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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 19namespace base { 20 21namespace { 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. 26Value* 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. 67class 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 84Value::~Value() { 85} 86 87// static 88Value* Value::CreateNullValue() { 89 return new Value(TYPE_NULL); 90} 91 92bool Value::GetAsBoolean(bool* out_value) const { 93 return false; 94} 95 96bool Value::GetAsInteger(int* out_value) const { 97 return false; 98} 99 100bool Value::GetAsDouble(double* out_value) const { 101 return false; 102} 103 104bool Value::GetAsString(std::string* out_value) const { 105 return false; 106} 107 108bool Value::GetAsString(string16* out_value) const { 109 return false; 110} 111 112bool Value::GetAsString(const StringValue** out_value) const { 113 return false; 114} 115 116bool Value::GetAsList(ListValue** out_value) { 117 return false; 118} 119 120bool Value::GetAsList(const ListValue** out_value) const { 121 return false; 122} 123 124bool Value::GetAsDictionary(DictionaryValue** out_value) { 125 return false; 126} 127 128bool Value::GetAsDictionary(const DictionaryValue** out_value) const { 129 return false; 130} 131 132Value* 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 139bool 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 147bool 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 153Value::Value(Type type) : type_(type) {} 154 155Value::Value(const Value& that) : type_(that.type_) {} 156 157Value& Value::operator=(const Value& that) { 158 type_ = that.type_; 159 return *this; 160} 161 162///////////////////// FundamentalValue //////////////////// 163 164FundamentalValue::FundamentalValue(bool in_value) 165 : Value(TYPE_BOOLEAN), boolean_value_(in_value) { 166} 167 168FundamentalValue::FundamentalValue(int in_value) 169 : Value(TYPE_INTEGER), integer_value_(in_value) { 170} 171 172FundamentalValue::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 181FundamentalValue::~FundamentalValue() { 182} 183 184bool 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 190bool 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 196bool 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 204FundamentalValue* 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 221bool 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 246StringValue::StringValue(const std::string& in_value) 247 : Value(TYPE_STRING), 248 value_(in_value) { 249 DCHECK(IsStringUTF8(in_value)); 250} 251 252StringValue::StringValue(const string16& in_value) 253 : Value(TYPE_STRING), 254 value_(UTF16ToUTF8(in_value)) { 255} 256 257StringValue::~StringValue() { 258} 259 260std::string* StringValue::GetString() { 261 return &value_; 262} 263 264const std::string& StringValue::GetString() const { 265 return value_; 266} 267 268bool StringValue::GetAsString(std::string* out_value) const { 269 if (out_value) 270 *out_value = value_; 271 return true; 272} 273 274bool StringValue::GetAsString(string16* out_value) const { 275 if (out_value) 276 *out_value = UTF8ToUTF16(value_); 277 return true; 278} 279 280bool StringValue::GetAsString(const StringValue** out_value) const { 281 if (out_value) 282 *out_value = this; 283 return true; 284} 285 286StringValue* StringValue::DeepCopy() const { 287 return new StringValue(value_); 288} 289 290bool 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 299BinaryValue::BinaryValue() 300 : Value(TYPE_BINARY), 301 size_(0) { 302} 303 304BinaryValue::BinaryValue(scoped_ptr<char[]> buffer, size_t size) 305 : Value(TYPE_BINARY), 306 buffer_(buffer.Pass()), 307 size_(size) { 308} 309 310BinaryValue::~BinaryValue() { 311} 312 313// static 314BinaryValue* 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 322BinaryValue* BinaryValue::DeepCopy() const { 323 return CreateWithCopiedBuffer(buffer_.get(), size_); 324} 325 326bool 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 337DictionaryValue::DictionaryValue() 338 : Value(TYPE_DICTIONARY) { 339} 340 341DictionaryValue::~DictionaryValue() { 342 Clear(); 343} 344 345bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) { 346 if (out_value) 347 *out_value = this; 348 return true; 349} 350 351bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const { 352 if (out_value) 353 *out_value = this; 354 return true; 355} 356 357bool 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 364void 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 374void 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 398void DictionaryValue::SetBoolean(const std::string& path, bool in_value) { 399 Set(path, new FundamentalValue(in_value)); 400} 401 402void DictionaryValue::SetInteger(const std::string& path, int in_value) { 403 Set(path, new FundamentalValue(in_value)); 404} 405 406void DictionaryValue::SetDouble(const std::string& path, double in_value) { 407 Set(path, new FundamentalValue(in_value)); 408} 409 410void DictionaryValue::SetString(const std::string& path, 411 const std::string& in_value) { 412 Set(path, new StringValue(in_value)); 413} 414 415void DictionaryValue::SetString(const std::string& path, 416 const string16& in_value) { 417 Set(path, new StringValue(in_value)); 418} 419 420void 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 433void DictionaryValue::SetBooleanWithoutPathExpansion( 434 const std::string& path, bool in_value) { 435 SetWithoutPathExpansion(path, new FundamentalValue(in_value)); 436} 437 438void DictionaryValue::SetIntegerWithoutPathExpansion( 439 const std::string& path, int in_value) { 440 SetWithoutPathExpansion(path, new FundamentalValue(in_value)); 441} 442 443void DictionaryValue::SetDoubleWithoutPathExpansion( 444 const std::string& path, double in_value) { 445 SetWithoutPathExpansion(path, new FundamentalValue(in_value)); 446} 447 448void DictionaryValue::SetStringWithoutPathExpansion( 449 const std::string& path, const std::string& in_value) { 450 SetWithoutPathExpansion(path, new StringValue(in_value)); 451} 452 453void DictionaryValue::SetStringWithoutPathExpansion( 454 const std::string& path, const string16& in_value) { 455 SetWithoutPathExpansion(path, new StringValue(in_value)); 456} 457 458bool 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 478bool 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 484bool 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 493bool 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 502bool 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 511bool 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 520bool 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 529bool 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 544bool 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 557bool 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 564bool 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 577bool 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 584bool 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 597bool 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 603bool 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 616bool 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 623bool 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 632bool 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 641bool 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 650bool 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 660bool 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 669bool 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 683bool 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 693bool 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 707bool 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 715bool 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 732bool 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 748bool 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 768DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() const { 769 Value* copy = CopyWithoutEmptyChildren(this); 770 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue; 771} 772 773void 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 790void DictionaryValue::Swap(DictionaryValue* other) { 791 dictionary_.swap(other->dictionary_); 792} 793 794DictionaryValue::Iterator::Iterator(const DictionaryValue& target) 795 : target_(target), 796 it_(target.dictionary_.begin()) {} 797 798DictionaryValue::Iterator::~Iterator() {} 799 800DictionaryValue* 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 812bool 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 836ListValue::ListValue() : Value(TYPE_LIST) { 837} 838 839ListValue::~ListValue() { 840 Clear(); 841} 842 843void ListValue::Clear() { 844 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) 845 delete *i; 846 list_.clear(); 847} 848 849bool 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 866bool 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 876bool 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 882bool 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 890bool 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 898bool 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 906bool 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 914bool 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 922bool 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 934bool 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 940bool 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 953bool 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 959bool 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 971bool 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 977bool 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 990bool 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 1005ListValue::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 1015void ListValue::Append(Value* in_value) { 1016 DCHECK(in_value); 1017 list_.push_back(in_value); 1018} 1019 1020void ListValue::AppendBoolean(bool in_value) { 1021 Append(new FundamentalValue(in_value)); 1022} 1023 1024void ListValue::AppendInteger(int in_value) { 1025 Append(new FundamentalValue(in_value)); 1026} 1027 1028void ListValue::AppendDouble(double in_value) { 1029 Append(new FundamentalValue(in_value)); 1030} 1031 1032void ListValue::AppendString(const std::string& in_value) { 1033 Append(new StringValue(in_value)); 1034} 1035 1036void ListValue::AppendString(const string16& in_value) { 1037 Append(new StringValue(in_value)); 1038} 1039 1040void 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 1047void 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 1054bool 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 1066bool 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 1075ListValue::const_iterator ListValue::Find(const Value& value) const { 1076 return std::find_if(list_.begin(), list_.end(), ValueEquals(&value)); 1077} 1078 1079void ListValue::Swap(ListValue* other) { 1080 list_.swap(other->list_); 1081} 1082 1083bool ListValue::GetAsList(ListValue** out_value) { 1084 if (out_value) 1085 *out_value = this; 1086 return true; 1087} 1088 1089bool ListValue::GetAsList(const ListValue** out_value) const { 1090 if (out_value) 1091 *out_value = this; 1092 return true; 1093} 1094 1095ListValue* 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 1104bool 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 1123ValueSerializer::~ValueSerializer() { 1124} 1125 1126std::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