Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: base/values.cc

Issue 2683203004: Move Storage for ListValue and DictValue in Union (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/values.h" 5 #include "base/values.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 66
67 case Value::Type::DICTIONARY: 67 case Value::Type::DICTIONARY:
68 return CopyDictionaryWithoutEmptyChildren( 68 return CopyDictionaryWithoutEmptyChildren(
69 static_cast<const DictionaryValue&>(node)); 69 static_cast<const DictionaryValue&>(node));
70 70
71 default: 71 default:
72 return node.CreateDeepCopy(); 72 return node.CreateDeepCopy();
73 } 73 }
74 } 74 }
75 75
76 // TODO(crbug.com/646113): Remove this once all types are implemented.
77 bool IsAssignmentSafe(Value::Type lhs, Value::Type rhs) {
78 auto IsImplemented = [](Value::Type type) {
79 return type == Value::Type::NONE || type == Value::Type::BOOLEAN ||
80 type == Value::Type::INTEGER || type == Value::Type::DOUBLE ||
81 type == Value::Type::STRING || type == Value::Type::BINARY;
82 };
83
84 return lhs == rhs || (IsImplemented(lhs) && IsImplemented(rhs));
85 }
86
87 } // namespace 76 } // namespace
88 77
89 // static 78 // static
90 std::unique_ptr<Value> Value::CreateNullValue() { 79 std::unique_ptr<Value> Value::CreateNullValue() {
91 return WrapUnique(new Value(Type::NONE)); 80 return WrapUnique(new Value(Type::NONE));
92 } 81 }
93 82
94 // static 83 // static
95 std::unique_ptr<BinaryValue> BinaryValue::CreateWithCopiedBuffer( 84 std::unique_ptr<BinaryValue> BinaryValue::CreateWithCopiedBuffer(
96 const char* buffer, 85 const char* buffer,
(...skipping 25 matching lines...) Expand all
122 return; 111 return;
123 case Type::DOUBLE: 112 case Type::DOUBLE:
124 double_value_ = 0.0; 113 double_value_ = 0.0;
125 return; 114 return;
126 case Type::STRING: 115 case Type::STRING:
127 string_value_.Init(); 116 string_value_.Init();
128 return; 117 return;
129 case Type::BINARY: 118 case Type::BINARY:
130 binary_value_.Init(); 119 binary_value_.Init();
131 return; 120 return;
132 121 case Type::DICTIONARY:
133 // TODO(crbug.com/646113): Implement these once the corresponding derived 122 dictionary_.Init();
134 // classes are removed. 123 return;
135 case Type::LIST: 124 case Type::LIST:
136 case Type::DICTIONARY: 125 list_.Init();
137 return; 126 return;
138 } 127 }
139 } 128 }
140 129
141 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {} 130 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
142 131
143 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {} 132 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
144 133
145 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) { 134 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) {
146 if (!std::isfinite(double_value_)) { 135 if (!std::isfinite(double_value_)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) { 167 Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) {
179 binary_value_.Init(in_blob); 168 binary_value_.Init(in_blob);
180 } 169 }
181 170
182 Value::Value(std::vector<char>&& in_blob) : type_(Type::BINARY) { 171 Value::Value(std::vector<char>&& in_blob) : type_(Type::BINARY) {
183 binary_value_.Init(std::move(in_blob)); 172 binary_value_.Init(std::move(in_blob));
184 } 173 }
185 174
186 Value& Value::operator=(const Value& that) { 175 Value& Value::operator=(const Value& that) {
187 if (this != &that) { 176 if (this != &that) {
188 DCHECK(IsAssignmentSafe(type_, that.type_));
189 if (type_ == that.type_) { 177 if (type_ == that.type_) {
190 InternalCopyAssignFrom(that); 178 InternalCopyAssignFrom(that);
191 } else { 179 } else {
192 InternalCleanup(); 180 InternalCleanup();
193 InternalCopyConstructFrom(that); 181 InternalCopyConstructFrom(that);
194 } 182 }
195 } 183 }
196 184
197 return *this; 185 return *this;
198 } 186 }
199 187
200 Value& Value::operator=(Value&& that) { 188 Value& Value::operator=(Value&& that) {
201 if (this != &that) { 189 if (this != &that) {
202 DCHECK(IsAssignmentSafe(type_, that.type_));
203 if (type_ == that.type_) { 190 if (type_ == that.type_) {
204 InternalMoveAssignFrom(std::move(that)); 191 InternalMoveAssignFrom(std::move(that));
205 } else { 192 } else {
206 InternalCleanup(); 193 InternalCleanup();
207 InternalMoveConstructFrom(std::move(that)); 194 InternalMoveConstructFrom(std::move(that));
208 } 195 }
209 } 196 }
210 197
211 return *this; 198 return *this;
212 } 199 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 308
322 bool Value::GetAsBinary(const BinaryValue** out_value) const { 309 bool Value::GetAsBinary(const BinaryValue** out_value) const {
323 if (out_value && is_blob()) { 310 if (out_value && is_blob()) {
324 *out_value = this; 311 *out_value = this;
325 return true; 312 return true;
326 } 313 }
327 return is_blob(); 314 return is_blob();
328 } 315 }
329 316
330 bool Value::GetAsList(ListValue** out_value) { 317 bool Value::GetAsList(ListValue** out_value) {
331 return false; 318 if (out_value && is_list()) {
319 *out_value = static_cast<ListValue*>(this);
320 return true;
321 }
322 return is_list();
332 } 323 }
333 324
334 bool Value::GetAsList(const ListValue** out_value) const { 325 bool Value::GetAsList(const ListValue** out_value) const {
335 return false; 326 if (out_value && is_list()) {
327 *out_value = static_cast<const ListValue*>(this);
328 return true;
329 }
330 return is_list();
336 } 331 }
337 332
338 bool Value::GetAsDictionary(DictionaryValue** out_value) { 333 bool Value::GetAsDictionary(DictionaryValue** out_value) {
339 return false; 334 if (out_value && is_dict()) {
335 *out_value = static_cast<DictionaryValue*>(this);
336 return true;
337 }
338 return is_dict();
340 } 339 }
341 340
342 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { 341 bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
343 return false; 342 if (out_value && is_dict()) {
343 *out_value = static_cast<const DictionaryValue*>(this);
344 return true;
345 }
346 return is_dict();
344 } 347 }
345 348
346 Value* Value::DeepCopy() const { 349 Value* Value::DeepCopy() const {
347 // This method should only be getting called for null Values--all subclasses 350 // This method should only be getting called for null Values--all subclasses
348 // need to provide their own implementation;. 351 // need to provide their own implementation;.
349 switch (type()) { 352 switch (type()) {
350 case Type::NONE: 353 case Type::NONE:
351 return CreateNullValue().release(); 354 return CreateNullValue().release();
352 355
353 // For now, make FundamentalValues for backward-compatibility. Convert to 356 // For now, make FundamentalValues for backward-compatibility. Convert to
354 // Value when that code is deleted. 357 // Value when that code is deleted.
355 case Type::BOOLEAN: 358 case Type::BOOLEAN:
356 return new FundamentalValue(bool_value_); 359 return new FundamentalValue(bool_value_);
357 case Type::INTEGER: 360 case Type::INTEGER:
358 return new FundamentalValue(int_value_); 361 return new FundamentalValue(int_value_);
359 case Type::DOUBLE: 362 case Type::DOUBLE:
360 return new FundamentalValue(double_value_); 363 return new FundamentalValue(double_value_);
361 // For now, make StringValues for backward-compatibility. Convert to 364 // For now, make StringValues for backward-compatibility. Convert to
362 // Value when that code is deleted. 365 // Value when that code is deleted.
363 case Type::STRING: 366 case Type::STRING:
364 return new StringValue(*string_value_); 367 return new StringValue(*string_value_);
365 // For now, make BinaryValues for backward-compatibility. Convert to 368 // For now, make BinaryValues for backward-compatibility. Convert to
366 // Value when that code is deleted. 369 // Value when that code is deleted.
367 case Type::BINARY: 370 case Type::BINARY:
368 return new BinaryValue(*binary_value_); 371 return new BinaryValue(*binary_value_);
369 372
373 // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
374 // are completely inlined.
375 case Type::DICTIONARY: {
376 DictionaryValue* result = new DictionaryValue;
377
378 for (const auto& current_entry : *dictionary_) {
379 result->SetWithoutPathExpansion(current_entry.first,
380 current_entry.second->CreateDeepCopy());
381 }
382
383 return result;
384 }
385
386 case Type::LIST: {
387 ListValue* result = new ListValue;
388
389 for (const auto& entry : *list_)
390 result->Append(entry->CreateDeepCopy());
391
392 return result;
393 }
394
370 default: 395 default:
371 // All other types should be handled by subclasses.
372 NOTREACHED(); 396 NOTREACHED();
373 return nullptr; 397 return nullptr;
374 } 398 }
375 } 399 }
376 400
377 std::unique_ptr<Value> Value::CreateDeepCopy() const { 401 std::unique_ptr<Value> Value::CreateDeepCopy() const {
378 return WrapUnique(DeepCopy()); 402 return WrapUnique(DeepCopy());
379 } 403 }
380 404
381 bool Value::Equals(const Value* other) const { 405 bool Value::Equals(const Value* other) const {
382 if (other->type() != type()) 406 if (other->type() != type())
383 return false; 407 return false;
384 408
385 switch (type()) { 409 switch (type()) {
386 case Type::NONE: 410 case Type::NONE:
387 return true; 411 return true;
388 case Type::BOOLEAN: 412 case Type::BOOLEAN:
389 return bool_value_ == other->bool_value_; 413 return bool_value_ == other->bool_value_;
390 case Type::INTEGER: 414 case Type::INTEGER:
391 return int_value_ == other->int_value_; 415 return int_value_ == other->int_value_;
392 case Type::DOUBLE: 416 case Type::DOUBLE:
393 return double_value_ == other->double_value_; 417 return double_value_ == other->double_value_;
394 case Type::STRING: 418 case Type::STRING:
395 return *string_value_ == *(other->string_value_); 419 return *string_value_ == *(other->string_value_);
396 case Type::BINARY: 420 case Type::BINARY:
397 return *binary_value_ == *(other->binary_value_); 421 return *binary_value_ == *(other->binary_value_);
398 default: 422 // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
399 // This method should only be getting called for the above types -- all 423 // are completely inlined.
400 // subclasses need to provide their own implementation;. 424 case Type::DICTIONARY: {
401 NOTREACHED(); 425 if (dictionary_->size() != other->dictionary_->size())
402 return false; 426 return false;
427
428 return std::equal(std::begin(*dictionary_), std::end(*dictionary_),
429 std::begin(*(other->dictionary_)),
430 [](const DictStorage::value_type& lhs,
431 const DictStorage::value_type& rhs) {
432 if (lhs.first != rhs.first)
433 return false;
434
435 return lhs.second->Equals(rhs.second.get());
436 });
437 }
438 case Type::LIST: {
439 if (list_->size() != other->list_->size())
440 return false;
441
442 return std::equal(std::begin(*list_), std::end(*list_),
443 std::begin(*(other->list_)),
444 [](const ListStorage::value_type& lhs,
445 const ListStorage::value_type& rhs) {
446 return lhs->Equals(rhs.get());
447 });
448 }
403 } 449 }
450
451 NOTREACHED();
452 return false;
404 } 453 }
405 454
406 // static 455 // static
407 bool Value::Equals(const Value* a, const Value* b) { 456 bool Value::Equals(const Value* a, const Value* b) {
408 if ((a == NULL) && (b == NULL)) return true; 457 if ((a == NULL) && (b == NULL)) return true;
409 if ((a == NULL) ^ (b == NULL)) return false; 458 if ((a == NULL) ^ (b == NULL)) return false;
410 return a->Equals(b); 459 return a->Equals(b);
411 } 460 }
412 461
413 void Value::InternalCopyFundamentalValue(const Value& that) { 462 void Value::InternalCopyFundamentalValue(const Value& that) {
(...skipping 27 matching lines...) Expand all
441 case Type::DOUBLE: 490 case Type::DOUBLE:
442 InternalCopyFundamentalValue(that); 491 InternalCopyFundamentalValue(that);
443 return; 492 return;
444 493
445 case Type::STRING: 494 case Type::STRING:
446 string_value_.Init(*that.string_value_); 495 string_value_.Init(*that.string_value_);
447 return; 496 return;
448 case Type::BINARY: 497 case Type::BINARY:
449 binary_value_.Init(*that.binary_value_); 498 binary_value_.Init(*that.binary_value_);
450 return; 499 return;
451 500 case Type::DICTIONARY:
452 // TODO(crbug.com/646113): Implement these once the corresponding derived 501 // Currently not implementable due to the presence of unique_ptrs in
453 // classes are removed. 502 // DictStorage.
503 // TODO(crbug.com/646113): Implement this when DictionaryValues are
504 // completely inlined.
505 return;
454 case Type::LIST: 506 case Type::LIST:
455 case Type::DICTIONARY: 507 // Currently not implementable due to the presence of unique_ptrs in
508 // ListStorage.
509 // TODO(crbug.com/646113): Implement this when ListValues are completely
510 // inlined.
456 return; 511 return;
457 } 512 }
458 } 513 }
459 514
460 void Value::InternalMoveConstructFrom(Value&& that) { 515 void Value::InternalMoveConstructFrom(Value&& that) {
461 type_ = that.type_; 516 type_ = that.type_;
462 517
463 switch (type_) { 518 switch (type_) {
464 case Type::NONE: 519 case Type::NONE:
465 case Type::BOOLEAN: 520 case Type::BOOLEAN:
466 case Type::INTEGER: 521 case Type::INTEGER:
467 case Type::DOUBLE: 522 case Type::DOUBLE:
468 InternalCopyFundamentalValue(that); 523 InternalCopyFundamentalValue(that);
469 return; 524 return;
470 525
471 case Type::STRING: 526 case Type::STRING:
472 string_value_.InitFromMove(std::move(that.string_value_)); 527 string_value_.InitFromMove(std::move(that.string_value_));
473 return; 528 return;
474 case Type::BINARY: 529 case Type::BINARY:
475 binary_value_.InitFromMove(std::move(that.binary_value_)); 530 binary_value_.InitFromMove(std::move(that.binary_value_));
476 return; 531 return;
477 532 case Type::DICTIONARY:
478 // TODO(crbug.com/646113): Implement these once the corresponding derived 533 dictionary_.InitFromMove(std::move(that.dictionary_));
479 // classes are removed. 534 return;
480 case Type::LIST: 535 case Type::LIST:
481 case Type::DICTIONARY: 536 list_.InitFromMove(std::move(that.list_));
482 return; 537 return;
483 } 538 }
484 } 539 }
485 540
486 void Value::InternalCopyAssignFrom(const Value& that) { 541 void Value::InternalCopyAssignFrom(const Value& that) {
487 type_ = that.type_; 542 type_ = that.type_;
488 543
489 switch (type_) { 544 switch (type_) {
490 case Type::NONE: 545 case Type::NONE:
491 case Type::BOOLEAN: 546 case Type::BOOLEAN:
492 case Type::INTEGER: 547 case Type::INTEGER:
493 case Type::DOUBLE: 548 case Type::DOUBLE:
494 InternalCopyFundamentalValue(that); 549 InternalCopyFundamentalValue(that);
495 return; 550 return;
496 551
497 case Type::STRING: 552 case Type::STRING:
498 *string_value_ = *that.string_value_; 553 *string_value_ = *that.string_value_;
499 return; 554 return;
500 case Type::BINARY: 555 case Type::BINARY:
501 *binary_value_ = *that.binary_value_; 556 *binary_value_ = *that.binary_value_;
502 return; 557 return;
503 558 case Type::DICTIONARY:
504 // TODO(crbug.com/646113): Implement these once the corresponding derived 559 // Currently not implementable due to the presence of unique_ptrs in
505 // classes are removed. 560 // DictStorage.
561 // TODO(crbug.com/646113): Implement this when DictionaryValues are
562 // completely inlined.
563 return;
506 case Type::LIST: 564 case Type::LIST:
507 case Type::DICTIONARY: 565 // Currently not implementable due to the presence of unique_ptrs in
566 // ListStorage.
567 // TODO(crbug.com/646113): Implement this when ListValues are completely
568 // inlined.
508 return; 569 return;
509 } 570 }
510 } 571 }
511 572
512 void Value::InternalMoveAssignFrom(Value&& that) { 573 void Value::InternalMoveAssignFrom(Value&& that) {
513 type_ = that.type_; 574 type_ = that.type_;
514 575
515 switch (type_) { 576 switch (type_) {
516 case Type::NONE: 577 case Type::NONE:
517 case Type::BOOLEAN: 578 case Type::BOOLEAN:
518 case Type::INTEGER: 579 case Type::INTEGER:
519 case Type::DOUBLE: 580 case Type::DOUBLE:
520 InternalCopyFundamentalValue(that); 581 InternalCopyFundamentalValue(that);
521 return; 582 return;
522 583
523 case Type::STRING: 584 case Type::STRING:
524 *string_value_ = std::move(*that.string_value_); 585 *string_value_ = std::move(*that.string_value_);
525 return; 586 return;
526 case Type::BINARY: 587 case Type::BINARY:
527 *binary_value_ = std::move(*that.binary_value_); 588 *binary_value_ = std::move(*that.binary_value_);
528 return; 589 return;
529 590 case Type::DICTIONARY:
530 // TODO(crbug.com/646113): Implement these once the corresponding derived 591 *dictionary_ = std::move(*that.dictionary_);
531 // classes are removed. 592 return;
532 case Type::LIST: 593 case Type::LIST:
533 case Type::DICTIONARY: 594 *list_ = std::move(*that.list_);
534 return; 595 return;
535 } 596 }
536 } 597 }
537 598
538 void Value::InternalCleanup() { 599 void Value::InternalCleanup() {
539 switch (type_) { 600 switch (type_) {
540 case Type::NONE: 601 case Type::NONE:
541 case Type::BOOLEAN: 602 case Type::BOOLEAN:
542 case Type::INTEGER: 603 case Type::INTEGER:
543 case Type::DOUBLE: 604 case Type::DOUBLE:
544 // Nothing to do 605 // Nothing to do
545 return; 606 return;
546 607
547 case Type::STRING: 608 case Type::STRING:
548 string_value_.Destroy(); 609 string_value_.Destroy();
549 return; 610 return;
550 case Type::BINARY: 611 case Type::BINARY:
551 binary_value_.Destroy(); 612 binary_value_.Destroy();
552 return; 613 return;
553 614 case Type::DICTIONARY:
554 // TODO(crbug.com/646113): Implement these once the corresponding derived 615 dictionary_.Destroy();
555 // classes are removed. 616 return;
556 case Type::LIST: 617 case Type::LIST:
557 case Type::DICTIONARY: 618 list_.Destroy();
558 return; 619 return;
559 } 620 }
560 } 621 }
561 622
562 ///////////////////// DictionaryValue //////////////////// 623 ///////////////////// DictionaryValue ////////////////////
563 624
564 // static 625 // static
565 std::unique_ptr<DictionaryValue> DictionaryValue::From( 626 std::unique_ptr<DictionaryValue> DictionaryValue::From(
566 std::unique_ptr<Value> value) { 627 std::unique_ptr<Value> value) {
567 DictionaryValue* out; 628 DictionaryValue* out;
568 if (value && value->GetAsDictionary(&out)) { 629 if (value && value->GetAsDictionary(&out)) {
569 ignore_result(value.release()); 630 ignore_result(value.release());
570 return WrapUnique(out); 631 return WrapUnique(out);
571 } 632 }
572 return nullptr; 633 return nullptr;
573 } 634 }
574 635
575 DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {} 636 DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {}
576 637
577 DictionaryValue::~DictionaryValue() { 638 DictionaryValue::~DictionaryValue() = default;
578 Clear();
579 }
580
581 bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) {
582 if (out_value)
583 *out_value = this;
584 return true;
585 }
586
587 bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const {
588 if (out_value)
589 *out_value = this;
590 return true;
591 }
592 639
593 bool DictionaryValue::HasKey(StringPiece key) const { 640 bool DictionaryValue::HasKey(StringPiece key) const {
594 DCHECK(IsStringUTF8(key)); 641 DCHECK(IsStringUTF8(key));
595 auto current_entry = dictionary_.find(key.as_string()); 642 auto current_entry = dictionary_->find(key.as_string());
596 DCHECK((current_entry == dictionary_.end()) || current_entry->second); 643 DCHECK((current_entry == dictionary_->end()) || current_entry->second);
597 return current_entry != dictionary_.end(); 644 return current_entry != dictionary_->end();
598 } 645 }
599 646
600 void DictionaryValue::Clear() { 647 void DictionaryValue::Clear() {
601 dictionary_.clear(); 648 dictionary_->clear();
602 } 649 }
603 650
604 void DictionaryValue::Set(StringPiece path, std::unique_ptr<Value> in_value) { 651 void DictionaryValue::Set(StringPiece path, std::unique_ptr<Value> in_value) {
605 DCHECK(IsStringUTF8(path)); 652 DCHECK(IsStringUTF8(path));
606 DCHECK(in_value); 653 DCHECK(in_value);
607 654
608 StringPiece current_path(path); 655 StringPiece current_path(path);
609 DictionaryValue* current_dictionary = this; 656 DictionaryValue* current_dictionary = this;
610 for (size_t delimiter_position = current_path.find('.'); 657 for (size_t delimiter_position = current_path.find('.');
611 delimiter_position != StringPiece::npos; 658 delimiter_position != StringPiece::npos;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 void DictionaryValue::SetString(StringPiece path, StringPiece in_value) { 693 void DictionaryValue::SetString(StringPiece path, StringPiece in_value) {
647 Set(path, new StringValue(in_value)); 694 Set(path, new StringValue(in_value));
648 } 695 }
649 696
650 void DictionaryValue::SetString(StringPiece path, const string16& in_value) { 697 void DictionaryValue::SetString(StringPiece path, const string16& in_value) {
651 Set(path, new StringValue(in_value)); 698 Set(path, new StringValue(in_value));
652 } 699 }
653 700
654 void DictionaryValue::SetWithoutPathExpansion(StringPiece key, 701 void DictionaryValue::SetWithoutPathExpansion(StringPiece key,
655 std::unique_ptr<Value> in_value) { 702 std::unique_ptr<Value> in_value) {
656 dictionary_[key.as_string()] = std::move(in_value); 703 (*dictionary_)[key.as_string()] = std::move(in_value);
657 } 704 }
658 705
659 void DictionaryValue::SetWithoutPathExpansion(StringPiece key, 706 void DictionaryValue::SetWithoutPathExpansion(StringPiece key,
660 Value* in_value) { 707 Value* in_value) {
661 SetWithoutPathExpansion(key, WrapUnique(in_value)); 708 SetWithoutPathExpansion(key, WrapUnique(in_value));
662 } 709 }
663 710
664 void DictionaryValue::SetBooleanWithoutPathExpansion(StringPiece path, 711 void DictionaryValue::SetBooleanWithoutPathExpansion(StringPiece path,
665 bool in_value) { 712 bool in_value) {
666 SetWithoutPathExpansion(path, 713 SetWithoutPathExpansion(path,
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 873
827 bool DictionaryValue::GetList(StringPiece path, ListValue** out_value) { 874 bool DictionaryValue::GetList(StringPiece path, ListValue** out_value) {
828 return static_cast<const DictionaryValue&>(*this).GetList( 875 return static_cast<const DictionaryValue&>(*this).GetList(
829 path, 876 path,
830 const_cast<const ListValue**>(out_value)); 877 const_cast<const ListValue**>(out_value));
831 } 878 }
832 879
833 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key, 880 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key,
834 const Value** out_value) const { 881 const Value** out_value) const {
835 DCHECK(IsStringUTF8(key)); 882 DCHECK(IsStringUTF8(key));
836 auto entry_iterator = dictionary_.find(key.as_string()); 883 auto entry_iterator = dictionary_->find(key.as_string());
837 if (entry_iterator == dictionary_.end()) 884 if (entry_iterator == dictionary_->end())
838 return false; 885 return false;
839 886
840 if (out_value) 887 if (out_value)
841 *out_value = entry_iterator->second.get(); 888 *out_value = entry_iterator->second.get();
842 return true; 889 return true;
843 } 890 }
844 891
845 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key, 892 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key,
846 Value** out_value) { 893 Value** out_value) {
847 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion( 894 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion(
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 } 1002 }
956 1003
957 return current_dictionary->RemoveWithoutPathExpansion(current_path, 1004 return current_dictionary->RemoveWithoutPathExpansion(current_path,
958 out_value); 1005 out_value);
959 } 1006 }
960 1007
961 bool DictionaryValue::RemoveWithoutPathExpansion( 1008 bool DictionaryValue::RemoveWithoutPathExpansion(
962 StringPiece key, 1009 StringPiece key,
963 std::unique_ptr<Value>* out_value) { 1010 std::unique_ptr<Value>* out_value) {
964 DCHECK(IsStringUTF8(key)); 1011 DCHECK(IsStringUTF8(key));
965 auto entry_iterator = dictionary_.find(key.as_string()); 1012 auto entry_iterator = dictionary_->find(key.as_string());
966 if (entry_iterator == dictionary_.end()) 1013 if (entry_iterator == dictionary_->end())
967 return false; 1014 return false;
968 1015
969 if (out_value) 1016 if (out_value)
970 *out_value = std::move(entry_iterator->second); 1017 *out_value = std::move(entry_iterator->second);
971 dictionary_.erase(entry_iterator); 1018 dictionary_->erase(entry_iterator);
972 return true; 1019 return true;
973 } 1020 }
974 1021
975 bool DictionaryValue::RemovePath(StringPiece path, 1022 bool DictionaryValue::RemovePath(StringPiece path,
976 std::unique_ptr<Value>* out_value) { 1023 std::unique_ptr<Value>* out_value) {
977 bool result = false; 1024 bool result = false;
978 size_t delimiter_position = path.find('.'); 1025 size_t delimiter_position = path.find('.');
979 1026
980 if (delimiter_position == std::string::npos) 1027 if (delimiter_position == std::string::npos)
981 return RemoveWithoutPathExpansion(path, out_value); 1028 return RemoveWithoutPathExpansion(path, out_value);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 continue; 1060 continue;
1014 } 1061 }
1015 } 1062 }
1016 // All other cases: Make a copy and hook it up. 1063 // All other cases: Make a copy and hook it up.
1017 SetWithoutPathExpansion(it.key(), 1064 SetWithoutPathExpansion(it.key(),
1018 base::WrapUnique(merge_value->DeepCopy())); 1065 base::WrapUnique(merge_value->DeepCopy()));
1019 } 1066 }
1020 } 1067 }
1021 1068
1022 void DictionaryValue::Swap(DictionaryValue* other) { 1069 void DictionaryValue::Swap(DictionaryValue* other) {
1023 dictionary_.swap(other->dictionary_); 1070 dictionary_->swap(*(other->dictionary_));
1024 } 1071 }
1025 1072
1026 DictionaryValue::Iterator::Iterator(const DictionaryValue& target) 1073 DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
1027 : target_(target), 1074 : target_(target), it_(target.dictionary_->begin()) {}
1028 it_(target.dictionary_.begin()) {}
1029 1075
1030 DictionaryValue::Iterator::Iterator(const Iterator& other) = default; 1076 DictionaryValue::Iterator::Iterator(const Iterator& other) = default;
1031 1077
1032 DictionaryValue::Iterator::~Iterator() {} 1078 DictionaryValue::Iterator::~Iterator() {}
1033 1079
1034 DictionaryValue* DictionaryValue::DeepCopy() const { 1080 DictionaryValue* DictionaryValue::DeepCopy() const {
1035 DictionaryValue* result = new DictionaryValue; 1081 return static_cast<DictionaryValue*>(Value::DeepCopy());
1036
1037 for (const auto& current_entry : dictionary_) {
1038 result->SetWithoutPathExpansion(current_entry.first,
1039 current_entry.second->CreateDeepCopy());
1040 }
1041
1042 return result;
1043 } 1082 }
1044 1083
1045 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const { 1084 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
1046 return WrapUnique(DeepCopy()); 1085 return WrapUnique(DeepCopy());
1047 } 1086 }
1048 1087
1049 bool DictionaryValue::Equals(const Value* other) const {
1050 if (other->GetType() != GetType())
1051 return false;
1052
1053 const DictionaryValue* other_dict =
1054 static_cast<const DictionaryValue*>(other);
1055 Iterator lhs_it(*this);
1056 Iterator rhs_it(*other_dict);
1057 while (!lhs_it.IsAtEnd() && !rhs_it.IsAtEnd()) {
1058 if (lhs_it.key() != rhs_it.key() ||
1059 !lhs_it.value().Equals(&rhs_it.value())) {
1060 return false;
1061 }
1062 lhs_it.Advance();
1063 rhs_it.Advance();
1064 }
1065 if (!lhs_it.IsAtEnd() || !rhs_it.IsAtEnd())
1066 return false;
1067
1068 return true;
1069 }
1070
1071 ///////////////////// ListValue //////////////////// 1088 ///////////////////// ListValue ////////////////////
1072 1089
1073 // static 1090 // static
1074 std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) { 1091 std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) {
1075 ListValue* out; 1092 ListValue* out;
1076 if (value && value->GetAsList(&out)) { 1093 if (value && value->GetAsList(&out)) {
1077 ignore_result(value.release()); 1094 ignore_result(value.release());
1078 return WrapUnique(out); 1095 return WrapUnique(out);
1079 } 1096 }
1080 return nullptr; 1097 return nullptr;
1081 } 1098 }
1082 1099
1083 ListValue::ListValue() : Value(Type::LIST) {} 1100 ListValue::ListValue() : Value(Type::LIST) {}
1084 1101
1085 ListValue::~ListValue() { 1102 ListValue::~ListValue() = default;
1086 Clear();
1087 }
1088 1103
1089 void ListValue::Clear() { 1104 void ListValue::Clear() {
1090 list_.clear(); 1105 list_->clear();
1091 } 1106 }
1092 1107
1093 bool ListValue::Set(size_t index, Value* in_value) { 1108 bool ListValue::Set(size_t index, Value* in_value) {
1094 return Set(index, WrapUnique(in_value)); 1109 return Set(index, WrapUnique(in_value));
1095 } 1110 }
1096 1111
1097 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) { 1112 bool ListValue::Set(size_t index, std::unique_ptr<Value> in_value) {
1098 if (!in_value) 1113 if (!in_value)
1099 return false; 1114 return false;
1100 1115
1101 if (index >= list_.size()) { 1116 if (index >= list_->size()) {
1102 // Pad out any intermediate indexes with null settings 1117 // Pad out any intermediate indexes with null settings
1103 while (index > list_.size()) 1118 while (index > list_->size())
1104 Append(CreateNullValue()); 1119 Append(CreateNullValue());
1105 Append(std::move(in_value)); 1120 Append(std::move(in_value));
1106 } else { 1121 } else {
1107 // TODO(dcheng): remove this DCHECK once the raw pointer version is removed? 1122 // TODO(dcheng): remove this DCHECK once the raw pointer version is removed?
1108 DCHECK(list_[index] != in_value); 1123 DCHECK((*list_)[index] != in_value);
1109 list_[index] = std::move(in_value); 1124 (*list_)[index] = std::move(in_value);
1110 } 1125 }
1111 return true; 1126 return true;
1112 } 1127 }
1113 1128
1114 bool ListValue::Get(size_t index, const Value** out_value) const { 1129 bool ListValue::Get(size_t index, const Value** out_value) const {
1115 if (index >= list_.size()) 1130 if (index >= list_->size())
1116 return false; 1131 return false;
1117 1132
1118 if (out_value) 1133 if (out_value)
1119 *out_value = list_[index].get(); 1134 *out_value = (*list_)[index].get();
1120 1135
1121 return true; 1136 return true;
1122 } 1137 }
1123 1138
1124 bool ListValue::Get(size_t index, Value** out_value) { 1139 bool ListValue::Get(size_t index, Value** out_value) {
1125 return static_cast<const ListValue&>(*this).Get( 1140 return static_cast<const ListValue&>(*this).Get(
1126 index, 1141 index,
1127 const_cast<const Value**>(out_value)); 1142 const_cast<const Value**>(out_value));
1128 } 1143 }
1129 1144
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 return true; 1231 return true;
1217 } 1232 }
1218 1233
1219 bool ListValue::GetList(size_t index, ListValue** out_value) { 1234 bool ListValue::GetList(size_t index, ListValue** out_value) {
1220 return static_cast<const ListValue&>(*this).GetList( 1235 return static_cast<const ListValue&>(*this).GetList(
1221 index, 1236 index,
1222 const_cast<const ListValue**>(out_value)); 1237 const_cast<const ListValue**>(out_value));
1223 } 1238 }
1224 1239
1225 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) { 1240 bool ListValue::Remove(size_t index, std::unique_ptr<Value>* out_value) {
1226 if (index >= list_.size()) 1241 if (index >= list_->size())
1227 return false; 1242 return false;
1228 1243
1229 if (out_value) 1244 if (out_value)
1230 *out_value = std::move(list_[index]); 1245 *out_value = std::move((*list_)[index]);
1231 1246
1232 list_.erase(list_.begin() + index); 1247 list_->erase(list_->begin() + index);
1233 return true; 1248 return true;
1234 } 1249 }
1235 1250
1236 bool ListValue::Remove(const Value& value, size_t* index) { 1251 bool ListValue::Remove(const Value& value, size_t* index) {
1237 for (auto it = list_.begin(); it != list_.end(); ++it) { 1252 for (auto it = list_->begin(); it != list_->end(); ++it) {
1238 if ((*it)->Equals(&value)) { 1253 if ((*it)->Equals(&value)) {
1239 size_t previous_index = it - list_.begin(); 1254 size_t previous_index = it - list_->begin();
1240 list_.erase(it); 1255 list_->erase(it);
1241 1256
1242 if (index) 1257 if (index)
1243 *index = previous_index; 1258 *index = previous_index;
1244 return true; 1259 return true;
1245 } 1260 }
1246 } 1261 }
1247 return false; 1262 return false;
1248 } 1263 }
1249 1264
1250 ListValue::iterator ListValue::Erase(iterator iter, 1265 ListValue::iterator ListValue::Erase(iterator iter,
1251 std::unique_ptr<Value>* out_value) { 1266 std::unique_ptr<Value>* out_value) {
1252 if (out_value) 1267 if (out_value)
1253 *out_value = std::move(*Storage::iterator(iter)); 1268 *out_value = std::move(*ListStorage::iterator(iter));
1254 1269
1255 return list_.erase(iter); 1270 return list_->erase(iter);
1256 } 1271 }
1257 1272
1258 void ListValue::Append(std::unique_ptr<Value> in_value) { 1273 void ListValue::Append(std::unique_ptr<Value> in_value) {
1259 list_.push_back(std::move(in_value)); 1274 list_->push_back(std::move(in_value));
1260 } 1275 }
1261 1276
1262 #if !defined(OS_LINUX) 1277 #if !defined(OS_LINUX)
1263 void ListValue::Append(Value* in_value) { 1278 void ListValue::Append(Value* in_value) {
1264 DCHECK(in_value); 1279 DCHECK(in_value);
1265 Append(WrapUnique(in_value)); 1280 Append(WrapUnique(in_value));
1266 } 1281 }
1267 #endif 1282 #endif
1268 1283
1269 void ListValue::AppendBoolean(bool in_value) { 1284 void ListValue::AppendBoolean(bool in_value) {
(...skipping 25 matching lines...) Expand all
1295 1310
1296 void ListValue::AppendStrings(const std::vector<string16>& in_values) { 1311 void ListValue::AppendStrings(const std::vector<string16>& in_values) {
1297 for (std::vector<string16>::const_iterator it = in_values.begin(); 1312 for (std::vector<string16>::const_iterator it = in_values.begin();
1298 it != in_values.end(); ++it) { 1313 it != in_values.end(); ++it) {
1299 AppendString(*it); 1314 AppendString(*it);
1300 } 1315 }
1301 } 1316 }
1302 1317
1303 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) { 1318 bool ListValue::AppendIfNotPresent(std::unique_ptr<Value> in_value) {
1304 DCHECK(in_value); 1319 DCHECK(in_value);
1305 for (const auto& entry : list_) { 1320 for (const auto& entry : *list_) {
1306 if (entry->Equals(in_value.get())) { 1321 if (entry->Equals(in_value.get())) {
1307 return false; 1322 return false;
1308 } 1323 }
1309 } 1324 }
1310 list_.push_back(std::move(in_value)); 1325 list_->push_back(std::move(in_value));
1311 return true; 1326 return true;
1312 } 1327 }
1313 1328
1314 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) { 1329 bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) {
1315 DCHECK(in_value); 1330 DCHECK(in_value);
1316 if (index > list_.size()) 1331 if (index > list_->size())
1317 return false; 1332 return false;
1318 1333
1319 list_.insert(list_.begin() + index, std::move(in_value)); 1334 list_->insert(list_->begin() + index, std::move(in_value));
1320 return true; 1335 return true;
1321 } 1336 }
1322 1337
1323 ListValue::const_iterator ListValue::Find(const Value& value) const { 1338 ListValue::const_iterator ListValue::Find(const Value& value) const {
1324 return std::find_if(list_.begin(), list_.end(), 1339 return std::find_if(list_->begin(), list_->end(),
1325 [&value](const std::unique_ptr<Value>& entry) { 1340 [&value](const std::unique_ptr<Value>& entry) {
1326 return entry->Equals(&value); 1341 return entry->Equals(&value);
1327 }); 1342 });
1328 } 1343 }
1329 1344
1330 void ListValue::Swap(ListValue* other) { 1345 void ListValue::Swap(ListValue* other) {
1331 list_.swap(other->list_); 1346 list_->swap(*(other->list_));
1332 }
1333
1334 bool ListValue::GetAsList(ListValue** out_value) {
1335 if (out_value)
1336 *out_value = this;
1337 return true;
1338 }
1339
1340 bool ListValue::GetAsList(const ListValue** out_value) const {
1341 if (out_value)
1342 *out_value = this;
1343 return true;
1344 } 1347 }
1345 1348
1346 ListValue* ListValue::DeepCopy() const { 1349 ListValue* ListValue::DeepCopy() const {
1347 ListValue* result = new ListValue; 1350 return static_cast<ListValue*>(Value::DeepCopy());
1348
1349 for (const auto& entry : list_)
1350 result->Append(entry->CreateDeepCopy());
1351
1352 return result;
1353 } 1351 }
1354 1352
1355 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const { 1353 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const {
1356 return WrapUnique(DeepCopy()); 1354 return WrapUnique(DeepCopy());
1357 } 1355 }
1358 1356
1359 bool ListValue::Equals(const Value* other) const {
1360 if (other->GetType() != GetType())
1361 return false;
1362
1363 const ListValue* other_list =
1364 static_cast<const ListValue*>(other);
1365 Storage::const_iterator lhs_it, rhs_it;
1366 for (lhs_it = begin(), rhs_it = other_list->begin();
1367 lhs_it != end() && rhs_it != other_list->end();
1368 ++lhs_it, ++rhs_it) {
1369 if (!(*lhs_it)->Equals(rhs_it->get()))
1370 return false;
1371 }
1372 if (lhs_it != end() || rhs_it != other_list->end())
1373 return false;
1374
1375 return true;
1376 }
1377
1378 ValueSerializer::~ValueSerializer() { 1357 ValueSerializer::~ValueSerializer() {
1379 } 1358 }
1380 1359
1381 ValueDeserializer::~ValueDeserializer() { 1360 ValueDeserializer::~ValueDeserializer() {
1382 } 1361 }
1383 1362
1384 std::ostream& operator<<(std::ostream& out, const Value& value) { 1363 std::ostream& operator<<(std::ostream& out, const Value& value) {
1385 std::string json; 1364 std::string json;
1386 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json); 1365 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json);
1387 return out << json; 1366 return out << json;
1388 } 1367 }
1389 1368
1390 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { 1369 std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1391 if (static_cast<int>(type) < 0 || 1370 if (static_cast<int>(type) < 0 ||
1392 static_cast<size_t>(type) >= arraysize(kTypeNames)) 1371 static_cast<size_t>(type) >= arraysize(kTypeNames))
1393 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; 1372 return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1394 return out << Value::GetTypeName(type); 1373 return out << Value::GetTypeName(type);
1395 } 1374 }
1396 1375
1397 } // namespace base 1376 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698