From e7da6a5abcbda7ebd9130a6ed3d712614335abc3 Mon Sep 17 00:00:00 2001 From: Nomango Date: Thu, 28 May 2020 02:42:32 +0800 Subject: [PATCH] add ConfigIni & remove LocalStorage --- projects/kiwano/kiwano.vcxproj | 4 +- projects/kiwano/kiwano.vcxproj.filters | 12 +- src/kiwano/kiwano.h | 2 +- src/kiwano/utils/ConfigIni.cpp | 353 +++++++++++++++++++++++++ src/kiwano/utils/ConfigIni.h | 185 +++++++++++++ src/kiwano/utils/LocalStorage.cpp | 106 -------- src/kiwano/utils/LocalStorage.h | 163 ------------ 7 files changed, 547 insertions(+), 278 deletions(-) create mode 100644 src/kiwano/utils/ConfigIni.cpp create mode 100644 src/kiwano/utils/ConfigIni.h delete mode 100644 src/kiwano/utils/LocalStorage.cpp delete mode 100644 src/kiwano/utils/LocalStorage.h diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj index 06fa487e..8883793a 100644 --- a/projects/kiwano/kiwano.vcxproj +++ b/projects/kiwano/kiwano.vcxproj @@ -96,9 +96,9 @@ + - @@ -174,8 +174,8 @@ + - diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters index 9a950f94..9d5619f2 100644 --- a/projects/kiwano/kiwano.vcxproj.filters +++ b/projects/kiwano/kiwano.vcxproj.filters @@ -105,9 +105,6 @@ 2d\action - - utils - utils @@ -351,6 +348,9 @@ base\component + + utils + @@ -401,9 +401,6 @@ 2d\action - - utils - utils @@ -575,6 +572,9 @@ base\component + + utils + diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index 50ef674e..1bd37f0f 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -127,7 +127,6 @@ // #include -#include #include #include #include @@ -135,3 +134,4 @@ #include #include #include +#include diff --git a/src/kiwano/utils/ConfigIni.cpp b/src/kiwano/utils/ConfigIni.cpp new file mode 100644 index 00000000..ed2374e5 --- /dev/null +++ b/src/kiwano/utils/ConfigIni.cpp @@ -0,0 +1,353 @@ +// Copyright (c) 2016-2018 Kiwano - Nomango +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include +#include +#include +#include + +#define KGE_DEFAULT_INI_SECTION_NAME "default" + +namespace kiwano +{ + +StringView Trim(StringView str) +{ + if (!str.IsEmpty()) + { + std::size_t start = 0, end = str.GetLength(); + while (std::isspace(str[start])) + ++start; + while (std::isspace(str[end - 1])) + --end; + + if (end - start) + return StringView(str.Data() + start, end - start); + } + return StringView(); +} + +class IniParser +{ + StringView line_; +public: + IniParser(StringView line) + : line_(line) + { + } + + bool ClearComment() + { + auto pos = line_.Find(';'); + if (pos != String::npos) + { + if (pos == 0) + return true; + + if (std::isspace(line_[pos - 1])) + { + line_ = Trim(line_.SubStr(0, pos - 1)); + return line_.IsEmpty(); + } + } + return false; + } + + bool IsSection() const + { + return line_[0] == '[' && line_.GetLength() > 2 && line_[line_.GetLength() - 1] == ']'; + } + + StringView GetSectionName() const + { + return Trim(line_.SubStr(1, line_.GetLength() - 2)); + } + + bool GetKeyValue(StringView* key, StringView* value) + { + auto pos = line_.Find('='); + if (pos == String::npos) + return false; + + *key = Trim(line_.SubStr(0, pos)); + *value = Trim(line_.SubStr(pos + 1)); + + return !(*key).IsEmpty() && !(*value).IsEmpty(); + } +}; + +ConfigIniPtr ConfigIni::Create(const String& file_path) +{ + ConfigIniPtr ptr = memory::New(); + if (ptr) + { + if (!ptr->Load(file_path)) + { + return nullptr; + } + } + return ptr; +} + +bool ConfigIni::Load(const String& file_path) +{ + std::ifstream ifs(file_path); + + if (ifs.is_open()) + { + return Load(ifs); + } + return false; +} + +bool ConfigIni::Load(std::istream& istream) +{ + try + { + String section = KGE_DEFAULT_INI_SECTION_NAME; + for (String line; std::getline(istream, line);) + { + ParseLine(line, §ion); + } + return true; + } + catch (Exception) + { + return false; + } + return false; +} + +bool ConfigIni::Save(const String& file_path) +{ + std::ofstream ofs(file_path); + + if (ofs.is_open()) + { + return Save(ofs); + } + return false; +} + +bool ConfigIni::Save(std::ostream& os) +{ + // Get all keys + Vector keys; + keys.reserve(sections_.size()); + std::for_each(sections_.begin(), sections_.end(), [&](SectionMap::value_type& pair) { keys.push_back(pair.first); }); + + // Sort for keys + std::sort(keys.begin(), keys.end()); + + // Output to ini + for (const auto& key : keys) + { + os << '[' << key << ']' << std::endl; + for (const auto& pair : sections_[key]) + { + os << pair.first << " = " << pair.second << std::endl; + } + os << std::endl; + } + return false; +} + +ConfigIni::SectionMap ConfigIni::GetSectionMap() const +{ + return sections_; +} + +ConfigIni::ValueMap ConfigIni::GetSection(const String& section) const +{ + auto iter = sections_.find(section); + if (iter != sections_.end()) + return iter->second; + return ValueMap(); +} + +String ConfigIni::GetString(const String& section_name, const String& key) const +{ + if (HasSection(section_name)) + { + const auto& section = sections_.at(section_name); + + auto iter_key = section.find(key); + if (iter_key != section.end()) + return iter_key->second; + } + return String(); +} + +float ConfigIni::GetFloat(const String& section, const String& key, float default_value) const +{ + String str = GetString(section, key); + if (str.empty()) + return default_value; + + try + { + std::size_t pos = 0; + float value = std::stof(str, &pos); + if (pos == str.size()) + return value; + } + catch (std::invalid_argument) + { + return default_value; + } + return default_value; +} + +double ConfigIni::GetDouble(const String& section, const String& key, double default_value) const +{ + String str = GetString(section, key); + if (str.empty()) + return default_value; + + try + { + std::size_t pos = 0; + double value = std::stod(str, &pos); + if (pos == str.size()) + return value; + } + catch (std::invalid_argument) + { + return default_value; + } + return default_value; +} + +int ConfigIni::GetInt(const String& section, const String& key, int default_value) const +{ + String str = GetString(section, key); + if (str.empty()) + return default_value; + + try + { + std::size_t pos = 0; + int value = std::stoi(str, &pos); + if (pos == str.size()) + return value; + } + catch (std::invalid_argument) + { + return default_value; + } + return default_value; +} + +bool ConfigIni::GetBool(const String& section, const String& key, bool default_value) const +{ + String str = GetString(section, key); + if (!str.empty()) + { + if (str == "true") + return true; + else if (str == "false") + return false; + } + return default_value; +} + +bool ConfigIni::HasSection(const String& section) const +{ + return !!sections_.count(section); +} + +bool ConfigIni::HasValue(const String& section, const String& key) const +{ + if (HasSection(section)) + { + return !!sections_.at(section).count(section); + } + return false; +} + +void ConfigIni::SetSectionMap(const SectionMap& sections) +{ + sections_ = sections; +} + +void ConfigIni::SetSection(const String& section, const ValueMap& values) +{ + sections_.insert(std::make_pair(section, values)); +} + +void ConfigIni::SetString(const String& section, const String& key, const String& value) +{ + if (HasSection(section)) + sections_[section].insert(std::make_pair(key, value)); + else + SetSection(section, ValueMap{ { key, value } }); +} + +void ConfigIni::SetFloat(const String& section, const String& key, float value) +{ + String str = std::to_string(value); + SetString(section, key, str); +} + +void ConfigIni::SetDouble(const String& section, const String& key, double value) +{ + String str = std::to_string(value); + SetString(section, key, str); +} + +void ConfigIni::SetInt(const String& section, const String& key, int value) +{ + String str = std::to_string(value); + SetString(section, key, str); +} + +void ConfigIni::SetBool(const String& section, const String& key, bool value) +{ + SetString(section, key, value ? "true" : "false"); +} + +void ConfigIni::ParseLine(StringView line, String* section) +{ + line = Trim(line); + if (line.IsEmpty()) + return; + + IniParser parser(line); + if (parser.ClearComment()) + return; + + if (parser.IsSection()) + { + auto name = parser.GetSectionName(); + if (name.IsEmpty()) + throw Exception("Empty section name"); + *section = name; + return; + } + + StringView key, value; + if (!parser.GetKeyValue(&key, &value)) + { + throw Exception("Parse key-value failed"); + } + SetString(*section, key, value); +} + +} // namespace kiwano diff --git a/src/kiwano/utils/ConfigIni.h b/src/kiwano/utils/ConfigIni.h new file mode 100644 index 00000000..dac12b6c --- /dev/null +++ b/src/kiwano/utils/ConfigIni.h @@ -0,0 +1,185 @@ +// Copyright (c) 2016-2018 Kiwano - Nomango +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once +#include +#include + +namespace kiwano +{ + +KGE_DECLARE_SMART_PTR(ConfigIni); + +/// \~chinese +/// @brief ini格式文件 +class KGE_API ConfigIni : public ObjectBase +{ +public: + /// \~chinese + /// @brief 加载 ini 文件 + /// @param file_path 文件路径 + static ConfigIniPtr Create(const String& file_path); + + /// \~chinese + /// @brief 键值字典 + typedef Map ValueMap; + + /// \~chinese + /// @brief Section字典 + typedef UnorderedMap SectionMap; + + /// \~chinese + /// @brief 加载 ini 文件 + /// @param file_path 文件路径 + bool Load(const String& file_path); + + /// \~chinese + /// @brief 加载 ini 文件 + /// @param is 输入流 + bool Load(std::istream& is); + + /// \~chinese + /// @brief 保存至 ini 文件 + /// @param file_path 文件路径 + bool Save(const String& file_path); + + /// \~chinese + /// @brief 保存至 ini 文件 + /// @param os 输出流 + bool Save(std::ostream& os); + + /// \~chinese + /// @brief 获取所有section + SectionMap GetSectionMap() const; + + /// \~chinese + /// @brief 获取section + /// @param section section的名称 + ValueMap GetSection(const String& section) const; + + /// \~chinese + /// @brief 获取值 + /// @param section section的名称 + /// @param key key的名称 + String GetString(const String& section, const String& key) const; + + /// \~chinese + /// @brief 获取值 + /// @param section section的名称 + /// @param key key的名称 + /// @param default_value 不存在时的默认值 + float GetFloat(const String& section, const String& key, float default_value = 0.0f) const; + + /// \~chinese + /// @brief 获取值 + /// @param section section的名称 + /// @param key key的名称 + /// @param default_value 不存在时的默认值 + double GetDouble(const String& section, const String& key, double default_value = 0.0) const; + + /// \~chinese + /// @brief 获取值 + /// @param section section的名称 + /// @param key key的名称 + /// @param default_value 不存在时的默认值 + int GetInt(const String& section, const String& key, int default_value = 0) const; + + /// \~chinese + /// @brief 获取值 + /// @param section section的名称 + /// @param key key的名称 + /// @param default_value 不存在时的默认值 + bool GetBool(const String& section, const String& key, bool default_value = false) const; + + /// \~chinese + /// @brief 是否存在section + /// @param section section的名称 + bool HasSection(const String& section) const; + + /// \~chinese + /// @brief 是否存在值 + /// @param section section的名称 + /// @param key key的名称 + bool HasValue(const String& section, const String& key) const; + + /// \~chinese + /// @brief 设置所有section + /// @param sections section字典 + void SetSectionMap(const SectionMap& sections); + + /// \~chinese + /// @brief 设置section + /// @param section section的名称 + /// @param values 键值字典 + void SetSection(const String& section, const ValueMap& values); + + /// \~chinese + /// @brief 设置值 + /// @param section section的名称 + /// @param key key的名称 + /// @param value 值 + void SetString(const String& section, const String& key, const String& value); + + /// \~chinese + /// @brief 设置值 + /// @param section section的名称 + /// @param key key的名称 + /// @param value 值 + void SetFloat(const String& section, const String& key, float value); + + /// \~chinese + /// @brief 设置值 + /// @param section section的名称 + /// @param key key的名称 + /// @param value 值 + void SetDouble(const String& section, const String& key, double value); + + /// \~chinese + /// @brief 设置值 + /// @param section section的名称 + /// @param key key的名称 + /// @param value 值 + void SetInt(const String& section, const String& key, int value); + + /// \~chinese + /// @brief 设置值 + /// @param section section的名称 + /// @param key key的名称 + /// @param value 值 + void SetBool(const String& section, const String& key, bool value); + + inline ValueMap& operator[](const String& section) + { + return sections_[section]; + } + + inline const ValueMap& operator[](const String& section) const + { + return sections_.at(section); + } + +private: + void ParseLine(StringView line, String* section); + +private: + SectionMap sections_; +}; + +} // namespace kiwano diff --git a/src/kiwano/utils/LocalStorage.cpp b/src/kiwano/utils/LocalStorage.cpp deleted file mode 100644 index 6e98d9ab..00000000 --- a/src/kiwano/utils/LocalStorage.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2016-2018 Kiwano - Nomango -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include - -namespace kiwano -{ - -LocalStorage::LocalStorage(const String& file_path, const String& field) -{ - SetFilePath(file_path); - SetFieldName(field); -} - -bool LocalStorage::Exists(const String& key) const -{ - char temp[256] = { 0 }; - ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), "", temp, 255, file_path_.c_str()); - return temp[0] == '\0'; -} - -bool LocalStorage::SaveInt(const String& key, int val) const -{ - BOOL ret = - ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), std::to_string(val).c_str(), file_path_.c_str()); - return ret == TRUE; -} - -bool LocalStorage::SaveFloat(const String& key, float val) const -{ - BOOL ret = - ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), std::to_string(val).c_str(), file_path_.c_str()); - return ret == TRUE; -} - -bool LocalStorage::SaveDouble(const String& key, double val) const -{ - BOOL ret = - ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), std::to_string(val).c_str(), file_path_.c_str()); - return ret == TRUE; -} - -bool LocalStorage::SaveBool(const String& key, bool val) const -{ - BOOL ret = ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), (val ? "1" : "0"), file_path_.c_str()); - return ret == TRUE; -} - -bool LocalStorage::SaveString(const String& key, const String& val) const -{ - BOOL ret = ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), val.c_str(), file_path_.c_str()); - return ret == TRUE; -} - -int LocalStorage::GetInt(const String& key, int default_value) const -{ - return ::GetPrivateProfileIntA(field_name_.c_str(), key.c_str(), default_value, file_path_.c_str()); -} - -float LocalStorage::GetFloat(const String& key, float default_value) const -{ - char temp[32] = { 0 }; - String default_str = std::to_string(default_value); - ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), default_str.c_str(), temp, 31, file_path_.c_str()); - return std::stof(temp); -} - -double LocalStorage::GetDouble(const String& key, double default_value) const -{ - char temp[32] = { 0 }; - String default_str = std::to_string(default_value); - ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), default_str.c_str(), temp, 31, file_path_.c_str()); - return std::stod(temp); -} - -bool LocalStorage::GetBool(const String& key, bool default_value) const -{ - int nValue = ::GetPrivateProfileIntA(field_name_.c_str(), key.c_str(), default_value ? 1 : 0, file_path_.c_str()); - return nValue == TRUE; -} - -String LocalStorage::GetString(const String& key, const String& default_value) const -{ - char temp[256] = { 0 }; - ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), default_value.c_str(), temp, 255, file_path_.c_str()); - return temp; -} - -} // namespace kiwano diff --git a/src/kiwano/utils/LocalStorage.h b/src/kiwano/utils/LocalStorage.h deleted file mode 100644 index d3475cab..00000000 --- a/src/kiwano/utils/LocalStorage.h +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 2016-2018 Kiwano - Nomango -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#pragma once -#include -#include - -namespace kiwano -{ - -KGE_DECLARE_SMART_PTR(LocalStorage); - -/// \~chinese -/// @brief 本地存储 -/// @details LocalStorage是一个简易的持久化工具,存放(字符串-值)的键值对 -/// 支持的数据类型包括 (bool | int | float | double | String) -/// 例如, 保存游戏最高分, 以便下次进行游戏时读取: -/// @code -/// LocalStorage data; // 创建数据对象 -/// data.SaveInt("best-score", 20); // 保存最高分 20 -/// int best = data.GetInt("best-score"); // 读取之前储存的最高分 -/// @endcode -class KGE_API LocalStorage : public ObjectBase -{ -public: - /// \~chinese - /// @brief 构建本地存储对象 - /// @param file_path 文件储存路径 - /// @param field 字段名 - LocalStorage(const String& file_path = "data.ini", const String& field = "defalut"); - - /// \~chinese - /// @brief 获取文件储存路径 - const String& GetFilePath() const; - - /// \~chinese - /// @brief 设置文件储存路径 - void SetFilePath(const String& file_path); - - /// \~chinese - /// @brief 获取字段名 - const String& GetFieldName() const; - - /// \~chinese - /// @brief 设置字段名 - void SetFieldName(const String& field); - - /// \~chinese - /// @brief 判断键对应的数据是否存在 - bool Exists(const String& key) const; - - /// \~chinese - /// @brief 保存 int 类型的值 - /// @param key 键 - /// @param val 值 - /// @return 操作是否成功 - bool SaveInt(const String& key, int val) const; - - /// \~chinese - /// @brief 保存 float 类型的值 - /// @param key 键 - /// @param val 值 - /// @return 操作是否成功 - bool SaveFloat(const String& key, float val) const; - - /// \~chinese - /// @brief 保存 double 类型的值 - /// @param key 键 - /// @param val 值 - /// @return 操作是否成功 - bool SaveDouble(const String& key, double val) const; - - /// \~chinese - /// @brief 保存 bool 类型的值 - /// @param key 键 - /// @param val 值 - /// @return 操作是否成功 - bool SaveBool(const String& key, bool val) const; - - /// \~chinese - /// @brief 保存 String 类型的值 - /// @param key 键 - /// @param val 值 - /// @return 操作是否成功 - bool SaveString(const String& key, const String& val) const; - - /// \~chinese - /// @brief 获取 int 类型的值 - /// @param key 键 - /// @param default_value 值不存在时返回的默认值 - /// @return 值 - int GetInt(const String& key, int default_value = 0) const; - - /// \~chinese - /// @brief 获取 float 类型的值 - /// @param key 键 - /// @param default_value 值不存在时返回的默认值 - /// @return 值 - float GetFloat(const String& key, float default_value = 0.0f) const; - - /// \~chinese - /// @brief 获取 double 类型的值 - /// @param key 键 - /// @param default_value 值不存在时返回的默认值 - /// @return 值 - double GetDouble(const String& key, double default_value = 0.0) const; - - /// \~chinese - /// @brief 获取 bool 类型的值 - /// @param key 键 - /// @param default_value 值不存在时返回的默认值 - /// @return 值 - bool GetBool(const String& key, bool default_value = false) const; - - /// \~chinese - /// @brief 获取 字符串 类型的值 - /// @param key 键 - /// @param default_value 值不存在时返回的默认值 - /// @return 值 - String GetString(const String& key, const String& default_value = String()) const; - -private: - String file_path_; - String field_name_; -}; - -inline const String& LocalStorage::GetFilePath() const -{ - return file_path_; -} - -inline const String& LocalStorage::GetFieldName() const -{ - return field_name_; -} - -inline void LocalStorage::SetFilePath(const String& file_path) -{ - file_path_ = file_path; -} - -inline void LocalStorage::SetFieldName(const String& field_name) -{ - field_name_ = field_name; -} -} // namespace kiwano