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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) { | 62 std::unique_ptr<Value> CopyWithoutEmptyChildren(const Value& node) { |
63 switch (node.GetType()) { | 63 switch (node.GetType()) { |
64 case Value::Type::LIST: | 64 case Value::Type::LIST: |
65 return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node)); | 65 return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node)); |
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 MakeUnique<Value>(node); |
73 } | 73 } |
74 } | 74 } |
75 | 75 |
76 } // namespace | 76 } // namespace |
77 | 77 |
78 // static | 78 // static |
79 std::unique_ptr<Value> Value::CreateNullValue() { | 79 std::unique_ptr<Value> Value::CreateNullValue() { |
80 return WrapUnique(new Value(Type::NONE)); | 80 return WrapUnique(new Value(Type::NONE)); |
81 } | 81 } |
82 | 82 |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 | 334 |
335 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { | 335 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { |
336 if (out_value && is_dict()) { | 336 if (out_value && is_dict()) { |
337 *out_value = static_cast<const DictionaryValue*>(this); | 337 *out_value = static_cast<const DictionaryValue*>(this); |
338 return true; | 338 return true; |
339 } | 339 } |
340 return is_dict(); | 340 return is_dict(); |
341 } | 341 } |
342 | 342 |
343 Value* Value::DeepCopy() const { | 343 Value* Value::DeepCopy() const { |
344 // This method should only be getting called for null Values--all subclasses | 344 return new Value(*this); |
345 // need to provide their own implementation;. | |
346 switch (type()) { | |
347 case Type::NONE: | |
348 return CreateNullValue().release(); | |
349 | |
350 case Type::BOOLEAN: | |
351 return new Value(bool_value_); | |
352 case Type::INTEGER: | |
353 return new Value(int_value_); | |
354 case Type::DOUBLE: | |
355 return new Value(double_value_); | |
356 case Type::STRING: | |
357 return new Value(*string_value_); | |
358 // For now, make BinaryValues for backward-compatibility. Convert to | |
359 // Value when that code is deleted. | |
360 case Type::BINARY: | |
361 return new Value(*binary_value_); | |
362 | |
363 // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue | |
364 // are completely inlined. | |
365 case Type::DICTIONARY: { | |
366 DictionaryValue* result = new DictionaryValue; | |
367 | |
368 for (const auto& current_entry : **dict_ptr_) { | |
369 result->SetWithoutPathExpansion(current_entry.first, | |
370 current_entry.second->CreateDeepCopy()); | |
371 } | |
372 | |
373 return result; | |
374 } | |
375 | |
376 case Type::LIST: { | |
377 ListValue* result = new ListValue; | |
378 | |
379 for (const auto& entry : *list_) | |
380 result->Append(entry->CreateDeepCopy()); | |
381 | |
382 return result; | |
383 } | |
384 | |
385 default: | |
386 NOTREACHED(); | |
387 return nullptr; | |
388 } | |
389 } | 345 } |
390 | 346 |
391 std::unique_ptr<Value> Value::CreateDeepCopy() const { | 347 std::unique_ptr<Value> Value::CreateDeepCopy() const { |
392 return WrapUnique(DeepCopy()); | 348 return MakeUnique<Value>(*this); |
393 } | 349 } |
394 | 350 |
395 bool operator==(const Value& lhs, const Value& rhs) { | 351 bool operator==(const Value& lhs, const Value& rhs) { |
396 if (lhs.type_ != rhs.type_) | 352 if (lhs.type_ != rhs.type_) |
397 return false; | 353 return false; |
398 | 354 |
399 switch (lhs.type_) { | 355 switch (lhs.type_) { |
400 case Value::Type::NONE: | 356 case Value::Type::NONE: |
401 return true; | 357 return true; |
402 case Value::Type::BOOLEAN: | 358 case Value::Type::BOOLEAN: |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 InternalCopyFundamentalValue(that); | 491 InternalCopyFundamentalValue(that); |
536 return; | 492 return; |
537 | 493 |
538 case Type::STRING: | 494 case Type::STRING: |
539 string_value_.Init(*that.string_value_); | 495 string_value_.Init(*that.string_value_); |
540 return; | 496 return; |
541 case Type::BINARY: | 497 case Type::BINARY: |
542 binary_value_.Init(*that.binary_value_); | 498 binary_value_.Init(*that.binary_value_); |
543 return; | 499 return; |
544 // DictStorage and ListStorage are move-only types due to the presence of | 500 // DictStorage and ListStorage are move-only types due to the presence of |
545 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. | 501 // unique_ptrs. This is why the explicit copy of every element is necessary |
| 502 // here. |
546 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage | 503 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage |
547 // can be copied directly. | 504 // can be copied directly. |
548 case Type::DICTIONARY: | 505 case Type::DICTIONARY: |
549 dict_ptr_.Init(std::move(*that.CreateDeepCopy()->dict_ptr_)); | 506 dict_ptr_.Init(MakeUnique<DictStorage>()); |
| 507 for (const auto& it : **that.dict_ptr_) { |
| 508 (*dict_ptr_) |
| 509 ->emplace_hint((*dict_ptr_)->end(), it.first, |
| 510 MakeUnique<Value>(*it.second)); |
| 511 } |
550 return; | 512 return; |
551 case Type::LIST: | 513 case Type::LIST: |
552 list_.Init(std::move(*that.CreateDeepCopy()->list_)); | 514 list_.Init(); |
| 515 list_->reserve(that.list_->size()); |
| 516 for (const auto& it : *that.list_) |
| 517 list_->push_back(MakeUnique<Value>(*it)); |
553 return; | 518 return; |
554 } | 519 } |
555 } | 520 } |
556 | 521 |
557 void Value::InternalMoveConstructFrom(Value&& that) { | 522 void Value::InternalMoveConstructFrom(Value&& that) { |
558 type_ = that.type_; | 523 type_ = that.type_; |
559 | 524 |
560 switch (type_) { | 525 switch (type_) { |
561 case Type::NONE: | 526 case Type::NONE: |
562 case Type::BOOLEAN: | 527 case Type::BOOLEAN: |
(...skipping 30 matching lines...) Expand all Loading... |
593 InternalCopyFundamentalValue(that); | 558 InternalCopyFundamentalValue(that); |
594 return; | 559 return; |
595 | 560 |
596 case Type::STRING: | 561 case Type::STRING: |
597 *string_value_ = *that.string_value_; | 562 *string_value_ = *that.string_value_; |
598 return; | 563 return; |
599 case Type::BINARY: | 564 case Type::BINARY: |
600 *binary_value_ = *that.binary_value_; | 565 *binary_value_ = *that.binary_value_; |
601 return; | 566 return; |
602 // DictStorage and ListStorage are move-only types due to the presence of | 567 // DictStorage and ListStorage are move-only types due to the presence of |
603 // unique_ptrs. This is why the call to |CreateDeepCopy| is necessary here. | 568 // unique_ptrs. This is why the explicit call to the copy constructor is |
| 569 // necessary here. |
604 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage | 570 // TODO(crbug.com/646113): Clean this up when DictStorage and ListStorage |
605 // can be copied directly. | 571 // can be copied directly. |
606 case Type::DICTIONARY: | 572 case Type::DICTIONARY: |
607 *dict_ptr_ = std::move(*that.CreateDeepCopy()->dict_ptr_); | 573 *dict_ptr_ = std::move(*Value(that).dict_ptr_); |
608 return; | 574 return; |
609 case Type::LIST: | 575 case Type::LIST: |
610 *list_ = std::move(*that.CreateDeepCopy()->list_); | 576 *list_ = std::move(*Value(that).list_); |
611 return; | 577 return; |
612 } | 578 } |
613 } | 579 } |
614 | 580 |
615 void Value::InternalCleanup() { | 581 void Value::InternalCleanup() { |
616 switch (type_) { | 582 switch (type_) { |
617 case Type::NONE: | 583 case Type::NONE: |
618 case Type::BOOLEAN: | 584 case Type::BOOLEAN: |
619 case Type::INTEGER: | 585 case Type::INTEGER: |
620 case Type::DOUBLE: | 586 case Type::DOUBLE: |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 // Check whether we have to merge dictionaries. | 1032 // Check whether we have to merge dictionaries. |
1067 if (merge_value->IsType(Value::Type::DICTIONARY)) { | 1033 if (merge_value->IsType(Value::Type::DICTIONARY)) { |
1068 DictionaryValue* sub_dict; | 1034 DictionaryValue* sub_dict; |
1069 if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) { | 1035 if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) { |
1070 sub_dict->MergeDictionary( | 1036 sub_dict->MergeDictionary( |
1071 static_cast<const DictionaryValue*>(merge_value)); | 1037 static_cast<const DictionaryValue*>(merge_value)); |
1072 continue; | 1038 continue; |
1073 } | 1039 } |
1074 } | 1040 } |
1075 // All other cases: Make a copy and hook it up. | 1041 // All other cases: Make a copy and hook it up. |
1076 SetWithoutPathExpansion(it.key(), | 1042 SetWithoutPathExpansion(it.key(), MakeUnique<Value>(*merge_value)); |
1077 base::WrapUnique(merge_value->DeepCopy())); | |
1078 } | 1043 } |
1079 } | 1044 } |
1080 | 1045 |
1081 void DictionaryValue::Swap(DictionaryValue* other) { | 1046 void DictionaryValue::Swap(DictionaryValue* other) { |
1082 CHECK(other->is_dict()); | 1047 CHECK(other->is_dict()); |
1083 dict_ptr_->swap(*(other->dict_ptr_)); | 1048 dict_ptr_->swap(*(other->dict_ptr_)); |
1084 } | 1049 } |
1085 | 1050 |
1086 DictionaryValue::Iterator::Iterator(const DictionaryValue& target) | 1051 DictionaryValue::Iterator::Iterator(const DictionaryValue& target) |
1087 : target_(target), it_((*target.dict_ptr_)->begin()) {} | 1052 : target_(target), it_((*target.dict_ptr_)->begin()) {} |
1088 | 1053 |
1089 DictionaryValue::Iterator::Iterator(const Iterator& other) = default; | 1054 DictionaryValue::Iterator::Iterator(const Iterator& other) = default; |
1090 | 1055 |
1091 DictionaryValue::Iterator::~Iterator() {} | 1056 DictionaryValue::Iterator::~Iterator() {} |
1092 | 1057 |
1093 DictionaryValue* DictionaryValue::DeepCopy() const { | 1058 DictionaryValue* DictionaryValue::DeepCopy() const { |
1094 return static_cast<DictionaryValue*>(Value::DeepCopy()); | 1059 return new DictionaryValue(*this); |
1095 } | 1060 } |
1096 | 1061 |
1097 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const { | 1062 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const { |
1098 return WrapUnique(DeepCopy()); | 1063 return MakeUnique<DictionaryValue>(*this); |
1099 } | 1064 } |
1100 | 1065 |
1101 ///////////////////// ListValue //////////////////// | 1066 ///////////////////// ListValue //////////////////// |
1102 | 1067 |
1103 // static | 1068 // static |
1104 std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) { | 1069 std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) { |
1105 ListValue* out; | 1070 ListValue* out; |
1106 if (value && value->GetAsList(&out)) { | 1071 if (value && value->GetAsList(&out)) { |
1107 ignore_result(value.release()); | 1072 ignore_result(value.release()); |
1108 return WrapUnique(out); | 1073 return WrapUnique(out); |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1351 return *entry == value; | 1316 return *entry == value; |
1352 }); | 1317 }); |
1353 } | 1318 } |
1354 | 1319 |
1355 void ListValue::Swap(ListValue* other) { | 1320 void ListValue::Swap(ListValue* other) { |
1356 CHECK(other->is_list()); | 1321 CHECK(other->is_list()); |
1357 list_->swap(*(other->list_)); | 1322 list_->swap(*(other->list_)); |
1358 } | 1323 } |
1359 | 1324 |
1360 ListValue* ListValue::DeepCopy() const { | 1325 ListValue* ListValue::DeepCopy() const { |
1361 return static_cast<ListValue*>(Value::DeepCopy()); | 1326 return new ListValue(*this); |
1362 } | 1327 } |
1363 | 1328 |
1364 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const { | 1329 std::unique_ptr<ListValue> ListValue::CreateDeepCopy() const { |
1365 return WrapUnique(DeepCopy()); | 1330 return MakeUnique<ListValue>(*this); |
1366 } | 1331 } |
1367 | 1332 |
1368 ValueSerializer::~ValueSerializer() { | 1333 ValueSerializer::~ValueSerializer() { |
1369 } | 1334 } |
1370 | 1335 |
1371 ValueDeserializer::~ValueDeserializer() { | 1336 ValueDeserializer::~ValueDeserializer() { |
1372 } | 1337 } |
1373 | 1338 |
1374 std::ostream& operator<<(std::ostream& out, const Value& value) { | 1339 std::ostream& operator<<(std::ostream& out, const Value& value) { |
1375 std::string json; | 1340 std::string json; |
1376 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json); | 1341 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json); |
1377 return out << json; | 1342 return out << json; |
1378 } | 1343 } |
1379 | 1344 |
1380 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { | 1345 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { |
1381 if (static_cast<int>(type) < 0 || | 1346 if (static_cast<int>(type) < 0 || |
1382 static_cast<size_t>(type) >= arraysize(kTypeNames)) | 1347 static_cast<size_t>(type) >= arraysize(kTypeNames)) |
1383 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; | 1348 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; |
1384 return out << Value::GetTypeName(type); | 1349 return out << Value::GetTypeName(type); |
1385 } | 1350 } |
1386 | 1351 |
1387 } // namespace base | 1352 } // namespace base |
OLD | NEW |