#include "Config.h"
Config::Config(std::string ConfigFileName) {
this->configFileName = ConfigFileName;
this->fileStream.open(this->configFileName);
if (this->fileStream.is_open()) {
this->searchPattern = boost::regex("^([ \\t]+)?([^#][^\\s]+)\\s*=\\s*(?:(\\d+)|(?:\"([^\"]*)\")).*$");
this->ReloadConfig();
}
}
void Config::lineParser()
{
//--keep thread alive until file is fully pushed into lineBuffer and lineBuffer is empty
while(this->isFileFinish == false || this->lineBuffer.size() != 0)
{
//--wait until lines for parsing are avaible
if (this->lineBuffer.size() == 0)
boost::this_thread::sleep(boost::posix_time::millisec(1));
//--
else
{
boost::match_results<std::string::const_iterator> matches;
//--lock lineBuffer object
this->lineBufferMutex.lock();
//copy first line into temp var
std::string line = *this->lineBuffer.begin();
//remove first line from lineBuffer
this->lineBuffer.pop_front();
this->lineBufferMutex.unlock();
//--
if (boost::regex_match(line, matches, this->searchPattern))
{
//--insert match into our configMap (we have to lock our configMap object first)
this->configMapMutex.lock();
if (matches[3].matched)
//insert number (without qoutes)
this->configMap.insert(std::make_pair(matches[2], matches[3]));
else
//insert string (in quoutes)
this->configMap.insert(std::make_pair(matches[2], matches[4]));
this->configMapMutex.unlock();
//--
}
}
//--
}
}
void Config::ReloadConfig() {
//--reset
this->configMap.clear();
this->fileStream.seekg(0, ios::beg);
this->isFileFinish = false;
//--
//--define variables
std::string line;
boost::thread_group threadPool;
//--
//--create parser-threads for each logical cpu
for(uint32 i = 0; i < boost::thread::hardware_concurrency(); i++)
{
threadPool.create_thread(boost::bind(&Config::lineParser, this));
}
//--
//--push lines from file in our lineBuffer
while(std::getline(this->fileStream, line))
{
this->lineBuffer.push_back(line);
}
//--
this->isFileFinish = true;
//wait until all lines are parsed
threadPool.join_all();
}
std::string Config::GetStringDefault(std::string Name, std::string DefaultValue)
{
stringMapType::const_iterator configNode = this->configMap.find(Name);
if(configNode != this->configMap.end())
return configNode->second;
else
return DefaultValue;
}
bool Config::GetBoolDefault(std::string Name, bool DefaultValue)
{
std::string baseValue = this->GetStringDefault(Name, "");
if (baseValue == "")
return DefaultValue;
else
return boost::lexical_cast<bool>(baseValue);
}
int Config::GetIntDefault(std::string Name, int DefaultValue)
{
std::string baseValue = this->GetStringDefault(Name, "");
if (baseValue == "")
return DefaultValue;
else
return boost::lexical_cast<int>(baseValue);
}
float Config::GetFloatDefault(std::string Name, float DefaultValue)
{
std::string baseValue = this->GetStringDefault(Name, "");
if (baseValue == "")
return DefaultValue;
else
return boost::lexical_cast<float>(baseValue);
}
Config::~Config() {
this->fileStream.close();
}