values.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2010 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 "base/logging.h" 8#include "base/string_util.h" 9#include "base/utf_string_conversions.h" 10 11namespace { 12 13// Make a deep copy of |node|, but don't include empty lists or dictionaries 14// in the copy. It's possible for this function to return NULL and it 15// expects |node| to always be non-NULL. 16Value* CopyWithoutEmptyChildren(Value* node) { 17 DCHECK(node); 18 switch (node->GetType()) { 19 case Value::TYPE_LIST: { 20 ListValue* list = static_cast<ListValue*>(node); 21 ListValue* copy = new ListValue; 22 for (ListValue::const_iterator it = list->begin(); it != list->end(); 23 ++it) { 24 Value* child_copy = CopyWithoutEmptyChildren(*it); 25 if (child_copy) 26 copy->Append(child_copy); 27 } 28 if (!copy->empty()) 29 return copy; 30 31 delete copy; 32 return NULL; 33 } 34 35 case Value::TYPE_DICTIONARY: { 36 DictionaryValue* dict = static_cast<DictionaryValue*>(node); 37 DictionaryValue* copy = new DictionaryValue; 38 for (DictionaryValue::key_iterator it = dict->begin_keys(); 39 it != dict->end_keys(); ++it) { 40 Value* child = NULL; 41 bool rv = dict->GetWithoutPathExpansion(*it, &child); 42 DCHECK(rv); 43 Value* child_copy = CopyWithoutEmptyChildren(child); 44 if (child_copy) 45 copy->SetWithoutPathExpansion(*it, child_copy); 46 } 47 if (!copy->empty()) 48 return copy; 49 50 delete copy; 51 return NULL; 52 } 53 54 default: 55 // For everything else, just make a copy. 56 return node->DeepCopy(); 57 } 58} 59 60} // namespace 61 62///////////////////// Value //////////////////// 63 64Value::~Value() { 65} 66 67// static 68Value* Value::CreateNullValue() { 69 return new Value(TYPE_NULL); 70} 71 72// static 73Value* Value::CreateBooleanValue(bool in_value) { 74 return new FundamentalValue(in_value); 75} 76 77// static 78Value* Value::CreateIntegerValue(int in_value) { 79 return new FundamentalValue(in_value); 80} 81 82// static 83Value* Value::CreateRealValue(double in_value) { 84 return new FundamentalValue(in_value); 85} 86 87// static 88Value* Value::CreateStringValue(const std::string& in_value) { 89 return new StringValue(in_value); 90} 91 92// static 93Value* Value::CreateStringValue(const std::wstring& in_value) { 94 return new StringValue(in_value); 95} 96 97// static 98Value* Value::CreateStringValueFromUTF16(const string16& in_value) { 99 return new StringValue(in_value); 100} 101 102// static 103BinaryValue* Value::CreateBinaryValue(char* buffer, size_t size) { 104 return BinaryValue::Create(buffer, size); 105} 106 107bool Value::GetAsBoolean(bool* in_value) const { 108 return false; 109} 110 111bool Value::GetAsInteger(int* in_value) const { 112 return false; 113} 114 115bool Value::GetAsReal(double* in_value) const { 116 return false; 117} 118 119bool Value::GetAsString(std::string* in_value) const { 120 return false; 121} 122 123bool Value::GetAsString(std::wstring* in_value) const { 124 return false; 125} 126 127bool Value::GetAsUTF16(string16* out_value) const { 128 return false; 129} 130 131Value* Value::DeepCopy() const { 132 // This method should only be getting called for null Values--all subclasses 133 // need to provide their own implementation;. 134 DCHECK(IsType(TYPE_NULL)); 135 return CreateNullValue(); 136} 137 138bool Value::Equals(const Value* other) const { 139 // This method should only be getting called for null Values--all subclasses 140 // need to provide their own implementation;. 141 DCHECK(IsType(TYPE_NULL)); 142 return other->IsType(TYPE_NULL); 143} 144 145Value::Value(ValueType type) : type_(type) { 146} 147 148///////////////////// FundamentalValue //////////////////// 149 150FundamentalValue::FundamentalValue(bool in_value) 151 : Value(TYPE_BOOLEAN), boolean_value_(in_value) { 152} 153 154FundamentalValue::FundamentalValue(int in_value) 155 : Value(TYPE_INTEGER), integer_value_(in_value) { 156} 157 158FundamentalValue::FundamentalValue(double in_value) 159 : Value(TYPE_REAL), real_value_(in_value) { 160} 161 162FundamentalValue::~FundamentalValue() { 163} 164 165bool FundamentalValue::GetAsBoolean(bool* out_value) const { 166 if (out_value && IsType(TYPE_BOOLEAN)) 167 *out_value = boolean_value_; 168 return (IsType(TYPE_BOOLEAN)); 169} 170 171bool FundamentalValue::GetAsInteger(int* out_value) const { 172 if (out_value && IsType(TYPE_INTEGER)) 173 *out_value = integer_value_; 174 return (IsType(TYPE_INTEGER)); 175} 176 177bool FundamentalValue::GetAsReal(double* out_value) const { 178 if (out_value && IsType(TYPE_REAL)) 179 *out_value = real_value_; 180 return (IsType(TYPE_REAL)); 181} 182 183Value* FundamentalValue::DeepCopy() const { 184 switch (GetType()) { 185 case TYPE_BOOLEAN: 186 return CreateBooleanValue(boolean_value_); 187 188 case TYPE_INTEGER: 189 return CreateIntegerValue(integer_value_); 190 191 case TYPE_REAL: 192 return CreateRealValue(real_value_); 193 194 default: 195 NOTREACHED(); 196 return NULL; 197 } 198} 199 200bool FundamentalValue::Equals(const Value* other) const { 201 if (other->GetType() != GetType()) 202 return false; 203 204 switch (GetType()) { 205 case TYPE_BOOLEAN: { 206 bool lhs, rhs; 207 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs; 208 } 209 case TYPE_INTEGER: { 210 int lhs, rhs; 211 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs; 212 } 213 case TYPE_REAL: { 214 double lhs, rhs; 215 return GetAsReal(&lhs) && other->GetAsReal(&rhs) && lhs == rhs; 216 } 217 default: 218 NOTREACHED(); 219 return false; 220 } 221} 222 223///////////////////// StringValue //////////////////// 224 225StringValue::StringValue(const std::string& in_value) 226 : Value(TYPE_STRING), 227 value_(in_value) { 228 DCHECK(IsStringUTF8(in_value)); 229} 230 231StringValue::StringValue(const std::wstring& in_value) 232 : Value(TYPE_STRING), 233 value_(WideToUTF8(in_value)) { 234} 235 236#if !defined(WCHAR_T_IS_UTF16) 237StringValue::StringValue(const string16& in_value) 238 : Value(TYPE_STRING), 239 value_(UTF16ToUTF8(in_value)) { 240} 241#endif 242 243StringValue::~StringValue() { 244} 245 246bool StringValue::GetAsString(std::string* out_value) const { 247 if (out_value) 248 *out_value = value_; 249 return true; 250} 251 252bool StringValue::GetAsString(std::wstring* out_value) const { 253 if (out_value) 254 *out_value = UTF8ToWide(value_); 255 return true; 256} 257 258bool StringValue::GetAsUTF16(string16* out_value) const { 259 if (out_value) 260 *out_value = UTF8ToUTF16(value_); 261 return true; 262} 263 264Value* StringValue::DeepCopy() const { 265 return CreateStringValue(value_); 266} 267 268bool StringValue::Equals(const Value* other) const { 269 if (other->GetType() != GetType()) 270 return false; 271 std::string lhs, rhs; 272 return GetAsString(&lhs) && other->GetAsString(&rhs) && lhs == rhs; 273} 274 275///////////////////// BinaryValue //////////////////// 276 277// static 278BinaryValue* BinaryValue::Create(char* buffer, size_t size) { 279 if (!buffer) 280 return NULL; 281 282 return new BinaryValue(buffer, size); 283} 284 285// static 286BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer, 287 size_t size) { 288 if (!buffer) 289 return NULL; 290 291 char* buffer_copy = new char[size]; 292 memcpy(buffer_copy, buffer, size); 293 return new BinaryValue(buffer_copy, size); 294} 295 296 297BinaryValue::BinaryValue(char* buffer, size_t size) 298 : Value(TYPE_BINARY), 299 buffer_(buffer), 300 size_(size) { 301 DCHECK(buffer_); 302} 303 304BinaryValue::~BinaryValue() { 305 DCHECK(buffer_); 306 if (buffer_) 307 delete[] buffer_; 308} 309 310Value* BinaryValue::DeepCopy() const { 311 return CreateWithCopiedBuffer(buffer_, size_); 312} 313 314bool BinaryValue::Equals(const Value* other) const { 315 if (other->GetType() != GetType()) 316 return false; 317 const BinaryValue* other_binary = static_cast<const BinaryValue*>(other); 318 if (other_binary->size_ != size_) 319 return false; 320 return !memcmp(buffer_, other_binary->buffer_, size_); 321} 322 323///////////////////// DictionaryValue //////////////////// 324 325DictionaryValue::DictionaryValue() 326 : Value(TYPE_DICTIONARY) { 327} 328 329DictionaryValue::~DictionaryValue() { 330 Clear(); 331} 332 333Value* DictionaryValue::DeepCopy() const { 334 DictionaryValue* result = new DictionaryValue; 335 336 for (ValueMap::const_iterator current_entry(dictionary_.begin()); 337 current_entry != dictionary_.end(); ++current_entry) { 338 result->SetWithoutPathExpansion(current_entry->first, 339 current_entry->second->DeepCopy()); 340 } 341 342 return result; 343} 344 345bool DictionaryValue::Equals(const Value* other) const { 346 if (other->GetType() != GetType()) 347 return false; 348 349 const DictionaryValue* other_dict = 350 static_cast<const DictionaryValue*>(other); 351 key_iterator lhs_it(begin_keys()); 352 key_iterator rhs_it(other_dict->begin_keys()); 353 while (lhs_it != end_keys() && rhs_it != other_dict->end_keys()) { 354 Value* lhs; 355 Value* rhs; 356 if (!GetWithoutPathExpansion(*lhs_it, &lhs) || 357 !other_dict->GetWithoutPathExpansion(*rhs_it, &rhs) || 358 !lhs->Equals(rhs)) { 359 return false; 360 } 361 ++lhs_it; 362 ++rhs_it; 363 } 364 if (lhs_it != end_keys() || rhs_it != other_dict->end_keys()) 365 return false; 366 367 return true; 368} 369 370bool DictionaryValue::HasKey(const std::wstring& key) const { 371 ValueMap::const_iterator current_entry = dictionary_.find(key); 372 DCHECK((current_entry == dictionary_.end()) || current_entry->second); 373 return current_entry != dictionary_.end(); 374} 375 376bool DictionaryValue::HasKeyASCII(const std::string& key) const { 377 return HasKey(ASCIIToWide(key)); 378} 379 380void DictionaryValue::Clear() { 381 ValueMap::iterator dict_iterator = dictionary_.begin(); 382 while (dict_iterator != dictionary_.end()) { 383 delete dict_iterator->second; 384 ++dict_iterator; 385 } 386 387 dictionary_.clear(); 388} 389 390void DictionaryValue::Set(const std::wstring& path, Value* in_value) { 391 DCHECK(in_value); 392 393 std::wstring current_path(path); 394 DictionaryValue* current_dictionary = this; 395 for (size_t delimiter_position = current_path.find('.'); 396 delimiter_position != std::wstring::npos; 397 delimiter_position = current_path.find('.')) { 398 // Assume that we're indexing into a dictionary. 399 std::wstring key(current_path, 0, delimiter_position); 400 DictionaryValue* child_dictionary = NULL; 401 if (!current_dictionary->GetDictionary(key, &child_dictionary)) { 402 child_dictionary = new DictionaryValue; 403 current_dictionary->SetWithoutPathExpansion(key, child_dictionary); 404 } 405 406 current_dictionary = child_dictionary; 407 current_path.erase(0, delimiter_position + 1); 408 } 409 410 current_dictionary->SetWithoutPathExpansion(current_path, in_value); 411} 412 413void DictionaryValue::SetBoolean(const std::wstring& path, bool in_value) { 414 Set(path, CreateBooleanValue(in_value)); 415} 416 417void DictionaryValue::SetInteger(const std::wstring& path, int in_value) { 418 Set(path, CreateIntegerValue(in_value)); 419} 420 421void DictionaryValue::SetReal(const std::wstring& path, double in_value) { 422 Set(path, CreateRealValue(in_value)); 423} 424 425void DictionaryValue::SetString(const std::wstring& path, 426 const std::string& in_value) { 427 Set(path, CreateStringValue(in_value)); 428} 429 430void DictionaryValue::SetString(const std::wstring& path, 431 const std::wstring& in_value) { 432 Set(path, CreateStringValue(in_value)); 433} 434 435void DictionaryValue::SetStringFromUTF16(const std::wstring& path, 436 const string16& in_value) { 437 Set(path, CreateStringValueFromUTF16(in_value)); 438} 439 440void DictionaryValue::SetWithoutPathExpansion(const std::wstring& key, 441 Value* in_value) { 442 // If there's an existing value here, we need to delete it, because 443 // we own all our children. 444 if (HasKey(key)) { 445 DCHECK(dictionary_[key] != in_value); // This would be bogus 446 delete dictionary_[key]; 447 } 448 449 dictionary_[key] = in_value; 450} 451 452bool DictionaryValue::Get(const std::wstring& path, Value** out_value) const { 453 std::wstring current_path(path); 454 const DictionaryValue* current_dictionary = this; 455 for (size_t delimiter_position = current_path.find('.'); 456 delimiter_position != std::wstring::npos; 457 delimiter_position = current_path.find('.')) { 458 DictionaryValue* child_dictionary = NULL; 459 if (!current_dictionary->GetDictionary( 460 current_path.substr(0, delimiter_position), &child_dictionary)) 461 return false; 462 463 current_dictionary = child_dictionary; 464 current_path.erase(0, delimiter_position + 1); 465 } 466 467 return current_dictionary->GetWithoutPathExpansion(current_path, out_value); 468} 469 470bool DictionaryValue::GetBoolean(const std::wstring& path, 471 bool* bool_value) const { 472 Value* value; 473 if (!Get(path, &value)) 474 return false; 475 476 return value->GetAsBoolean(bool_value); 477} 478 479bool DictionaryValue::GetInteger(const std::wstring& path, 480 int* out_value) const { 481 Value* value; 482 if (!Get(path, &value)) 483 return false; 484 485 return value->GetAsInteger(out_value); 486} 487 488bool DictionaryValue::GetReal(const std::wstring& path, 489 double* out_value) const { 490 Value* value; 491 if (!Get(path, &value)) 492 return false; 493 494 return value->GetAsReal(out_value); 495} 496 497bool DictionaryValue::GetString(const std::string& path, 498 string16* out_value) const { 499 return GetStringAsUTF16(ASCIIToWide(path), out_value); 500} 501 502bool DictionaryValue::GetStringASCII(const std::string& path, 503 std::string* out_value) const { 504 std::string out; 505 if (!GetString(ASCIIToWide(path), &out)) 506 return false; 507 508 if (!IsStringASCII(out)) { 509 NOTREACHED(); 510 return false; 511 } 512 513 out_value->assign(out); 514 return true; 515} 516 517bool DictionaryValue::GetString(const std::wstring& path, 518 std::string* out_value) const { 519 Value* value; 520 if (!Get(path, &value)) 521 return false; 522 523 return value->GetAsString(out_value); 524} 525 526bool DictionaryValue::GetString(const std::wstring& path, 527 std::wstring* out_value) const { 528 Value* value; 529 if (!Get(path, &value)) 530 return false; 531 532 return value->GetAsString(out_value); 533} 534 535bool DictionaryValue::GetStringAsUTF16(const std::wstring& path, 536 string16* out_value) const { 537 Value* value; 538 if (!Get(path, &value)) 539 return false; 540 541 return value->GetAsUTF16(out_value); 542} 543 544bool DictionaryValue::GetBinary(const std::wstring& path, 545 BinaryValue** out_value) const { 546 Value* value; 547 bool result = Get(path, &value); 548 if (!result || !value->IsType(TYPE_BINARY)) 549 return false; 550 551 if (out_value) 552 *out_value = static_cast<BinaryValue*>(value); 553 554 return true; 555} 556 557bool DictionaryValue::GetDictionary(const std::wstring& path, 558 DictionaryValue** out_value) const { 559 Value* value; 560 bool result = Get(path, &value); 561 if (!result || !value->IsType(TYPE_DICTIONARY)) 562 return false; 563 564 if (out_value) 565 *out_value = static_cast<DictionaryValue*>(value); 566 567 return true; 568} 569 570bool DictionaryValue::GetList(const std::wstring& path, 571 ListValue** out_value) const { 572 Value* value; 573 bool result = Get(path, &value); 574 if (!result || !value->IsType(TYPE_LIST)) 575 return false; 576 577 if (out_value) 578 *out_value = static_cast<ListValue*>(value); 579 580 return true; 581} 582 583bool DictionaryValue::GetWithoutPathExpansion(const std::wstring& key, 584 Value** out_value) const { 585 ValueMap::const_iterator entry_iterator = dictionary_.find(key); 586 if (entry_iterator == dictionary_.end()) 587 return false; 588 589 Value* entry = entry_iterator->second; 590 if (out_value) 591 *out_value = entry; 592 return true; 593} 594 595bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::wstring& path, 596 int* out_value) const { 597 Value* value; 598 if (!GetWithoutPathExpansion(path, &value)) 599 return false; 600 601 return value->GetAsInteger(out_value); 602} 603 604bool DictionaryValue::GetStringWithoutPathExpansion( 605 const std::wstring& path, 606 std::string* out_value) const { 607 Value* value; 608 if (!GetWithoutPathExpansion(path, &value)) 609 return false; 610 611 return value->GetAsString(out_value); 612} 613 614bool DictionaryValue::GetStringWithoutPathExpansion( 615 const std::wstring& path, 616 std::wstring* out_value) const { 617 Value* value; 618 if (!GetWithoutPathExpansion(path, &value)) 619 return false; 620 621 return value->GetAsString(out_value); 622} 623 624bool DictionaryValue::GetStringAsUTF16WithoutPathExpansion( 625 const std::wstring& path, 626 string16* out_value) const { 627 Value* value; 628 if (!GetWithoutPathExpansion(path, &value)) 629 return false; 630 631 return value->GetAsUTF16(out_value); 632} 633 634bool DictionaryValue::GetDictionaryWithoutPathExpansion( 635 const std::wstring& path, 636 DictionaryValue** out_value) const { 637 Value* value; 638 bool result = GetWithoutPathExpansion(path, &value); 639 if (!result || !value->IsType(TYPE_DICTIONARY)) 640 return false; 641 642 if (out_value) 643 *out_value = static_cast<DictionaryValue*>(value); 644 645 return true; 646} 647 648bool DictionaryValue::GetListWithoutPathExpansion(const std::wstring& path, 649 ListValue** out_value) const { 650 Value* value; 651 bool result = GetWithoutPathExpansion(path, &value); 652 if (!result || !value->IsType(TYPE_LIST)) 653 return false; 654 655 if (out_value) 656 *out_value = static_cast<ListValue*>(value); 657 658 return true; 659} 660 661bool DictionaryValue::Remove(const std::wstring& path, Value** out_value) { 662 std::wstring current_path(path); 663 DictionaryValue* current_dictionary = this; 664 size_t delimiter_position = current_path.rfind('.'); 665 if (delimiter_position != std::wstring::npos) { 666 if (!GetDictionary(current_path.substr(0, delimiter_position), 667 ¤t_dictionary)) 668 return false; 669 current_path.erase(0, delimiter_position + 1); 670 } 671 672 return current_dictionary->RemoveWithoutPathExpansion(current_path, 673 out_value); 674} 675 676bool DictionaryValue::RemoveWithoutPathExpansion(const std::wstring& key, 677 Value** out_value) { 678 ValueMap::iterator entry_iterator = dictionary_.find(key); 679 if (entry_iterator == dictionary_.end()) 680 return false; 681 682 Value* entry = entry_iterator->second; 683 if (out_value) 684 *out_value = entry; 685 else 686 delete entry; 687 dictionary_.erase(entry_iterator); 688 return true; 689} 690 691DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() { 692 Value* copy = CopyWithoutEmptyChildren(this); 693 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue; 694} 695 696void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) { 697 for (DictionaryValue::key_iterator key(dictionary->begin_keys()); 698 key != dictionary->end_keys(); ++key) { 699 Value* merge_value; 700 if (dictionary->GetWithoutPathExpansion(*key, &merge_value)) { 701 // Check whether we have to merge dictionaries. 702 if (merge_value->IsType(Value::TYPE_DICTIONARY)) { 703 DictionaryValue* sub_dict; 704 if (GetDictionaryWithoutPathExpansion(*key, &sub_dict)) { 705 sub_dict->MergeDictionary( 706 static_cast<const DictionaryValue*>(merge_value)); 707 continue; 708 } 709 } 710 // All other cases: Make a copy and hook it up. 711 SetWithoutPathExpansion(*key, merge_value->DeepCopy()); 712 } 713 } 714} 715 716///////////////////// ListValue //////////////////// 717 718ListValue::ListValue() : Value(TYPE_LIST) { 719} 720 721ListValue::~ListValue() { 722 Clear(); 723} 724 725void ListValue::Clear() { 726 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) 727 delete *i; 728 list_.clear(); 729} 730 731bool ListValue::Set(size_t index, Value* in_value) { 732 if (!in_value) 733 return false; 734 735 if (index >= list_.size()) { 736 // Pad out any intermediate indexes with null settings 737 while (index > list_.size()) 738 Append(CreateNullValue()); 739 Append(in_value); 740 } else { 741 DCHECK(list_[index] != in_value); 742 delete list_[index]; 743 list_[index] = in_value; 744 } 745 return true; 746} 747 748bool ListValue::Get(size_t index, Value** out_value) const { 749 if (index >= list_.size()) 750 return false; 751 752 if (out_value) 753 *out_value = list_[index]; 754 755 return true; 756} 757 758bool ListValue::GetBoolean(size_t index, bool* bool_value) const { 759 Value* value; 760 if (!Get(index, &value)) 761 return false; 762 763 return value->GetAsBoolean(bool_value); 764} 765 766bool ListValue::GetInteger(size_t index, int* out_value) const { 767 Value* value; 768 if (!Get(index, &value)) 769 return false; 770 771 return value->GetAsInteger(out_value); 772} 773 774bool ListValue::GetReal(size_t index, double* out_value) const { 775 Value* value; 776 if (!Get(index, &value)) 777 return false; 778 779 return value->GetAsReal(out_value); 780} 781 782bool ListValue::GetString(size_t index, std::string* out_value) const { 783 Value* value; 784 if (!Get(index, &value)) 785 return false; 786 787 return value->GetAsString(out_value); 788} 789 790bool ListValue::GetString(size_t index, std::wstring* out_value) const { 791 Value* value; 792 if (!Get(index, &value)) 793 return false; 794 795 return value->GetAsString(out_value); 796} 797 798bool ListValue::GetStringAsUTF16(size_t index, string16* out_value) const { 799 Value* value; 800 if (!Get(index, &value)) 801 return false; 802 803 return value->GetAsUTF16(out_value); 804} 805 806bool ListValue::GetBinary(size_t index, BinaryValue** out_value) const { 807 Value* value; 808 bool result = Get(index, &value); 809 if (!result || !value->IsType(TYPE_BINARY)) 810 return false; 811 812 if (out_value) 813 *out_value = static_cast<BinaryValue*>(value); 814 815 return true; 816} 817 818bool ListValue::GetDictionary(size_t index, DictionaryValue** out_value) const { 819 Value* value; 820 bool result = Get(index, &value); 821 if (!result || !value->IsType(TYPE_DICTIONARY)) 822 return false; 823 824 if (out_value) 825 *out_value = static_cast<DictionaryValue*>(value); 826 827 return true; 828} 829 830bool ListValue::GetList(size_t index, ListValue** out_value) const { 831 Value* value; 832 bool result = Get(index, &value); 833 if (!result || !value->IsType(TYPE_LIST)) 834 return false; 835 836 if (out_value) 837 *out_value = static_cast<ListValue*>(value); 838 839 return true; 840} 841 842bool ListValue::Remove(size_t index, Value** out_value) { 843 if (index >= list_.size()) 844 return false; 845 846 if (out_value) 847 *out_value = list_[index]; 848 else 849 delete list_[index]; 850 851 list_.erase(list_.begin() + index); 852 return true; 853} 854 855int ListValue::Remove(const Value& value) { 856 for (ValueVector::iterator i(list_.begin()); i != list_.end(); ++i) { 857 if ((*i)->Equals(&value)) { 858 size_t index = i - list_.begin(); 859 delete *i; 860 list_.erase(i); 861 862 // TODO(anyone): Returning a signed int type here is just wrong. 863 // Change this interface to return a size_t. 864 DCHECK(index <= INT_MAX); 865 int return_index = static_cast<int>(index); 866 return return_index; 867 } 868 } 869 return -1; 870} 871 872void ListValue::Append(Value* in_value) { 873 DCHECK(in_value); 874 list_.push_back(in_value); 875} 876 877bool ListValue::AppendIfNotPresent(Value* in_value) { 878 DCHECK(in_value); 879 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) { 880 if ((*i)->Equals(in_value)) 881 return false; 882 } 883 list_.push_back(in_value); 884 return true; 885} 886 887bool ListValue::Insert(size_t index, Value* in_value) { 888 DCHECK(in_value); 889 if (index > list_.size()) 890 return false; 891 892 list_.insert(list_.begin() + index, in_value); 893 return true; 894} 895 896Value* ListValue::DeepCopy() const { 897 ListValue* result = new ListValue; 898 899 for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) 900 result->Append((*i)->DeepCopy()); 901 902 return result; 903} 904 905bool ListValue::Equals(const Value* other) const { 906 if (other->GetType() != GetType()) 907 return false; 908 909 const ListValue* other_list = 910 static_cast<const ListValue*>(other); 911 const_iterator lhs_it, rhs_it; 912 for (lhs_it = begin(), rhs_it = other_list->begin(); 913 lhs_it != end() && rhs_it != other_list->end(); 914 ++lhs_it, ++rhs_it) { 915 if (!(*lhs_it)->Equals(*rhs_it)) 916 return false; 917 } 918 if (lhs_it != end() || rhs_it != other_list->end()) 919 return false; 920 921 return true; 922} 923 924ValueSerializer::~ValueSerializer() { 925} 926