Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 dict_ptr_.Init(MakeUnique<DictStorage>()); |
| 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 Loading... | |
| 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 Loading... | |
| 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 : **dict_ptr_) { | |
| 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 ((*dict_ptr_)->size() != (*other->dict_ptr_)->size()) |
| 402 return false; | 426 return false; |
| 427 | |
| 428 return std::equal(std::begin(**dict_ptr_), std::end(**dict_ptr_), | |
| 429 std::begin(**(other->dict_ptr_)), | |
| 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 Loading... | |
| 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 | |
| 453 // classes are removed. | |
| 454 case Type::LIST: | 501 case Type::LIST: |
| 455 case Type::DICTIONARY: | 502 // Currently not implementable due to the presence of unique_ptrs in |
|
brettw
2017/02/14 23:15:04
I don't quite follow. Shouldn't this be the same a
jdoerrie
2017/02/15 15:29:08
Yes, you are right. When writing this I just consi
| |
| 503 // DictStorage and ListStorage. | |
| 504 // TODO(crbug.com/646113): Implement this when DictionaryValues and | |
| 505 // ListValues are completely inlined. | |
| 506 NOTREACHED(); | |
| 456 return; | 507 return; |
| 457 } | 508 } |
| 458 } | 509 } |
| 459 | 510 |
| 460 void Value::InternalMoveConstructFrom(Value&& that) { | 511 void Value::InternalMoveConstructFrom(Value&& that) { |
| 461 type_ = that.type_; | 512 type_ = that.type_; |
| 462 | 513 |
| 463 switch (type_) { | 514 switch (type_) { |
| 464 case Type::NONE: | 515 case Type::NONE: |
| 465 case Type::BOOLEAN: | 516 case Type::BOOLEAN: |
| 466 case Type::INTEGER: | 517 case Type::INTEGER: |
| 467 case Type::DOUBLE: | 518 case Type::DOUBLE: |
| 468 InternalCopyFundamentalValue(that); | 519 InternalCopyFundamentalValue(that); |
| 469 return; | 520 return; |
| 470 | 521 |
| 471 case Type::STRING: | 522 case Type::STRING: |
| 472 string_value_.InitFromMove(std::move(that.string_value_)); | 523 string_value_.InitFromMove(std::move(that.string_value_)); |
| 473 return; | 524 return; |
| 474 case Type::BINARY: | 525 case Type::BINARY: |
| 475 binary_value_.InitFromMove(std::move(that.binary_value_)); | 526 binary_value_.InitFromMove(std::move(that.binary_value_)); |
| 476 return; | 527 return; |
| 477 | 528 case Type::DICTIONARY: |
| 478 // TODO(crbug.com/646113): Implement these once the corresponding derived | 529 dict_ptr_.InitFromMove(std::move(that.dict_ptr_)); |
| 479 // classes are removed. | 530 return; |
| 480 case Type::LIST: | 531 case Type::LIST: |
| 481 case Type::DICTIONARY: | 532 list_.InitFromMove(std::move(that.list_)); |
| 482 return; | 533 return; |
| 483 } | 534 } |
| 484 } | 535 } |
| 485 | 536 |
| 486 void Value::InternalCopyAssignFrom(const Value& that) { | 537 void Value::InternalCopyAssignFrom(const Value& that) { |
| 487 type_ = that.type_; | 538 type_ = that.type_; |
| 488 | 539 |
| 489 switch (type_) { | 540 switch (type_) { |
| 490 case Type::NONE: | 541 case Type::NONE: |
| 491 case Type::BOOLEAN: | 542 case Type::BOOLEAN: |
| 492 case Type::INTEGER: | 543 case Type::INTEGER: |
| 493 case Type::DOUBLE: | 544 case Type::DOUBLE: |
| 494 InternalCopyFundamentalValue(that); | 545 InternalCopyFundamentalValue(that); |
| 495 return; | 546 return; |
| 496 | 547 |
| 497 case Type::STRING: | 548 case Type::STRING: |
| 498 *string_value_ = *that.string_value_; | 549 *string_value_ = *that.string_value_; |
| 499 return; | 550 return; |
| 500 case Type::BINARY: | 551 case Type::BINARY: |
| 501 *binary_value_ = *that.binary_value_; | 552 *binary_value_ = *that.binary_value_; |
| 502 return; | 553 return; |
| 503 | 554 case Type::DICTIONARY: |
| 504 // TODO(crbug.com/646113): Implement these once the corresponding derived | |
| 505 // classes are removed. | |
| 506 case Type::LIST: | 555 case Type::LIST: |
| 507 case Type::DICTIONARY: | 556 // Currently not implementable due to the presence of unique_ptrs in |
|
brettw
2017/02/14 23:15:05
Same here.
jdoerrie
2017/02/15 15:29:08
Acknowledged.
| |
| 557 // DictStorage and ListStorage. | |
| 558 // TODO(crbug.com/646113): Implement this when DictionaryValues and | |
| 559 // ListValues are completely inlined. | |
| 560 NOTREACHED(); | |
| 508 return; | 561 return; |
| 509 } | 562 } |
| 510 } | 563 } |
| 511 | 564 |
| 512 void Value::InternalMoveAssignFrom(Value&& that) { | 565 void Value::InternalMoveAssignFrom(Value&& that) { |
| 513 type_ = that.type_; | 566 type_ = that.type_; |
| 514 | 567 |
| 515 switch (type_) { | 568 switch (type_) { |
| 516 case Type::NONE: | 569 case Type::NONE: |
| 517 case Type::BOOLEAN: | 570 case Type::BOOLEAN: |
| 518 case Type::INTEGER: | 571 case Type::INTEGER: |
| 519 case Type::DOUBLE: | 572 case Type::DOUBLE: |
| 520 InternalCopyFundamentalValue(that); | 573 InternalCopyFundamentalValue(that); |
| 521 return; | 574 return; |
| 522 | 575 |
| 523 case Type::STRING: | 576 case Type::STRING: |
| 524 *string_value_ = std::move(*that.string_value_); | 577 *string_value_ = std::move(*that.string_value_); |
| 525 return; | 578 return; |
| 526 case Type::BINARY: | 579 case Type::BINARY: |
| 527 *binary_value_ = std::move(*that.binary_value_); | 580 *binary_value_ = std::move(*that.binary_value_); |
| 528 return; | 581 return; |
| 529 | 582 case Type::DICTIONARY: |
| 530 // TODO(crbug.com/646113): Implement these once the corresponding derived | 583 *dict_ptr_ = std::move(*that.dict_ptr_); |
| 531 // classes are removed. | 584 return; |
| 532 case Type::LIST: | 585 case Type::LIST: |
| 533 case Type::DICTIONARY: | 586 *list_ = std::move(*that.list_); |
| 534 return; | 587 return; |
| 535 } | 588 } |
| 536 } | 589 } |
| 537 | 590 |
| 538 void Value::InternalCleanup() { | 591 void Value::InternalCleanup() { |
| 539 switch (type_) { | 592 switch (type_) { |
| 540 case Type::NONE: | 593 case Type::NONE: |
| 541 case Type::BOOLEAN: | 594 case Type::BOOLEAN: |
| 542 case Type::INTEGER: | 595 case Type::INTEGER: |
| 543 case Type::DOUBLE: | 596 case Type::DOUBLE: |
| 544 // Nothing to do | 597 // Nothing to do |
| 545 return; | 598 return; |
| 546 | 599 |
| 547 case Type::STRING: | 600 case Type::STRING: |
| 548 string_value_.Destroy(); | 601 string_value_.Destroy(); |
| 549 return; | 602 return; |
| 550 case Type::BINARY: | 603 case Type::BINARY: |
| 551 binary_value_.Destroy(); | 604 binary_value_.Destroy(); |
| 552 return; | 605 return; |
| 553 | 606 case Type::DICTIONARY: |
| 554 // TODO(crbug.com/646113): Implement these once the corresponding derived | 607 dict_ptr_.Destroy(); |
| 555 // classes are removed. | 608 return; |
| 556 case Type::LIST: | 609 case Type::LIST: |
| 557 case Type::DICTIONARY: | 610 list_.Destroy(); |
| 558 return; | 611 return; |
| 559 } | 612 } |
| 560 } | 613 } |
| 561 | 614 |
| 562 ///////////////////// DictionaryValue //////////////////// | 615 ///////////////////// DictionaryValue //////////////////// |
| 563 | 616 |
| 564 // static | 617 // static |
| 565 std::unique_ptr<DictionaryValue> DictionaryValue::From( | 618 std::unique_ptr<DictionaryValue> DictionaryValue::From( |
| 566 std::unique_ptr<Value> value) { | 619 std::unique_ptr<Value> value) { |
| 567 DictionaryValue* out; | 620 DictionaryValue* out; |
| 568 if (value && value->GetAsDictionary(&out)) { | 621 if (value && value->GetAsDictionary(&out)) { |
| 569 ignore_result(value.release()); | 622 ignore_result(value.release()); |
| 570 return WrapUnique(out); | 623 return WrapUnique(out); |
| 571 } | 624 } |
| 572 return nullptr; | 625 return nullptr; |
| 573 } | 626 } |
| 574 | 627 |
| 575 DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {} | 628 DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {} |
| 576 | 629 |
| 577 DictionaryValue::~DictionaryValue() { | 630 DictionaryValue::DictionaryValue(DictionaryValue&& that) = default; |
| 578 Clear(); | |
| 579 } | |
| 580 | 631 |
| 581 bool DictionaryValue::GetAsDictionary(DictionaryValue** out_value) { | 632 DictionaryValue& DictionaryValue::operator=(DictionaryValue&& that) = default; |
| 582 if (out_value) | |
| 583 *out_value = this; | |
| 584 return true; | |
| 585 } | |
| 586 | 633 |
| 587 bool DictionaryValue::GetAsDictionary(const DictionaryValue** out_value) const { | 634 DictionaryValue::~DictionaryValue() = default; |
| 588 if (out_value) | |
| 589 *out_value = this; | |
| 590 return true; | |
| 591 } | |
| 592 | 635 |
| 593 bool DictionaryValue::HasKey(StringPiece key) const { | 636 bool DictionaryValue::HasKey(StringPiece key) const { |
| 594 DCHECK(IsStringUTF8(key)); | 637 DCHECK(IsStringUTF8(key)); |
| 595 auto current_entry = dictionary_.find(key.as_string()); | 638 auto current_entry = (*dict_ptr_)->find(key.as_string()); |
| 596 DCHECK((current_entry == dictionary_.end()) || current_entry->second); | 639 DCHECK((current_entry == (*dict_ptr_)->end()) || current_entry->second); |
| 597 return current_entry != dictionary_.end(); | 640 return current_entry != (*dict_ptr_)->end(); |
| 598 } | 641 } |
| 599 | 642 |
| 600 void DictionaryValue::Clear() { | 643 void DictionaryValue::Clear() { |
| 601 dictionary_.clear(); | 644 (*dict_ptr_)->clear(); |
| 602 } | 645 } |
| 603 | 646 |
| 604 void DictionaryValue::Set(StringPiece path, std::unique_ptr<Value> in_value) { | 647 void DictionaryValue::Set(StringPiece path, std::unique_ptr<Value> in_value) { |
| 605 DCHECK(IsStringUTF8(path)); | 648 DCHECK(IsStringUTF8(path)); |
| 606 DCHECK(in_value); | 649 DCHECK(in_value); |
| 607 | 650 |
| 608 StringPiece current_path(path); | 651 StringPiece current_path(path); |
| 609 DictionaryValue* current_dictionary = this; | 652 DictionaryValue* current_dictionary = this; |
| 610 for (size_t delimiter_position = current_path.find('.'); | 653 for (size_t delimiter_position = current_path.find('.'); |
| 611 delimiter_position != StringPiece::npos; | 654 delimiter_position != StringPiece::npos; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 646 void DictionaryValue::SetString(StringPiece path, StringPiece in_value) { | 689 void DictionaryValue::SetString(StringPiece path, StringPiece in_value) { |
| 647 Set(path, new StringValue(in_value)); | 690 Set(path, new StringValue(in_value)); |
| 648 } | 691 } |
| 649 | 692 |
| 650 void DictionaryValue::SetString(StringPiece path, const string16& in_value) { | 693 void DictionaryValue::SetString(StringPiece path, const string16& in_value) { |
| 651 Set(path, new StringValue(in_value)); | 694 Set(path, new StringValue(in_value)); |
| 652 } | 695 } |
| 653 | 696 |
| 654 void DictionaryValue::SetWithoutPathExpansion(StringPiece key, | 697 void DictionaryValue::SetWithoutPathExpansion(StringPiece key, |
| 655 std::unique_ptr<Value> in_value) { | 698 std::unique_ptr<Value> in_value) { |
| 656 dictionary_[key.as_string()] = std::move(in_value); | 699 (**dict_ptr_)[key.as_string()] = std::move(in_value); |
| 657 } | 700 } |
| 658 | 701 |
| 659 void DictionaryValue::SetWithoutPathExpansion(StringPiece key, | 702 void DictionaryValue::SetWithoutPathExpansion(StringPiece key, |
| 660 Value* in_value) { | 703 Value* in_value) { |
| 661 SetWithoutPathExpansion(key, WrapUnique(in_value)); | 704 SetWithoutPathExpansion(key, WrapUnique(in_value)); |
| 662 } | 705 } |
| 663 | 706 |
| 664 void DictionaryValue::SetBooleanWithoutPathExpansion(StringPiece path, | 707 void DictionaryValue::SetBooleanWithoutPathExpansion(StringPiece path, |
| 665 bool in_value) { | 708 bool in_value) { |
| 666 SetWithoutPathExpansion(path, | 709 SetWithoutPathExpansion(path, |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 | 869 |
| 827 bool DictionaryValue::GetList(StringPiece path, ListValue** out_value) { | 870 bool DictionaryValue::GetList(StringPiece path, ListValue** out_value) { |
| 828 return static_cast<const DictionaryValue&>(*this).GetList( | 871 return static_cast<const DictionaryValue&>(*this).GetList( |
| 829 path, | 872 path, |
| 830 const_cast<const ListValue**>(out_value)); | 873 const_cast<const ListValue**>(out_value)); |
| 831 } | 874 } |
| 832 | 875 |
| 833 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key, | 876 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key, |
| 834 const Value** out_value) const { | 877 const Value** out_value) const { |
| 835 DCHECK(IsStringUTF8(key)); | 878 DCHECK(IsStringUTF8(key)); |
| 836 auto entry_iterator = dictionary_.find(key.as_string()); | 879 auto entry_iterator = (*dict_ptr_)->find(key.as_string()); |
| 837 if (entry_iterator == dictionary_.end()) | 880 if (entry_iterator == (*dict_ptr_)->end()) |
| 838 return false; | 881 return false; |
| 839 | 882 |
| 840 if (out_value) | 883 if (out_value) |
| 841 *out_value = entry_iterator->second.get(); | 884 *out_value = entry_iterator->second.get(); |
| 842 return true; | 885 return true; |
| 843 } | 886 } |
| 844 | 887 |
| 845 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key, | 888 bool DictionaryValue::GetWithoutPathExpansion(StringPiece key, |
| 846 Value** out_value) { | 889 Value** out_value) { |
| 847 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion( | 890 return static_cast<const DictionaryValue&>(*this).GetWithoutPathExpansion( |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 955 } | 998 } |
| 956 | 999 |
| 957 return current_dictionary->RemoveWithoutPathExpansion(current_path, | 1000 return current_dictionary->RemoveWithoutPathExpansion(current_path, |
| 958 out_value); | 1001 out_value); |
| 959 } | 1002 } |
| 960 | 1003 |
| 961 bool DictionaryValue::RemoveWithoutPathExpansion( | 1004 bool DictionaryValue::RemoveWithoutPathExpansion( |
| 962 StringPiece key, | 1005 StringPiece key, |
| 963 std::unique_ptr<Value>* out_value) { | 1006 std::unique_ptr<Value>* out_value) { |
| 964 DCHECK(IsStringUTF8(key)); | 1007 DCHECK(IsStringUTF8(key)); |
| 965 auto entry_iterator = dictionary_.find(key.as_string()); | 1008 auto entry_iterator = (*dict_ptr_)->find(key.as_string()); |
| 966 if (entry_iterator == dictionary_.end()) | 1009 if (entry_iterator == (*dict_ptr_)->end()) |
| 967 return false; | 1010 return false; |
| 968 | 1011 |
| 969 if (out_value) | 1012 if (out_value) |
| 970 *out_value = std::move(entry_iterator->second); | 1013 *out_value = std::move(entry_iterator->second); |
| 971 dictionary_.erase(entry_iterator); | 1014 (*dict_ptr_)->erase(entry_iterator); |
| 972 return true; | 1015 return true; |
| 973 } | 1016 } |
| 974 | 1017 |
| 975 bool DictionaryValue::RemovePath(StringPiece path, | 1018 bool DictionaryValue::RemovePath(StringPiece path, |
| 976 std::unique_ptr<Value>* out_value) { | 1019 std::unique_ptr<Value>* out_value) { |
| 977 bool result = false; | 1020 bool result = false; |
| 978 size_t delimiter_position = path.find('.'); | 1021 size_t delimiter_position = path.find('.'); |
| 979 | 1022 |
| 980 if (delimiter_position == std::string::npos) | 1023 if (delimiter_position == std::string::npos) |
| 981 return RemoveWithoutPathExpansion(path, out_value); | 1024 return RemoveWithoutPathExpansion(path, out_value); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1013 continue; | 1056 continue; |
| 1014 } | 1057 } |
| 1015 } | 1058 } |
| 1016 // All other cases: Make a copy and hook it up. | 1059 // All other cases: Make a copy and hook it up. |
| 1017 SetWithoutPathExpansion(it.key(), | 1060 SetWithoutPathExpansion(it.key(), |
| 1018 base::WrapUnique(merge_value->DeepCopy())); | 1061 base::WrapUnique(merge_value->DeepCopy())); |
| 1019 } | 1062 } |
| 1020 } | 1063 } |
| 1021 | 1064 |
| 1022 void DictionaryValue::Swap(DictionaryValue* other) { | 1065 void DictionaryValue::Swap(DictionaryValue* other) { |
| 1023 dictionary_.swap(other->dictionary_); | 1066 dict_ptr_->swap(*(other->dict_ptr_)); |
| 1024 } | 1067 } |
| 1025 | 1068 |
| 1026 DictionaryValue::Iterator::Iterator(const DictionaryValue& target) | 1069 DictionaryValue::Iterator::Iterator(const DictionaryValue& target) |
| 1027 : target_(target), | 1070 : target_(target), it_((*target.dict_ptr_)->begin()) {} |
| 1028 it_(target.dictionary_.begin()) {} | |
| 1029 | 1071 |
| 1030 DictionaryValue::Iterator::Iterator(const Iterator& other) = default; | 1072 DictionaryValue::Iterator::Iterator(const Iterator& other) = default; |
| 1031 | 1073 |
| 1032 DictionaryValue::Iterator::~Iterator() {} | 1074 DictionaryValue::Iterator::~Iterator() {} |
| 1033 | 1075 |
| 1034 DictionaryValue* DictionaryValue::DeepCopy() const { | 1076 DictionaryValue* DictionaryValue::DeepCopy() const { |
| 1035 DictionaryValue* result = new DictionaryValue; | 1077 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 } | 1078 } |
| 1044 | 1079 |
| 1045 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const { | 1080 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const { |
| 1046 return WrapUnique(DeepCopy()); | 1081 return WrapUnique(DeepCopy()); |
| 1047 } | 1082 } |
| 1048 | 1083 |
| 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 //////////////////// | 1084 ///////////////////// ListValue //////////////////// |
| 1072 | 1085 |
| 1073 // static | 1086 // static |
| 1074 std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) { | 1087 std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) { |
| 1075 ListValue* out; | 1088 ListValue* out; |
| 1076 if (value && value->GetAsList(&out)) { | 1089 if (value && value->GetAsList(&out)) { |
| 1077 ignore_result(value.release()); | 1090 ignore_result(value.release()); |
| 1078 return WrapUnique(out); | 1091 return WrapUnique(out); |
| 1079 } | 1092 } |
| 1080 return nullptr; | 1093 return nullptr; |
| 1081 } | 1094 } |
| 1082 | 1095 |
| 1083 ListValue::ListValue() : Value(Type::LIST) {} | 1096 ListValue::ListValue() : Value(Type::LIST) {} |
| 1084 | 1097 |
| 1085 ListValue::~ListValue() { | 1098 ListValue::ListValue(ListValue&& that) = default; |
| 1086 Clear(); | 1099 |
| 1087 } | 1100 ListValue& ListValue::operator=(ListValue&& that) = default; |
| 1101 | |
| 1102 ListValue::~ListValue() = default; | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |