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

Side by Side Diff: base/values.cc

Issue 1150863002: Make DictionaryValue::DeepCopyWithoutEmptyChildren return a scoped_ptr (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove semicolons Created 5 years, 7 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
« no previous file with comments | « base/values.h ('k') | base/values_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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>
11 #include <ostream> 11 #include <ostream>
12 12
13 #include "base/json/json_writer.h" 13 #include "base/json/json_writer.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/move.h" 15 #include "base/move.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 18
19 namespace base { 19 namespace base {
20 20
21 namespace { 21 namespace {
22 22
23 scoped_ptr<Value> CopyWithoutEmptyChildren(const Value& node);
24
23 // Make a deep copy of |node|, but don't include empty lists or dictionaries 25 // Make a deep copy of |node|, but don't include empty lists or dictionaries
24 // in the copy. It's possible for this function to return NULL and it 26 // in the copy. It's possible for this function to return NULL and it
25 // expects |node| to always be non-NULL. 27 // expects |node| to always be non-NULL.
26 Value* CopyWithoutEmptyChildren(const Value* node) { 28 scoped_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) {
27 DCHECK(node); 29 scoped_ptr<ListValue> copy;
28 switch (node->GetType()) { 30 for (ListValue::const_iterator it = list.begin(); it != list.end(); ++it) {
29 case Value::TYPE_LIST: { 31 scoped_ptr<Value> child_copy = CopyWithoutEmptyChildren(**it);
30 const ListValue* list = static_cast<const ListValue*>(node); 32 if (child_copy) {
31 ListValue* copy = new ListValue; 33 if (!copy)
32 for (ListValue::const_iterator it = list->begin(); it != list->end(); 34 copy.reset(new ListValue);
33 ++it) { 35 copy->Append(child_copy.Pass());
34 Value* child_copy = CopyWithoutEmptyChildren(*it); 36 }
35 if (child_copy) 37 }
36 copy->Append(child_copy); 38 return copy;
37 } 39 }
38 if (!copy->empty())
39 return copy;
40 40
41 delete copy; 41 scoped_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren(
42 return NULL; 42 const DictionaryValue& dict) {
43 scoped_ptr<DictionaryValue> copy;
44 for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
45 scoped_ptr<Value> child_copy = CopyWithoutEmptyChildren(it.value());
46 if (child_copy) {
47 if (!copy)
48 copy.reset(new DictionaryValue);
49 copy->SetWithoutPathExpansion(it.key(), child_copy.Pass());
43 } 50 }
51 }
52 return copy;
53 }
44 54
45 case Value::TYPE_DICTIONARY: { 55 scoped_ptr<Value> CopyWithoutEmptyChildren(const Value& node) {
46 const DictionaryValue* dict = static_cast<const DictionaryValue*>(node); 56 switch (node.GetType()) {
47 DictionaryValue* copy = new DictionaryValue; 57 case Value::TYPE_LIST:
48 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { 58 return CopyListWithoutEmptyChildren(static_cast<const ListValue&>(node));
49 Value* child_copy = CopyWithoutEmptyChildren(&it.value());
50 if (child_copy)
51 copy->SetWithoutPathExpansion(it.key(), child_copy);
52 }
53 if (!copy->empty())
54 return copy;
55 59
56 delete copy; 60 case Value::TYPE_DICTIONARY:
57 return NULL; 61 return CopyDictionaryWithoutEmptyChildren(
58 } 62 static_cast<const DictionaryValue&>(node));
59 63
60 default: 64 default:
61 // For everything else, just make a copy. 65 return node.CreateDeepCopy();
62 return node->DeepCopy();
63 } 66 }
64 } 67 }
65 68
66 // A small functor for comparing Values for std::find_if and similar. 69 // A small functor for comparing Values for std::find_if and similar.
67 class ValueEquals { 70 class ValueEquals {
68 public: 71 public:
69 // Pass the value against which all consecutive calls of the () operator will 72 // Pass the value against which all consecutive calls of the () operator will
70 // compare their argument to. This Value object must not be destroyed while 73 // compare their argument to. This Value object must not be destroyed while
71 // the ValueEquals is in use. 74 // the ValueEquals is in use.
72 explicit ValueEquals(const Value* first) : first_(first) { } 75 explicit ValueEquals(const Value* first) : first_(first) { }
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 if (!GetDictionary(subdict_path, &subdict)) 785 if (!GetDictionary(subdict_path, &subdict))
783 return false; 786 return false;
784 result = subdict->RemovePath(path.substr(delimiter_position + 1), 787 result = subdict->RemovePath(path.substr(delimiter_position + 1),
785 out_value); 788 out_value);
786 if (result && subdict->empty()) 789 if (result && subdict->empty())
787 RemoveWithoutPathExpansion(subdict_path, NULL); 790 RemoveWithoutPathExpansion(subdict_path, NULL);
788 791
789 return result; 792 return result;
790 } 793 }
791 794
792 DictionaryValue* DictionaryValue::DeepCopyWithoutEmptyChildren() const { 795 scoped_ptr<DictionaryValue> DictionaryValue::DeepCopyWithoutEmptyChildren()
793 Value* copy = CopyWithoutEmptyChildren(this); 796 const {
794 return copy ? static_cast<DictionaryValue*>(copy) : new DictionaryValue; 797 scoped_ptr<DictionaryValue> copy = CopyDictionaryWithoutEmptyChildren(*this);
798 if (!copy)
799 copy.reset(new DictionaryValue);
800 return copy;
795 } 801 }
796 802
797 void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) { 803 void DictionaryValue::MergeDictionary(const DictionaryValue* dictionary) {
798 for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) { 804 for (DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) {
799 const Value* merge_value = &it.value(); 805 const Value* merge_value = &it.value();
800 // Check whether we have to merge dictionaries. 806 // Check whether we have to merge dictionaries.
801 if (merge_value->IsType(Value::TYPE_DICTIONARY)) { 807 if (merge_value->IsType(Value::TYPE_DICTIONARY)) {
802 DictionaryValue* sub_dict; 808 DictionaryValue* sub_dict;
803 if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) { 809 if (GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) {
804 sub_dict->MergeDictionary( 810 sub_dict->MergeDictionary(
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 ValueDeserializer::~ValueDeserializer() { 1172 ValueDeserializer::~ValueDeserializer() {
1167 } 1173 }
1168 1174
1169 std::ostream& operator<<(std::ostream& out, const Value& value) { 1175 std::ostream& operator<<(std::ostream& out, const Value& value) {
1170 std::string json; 1176 std::string json;
1171 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json); 1177 JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json);
1172 return out << json; 1178 return out << json;
1173 } 1179 }
1174 1180
1175 } // namespace base 1181 } // namespace base
OLDNEW
« no previous file with comments | « base/values.h ('k') | base/values_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698