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