You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.5 KiB
135 lines
3.5 KiB
// 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 <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::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::TrimWhitespaceASCII(key, base::TRIM_ALL, &trimmed_key);
|
|
CHECK(!trimmed_key.empty());
|
|
return trimmed_key;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
KeyValueStore::KeyValueStore() = default;
|
|
KeyValueStore::~KeyValueStore() = default;
|
|
KeyValueStore::KeyValueStore(KeyValueStore&&) = default;
|
|
KeyValueStore& KeyValueStore::operator=(KeyValueStore&&) = default;
|
|
|
|
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::SplitString(data, "\n", base::KEEP_WHITESPACE,
|
|
base::SPLIT_WANT_ALL);
|
|
for (auto it = lines.begin(); it != lines.end(); ++it) {
|
|
std::string line;
|
|
base::TrimWhitespaceASCII(*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::TrimWhitespaceASCII(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;
|
|
}
|
|
|
|
void KeyValueStore::Clear() {
|
|
store_.clear();
|
|
}
|
|
|
|
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
|