shill: refactor KeyValueStore internal data structures

Use a single chromeos::VariantDictionary to store all key value
pairs instead of having one map per data type.

Also overload the == and != operators for equality comparison
when KeyValueStore is wrapped inside a chromeos::Any object, which
is needed for nested KeyValueStore.

BUG=chromium:510238
TEST=USE="asan clang" FEATURES=test emerge-$BOARD shill

Change-Id: I8b014d602b9d67538a86d0f5e0fdd1fb07556533
Reviewed-on: https://chromium-review.googlesource.com/285930
Reviewed-by: Zeping Qiu <zqiu@chromium.org>
Tested-by: Zeping Qiu <zqiu@chromium.org>
Commit-Queue: Zeping Qiu <zqiu@chromium.org>
diff --git a/key_file_store.cc b/key_file_store.cc
index bb656f2..827406a 100644
--- a/key_file_store.cc
+++ b/key_file_store.cc
@@ -371,23 +371,25 @@
 
 bool KeyFileStore::DoesGroupMatchProperties(
     const string& group, const KeyValueStore& properties) const {
-  map<string, bool>::const_iterator bool_it;
-  for (const auto& property : properties.bool_properties()) {
-    bool value;
-    if (!GetBool(group, property.first, &value) || value != property.second) {
-      return false;
-    }
-  }
-  for (const auto& property : properties.int_properties()) {
-    int value;
-    if (!GetInt(group, property.first, &value) || value != property.second) {
-      return false;
-    }
-  }
-  for (const auto& property : properties.string_properties()) {
-    string value;
-    if (!GetString(group, property.first, &value) || value != property.second) {
-      return false;
+  for (const auto& property : properties.properties()) {
+    if (property.second.GetType() == typeid(bool)) {    // NOLINT
+      bool value;
+      if (!GetBool(group, property.first, &value) ||
+          value != property.second.Get<bool>()) {
+        return false;
+      }
+    } else if (property.second.GetType() == typeid(int32_t)) {
+      int value;
+      if (!GetInt(group, property.first, &value) ||
+          value != property.second.Get<int32_t>()) {
+        return false;
+      }
+    } else if (property.second.GetType() == typeid(string)) {
+      string value;
+      if (!GetString(group, property.first, &value) ||
+          value != property.second.Get<string>()) {
+        return false;
+      }
     }
   }
   return true;