206 lines
5.1 KiB
C++
206 lines
5.1 KiB
C++
#include "Config.h"
|
|
#include <cctype>
|
|
#include <functional>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <utility>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
|
|
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<int, int>(isspace))));
|
|
}
|
|
|
|
// trim from end (in place)
|
|
static inline void rtrim(string &s) {
|
|
s.erase(find_if(s.rbegin(), s.rend(),
|
|
not1(ptr_fun<int, int>(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<string, float>{key, ival});
|
|
}
|
|
else if (isFloat(value)) {
|
|
float fval = stof(value);
|
|
floats.insert(pair<string, float>{key, fval});
|
|
}
|
|
else if (value.find("true") == 0 && value.length() == 4) {
|
|
bools.insert(pair<string, bool>{key, true});
|
|
}
|
|
else if (value.find("false") == 0 && value.length() == 5) {
|
|
bools.insert(pair<string, bool>{key, false});
|
|
}
|
|
else {
|
|
strings.insert(pair<string, string>{key, value});
|
|
}
|
|
}
|
|
}
|
|
conf.close();
|
|
}
|
|
}
|
|
|
|
void Config::save() {
|
|
ofstream conf(path, ios::trunc);
|
|
if (conf.is_open()) {
|
|
vector<string> 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<string, string>{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<string, int>{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<string, float>{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<string, bool>{key, defaultvalue});
|
|
return defaultvalue;
|
|
}
|
|
}
|
|
|
|
|
|
Config::~Config() = default;
|
|
|
|
void Config::setString(std::string key, std::string value) {
|
|
deleteValue(key);
|
|
strings.insert(pair<string, string>{key, value});
|
|
}
|
|
|
|
void Config::setInt(std::string key, int value) {
|
|
deleteValue(key);
|
|
ints.insert(pair<string, int>{key, value});
|
|
}
|
|
|
|
void Config::setFloat(std::string key, float value) {
|
|
deleteValue(key);
|
|
floats.insert(pair<string, float>{key, value});
|
|
}
|
|
|
|
void Config::setBool(std::string key, bool value) {
|
|
deleteValue(key);
|
|
bools.insert(pair<string, bool>{key, value});
|
|
}
|