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