aboutsummaryrefslogtreecommitdiffstats
path: root/brillo/key_value_store.cc
diff options
context:
space:
mode:
Diffstat (limited to 'brillo/key_value_store.cc')
-rw-r--r--brillo/key_value_store.cc127
1 files changed, 127 insertions, 0 deletions
diff --git a/brillo/key_value_store.cc b/brillo/key_value_store.cc
new file mode 100644
index 0000000..2efa50e
--- /dev/null
+++ b/brillo/key_value_store.cc
@@ -0,0 +1,127 @@
+// 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 "brillo/key_value_store.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <base/files/file_util.h>
+#include <base/files/important_file_writer.h>
+#include <base/strings/string_split.h>
+#include <base/strings/string_util.h>
+#include <brillo/strings/string_utils.h>
+#include <brillo/map_utils.h>
+
+using std::map;
+using std::string;
+using std::vector;
+
+namespace brillo {
+
+namespace {
+
+// Values used for booleans.
+const char kTrueValue[] = "true";
+const char kFalseValue[] = "false";
+
+// Returns a copy of |key| with leading and trailing whitespace removed.
+string TrimKey(const string& key) {
+ string trimmed_key;
+ base::TrimWhitespace(key, base::TRIM_ALL, &trimmed_key);
+ CHECK(!trimmed_key.empty());
+ return trimmed_key;
+}
+
+} // namespace
+
+bool KeyValueStore::Load(const base::FilePath& path) {
+ string file_data;
+ if (!base::ReadFileToString(path, &file_data))
+ return false;
+ return LoadFromString(file_data);
+}
+
+bool KeyValueStore::LoadFromString(const std::string& data) {
+ // Split along '\n', then along '='.
+ vector<string> lines;
+ base::SplitStringDontTrim(data, '\n', &lines);
+ for (auto it = lines.begin(); it != lines.end(); ++it) {
+ std::string line;
+ base::TrimWhitespace(*it, base::TRIM_LEADING, &line);
+ if (line.empty() || line.front() == '#')
+ continue;
+
+ std::string key;
+ std::string value;
+ if (!string_utils::SplitAtFirst(line, "=", &key, &value, false))
+ return false;
+
+ base::TrimWhitespace(key, base::TRIM_TRAILING, &key);
+ if (key.empty())
+ return false;
+
+ // Append additional lines to the value as long as we see trailing
+ // backslashes.
+ while (!value.empty() && value.back() == '\\') {
+ ++it;
+ if (it == lines.end() || it->empty())
+ return false;
+ value.pop_back();
+ value += *it;
+ }
+
+ store_[key] = value;
+ }
+ return true;
+}
+
+bool KeyValueStore::Save(const base::FilePath& path) const {
+ return base::ImportantFileWriter::WriteFileAtomically(path, SaveToString());
+}
+
+string KeyValueStore::SaveToString() const {
+ string data;
+ for (const auto& key_value : store_)
+ data += key_value.first + "=" + key_value.second + "\n";
+ return data;
+}
+
+bool KeyValueStore::GetString(const string& key, string* value) const {
+ const auto key_value = store_.find(TrimKey(key));
+ if (key_value == store_.end())
+ return false;
+ *value = key_value->second;
+ return true;
+}
+
+void KeyValueStore::SetString(const string& key, const string& value) {
+ store_[TrimKey(key)] = value;
+}
+
+bool KeyValueStore::GetBoolean(const string& key, bool* value) const {
+ string string_value;
+ if (!GetString(key, &string_value))
+ return false;
+
+ if (string_value == kTrueValue) {
+ *value = true;
+ return true;
+ } else if (string_value == kFalseValue) {
+ *value = false;
+ return true;
+ }
+ return false;
+}
+
+void KeyValueStore::SetBoolean(const string& key, bool value) {
+ SetString(key, value ? kTrueValue : kFalseValue);
+}
+
+std::vector<std::string> KeyValueStore::GetKeys() const {
+ return GetMapKeysAsVector(store_);
+}
+
+} // namespace brillo