Move KeyValueStore to libchromeos

KeyValueStore is a key-value dictionary used to access and store settings
in a .conf file. It supports bool and strings only.

BUG=chromium:416932
TEST=FEATURES=test emerge-link libchromeos update_engine

Change-Id: I34a3add5536588ea1025976de659ad77ac6d8b39
Reviewed-on: https://chromium-review.googlesource.com/219552
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: David Pursell <dpursell@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
diff --git a/hwid_override.cc b/hwid_override.cc
index 768c86b..0ec949f 100644
--- a/hwid_override.cc
+++ b/hwid_override.cc
@@ -9,8 +9,7 @@
 
 #include <base/files/file_path.h>
 #include <base/files/file_util.h>
-
-#include "update_engine/simple_key_value_store.h"
+#include <chromeos/key_value_store.h>
 
 using std::map;
 using std::string;
@@ -24,8 +23,8 @@
 HwidOverride::~HwidOverride() {}
 
 std::string HwidOverride::Read(const base::FilePath& root) {
-  KeyValueStore lsb_release;
-  lsb_release.Load(root.value() + "/etc/lsb-release");
+  chromeos::KeyValueStore lsb_release;
+  lsb_release.Load(base::FilePath(root.value() + "/etc/lsb-release"));
   string result;
   if (lsb_release.GetString(kHwidOverrideKey, &result))
     return result;
diff --git a/omaha_request_params.cc b/omaha_request_params.cc
index 94de4f3..2a4a0ea 100644
--- a/omaha_request_params.cc
+++ b/omaha_request_params.cc
@@ -14,11 +14,11 @@
 
 #include <base/files/file_util.h>
 #include <base/strings/string_util.h>
+#include <chromeos/key_value_store.h>
 #include <policy/device_policy.h>
 
 #include "update_engine/constants.h"
 #include "update_engine/hardware_interface.h"
-#include "update_engine/simple_key_value_store.h"
 #include "update_engine/system_state.h"
 #include "update_engine/utils.h"
 
@@ -133,15 +133,15 @@
             << ", existing target channel = " << target_channel_
             << ", download channel = " << download_channel_;
   TEST_AND_RETURN_FALSE(IsValidChannel(new_target_channel));
-  KeyValueStore lsb_release;
+  chromeos::KeyValueStore lsb_release;
   base::FilePath kFile(root_ + kStatefulPartition + "/etc/lsb-release");
 
-  lsb_release.Load(kFile.value());
+  lsb_release.Load(kFile);
   lsb_release.SetString(kUpdateChannelKey, new_target_channel);
   lsb_release.SetBoolean(kIsPowerwashAllowedKey, is_powerwash_allowed);
 
   TEST_AND_RETURN_FALSE(base::CreateDirectory(kFile.DirName()));
-  TEST_AND_RETURN_FALSE(lsb_release.Save(kFile.value()));
+  TEST_AND_RETURN_FALSE(lsb_release.Save(kFile));
   target_channel_ = new_target_channel;
   is_powerwash_allowed_ = is_powerwash_allowed;
   return true;
@@ -217,8 +217,8 @@
        it != files.end(); ++it) {
     // TODO(adlr): make sure files checked are owned as root (and all their
     // parents are recursively, too).
-    KeyValueStore data;
-    if (!data.Load(root_ + *it))
+    chromeos::KeyValueStore data;
+    if (!data.Load(base::FilePath(root_ + *it)))
       continue;
 
     string value;
diff --git a/simple_key_value_store.cc b/simple_key_value_store.cc
deleted file mode 100644
index 5669df2..0000000
--- a/simple_key_value_store.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "update_engine/simple_key_value_store.h"
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include <base/files/file_util.h>
-#include <base/strings/string_split.h>
-#include <base/strings/string_util.h>
-
-#include "update_engine/utils.h"
-
-using std::map;
-using std::string;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-bool KeyValueStore::Load(const string& filename) {
-  string file_data;
-  if (!base::ReadFileToString(base::FilePath(filename), &file_data))
-    return false;
-
-  // Split along '\n', then along '='
-  vector<string> lines;
-  base::SplitStringDontTrim(file_data, '\n', &lines);
-  for (auto& it : lines) {
-    if (it.empty() || it[0] == '#')
-      continue;
-    string::size_type pos = it.find('=');
-    if (pos == string::npos)
-      continue;
-    store_[it.substr(0, pos)] = it.substr(pos + 1);
-  }
-  return true;
-}
-
-bool KeyValueStore::Save(const string& filename) const {
-  string data;
-  for (auto& it : store_)
-    data += it.first + "=" + it.second + "\n";
-
-  return utils::WriteFile(filename.c_str(), data.c_str(), data.size());
-}
-
-bool KeyValueStore::GetString(const string& key, string* value) const {
-  auto it = store_.find(key);
-  if (it == store_.end())
-    return false;
-  *value = it->second;
-  return true;
-}
-
-void KeyValueStore::SetString(const string& key, const string& value) {
-  store_[key] = value;
-}
-
-bool KeyValueStore::GetBoolean(const string& key, bool* value) const {
-  auto it = store_.find(key);
-  if (it == store_.end())
-    return false;
-  if (it->second == "true") {
-    *value = true;
-    return true;
-  } else if (it-> second == "false") {
-    *value = false;
-    return true;
-  }
-
-  return false;
-}
-
-void KeyValueStore::SetBoolean(const string& key, bool value) {
-  store_[key] = value ? "true" : "false";
-}
-
-}  // namespace chromeos_update_engine
diff --git a/simple_key_value_store.h b/simple_key_value_store.h
deleted file mode 100644
index a648cd4..0000000
--- a/simple_key_value_store.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// These functions can parse a blob of data that's formatted as a simple
-// key value store. Each key/value pair is stored on its own line and
-// separated by the first '=' on the line.
-
-#ifndef UPDATE_ENGINE_SIMPLE_KEY_VALUE_STORE_H_
-#define UPDATE_ENGINE_SIMPLE_KEY_VALUE_STORE_H_
-
-#include <map>
-#include <string>
-
-namespace chromeos_update_engine {
-
-class KeyValueStore {
- public:
-  // Creates an empty KeyValueStore.
-  KeyValueStore() {}
-
-  // Loads the key=value pairs from the given filename. Lines starting with
-  // '#' and empty lines are ignored. Adds all the readed key=values to the
-  // store, overriding those already defined but persisting the ones that
-  // aren't present on the passed file.
-  // Returns whether reading the file succeeded.
-  bool Load(const std::string& filename);
-
-  // Saves the current store to the given |filename| file. Returns whether the
-  // file creation succeeded.
-  bool Save(const std::string& filename) const;
-
-  // Getter for the given key. Returns whether the key was found on the store.
-  bool GetString(const std::string& key, std::string* value) const;
-
-  // Setter for the given key. It overrides the key if already exists.
-  void SetString(const std::string& key, const std::string& value);
-
-  // Boolean getter. Returns whether the key was found on the store and if it
-  // has a valid value ("true" or "false").
-  bool GetBoolean(const std::string& key, bool* value) const;
-
-  // Boolean setter. Sets the value as "true" or "false".
-  void SetBoolean(const std::string& key, bool value);
-
- private:
-  // The map storing all the key-value pairs.
-  std::map<std::string, std::string> store_;
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_SIMPLE_KEY_VALUE_STORE_H_
diff --git a/simple_key_value_store_unittest.cc b/simple_key_value_store_unittest.cc
deleted file mode 100644
index 1f9144f..0000000
--- a/simple_key_value_store_unittest.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "update_engine/simple_key_value_store.h"
-
-#include <map>
-#include <string>
-
-#include <gtest/gtest.h>
-#include <base/files/file_util.h>
-#include <base/strings/string_util.h>
-
-#include "update_engine/test_utils.h"
-
-using base::FilePath;
-using base::ReadFileToString;
-using std::map;
-using std::string;
-
-namespace chromeos_update_engine {
-
-class KeyValueStoreTest : public ::testing::Test {
- protected:
-  ScopedTempFile file_;
-  KeyValueStore store_;  // KeyValueStore under test.
-};
-
-TEST_F(KeyValueStoreTest, CommentsAreIgnored) {
-  string blob = "# comment\nA=B\n\n\n#another=comment\n\n";
-  ASSERT_TRUE(WriteFileString(file_.GetPath(), blob));
-  EXPECT_TRUE(store_.Load(file_.GetPath()));
-
-  EXPECT_TRUE(store_.Save(file_.GetPath()));
-  string read_blob;
-  ASSERT_TRUE(ReadFileToString(FilePath(file_.GetPath()), &read_blob));
-  EXPECT_EQ("A=B\n", read_blob);
-}
-
-TEST_F(KeyValueStoreTest, EmptyTest) {
-  ASSERT_TRUE(WriteFileString(file_.GetPath(), ""));
-  EXPECT_TRUE(store_.Load(file_.GetPath()));
-
-  EXPECT_TRUE(store_.Save(file_.GetPath()));
-  string read_blob;
-  ASSERT_TRUE(ReadFileToString(FilePath(file_.GetPath()), &read_blob));
-  EXPECT_EQ("", read_blob);
-}
-
-TEST_F(KeyValueStoreTest, LoadAndReloadTest) {
-  string blob = "A=B\nC=\n=\nFOO=BAR=BAZ\nBAR=BAX\nMISSING=NEWLINE";
-  ASSERT_TRUE(WriteFileString(file_.GetPath(), blob));
-  EXPECT_TRUE(store_.Load(file_.GetPath()));
-
-  map<string, string> expected = {
-      {"A", "B"}, {"C", ""}, {"", ""}, {"FOO", "BAR=BAZ"}, {"BAR", "BAX"},
-      {"MISSING", "NEWLINE"}};
-
-  // Test expected values
-  string value;
-  for (auto& it : expected) {
-    EXPECT_TRUE(store_.GetString(it.first, &value));
-    EXPECT_EQ(it.second, value) << "Testing key: " << it.first;
-  }
-
-  // Save, load and test again.
-  EXPECT_TRUE(store_.Save(file_.GetPath()));
-  KeyValueStore new_store;
-  EXPECT_TRUE(new_store.Load(file_.GetPath()));
-
-  for (auto& it : expected) {
-    EXPECT_TRUE(new_store.GetString(it.first, &value)) << "key: " << it.first;
-    EXPECT_EQ(it.second, value) << "key: " << it.first;
-  }
-}
-
-TEST_F(KeyValueStoreTest, SimpleBooleanTest) {
-  bool result;
-  EXPECT_FALSE(store_.GetBoolean("A", &result));
-
-  store_.SetBoolean("A", true);
-  EXPECT_TRUE(store_.GetBoolean("A", &result));
-  EXPECT_TRUE(result);
-
-  store_.SetBoolean("A", false);
-  EXPECT_TRUE(store_.GetBoolean("A", &result));
-  EXPECT_FALSE(result);
-}
-
-TEST_F(KeyValueStoreTest, BooleanParsingTest) {
-  string blob = "TRUE=true\nfalse=false\nvar=false\nDONT_SHOUT=TRUE\n";
-  WriteFileString(file_.GetPath(), blob);
-  EXPECT_TRUE(store_.Load(file_.GetPath()));
-
-  map<string, bool> expected = {
-      {"TRUE", true}, {"false", false}, {"var", false}};
-  bool value;
-  EXPECT_FALSE(store_.GetBoolean("DONT_SHOUT", &value));
-  string str_value;
-  EXPECT_TRUE(store_.GetString("DONT_SHOUT", &str_value));
-
-  // Test expected values
-  for (auto& it : expected) {
-    EXPECT_TRUE(store_.GetBoolean(it.first, &value)) << "key: " << it.first;
-    EXPECT_EQ(it.second, value) << "key: " << it.first;
-  }
-}
-
-}  // namespace chromeos_update_engine
diff --git a/update_engine.gyp b/update_engine.gyp
index 490926e..83269c9 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -170,7 +170,6 @@
         'prefs.cc',
         'proxy_resolver.cc',
         'real_system_state.cc',
-        'simple_key_value_store.cc',
         'subprocess.cc',
         'terminator.cc',
         'update_attempter.cc',
@@ -371,7 +370,6 @@
             'payload_state_unittest.cc',
             'postinstall_runner_action_unittest.cc',
             'prefs_unittest.cc',
-            'simple_key_value_store_unittest.cc',
             'subprocess_unittest.cc',
             'terminator_unittest.cc',
             'test_utils.cc',
diff --git a/update_manager/real_config_provider.cc b/update_manager/real_config_provider.cc
index 0e76b73..d986b10 100644
--- a/update_manager/real_config_provider.cc
+++ b/update_manager/real_config_provider.cc
@@ -4,14 +4,15 @@
 
 #include "update_engine/update_manager/real_config_provider.h"
 
+#include <base/files/file_path.h>
 #include <base/logging.h>
+#include <chromeos/key_value_store.h>
 
 #include "update_engine/constants.h"
-#include "update_engine/simple_key_value_store.h"
 #include "update_engine/update_manager/generic_variables.h"
 #include "update_engine/utils.h"
 
-using chromeos_update_engine::KeyValueStore;
+using chromeos::KeyValueStore;
 using std::string;
 
 namespace {
@@ -29,13 +30,14 @@
   KeyValueStore store;
 
   if (hardware_->IsNormalBootMode()) {
-    store.Load(root_prefix_ + kConfigFilePath);
+    store.Load(base::FilePath(root_prefix_ + kConfigFilePath));
   } else {
-    if (store.Load(root_prefix_ + chromeos_update_engine::kStatefulPartition +
-                   kConfigFilePath)) {
+    if (store.Load(base::FilePath(root_prefix_ +
+                                  chromeos_update_engine::kStatefulPartition +
+                                  kConfigFilePath))) {
       LOG(INFO) << "UpdateManager Config loaded from stateful partition.";
     } else {
-      store.Load(root_prefix_ + kConfigFilePath);
+      store.Load(base::FilePath(root_prefix_ + kConfigFilePath));
     }
   }