You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
3.3 KiB
109 lines
3.3 KiB
/* Config.cpp |
|
* |
|
* Loads and stores configuration data in an INI-like format. |
|
*/ |
|
|
|
#include <algorithm> |
|
#include <fstream> |
|
#include <iostream> |
|
|
|
#include "Config.h" |
|
#include "StringUtil.h" |
|
|
|
namespace PlipSdl { |
|
const std::unordered_map<std::string, std::string> *Config::GetSection(const std::string &key) { |
|
auto keyLower = StringUtil::ToLower(key); |
|
|
|
auto itSection = m_section.find(keyLower); |
|
if(itSection == m_section.end()) return nullptr; |
|
|
|
return &(itSection->second); |
|
} |
|
|
|
const std::string &Config::GetValue(const std::string &key) { |
|
return GetValue(global, key); |
|
} |
|
|
|
const std::string &Config::GetValue(const std::string §ion, const std::string &key) { |
|
auto secLower = StringUtil::ToLower(section); |
|
auto keyLower = StringUtil::ToLower(key); |
|
|
|
auto itSection = m_section.find(secLower); |
|
if(itSection == m_section.cend()) return empty; |
|
|
|
auto itKey = itSection->second.find(keyLower); |
|
if(itKey == itSection->second.cend()) return empty; |
|
|
|
return itKey->second; |
|
} |
|
|
|
bool Config::LoadFile(const std::string &filename) { |
|
std::string section = global; |
|
|
|
std::ifstream file; |
|
file.open(filename); |
|
|
|
if(!file.is_open()) return false; |
|
|
|
std::string line; |
|
int lineNum = 0; |
|
while(std::getline(file, line)) { |
|
line = StringUtil::Trim(line); |
|
++lineNum; |
|
|
|
if(line.empty()) continue; |
|
|
|
// Comment. |
|
if(line.front() == '#') continue; |
|
|
|
if(line.front() == '[' && line.back() == ']') { |
|
// Section |
|
line.erase(line.cbegin()); |
|
line.erase(line.cend() - 1); |
|
section = StringUtil::Trim(line); |
|
continue; |
|
} |
|
|
|
// Everything else. :) |
|
auto equals = line.find('=', 0); |
|
if(equals == std::string::npos) { |
|
std::cerr << filename << ": no value specified on line " << lineNum << std::endl; |
|
continue; |
|
} |
|
|
|
auto key = StringUtil::Trim(line.substr(0, equals)); |
|
auto value = StringUtil::Trim(line.substr(equals + 1, std::string::npos)); |
|
SetValue(section, key, value); |
|
} |
|
|
|
file.close(); |
|
return true; |
|
} |
|
|
|
void Config::SetValue(const std::string &key, const std::string &value) { |
|
SetValue(global, key, value); |
|
} |
|
|
|
void Config::SetValue(const std::string §ion, const std::string &key, const std::string &value) { |
|
auto secLower = StringUtil::ToLower(section); |
|
auto keyLower = StringUtil::ToLower(key); |
|
|
|
auto itSection = m_section.find(secLower); |
|
if(itSection == m_section.cend()) { |
|
// O.o |
|
auto newSection = std::pair<std::string, std::unordered_map<std::string, std::string>> |
|
(secLower, std::unordered_map<std::string, std::string>()); |
|
newSection.second.insert(std::pair<std::string, std::string>(keyLower, value)); |
|
m_section.insert(newSection); |
|
return; |
|
} |
|
|
|
auto itKey = itSection->second.find(keyLower); |
|
if(itKey == itSection->second.cend()) { |
|
itSection->second.insert(std::pair<std::string, std::string>(keyLower, value)); |
|
return; |
|
} |
|
|
|
itKey->second = value; |
|
} |
|
}
|
|
|