File 03-basevalue.patch of Package chromium

From fca8c4b5680297d58fa16a3ccf174f954b66cb48 Mon Sep 17 00:00:00 2001
From: David 'Digit' Turner <digit@google.com>
Date: Tue, 26 Mar 2019 11:14:06 +0000
Subject: [PATCH] base: Add Value::Find{Blob,List,Dict}Key() methods
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This CL adds new Value::Find<Type>Key() methods for convenience.
This saves typing and makes the code simpler to read and
understand as well.

+ Fix minor typo in values_unittest.cc

BUG=646113
R=dcheng@chromium.org,jdoerrie@chromium.org,sdefresne@chromium.org,hidehiko@chromium.org
TBR=palmer@chromium.org

Change-Id: I7cbc3f84da0f682411c7f5384849e7c0923c2fb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1530910
Commit-Queue: David Turner <digit@chromium.org>
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Mark Pearson <mpearson@chromium.org>
Reviewed-by: Primiano Tucci <primiano@chromium.org>
Reviewed-by: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#644251}
---
 base/json/json_reader_unittest.cc            | 15 ++--
 base/metrics/statistics_recorder_unittest.cc | 11 ++-
 base/trace_event/trace_config.cc             |  3 +-
 base/values.cc                               | 21 ++++++
 base/values.h                                | 11 +++
 base/values_unittest.cc                      | 74 ++++++++++++++++++--
 6 files changed, 113 insertions(+), 22 deletions(-)

diff --git a/base/json/json_reader_unittest.cc b/base/json/json_reader_unittest.cc
index 5023f33ed7cd..186a6f1dce30 100644
--- a/base/json/json_reader_unittest.cc
+++ b/base/json/json_reader_unittest.cc
@@ -371,17 +371,15 @@ TEST(JSONReaderTest, NestedDictionaries) {
       "{\"inner\":{\"array\":[true]},\"false\":false,\"d\":{}}");
   ASSERT_TRUE(dict_val);
   ASSERT_TRUE(dict_val->is_dict());
-  const Value* inner_dict =
-      dict_val->FindKeyOfType("inner", base::Value::Type::DICTIONARY);
+  const Value* inner_dict = dict_val->FindDictKey("inner");
   ASSERT_TRUE(inner_dict);
-  const Value* inner_array =
-      inner_dict->FindKeyOfType("array", base::Value::Type::LIST);
+  const Value* inner_array = inner_dict->FindListKey("array");
   ASSERT_TRUE(inner_array);
   EXPECT_EQ(1U, inner_array->GetList().size());
   auto bool_value = dict_val->FindBoolKey("false");
   ASSERT_TRUE(bool_value);
   EXPECT_FALSE(*bool_value);
-  inner_dict = dict_val->FindKeyOfType("d", base::Value::Type::DICTIONARY);
+  inner_dict = dict_val->FindDictKey("d");
   EXPECT_TRUE(inner_dict);
 
   Optional<Value> root2 = JSONReader::Read(
@@ -403,8 +401,7 @@ TEST(JSONReaderTest, DictionaryKeysWithPeriods) {
   integer_value = dict_val->FindIntKey("c");
   ASSERT_TRUE(integer_value);
   EXPECT_EQ(2, *integer_value);
-  const Value* inner_dict =
-      dict_val->FindKeyOfType("d.e.f", base::Value::Type::DICTIONARY);
+  const Value* inner_dict = dict_val->FindDictKey("d.e.f");
   ASSERT_TRUE(inner_dict);
   EXPECT_EQ(1U, inner_dict->DictSize());
   integer_value = inner_dict->FindIntKey("g.h.i.j");
@@ -595,9 +592,9 @@ TEST(JSONReaderTest, StringOptimizations) {
     ASSERT_TRUE(root);
     ASSERT_TRUE(root->is_dict());
 
-    Value* dict = root->FindKeyOfType("test", Value::Type::DICTIONARY);
+    Value* dict = root->FindDictKey("test");
     ASSERT_TRUE(dict);
-    Value* list = root->FindKeyOfType("list", Value::Type::LIST);
+    Value* list = root->FindListKey("list");
     ASSERT_TRUE(list);
 
     Value* to_move = dict->FindKey("foo");
diff --git a/base/metrics/statistics_recorder_unittest.cc b/base/metrics/statistics_recorder_unittest.cc
index f54f4146037a..9392e17cd25a 100644
--- a/base/metrics/statistics_recorder_unittest.cc
+++ b/base/metrics/statistics_recorder_unittest.cc
@@ -366,8 +366,7 @@ TEST_P(StatisticsRecorderTest, ToJSON) {
   // No query should be set.
   ASSERT_FALSE(root->FindKey("query"));
 
-  const Value* histogram_list =
-      root->FindKeyOfType("histograms", base::Value::Type::LIST);
+  const Value* histogram_list = root->FindListKey("histograms");
 
   ASSERT_TRUE(histogram_list);
   ASSERT_EQ(2u, histogram_list->GetList().size());
@@ -380,8 +379,7 @@ TEST_P(StatisticsRecorderTest, ToJSON) {
   ASSERT_TRUE(sample_count);
   EXPECT_EQ(2, *sample_count);
 
-  const Value* buckets_list =
-      histogram_dict.FindKeyOfType("buckets", base::Value::Type::LIST);
+  const Value* buckets_list = histogram_dict.FindListKey("buckets");
   ASSERT_TRUE(buckets_list);
   EXPECT_EQ(2u, buckets_list->GetList().size());
 
@@ -390,7 +388,7 @@ TEST_P(StatisticsRecorderTest, ToJSON) {
   root = JSONReader::Read(json);
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_dict());
-  histogram_list = root->FindKeyOfType("histograms", base::Value::Type::LIST);
+  histogram_list = root->FindListKey("histograms");
   ASSERT_TRUE(histogram_list);
   ASSERT_EQ(2u, histogram_list->GetList().size());
   const Value& histogram_dict2 = histogram_list->GetList()[0];
@@ -398,8 +396,7 @@ TEST_P(StatisticsRecorderTest, ToJSON) {
   sample_count = histogram_dict2.FindIntKey("count");
   ASSERT_TRUE(sample_count);
   EXPECT_EQ(2, *sample_count);
-  buckets_list =
-      histogram_dict2.FindKeyOfType("buckets", base::Value::Type::LIST);
+  buckets_list = histogram_dict2.FindListKey("buckets");
   // Bucket information should be omitted.
   ASSERT_FALSE(buckets_list);
 }
diff --git a/base/trace_event/trace_config.cc b/base/trace_event/trace_config.cc
index e28456bdd0c9..e5bc3a58ed7d 100644
--- a/base/trace_event/trace_config.cc
+++ b/base/trace_event/trace_config.cc
@@ -147,8 +147,7 @@ void TraceConfig::ProcessFilterConfig::Merge(
 void TraceConfig::ProcessFilterConfig::InitializeFromConfigDict(
     const base::DictionaryValue& dict) {
   included_process_ids_.clear();
-  const Value* value =
-      dict.FindKeyOfType(kIncludedProcessesParam, Value::Type::LIST);
+  const Value* value = dict.FindListKey(kIncludedProcessesParam);
   if (!value)
     return;
   for (auto& pid_value : value->GetList()) {
diff --git a/base/values.cc b/base/values.cc
index 69d66ff8ab00..6f3a9e2cd8a2 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -354,6 +354,27 @@ const std::string* Value::FindStringKey(StringPiece key) const {
   return result ? &result->string_value_ : nullptr;
 }
 
+const Value::BlobStorage* Value::FindBlobKey(StringPiece key) const {
+  const Value* value = FindKeyOfType(key, Type::BINARY);
+  return value ? &value->binary_value_ : nullptr;
+}
+
+const Value* Value::FindDictKey(StringPiece key) const {
+  return FindKeyOfType(key, Type::DICTIONARY);
+}
+
+Value* Value::FindDictKey(StringPiece key) {
+  return FindKeyOfType(key, Type::DICTIONARY);
+}
+
+const Value* Value::FindListKey(StringPiece key) const {
+  return FindKeyOfType(key, Type::LIST);
+}
+
+Value* Value::FindListKey(StringPiece key) {
+  return FindKeyOfType(key, Type::LIST);
+}
+
 bool Value::RemoveKey(StringPiece key) {
   CHECK(is_dict());
   // NOTE: Can't directly return dict_->erase(key) due to MSVC warning C4800.
diff --git a/base/values.h b/base/values.h
index 6f2cd3cc3d79..7bc355ee586d 100644
--- a/base/values.h
+++ b/base/values.h
@@ -207,6 +207,17 @@ class BASE_EXPORT Value {
   // |FindStringKey| returns |nullptr| if value is not found or not a string.
   const std::string* FindStringKey(StringPiece key) const;
 
+  // Returns nullptr is value is not found or not a binary.
+  const BlobStorage* FindBlobKey(StringPiece key) const;
+
+  // Returns nullptr if value is not found or not a dictionary.
+  const Value* FindDictKey(StringPiece key) const;
+  Value* FindDictKey(StringPiece key);
+
+  // Returns nullptr if value is not found or not a list.
+  const Value* FindListKey(StringPiece key) const;
+  Value* FindListKey(StringPiece key);
+
   // |SetKey| looks up |key| in the underlying dictionary and sets the mapped
   // value to |value|. If |key| could not be found, a new element is inserted.
   // A pointer to the modified item is returned.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 7c545c09d947..2907dc066843 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -635,7 +635,7 @@ TEST(ValuesTest, FindBoolKey) {
   EXPECT_EQ(base::nullopt, dict.FindBoolKey("string"));
   EXPECT_EQ(base::nullopt, dict.FindBoolKey("blob"));
   EXPECT_EQ(base::nullopt, dict.FindBoolKey("list"));
-  EXPECT_EQ(base::nullopt, dict.FindBoolKey("dist"));
+  EXPECT_EQ(base::nullopt, dict.FindBoolKey("dict"));
 }
 
 TEST(ValuesTest, FindIntKey) {
@@ -657,7 +657,7 @@ TEST(ValuesTest, FindIntKey) {
   EXPECT_EQ(base::nullopt, dict.FindIntKey("string"));
   EXPECT_EQ(base::nullopt, dict.FindIntKey("blob"));
   EXPECT_EQ(base::nullopt, dict.FindIntKey("list"));
-  EXPECT_EQ(base::nullopt, dict.FindIntKey("dist"));
+  EXPECT_EQ(base::nullopt, dict.FindIntKey("dict"));
 }
 
 TEST(ValuesTest, FindDoubleKey) {
@@ -679,7 +679,7 @@ TEST(ValuesTest, FindDoubleKey) {
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("string"));
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("blob"));
   EXPECT_EQ(base::nullopt, dict.FindDoubleKey("list"));
-  EXPECT_EQ(base::nullopt, dict.FindDoubleKey("dist"));
+  EXPECT_EQ(base::nullopt, dict.FindDoubleKey("dict"));
 }
 
 TEST(ValuesTest, FindStringKey) {
@@ -701,7 +701,73 @@ TEST(ValuesTest, FindStringKey) {
   EXPECT_NE(nullptr, dict.FindStringKey("string"));
   EXPECT_EQ(nullptr, dict.FindStringKey("blob"));
   EXPECT_EQ(nullptr, dict.FindStringKey("list"));
-  EXPECT_EQ(nullptr, dict.FindStringKey("dist"));
+  EXPECT_EQ(nullptr, dict.FindStringKey("dict"));
+}
+
+TEST(ValuesTest, FindDictKey) {
+  Value::DictStorage storage;
+  storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
+  storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
+  storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
+  storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
+  storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
+  storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
+  storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
+  storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
+
+  const Value dict(std::move(storage));
+  EXPECT_EQ(nullptr, dict.FindDictKey("null"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("bool"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("int"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("double"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("string"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("blob"));
+  EXPECT_EQ(nullptr, dict.FindDictKey("list"));
+  EXPECT_NE(nullptr, dict.FindDictKey("dict"));
+}
+
+TEST(ValuesTest, FindListKey) {
+  Value::DictStorage storage;
+  storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
+  storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
+  storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
+  storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
+  storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
+  storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
+  storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
+  storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
+
+  const Value dict(std::move(storage));
+  EXPECT_EQ(nullptr, dict.FindListKey("null"));
+  EXPECT_EQ(nullptr, dict.FindListKey("bool"));
+  EXPECT_EQ(nullptr, dict.FindListKey("int"));
+  EXPECT_EQ(nullptr, dict.FindListKey("double"));
+  EXPECT_EQ(nullptr, dict.FindListKey("string"));
+  EXPECT_EQ(nullptr, dict.FindListKey("blob"));
+  EXPECT_NE(nullptr, dict.FindListKey("list"));
+  EXPECT_EQ(nullptr, dict.FindListKey("dict"));
+}
+
+TEST(ValuesTest, FindBlobKey) {
+  Value::DictStorage storage;
+  storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
+  storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
+  storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
+  storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
+  storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
+  storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
+  storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
+  storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
+
+  const Value dict(std::move(storage));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("null"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("bool"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("int"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("double"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("string"));
+  EXPECT_NE(nullptr, dict.FindBlobKey("blob"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("list"));
+  EXPECT_EQ(nullptr, dict.FindBlobKey("dict"));
 }
 
 TEST(ValuesTest, SetKey) {
-- 
2.21.0