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