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