File 04-basevalue.patch of Package chromium.openSUSE_Leap_15.0_Update
From e169e6c645c6c6f3175b052ed32bc0818bd637ee Mon Sep 17 00:00:00 2001
From: David 'Digit' Turner <digit@google.com>
Date: Thu, 28 Mar 2019 22:06:29 +0000
Subject: [PATCH] base: Add Value::Set<Type>Key() methods
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This CL adds convenience methods to set dictionary
keys to typed values. This is much more efficient than
calling SetKey() because it avoids the caller creating
and destroying a temporary Value instance that is later
moved into a heap allocated instance.
+ Update base/ sources that use SetBoolean(), SetInteger(),
SetDouble() and SetString() to the new equivalent
functions.
BUG=646113
R=dcheng@chromium.org,jdoerrie@chromium.org,sdefresne@chromium.org,hidehiko@chromium.org
Change-Id: I39e472bec36eb2018b5af0a083b3d1e3622eaad1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1530911
Commit-Queue: David Turner <digit@chromium.org>
Reviewed-by: oysteine <oysteine@chromium.org>
Reviewed-by: Mark Pearson <mpearson@chromium.org>
Reviewed-by: François Doray <fdoray@chromium.org>
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#645529}
---
base/json/json_perftest.cc | 8 +-
base/json/json_writer_unittest.cc | 14 +-
base/metrics/histogram.cc | 12 +-
base/metrics/histogram_base.cc | 10 +-
base/process/process_metrics.cc | 2 +-
base/process/process_metrics_linux.cc | 42 +++---
base/task/task_scheduler/task_tracker.cc | 8 +-
base/test/gtest_util.cc | 8 +-
base/test/launcher/test_launcher_tracer.cc | 6 +-
base/test/launcher/test_results_tracker.cc | 30 ++---
base/trace_event/traced_value.cc | 20 ++-
base/values.cc | 38 +++++-
base/values.h | 19 +++
base/values_unittest.cc | 144 +++++++++++++++++----
14 files changed, 250 insertions(+), 111 deletions(-)
Index: chromium-74.0.3729.108/base/json/json_perftest.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/json/json_perftest.cc
+++ chromium-74.0.3729.108/base/json/json_perftest.cc
@@ -18,10 +18,10 @@ namespace {
// list.
std::unique_ptr<DictionaryValue> GenerateDict() {
auto root = std::make_unique<DictionaryValue>();
- root->SetDouble("Double", 3.141);
- root->SetBoolean("Bool", true);
- root->SetInteger("Int", 42);
- root->SetString("String", "Foo");
+ root->SetDoubleKey("Double", 3.141);
+ root->SetBoolKey("Bool", true);
+ root->SetIntKey("Int", 42);
+ root->SetStringKey("String", "Foo");
auto list = std::make_unique<ListValue>();
list->Set(0, std::make_unique<Value>(2.718));
Index: chromium-74.0.3729.108/base/json/json_writer_unittest.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/json/json_writer_unittest.cc
+++ chromium-74.0.3729.108/base/json/json_writer_unittest.cc
@@ -59,7 +59,7 @@ TEST(JSONWriterTest, NestedTypes) {
DictionaryValue root_dict;
std::unique_ptr<ListValue> list(new ListValue());
std::unique_ptr<DictionaryValue> inner_dict(new DictionaryValue());
- inner_dict->SetInteger("inner int", 10);
+ inner_dict->SetIntKey("inner int", 10);
list->Append(std::move(inner_dict));
list->Append(std::make_unique<ListValue>());
list->AppendBoolean(true);
@@ -91,17 +91,17 @@ TEST(JSONWriterTest, KeysWithPeriods) {
std::string output_js;
DictionaryValue period_dict;
- period_dict.SetKey("a.b", base::Value(3));
- period_dict.SetKey("c", base::Value(2));
+ period_dict.SetIntKey("a.b", 3);
+ period_dict.SetIntKey("c", 2);
std::unique_ptr<DictionaryValue> period_dict2(new DictionaryValue());
- period_dict2->SetKey("g.h.i.j", base::Value(1));
+ period_dict2->SetIntKey("g.h.i.j", 1);
period_dict.SetWithoutPathExpansion("d.e.f", std::move(period_dict2));
EXPECT_TRUE(JSONWriter::Write(period_dict, &output_js));
EXPECT_EQ("{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}", output_js);
DictionaryValue period_dict3;
period_dict3.SetInteger("a.b", 2);
- period_dict3.SetKey("a.b", base::Value(1));
+ period_dict3.SetIntKey("a.b", 1);
EXPECT_TRUE(JSONWriter::Write(period_dict3, &output_js));
EXPECT_EQ("{\"a\":{\"b\":2},\"a.b\":1}", output_js);
}
@@ -130,9 +130,9 @@ TEST(JSONWriterTest, BinaryValues) {
DictionaryValue binary_dict;
binary_dict.Set("a", Value::CreateWithCopiedBuffer("asdf", 4));
- binary_dict.SetInteger("b", 5);
+ binary_dict.SetIntKey("b", 5);
binary_dict.Set("c", Value::CreateWithCopiedBuffer("asdf", 4));
- binary_dict.SetInteger("d", 2);
+ binary_dict.SetIntKey("d", 2);
binary_dict.Set("e", Value::CreateWithCopiedBuffer("asdf", 4));
EXPECT_FALSE(JSONWriter::Write(binary_dict, &output_js));
EXPECT_TRUE(JSONWriter::WriteWithOptions(
Index: chromium-74.0.3729.108/base/metrics/histogram.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/metrics/histogram.cc
+++ chromium-74.0.3729.108/base/metrics/histogram.cc
@@ -810,9 +810,9 @@ void Histogram::WriteAsciiBucketContext(
void Histogram::GetParameters(DictionaryValue* params) const {
params->SetString("type", HistogramTypeToString(GetHistogramType()));
- params->SetInteger("min", declared_min());
- params->SetInteger("max", declared_max());
- params->SetInteger("bucket_count", static_cast<int>(bucket_count()));
+ params->SetIntKey("min", declared_min());
+ params->SetIntKey("max", declared_max());
+ params->SetIntKey("bucket_count", static_cast<int>(bucket_count()));
}
void Histogram::GetCountAndBucketData(Count* count,
@@ -826,10 +826,10 @@ void Histogram::GetCountAndBucketData(Co
Sample count_at_index = snapshot->GetCountAtIndex(i);
if (count_at_index > 0) {
std::unique_ptr<DictionaryValue> bucket_value(new DictionaryValue());
- bucket_value->SetInteger("low", ranges(i));
+ bucket_value->SetIntKey("low", ranges(i));
if (i != bucket_count() - 1)
- bucket_value->SetInteger("high", ranges(i + 1));
- bucket_value->SetInteger("count", count_at_index);
+ bucket_value->SetIntKey("high", ranges(i + 1));
+ bucket_value->SetIntKey("count", count_at_index);
buckets->Set(index, std::move(bucket_value));
++index;
}
Index: chromium-74.0.3729.108/base/metrics/histogram_base.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/metrics/histogram_base.cc
+++ chromium-74.0.3729.108/base/metrics/histogram_base.cc
@@ -152,14 +152,14 @@ void HistogramBase::WriteJSON(std::strin
JSONStringValueSerializer serializer(output);
DictionaryValue root;
- root.SetString("name", histogram_name());
- root.SetInteger("count", count);
- root.SetDouble("sum", static_cast<double>(sum));
- root.SetInteger("flags", flags());
+ root.SetStringKey("name", histogram_name());
+ root.SetIntKey("count", count);
+ root.SetDoubleKey("sum", static_cast<double>(sum));
+ root.SetIntKey("flags", flags());
root.Set("params", std::move(parameters));
if (verbosity_level != JSON_VERBOSITY_LEVEL_OMIT_BUCKETS)
root.Set("buckets", std::move(buckets));
- root.SetInteger("pid", GetUniqueIdForProcess());
+ root.SetIntKey("pid", GetUniqueIdForProcess());
serializer.Serialize(root);
}
Index: chromium-74.0.3729.108/base/process/process_metrics.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/process/process_metrics.cc
+++ chromium-74.0.3729.108/base/process/process_metrics.cc
@@ -74,7 +74,7 @@ SystemMetrics SystemMetrics::Sample() {
std::unique_ptr<Value> SystemMetrics::ToValue() const {
std::unique_ptr<DictionaryValue> res(new DictionaryValue());
- res->SetInteger("committed_memory", static_cast<int>(committed_memory_));
+ res->SetIntKey("committed_memory", static_cast<int>(committed_memory_));
#if defined(OS_LINUX) || defined(OS_ANDROID)
std::unique_ptr<DictionaryValue> meminfo = memory_info_.ToValue();
std::unique_ptr<DictionaryValue> vmstat = vmstat_info_.ToValue();
Index: chromium-74.0.3729.108/base/process/process_metrics_linux.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/process/process_metrics_linux.cc
+++ chromium-74.0.3729.108/base/process/process_metrics_linux.cc
@@ -470,25 +470,25 @@ const size_t kDiskWeightedIOTime = 13;
std::unique_ptr<DictionaryValue> SystemMemoryInfoKB::ToValue() const {
auto res = std::make_unique<DictionaryValue>();
- res->SetInteger("total", total);
- res->SetInteger("free", free);
- res->SetInteger("available", available);
- res->SetInteger("buffers", buffers);
- res->SetInteger("cached", cached);
- res->SetInteger("active_anon", active_anon);
- res->SetInteger("inactive_anon", inactive_anon);
- res->SetInteger("active_file", active_file);
- res->SetInteger("inactive_file", inactive_file);
- res->SetInteger("swap_total", swap_total);
- res->SetInteger("swap_free", swap_free);
- res->SetInteger("swap_used", swap_total - swap_free);
- res->SetInteger("dirty", dirty);
- res->SetInteger("reclaimable", reclaimable);
+ res->SetIntKey("total", total);
+ res->SetIntKey("free", free);
+ res->SetIntKey("available", available);
+ res->SetIntKey("buffers", buffers);
+ res->SetIntKey("cached", cached);
+ res->SetIntKey("active_anon", active_anon);
+ res->SetIntKey("inactive_anon", inactive_anon);
+ res->SetIntKey("active_file", active_file);
+ res->SetIntKey("inactive_file", inactive_file);
+ res->SetIntKey("swap_total", swap_total);
+ res->SetIntKey("swap_free", swap_free);
+ res->SetIntKey("swap_used", swap_total - swap_free);
+ res->SetIntKey("dirty", dirty);
+ res->SetIntKey("reclaimable", reclaimable);
#ifdef OS_CHROMEOS
- res->SetInteger("shmem", shmem);
- res->SetInteger("slab", slab);
- res->SetInteger("gem_objects", gem_objects);
- res->SetInteger("gem_size", gem_size);
+ res->SetIntKey("shmem", shmem);
+ res->SetIntKey("slab", slab);
+ res->SetIntKey("gem_objects", gem_objects);
+ res->SetIntKey("gem_size", gem_size);
#endif
return res;
@@ -635,9 +635,9 @@ bool GetSystemMemoryInfo(SystemMemoryInf
std::unique_ptr<DictionaryValue> VmStatInfo::ToValue() const {
auto res = std::make_unique<DictionaryValue>();
- res->SetInteger("pswpin", pswpin);
- res->SetInteger("pswpout", pswpout);
- res->SetInteger("pgmajfault", pgmajfault);
+ res->SetIntKey("pswpin", pswpin);
+ res->SetIntKey("pswpout", pswpout);
+ res->SetIntKey("pgmajfault", pgmajfault);
return res;
}
Index: chromium-74.0.3729.108/base/task/task_scheduler/task_tracker.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/task/task_scheduler/task_tracker.cc
+++ chromium-74.0.3729.108/base/task/task_scheduler/task_tracker.cc
@@ -61,11 +61,11 @@ class TaskTracingInfo : public trace_eve
void TaskTracingInfo::AppendAsTraceFormat(std::string* out) const {
DictionaryValue dict;
- dict.SetString("task_priority",
- base::TaskPriorityToString(task_traits_.priority()));
- dict.SetString("execution_mode", execution_mode_);
+ dict.SetStringKey("task_priority",
+ base::TaskPriorityToString(task_traits_.priority()));
+ dict.SetStringKey("execution_mode", execution_mode_);
if (execution_mode_ != kParallelExecutionMode)
- dict.SetInteger("sequence_token", sequence_token_.ToInternalValue());
+ dict.SetIntKey("sequence_token", sequence_token_.ToInternalValue());
std::string tmp;
JSONWriter::Write(dict, &tmp);
Index: chromium-74.0.3729.108/base/test/gtest_util.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/test/gtest_util.cc
+++ chromium-74.0.3729.108/base/test/gtest_util.cc
@@ -56,10 +56,10 @@ bool WriteCompiledInTestsToFile(const Fi
ListValue root;
for (const auto& i : tests) {
std::unique_ptr<DictionaryValue> test_info(new DictionaryValue);
- test_info->SetString("test_case_name", i.test_case_name);
- test_info->SetString("test_name", i.test_name);
- test_info->SetString("file", i.file);
- test_info->SetInteger("line", i.line);
+ test_info->SetStringKey("test_case_name", i.test_case_name);
+ test_info->SetStringKey("test_name", i.test_name);
+ test_info->SetStringKey("file", i.file);
+ test_info->SetIntKey("line", i.line);
root.Append(std::move(test_info));
}
Index: chromium-74.0.3729.108/base/test/launcher/test_launcher_tracer.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/test/launcher/test_launcher_tracer.cc
+++ chromium-74.0.3729.108/base/test/launcher/test_launcher_tracer.cc
@@ -37,11 +37,11 @@ bool TestLauncherTracer::Dump(const File
json_event->SetString("ph", "X");
json_event->SetInteger(
"ts", (event.timestamp - trace_start_time_).InMicroseconds());
- json_event->SetInteger("dur", event.duration.InMicroseconds());
- json_event->SetInteger("tid", event.thread_id);
+ json_event->SetIntKey("dur", event.duration.InMicroseconds());
+ json_event->SetIntKey("tid", event.thread_id);
// Add fake values required by the trace viewer.
- json_event->SetInteger("pid", 0);
+ json_event->SetIntKey("pid", 0);
json_events->Append(std::move(json_event));
}
Index: chromium-74.0.3729.108/base/test/launcher/test_results_tracker.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/test/launcher/test_results_tracker.cc
+++ chromium-74.0.3729.108/base/test/launcher/test_results_tracker.cc
@@ -404,7 +404,7 @@ bool TestResultsTracker::SaveSummaryAsJS
std::unique_ptr<DictionaryValue> test_result_value(new DictionaryValue);
- test_result_value->SetString("status", test_result.StatusAsString());
+ test_result_value->SetStringKey("status", test_result.StatusAsString());
test_result_value->SetInteger(
"elapsed_time_ms",
static_cast<int>(test_result.elapsed_time.InMilliseconds()));
@@ -422,7 +422,7 @@ bool TestResultsTracker::SaveSummaryAsJS
// TODO(phajdan.jr): Fix typo in JSON key (losless -> lossless)
// making sure not to break any consumers of this data.
- test_result_value->SetBoolean("losless_snippet", lossless_snippet);
+ test_result_value->SetBoolKey("losless_snippet", lossless_snippet);
// Also include the raw version (base64-encoded so that it can be safely
// JSON-serialized - there are no guarantees about character encoding
@@ -430,43 +430,43 @@ bool TestResultsTracker::SaveSummaryAsJS
// debugging a test failure related to character encoding.
std::string base64_output_snippet;
Base64Encode(test_result.output_snippet, &base64_output_snippet);
- test_result_value->SetString("output_snippet_base64",
- base64_output_snippet);
+ test_result_value->SetStringKey("output_snippet_base64",
+ base64_output_snippet);
std::unique_ptr<ListValue> test_result_parts(new ListValue);
for (const TestResultPart& result_part :
test_result.test_result_parts) {
std::unique_ptr<DictionaryValue> result_part_value(
new DictionaryValue);
- result_part_value->SetString("type", result_part.TypeAsString());
- result_part_value->SetString("file", result_part.file_name);
- result_part_value->SetInteger("line", result_part.line_number);
+ result_part_value->SetStringKey("type", result_part.TypeAsString());
+ result_part_value->SetStringKey("file", result_part.file_name);
+ result_part_value->SetIntKey("line", result_part.line_number);
bool lossless_summary = IsStringUTF8(result_part.summary);
if (lossless_summary) {
- result_part_value->SetString("summary", result_part.summary);
+ result_part_value->SetStringKey("summary", result_part.summary);
} else {
result_part_value->SetString(
"summary", "<non-UTF-8 snippet, see summary_base64>");
}
- result_part_value->SetBoolean("lossless_summary", lossless_summary);
+ result_part_value->SetBoolKey("lossless_summary", lossless_summary);
std::string encoded_summary;
Base64Encode(result_part.summary, &encoded_summary);
- result_part_value->SetString("summary_base64", encoded_summary);
+ result_part_value->SetStringKey("summary_base64", encoded_summary);
bool lossless_message = IsStringUTF8(result_part.message);
if (lossless_message) {
- result_part_value->SetString("message", result_part.message);
+ result_part_value->SetStringKey("message", result_part.message);
} else {
result_part_value->SetString(
"message", "<non-UTF-8 snippet, see message_base64>");
}
- result_part_value->SetBoolean("lossless_message", lossless_message);
+ result_part_value->SetBoolKey("lossless_message", lossless_message);
std::string encoded_message;
Base64Encode(result_part.message, &encoded_message);
- result_part_value->SetString("message_base64", encoded_message);
+ result_part_value->SetStringKey("message_base64", encoded_message);
test_result_parts->Append(std::move(result_part_value));
}
@@ -487,8 +487,8 @@ bool TestResultsTracker::SaveSummaryAsJS
std::string test_name = item.first;
CodeLocation location = item.second;
std::unique_ptr<DictionaryValue> location_value(new DictionaryValue);
- location_value->SetString("file", location.file);
- location_value->SetInteger("line", location.line);
+ location_value->SetStringKey("file", location.file);
+ location_value->SetIntKey("line", location.line);
test_locations->SetWithoutPathExpansion(test_name,
std::move(location_value));
}
Index: chromium-74.0.3729.108/base/trace_event/traced_value.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/trace_event/traced_value.cc
+++ chromium-74.0.3729.108/base/trace_event/traced_value.cc
@@ -380,44 +380,40 @@ class PickleWriter final : public Traced
case kTypeBool: {
bool value;
CHECK(it.ReadBool(&value));
- base::Value new_bool(value);
if (cur_dict) {
- cur_dict->SetKey(ReadKeyName(it), std::move(new_bool));
+ cur_dict->SetBoolKey(ReadKeyName(it), value);
} else {
- cur_list->GetList().push_back(std::move(new_bool));
+ cur_list->GetList().emplace_back(value);
}
} break;
case kTypeInt: {
int value;
CHECK(it.ReadInt(&value));
- base::Value new_int(value);
if (cur_dict) {
- cur_dict->SetKey(ReadKeyName(it), std::move(new_int));
+ cur_dict->SetIntKey(ReadKeyName(it), value);
} else {
- cur_list->GetList().push_back(std::move(new_int));
+ cur_list->GetList().emplace_back(value);
}
} break;
case kTypeDouble: {
double value;
CHECK(it.ReadDouble(&value));
- base::Value new_double(value);
if (cur_dict) {
- cur_dict->SetKey(ReadKeyName(it), std::move(new_double));
+ cur_dict->SetDoubleKey(ReadKeyName(it), value);
} else {
- cur_list->GetList().push_back(std::move(new_double));
+ cur_list->GetList().emplace_back(value);
}
} break;
case kTypeString: {
std::string value;
CHECK(it.ReadString(&value));
- base::Value new_str(std::move(value));
if (cur_dict) {
- cur_dict->SetKey(ReadKeyName(it), std::move(new_str));
+ cur_dict->SetStringKey(ReadKeyName(it), std::move(value));
} else {
- cur_list->GetList().push_back(std::move(new_str));
+ cur_list->GetList().emplace_back(std::move(value));
}
} break;
Index: chromium-74.0.3729.108/base/values.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/values.cc
+++ chromium-74.0.3729.108/base/values.cc
@@ -381,11 +381,11 @@ bool Value::RemoveKey(StringPiece key) {
return dict_.erase(key) != 0;
}
-Value* Value::SetKey(StringPiece key, Value&& value) {
+Value* Value::SetKeyInternal(StringPiece key,
+ std::unique_ptr<Value>&& val_ptr) {
CHECK(is_dict());
// NOTE: We can't use |insert_or_assign| here, as only |try_emplace| does
// an explicit conversion from StringPiece to std::string if necessary.
- auto val_ptr = std::make_unique<Value>(std::move(value));
auto result = dict_.try_emplace(key, std::move(val_ptr));
if (!result.second) {
// val_ptr is guaranteed to be still intact at this point.
@@ -394,6 +394,38 @@ Value* Value::SetKey(StringPiece key, Va
return result.first->second.get();
}
+Value* Value::SetBoolKey(StringPiece key, bool value) {
+ return SetKeyInternal(key, std::make_unique<Value>(value));
+}
+
+Value* Value::SetIntKey(StringPiece key, int value) {
+ return SetKeyInternal(key, std::make_unique<Value>(value));
+}
+
+Value* Value::SetDoubleKey(StringPiece key, double value) {
+ return SetKeyInternal(key, std::make_unique<Value>(value));
+}
+
+Value* Value::SetStringKey(StringPiece key, StringPiece value) {
+ return SetKeyInternal(key, std::make_unique<Value>(value));
+}
+
+Value* Value::SetStringKey(StringPiece key, const char* value) {
+ return SetKeyInternal(key, std::make_unique<Value>(value));
+}
+
+Value* Value::SetStringKey(StringPiece key, std::string&& value) {
+ return SetKeyInternal(key, std::make_unique<Value>(std::move(value)));
+}
+
+Value* Value::SetStringKey(StringPiece key, StringPiece16 value) {
+ return SetKeyInternal(key, std::make_unique<Value>(value));
+}
+
+Value* Value::SetKey(StringPiece key, Value&& value) {
+ return SetKeyInternal(key, std::make_unique<Value>(std::move(value)));
+}
+
Value* Value::SetKey(std::string&& key, Value&& value) {
CHECK(is_dict());
return dict_
@@ -403,7 +435,7 @@ Value* Value::SetKey(std::string&& key,
}
Value* Value::SetKey(const char* key, Value&& value) {
- return SetKey(StringPiece(key), std::move(value));
+ return SetKeyInternal(key, std::make_unique<Value>(std::move(value)));
}
Value* Value::FindPath(std::initializer_list<StringPiece> path) {
Index: chromium-74.0.3729.108/base/values.h
===================================================================
--- chromium-74.0.3729.108.orig/base/values.h
+++ chromium-74.0.3729.108/base/values.h
@@ -222,6 +222,7 @@ class BASE_EXPORT Value {
// value to |value|. If |key| could not be found, a new element is inserted.
// A pointer to the modified item is returned.
// Note: This fatally asserts if type() is not Type::DICTIONARY.
+ // Note: Prefer Set<Type>Key() for simple values.
//
// Example:
// SetKey("foo", std::move(myvalue));
@@ -231,6 +232,20 @@ class BASE_EXPORT Value {
// This overload is necessary to avoid ambiguity for const char* arguments.
Value* SetKey(const char* key, Value&& value);
+ // |Set<Type>Key| looks up |key| in the underlying dictionary and associates
+ // a corresponding Value() constructed from the second parameter. Compared
+ // to SetKey(), this avoids un-necessary temporary Value() creation, as well
+ // ambiguities in the value type.
+ Value* SetBoolKey(StringPiece key, bool val);
+ Value* SetIntKey(StringPiece key, int val);
+ Value* SetDoubleKey(StringPiece key, double val);
+ Value* SetStringKey(StringPiece key, StringPiece val);
+ // NOTE: These two overloads are provided as performance / code generation
+ // optimizations.
+ Value* SetStringKey(StringPiece key, const char* val);
+ Value* SetStringKey(StringPiece key, std::string&& val);
+ Value* SetStringKey(StringPiece key, StringPiece16 val);
+
// This attemps to remove the value associated with |key|. In case of failure,
// e.g. the key does not exist, |false| is returned and the underlying
// dictionary is not changed. In case of success, |key| is deleted from the
@@ -469,6 +484,10 @@ class BASE_EXPORT Value {
void InternalMoveConstructFrom(Value&& that);
void InternalCleanup();
+ // NOTE: Using a movable reference here is done for performance (it avoids
+ // creating + moving + destroying a temporary unique ptr).
+ Value* SetKeyInternal(StringPiece key, std::unique_ptr<Value>&& val_ptr);
+
DISALLOW_COPY_AND_ASSIGN(Value);
};
Index: chromium-74.0.3729.108/base/values_unittest.cc
===================================================================
--- chromium-74.0.3729.108.orig/base/values_unittest.cc
+++ chromium-74.0.3729.108/base/values_unittest.cc
@@ -794,6 +794,97 @@ TEST(ValuesTest, SetKey) {
EXPECT_EQ(Value(std::move(storage)), dict);
}
+TEST(ValuesTest, SetBoolKey) {
+ base::Optional<bool> value;
+
+ DictionaryValue dict;
+ dict.SetBoolKey("true_key", true);
+ dict.SetBoolKey("false_key", false);
+
+ value = dict.FindBoolKey("true_key");
+ ASSERT_TRUE(value);
+ ASSERT_TRUE(*value);
+
+ value = dict.FindBoolKey("false_key");
+ ASSERT_TRUE(value);
+ ASSERT_FALSE(*value);
+
+ value = dict.FindBoolKey("missing_key");
+ ASSERT_FALSE(value);
+}
+
+TEST(ValuesTest, SetIntKey) {
+ base::Optional<int> value;
+
+ DictionaryValue dict;
+ dict.SetIntKey("one_key", 1);
+ dict.SetIntKey("minus_one_key", -1);
+
+ value = dict.FindIntKey("one_key");
+ ASSERT_TRUE(value);
+ ASSERT_EQ(1, *value);
+
+ value = dict.FindIntKey("minus_one_key");
+ ASSERT_TRUE(value);
+ ASSERT_EQ(-1, *value);
+
+ value = dict.FindIntKey("missing_key");
+ ASSERT_FALSE(value);
+}
+
+TEST(ValuesTest, SetDoubleKey) {
+ DictionaryValue dict;
+ dict.SetDoubleKey("one_key", 1.0);
+ dict.SetDoubleKey("minus_one_key", -1.0);
+ dict.SetDoubleKey("pi_key", 3.1415);
+
+ // NOTE: Use FindKey() instead of FindDoubleKey() because the latter will
+ // auto-convert integers to doubles as well.
+ const Value* value;
+
+ value = dict.FindKey("one_key");
+ ASSERT_TRUE(value);
+ EXPECT_TRUE(value->is_double());
+ EXPECT_EQ(1.0, value->GetDouble());
+
+ value = dict.FindKey("minus_one_key");
+ ASSERT_TRUE(value);
+ EXPECT_TRUE(value->is_double());
+ EXPECT_EQ(-1.0, value->GetDouble());
+
+ value = dict.FindKey("pi_key");
+ ASSERT_TRUE(value);
+ EXPECT_TRUE(value->is_double());
+ EXPECT_EQ(3.1415, value->GetDouble());
+}
+
+TEST(ValuesTest, SetStringKey) {
+ DictionaryValue dict;
+ dict.SetStringKey("one_key", "one");
+ dict.SetStringKey("hello_key", "hello world");
+
+ std::string movable_value("movable_value");
+ dict.SetStringKey("movable_key", std::move(movable_value));
+ ASSERT_TRUE(movable_value.empty());
+
+ const std::string* value;
+
+ value = dict.FindStringKey("one_key");
+ ASSERT_TRUE(value);
+ ASSERT_EQ("one", *value);
+
+ value = dict.FindStringKey("hello_key");
+ ASSERT_TRUE(value);
+ ASSERT_EQ("hello world", *value);
+
+ value = dict.FindStringKey("movable_key");
+ ASSERT_TRUE(value);
+ ASSERT_EQ("movable_value", *value);
+
+ value = dict.FindStringKey("missing_key");
+ ASSERT_FALSE(value);
+}
+
TEST(ValuesTest, FindPath) {
// Construct a dictionary path {root}.foo.bar = 123
Value foo(Value::Type::DICTIONARY);
@@ -893,7 +984,7 @@ TEST(ValuesTest, Basic) {
ASSERT_EQ(std::string("http://google.com"), homepage);
ASSERT_FALSE(settings.Get("global", nullptr));
- settings.SetBoolean("global", true);
+ settings.SetBoolKey("global", true);
ASSERT_TRUE(settings.Get("global", nullptr));
settings.SetString("global.homepage", "http://scurvy.com");
ASSERT_TRUE(settings.Get("global", nullptr));
@@ -911,8 +1002,8 @@ TEST(ValuesTest, Basic) {
ASSERT_TRUE(settings.GetList("global.toolbar.bookmarks", &toolbar_bookmarks));
std::unique_ptr<DictionaryValue> new_bookmark(new DictionaryValue);
- new_bookmark->SetString("name", "Froogle");
- new_bookmark->SetString("url", "http://froogle.com");
+ new_bookmark->SetStringKey("name", "Froogle");
+ new_bookmark->SetStringKey("url", "http://froogle.com");
toolbar_bookmarks->Append(std::move(new_bookmark));
ListValue* bookmark_list;
@@ -1276,7 +1367,7 @@ TEST(ValuesTest, DeepCopy) {
DictionaryValue* dict_weak = original_dict.SetDictionary(
"dictionary", std::make_unique<DictionaryValue>());
- dict_weak->SetString("key", "value");
+ dict_weak->SetStringKey("key", "value");
auto copy_dict = original_dict.CreateDeepCopy();
ASSERT_TRUE(copy_dict.get());
@@ -1392,11 +1483,11 @@ TEST(ValuesTest, Equals) {
EXPECT_NE(*null1, boolean);
DictionaryValue dv;
- dv.SetBoolean("a", false);
- dv.SetInteger("b", 2);
- dv.SetDouble("c", 2.5);
- dv.SetString("d1", "string");
- dv.SetString("d2", ASCIIToUTF16("http://google.com"));
+ dv.SetBoolKey("a", false);
+ dv.SetIntKey("b", 2);
+ dv.SetDoubleKey("c", 2.5);
+ dv.SetStringKey("d1", "string");
+ dv.SetStringKey("d2", ASCIIToUTF16("http://google.com"));
dv.Set("e", std::make_unique<Value>());
auto copy = dv.CreateDeepCopy();
@@ -1419,7 +1510,7 @@ TEST(ValuesTest, Equals) {
copy = dv.CreateDeepCopy();
EXPECT_EQ(dv, *copy);
copy->Remove("a", nullptr);
- copy->SetBoolean("aa", false);
+ copy->SetBoolKey("aa", false);
EXPECT_NE(dv, *copy);
}
@@ -1519,8 +1610,8 @@ TEST(ValuesTest, Comparisons) {
// Test Non Empty Dict Values.
DictionaryValue int_dict1;
DictionaryValue int_dict2;
- int_dict1.SetInteger("key", 1);
- int_dict2.SetInteger("key", 2);
+ int_dict1.SetIntKey("key", 1);
+ int_dict2.SetIntKey("key", 2);
EXPECT_FALSE(int_dict1 == int_dict2);
EXPECT_NE(int_dict1, int_dict2);
EXPECT_LT(int_dict1, int_dict2);
@@ -1599,9 +1690,9 @@ TEST(ValuesTest, RemoveEmptyChildren) {
EXPECT_TRUE(root->empty());
// Make sure we don't prune too much.
- root->SetBoolean("bool", true);
+ root->SetBoolKey("bool", true);
root->Set("empty_dict", std::make_unique<DictionaryValue>());
- root->SetString("empty_string", std::string());
+ root->SetStringKey("empty_string", std::string());
root = root->DeepCopyWithoutEmptyChildren();
EXPECT_EQ(2U, root->size());
@@ -1668,19 +1759,20 @@ TEST(ValuesTest, RemoveEmptyChildren) {
TEST(ValuesTest, MergeDictionary) {
std::unique_ptr<DictionaryValue> base(new DictionaryValue);
- base->SetString("base_key", "base_key_value_base");
- base->SetString("collide_key", "collide_key_value_base");
+ base->SetStringKey("base_key", "base_key_value_base");
+ base->SetStringKey("collide_key", "collide_key_value_base");
std::unique_ptr<DictionaryValue> base_sub_dict(new DictionaryValue);
- base_sub_dict->SetString("sub_base_key", "sub_base_key_value_base");
- base_sub_dict->SetString("sub_collide_key", "sub_collide_key_value_base");
+ base_sub_dict->SetStringKey("sub_base_key", "sub_base_key_value_base");
+ base_sub_dict->SetStringKey("sub_collide_key", "sub_collide_key_value_base");
base->Set("sub_dict_key", std::move(base_sub_dict));
std::unique_ptr<DictionaryValue> merge(new DictionaryValue);
- merge->SetString("merge_key", "merge_key_value_merge");
- merge->SetString("collide_key", "collide_key_value_merge");
+ merge->SetStringKey("merge_key", "merge_key_value_merge");
+ merge->SetStringKey("collide_key", "collide_key_value_merge");
std::unique_ptr<DictionaryValue> merge_sub_dict(new DictionaryValue);
- merge_sub_dict->SetString("sub_merge_key", "sub_merge_key_value_merge");
- merge_sub_dict->SetString("sub_collide_key", "sub_collide_key_value_merge");
+ merge_sub_dict->SetStringKey("sub_merge_key", "sub_merge_key_value_merge");
+ merge_sub_dict->SetStringKey("sub_collide_key",
+ "sub_collide_key_value_merge");
merge->Set("sub_dict_key", std::move(merge_sub_dict));
base->MergeDictionary(merge.get());
@@ -1714,7 +1806,7 @@ TEST(ValuesTest, MergeDictionary) {
TEST(ValuesTest, MergeDictionaryDeepCopy) {
std::unique_ptr<DictionaryValue> child(new DictionaryValue);
DictionaryValue* original_child = child.get();
- child->SetString("test", "value");
+ child->SetStringKey("test", "value");
EXPECT_EQ(1U, child->size());
std::string value;
@@ -1737,7 +1829,7 @@ TEST(ValuesTest, MergeDictionaryDeepCopy
EXPECT_TRUE(ptr->GetString("test", &value));
EXPECT_EQ("value", value);
- original_child->SetString("test", "overwrite");
+ original_child->SetStringKey("test", "overwrite");
base.reset();
EXPECT_TRUE(ptr->GetString("test", &value));
EXPECT_EQ("value", value);
@@ -2104,8 +2196,8 @@ TEST(ValuesTest, SelfSwap) {
TEST(ValuesTest, FromToUniquePtrValue) {
std::unique_ptr<DictionaryValue> dict = std::make_unique<DictionaryValue>();
- dict->SetString("name", "Froogle");
- dict->SetString("url", "http://froogle.com");
+ dict->SetStringKey("name", "Froogle");
+ dict->SetStringKey("url", "http://froogle.com");
Value dict_copy = dict->Clone();
Value dict_converted = Value::FromUniquePtrValue(std::move(dict));