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