diff options
Diffstat (limited to 'common/prefs.cc')
-rw-r--r-- | common/prefs.cc | 112 |
1 files changed, 99 insertions, 13 deletions
diff --git a/common/prefs.cc b/common/prefs.cc index 12d06c0c..1e06be44 100644 --- a/common/prefs.cc +++ b/common/prefs.cc @@ -18,22 +18,44 @@ #include <algorithm> +#include <base/files/file_enumerator.h> #include <base/files/file_util.h> #include <base/logging.h> #include <base/strings/string_number_conversions.h> +#include <base/strings/string_split.h> #include <base/strings/string_util.h> #include "update_engine/common/utils.h" using std::string; +using std::vector; namespace chromeos_update_engine { +namespace { + +void DeleteEmptyDirectories(const base::FilePath& path) { + base::FileEnumerator path_enum( + path, false /* recursive */, base::FileEnumerator::DIRECTORIES); + for (base::FilePath dir_path = path_enum.Next(); !dir_path.empty(); + dir_path = path_enum.Next()) { + DeleteEmptyDirectories(dir_path); + if (base::IsDirectoryEmpty(dir_path)) +#if BASE_VER < 800000 + base::DeleteFile(dir_path, false); +#else + base::DeleteFile(dir_path); +#endif + } +} + +} // namespace + bool PrefsBase::GetString(const string& key, string* value) const { return storage_->GetKey(key, value); } -bool PrefsBase::SetString(const string& key, const string& value) { +bool PrefsBase::SetString(const string& key, std::string_view value) { TEST_AND_RETURN_FALSE(storage_->SetKey(key, value)); const auto observers_for_key = observers_.find(key); if (observers_for_key != observers_.end()) { @@ -54,7 +76,7 @@ bool PrefsBase::GetInt64(const string& key, int64_t* value) const { } bool PrefsBase::SetInt64(const string& key, const int64_t value) { - return SetString(key, base::Int64ToString(value)); + return SetString(key, base::NumberToString(value)); } bool PrefsBase::GetBoolean(const string& key, bool* value) const { @@ -92,6 +114,28 @@ bool PrefsBase::Delete(const string& key) { return true; } +bool PrefsBase::Delete(const string& pref_key, const vector<string>& nss) { + // Delete pref key for platform. + bool success = Delete(pref_key); + // Delete pref key in each namespace. + for (const auto& ns : nss) { + vector<string> namespace_keys; + success = GetSubKeys(ns, &namespace_keys) && success; + for (const auto& key : namespace_keys) { + auto last_key_seperator = key.find_last_of(kKeySeparator); + if (last_key_seperator != string::npos && + pref_key == key.substr(last_key_seperator + 1)) { + success = Delete(key) && success; + } + } + } + return success; +} + +bool PrefsBase::GetSubKeys(const string& ns, vector<string>* keys) const { + return storage_->GetSubKeys(ns, keys); +} + void PrefsBase::AddObserver(const string& key, ObserverInterface* observer) { observers_[key].push_back(observer); } @@ -104,6 +148,10 @@ void PrefsBase::RemoveObserver(const string& key, ObserverInterface* observer) { observers_for_key.erase(observer_it); } +string PrefsInterface::CreateSubKey(const vector<string>& ns_and_key) { + return base::JoinString(ns_and_key, string(1, kKeySeparator)); +} + // Prefs bool Prefs::Init(const base::FilePath& prefs_dir) { @@ -112,6 +160,8 @@ bool Prefs::Init(const base::FilePath& prefs_dir) { bool Prefs::FileStorage::Init(const base::FilePath& prefs_dir) { prefs_dir_ = prefs_dir; + // Delete empty directories. Ignore errors when deleting empty directories. + DeleteEmptyDirectories(prefs_dir_); return true; } @@ -119,13 +169,30 @@ bool Prefs::FileStorage::GetKey(const string& key, string* value) const { base::FilePath filename; TEST_AND_RETURN_FALSE(GetFileNameForKey(key, &filename)); if (!base::ReadFileToString(filename, value)) { - LOG(INFO) << key << " not present in " << prefs_dir_.value(); return false; } return true; } -bool Prefs::FileStorage::SetKey(const string& key, const string& value) { +bool Prefs::FileStorage::GetSubKeys(const string& ns, + vector<string>* keys) const { + base::FilePath filename; + TEST_AND_RETURN_FALSE(GetFileNameForKey(ns, &filename)); + base::FileEnumerator namespace_enum( + prefs_dir_, true, base::FileEnumerator::FILES); + for (base::FilePath f = namespace_enum.Next(); !f.empty(); + f = namespace_enum.Next()) { + auto filename_str = filename.value(); + if (f.value().compare(0, filename_str.length(), filename_str) == 0) { + // Only return the key portion excluding the |prefs_dir_| with slash. + keys->push_back(f.value().substr( + prefs_dir_.AsEndingWithSeparator().value().length())); + } + } + return true; +} + +bool Prefs::FileStorage::SetKey(const string& key, std::string_view value) { base::FilePath filename; TEST_AND_RETURN_FALSE(GetFileNameForKey(key, &filename)); if (!base::DirectoryExists(filename.DirName())) { @@ -147,19 +214,21 @@ bool Prefs::FileStorage::KeyExists(const string& key) const { bool Prefs::FileStorage::DeleteKey(const string& key) { base::FilePath filename; TEST_AND_RETURN_FALSE(GetFileNameForKey(key, &filename)); +#if BASE_VER < 800000 TEST_AND_RETURN_FALSE(base::DeleteFile(filename, false)); +#else + TEST_AND_RETURN_FALSE(base::DeleteFile(filename)); +#endif return true; } bool Prefs::FileStorage::GetFileNameForKey(const string& key, base::FilePath* filename) const { - // Allows only non-empty keys containing [A-Za-z0-9_-]. + // Allows only non-empty keys containing [A-Za-z0-9_-/]. TEST_AND_RETURN_FALSE(!key.empty()); - for (size_t i = 0; i < key.size(); ++i) { - char c = key.at(i); + for (char c : key) TEST_AND_RETURN_FALSE(base::IsAsciiAlpha(c) || base::IsAsciiDigit(c) || - c == '_' || c == '-'); - } + c == '_' || c == '-' || c == kKeySeparator); *filename = prefs_dir_.Append(key); return true; } @@ -175,8 +244,26 @@ bool MemoryPrefs::MemoryStorage::GetKey(const string& key, return true; } +bool MemoryPrefs::MemoryStorage::GetSubKeys(const string& ns, + vector<string>* keys) const { + using value_type = decltype(values_)::value_type; + using key_type = decltype(values_)::key_type; + auto lower_comp = [](const value_type& pr, const key_type& ns) { + return pr.first.substr(0, ns.length()) < ns; + }; + auto upper_comp = [](const key_type& ns, const value_type& pr) { + return ns < pr.first.substr(0, ns.length()); + }; + auto lower_it = + std::lower_bound(begin(values_), end(values_), ns, lower_comp); + auto upper_it = std::upper_bound(lower_it, end(values_), ns, upper_comp); + while (lower_it != upper_it) + keys->push_back((lower_it++)->first); + return true; +} + bool MemoryPrefs::MemoryStorage::SetKey(const string& key, - const string& value) { + std::string_view value) { values_[key] = value; return true; } @@ -187,9 +274,8 @@ bool MemoryPrefs::MemoryStorage::KeyExists(const string& key) const { bool MemoryPrefs::MemoryStorage::DeleteKey(const string& key) { auto it = values_.find(key); - if (it == values_.end()) - return false; - values_.erase(it); + if (it != values_.end()) + values_.erase(it); return true; } |