#include "Config.h" #include #include #include #include #include #include #include using namespace std; bool isFloat(const string &myString) { istringstream iss(myString); float f; iss >> noskipws >> f; // noskipws considers leading whitespace invalid // Check the entire string was consumed and if either failbit or badbit is set return iss.eof() && !iss.fail(); } bool isInt(const string &myString) { istringstream iss(myString); int i; iss >> noskipws >> i; // noskipws considers leading whitespace invalid // Check the entire string was consumed and if either failbit or badbit is set return iss.eof() && !iss.fail(); } // trim from start (in place) static inline void ltrim(string &s) { s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun(isspace)))); } // trim from end (in place) static inline void rtrim(string &s) { s.erase(find_if(s.rbegin(), s.rend(), not1(ptr_fun(isspace))).base(), s.end()); } // trim from both ends (in place) static inline void trim(string &s) { ltrim(s); rtrim(s); } Config::Config(string path) { this->path = std::move(path); } void Config::load() { strings.clear(); bools.clear(); floats.clear(); ifstream conf(path); if (conf.is_open()) { string line; while (getline(conf, line)) { unsigned int pos = line.find('='); if (pos > 0) { string key = line.substr(0, pos); string value = line.substr(pos + 1, line.length()); trim(key); trim(value); if (bools.find(key) != bools.end() || strings.find(key) != strings.end() || ints.find(key) != ints.end() || floats.find(key) != floats.end()) { continue; } if (isInt(value)) { int ival = stoi(value); ints.insert(pair{key, ival}); } else if (isFloat(value)) { float fval = stof(value); floats.insert(pair{key, fval}); } else if (value.find("true") == 0 && value.length() == 4) { bools.insert(pair{key, true}); } else if (value.find("false") == 0 && value.length() == 5) { bools.insert(pair{key, false}); } else { strings.insert(pair{key, value}); } } } conf.close(); } } void Config::save() { ofstream conf(path, ios::trunc); if (conf.is_open()) { vector vec; for (auto it : ints) { vec.push_back(it.first + " = " + to_string(it.second)); } for (auto it : floats) { vec.push_back(it.first + " = " + to_string(it.second)); } for (auto it : bools) { string b; if (it.second) { b = "true"; } else { b = "false"; } vec.push_back(it.first + " = " + b); } for (auto it : strings) { vec.push_back(it.first + " = " + it.second); } sort(vec.begin(), vec.end()); for (auto it : vec) { conf << it << "\n"; } conf.close(); } } void Config::deleteValue(string key) { strings.erase(key); ints.erase(key); floats.erase(key); bools.erase(key); } string Config::getString(string key, string defaultvalue) { auto iter = strings.find(key); if (iter != strings.end()) { return iter->second; } else { deleteValue(key); strings.insert(pair{key, defaultvalue}); return defaultvalue; } } int Config::getInt(string key, int defaultvalue) { auto iter = ints.find(key); if (iter != ints.end()) { return iter->second; } else { deleteValue(key); ints.insert(pair{key, defaultvalue}); return defaultvalue; } } float Config::getFloat(std::string key, float defaultvalue) { auto iter = floats.find(key); if (iter != floats.end()) { return iter->second; } else { deleteValue(key); floats.insert(pair{key, defaultvalue}); return defaultvalue; } } bool Config::getBool(std::string key, bool defaultvalue) { auto iter = bools.find(key); if (iter != bools.end()) { return iter->second; } else { deleteValue(key); bools.insert(pair{key, defaultvalue}); return defaultvalue; } } Config::~Config() = default; void Config::setString(std::string key, std::string value) { deleteValue(key); strings.insert(pair{key, value}); } void Config::setInt(std::string key, int value) { deleteValue(key); ints.insert(pair{key, value}); } void Config::setFloat(std::string key, float value) { deleteValue(key); floats.insert(pair{key, value}); } void Config::setBool(std::string key, bool value) { deleteValue(key); bools.insert(pair{key, value}); }