Files
pvAccess/pvAccessApp/utils/configuration.cpp
2013-11-20 21:29:33 +01:00

398 lines
9.3 KiB
C++

/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* pvAccessCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <algorithm>
#include <pv/epicsException.h>
#define epicsExportSharedSymbols
#include <pv/configuration.h>
#if defined(__GNUC__) && __GNUC__ < 3
#define OLDGCC
#define NO_STREAM_EXCEPTIONS
#endif
namespace epics {
namespace pvAccess {
using namespace epics::pvData;
using namespace std;
Properties::Properties()
{
_fileName = "";
_infile.reset(new ifstream());
_infile->exceptions (ifstream::failbit | ifstream::badbit );
_outfile.reset(new ofstream());
_outfile->exceptions (ofstream::failbit | ofstream::badbit );
}
Properties::Properties(const string &fileName)
{
_fileName = fileName;
_infile.reset(new ifstream());
_infile->exceptions (ifstream::failbit | ifstream::badbit );
_outfile.reset(new ofstream());
_outfile->exceptions (ofstream::failbit | ofstream::badbit );
}
Properties::~Properties()
{
}
void Properties::setProperty(const string &key, const string &value)
{
string oldValue;
std::map<std::string,std::string>::iterator propertiesIterator = _properties.find(key);
if(propertiesIterator != _properties.end()) //found in map
{
_properties.erase(propertiesIterator);
}
_properties[key] = value;
}
string Properties::getProperty(const string &key)
{
std::map<std::string,std::string>::iterator propertiesIterator = _properties.find(key);
if(propertiesIterator != _properties.end()) //found in map
{
return string(propertiesIterator->second);
}
else
{
string errMsg = "Property not found in the map: " + key;
THROW_BASE_EXCEPTION(errMsg.c_str());
}
}
string Properties::getProperty(const string &key, const string &defaultValue)
{
std::map<std::string,std::string>::iterator propertiesIterator = _properties.find(key);
if(propertiesIterator != _properties.end()) //found in map
{
return string(propertiesIterator->second);
}
return defaultValue;
}
bool Properties::hasProperty(const string &key)
{
return (_properties.find(key) != _properties.end());
}
void Properties::load()
{
_properties.clear();
#ifdef NO_STREAM_EXCEPTIONS
_infile->open(_fileName.c_str(),ifstream::in);
if (_infile->fail())
#else
try
{
_infile->open(_fileName.c_str(),ifstream::in);
}
catch (ifstream::failure& e)
#endif
{
string errMsg = "Error opening file: " + string(_fileName.c_str());
THROW_BASE_EXCEPTION(errMsg.c_str());
}
string line;
string property;
string key;
#ifndef NO_STREAM_EXCEPTIONS
try
{
#endif
while(!_infile->eof())
{
line.erase();
std::getline(*_infile,line);
#ifdef NO_STREAM_EXCEPTIONS
if (_infile->fail())
{
_infile->close();
if(_infile->eof())
{
return; //end of file
}
string errMsg = "Error reading file: " + _fileName;
THROW_BASE_EXCEPTION(errMsg.c_str());
}
#endif
//remove trailing spaces
truncate(line);
//empty line
if(line.length() == 0)
{
continue;
}
// comment
if(line[0] == '#')
{
continue;
}
//line is in format: propertyName=propertyValue
size_t pos = line.find_first_of('=',0);
if(pos == string::npos) //bad value (= not found)
{
string errMsg = "Bad property line found: " + line;
THROW_BASE_EXCEPTION(errMsg.c_str());
}
key = line.substr(0,pos);
truncate(key);
property = line.substr(pos + 1,line.length());
truncate(property);
_properties[key] = property;
}
#ifndef NO_STREAM_EXCEPTIONS
}
catch (ifstream::failure& e)
{
_infile->close();
if(_infile->eof())
{
return; //end of file
}
string errMsg = "Error reading file: " + _fileName;
THROW_BASE_EXCEPTION(errMsg.c_str());
}
#endif
_infile->close();
}
void Properties::load(const string &fileName)
{
_fileName = fileName;
load();
}
void Properties::store()
{
#ifdef NO_STREAM_EXCEPTIONS
_outfile->open(_fileName.c_str(),ifstream::trunc);
if (_outfile->fail())
#else
try
{
_outfile->open(_fileName.c_str(),ifstream::trunc);
}
catch (ofstream::failure& e)
#endif
{
string errMsg = "Error opening file: " + string(_fileName.c_str());
THROW_BASE_EXCEPTION(errMsg.c_str());
}
for (std::map<std::string,std::string>::iterator propertiesIterator = _properties.begin();
propertiesIterator != _properties.end();
propertiesIterator++ )
{
#ifndef NO_STREAM_EXCEPTIONS
try
{
#endif
string line = string(propertiesIterator->first) + string("=") + string(propertiesIterator->second) + string("\n");
_outfile->write(line.c_str(),line.length());
#ifdef NO_STREAM_EXCEPTIONS
if(_outfile->fail())
#else
}
catch (ofstream::failure& e)
#endif
{
_outfile->close();
string errMsg = "Error writing to file: " + string(_fileName.c_str());
THROW_BASE_EXCEPTION(errMsg.c_str());
}
}
_outfile->close();
}
void Properties::store(const string &fileName)
{
_fileName = fileName;
store();
}
void Properties::list()
{
for (std::map<std::string,std::string>::iterator propertiesIterator = _properties.begin() ;
propertiesIterator != _properties.end();
propertiesIterator++ )
{
cout << "Key:" << propertiesIterator->first << ",Value: " << propertiesIterator->second << endl;
}
}
SystemConfigurationImpl::SystemConfigurationImpl() :
_properties(new Properties())
{
_envParam.name = new char[256];
_envParam.pdflt = NULL;
// no exception, default value is taken
//_ibuffer.exceptions ( ifstream::failbit | ifstream::badbit );
//_obuffer.exceptions ( ifstream::failbit | ifstream::badbit );
}
SystemConfigurationImpl::~SystemConfigurationImpl()
{
if(_envParam.name) delete[] _envParam.name;
}
bool SystemConfigurationImpl::getPropertyAsBoolean(const string &name, const bool defaultValue)
{
/*
bool retval;
_ibuffer.clear();
_obuffer.clear();
_obuffer.str("");
_obuffer << defaultValue;
_ibuffer.str(getPropertyAsString(name,_obuffer.str()));
_ibuffer >> retval;
if (_ibuffer.fail() || _ibuffer.bad())
return defaultValue;
else
return retval;
*/
string value = getPropertyAsString(name, defaultValue ? "1" : "0");
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
bool isTrue = (value == "1") || (value == "true") || (value == "yes");
bool isFalse = (value == "0") || (value == "false") || (value == "no");
// invalid value
if (!(isTrue || isFalse))
return defaultValue;
else
return isTrue == true;
}
int32 SystemConfigurationImpl::getPropertyAsInteger(const string &name, const int32 defaultValue)
{
int32 retval;
_ibuffer.clear();
_obuffer.clear();
_obuffer.str("");
_obuffer << defaultValue;
_ibuffer.str(getPropertyAsString(name, _obuffer.str()));
_ibuffer >> retval;
if (_ibuffer.fail() || _ibuffer.bad())
return defaultValue;
else
return retval;
}
float SystemConfigurationImpl::getPropertyAsFloat(const string &name, const float defaultValue)
{
float retval;
_ibuffer.clear();
_obuffer.clear();
_obuffer.str("");
_obuffer << defaultValue;
_ibuffer.str(getPropertyAsString(name, _obuffer.str()));
_ibuffer >> retval;
if (_ibuffer.fail() || _ibuffer.bad())
return defaultValue;
else
return retval;
}
float SystemConfigurationImpl::getPropertyAsDouble(const string &name, const double defaultValue)
{
float retval;
_ibuffer.clear();
_obuffer.clear();
_obuffer.str("");
_obuffer << defaultValue;
_ibuffer.str(getPropertyAsString(name, _obuffer.str()));
_ibuffer >> retval;
if (_ibuffer.fail() || _ibuffer.bad())
return defaultValue;
else
return retval;
}
string SystemConfigurationImpl::getPropertyAsString(const string &name, const string &defaultValue)
{
strncpy(_envParam.name,name.c_str(),name.length() + 1);
const char* val = envGetConfigParamPtr(&_envParam);
if(val != NULL)
{
return _properties->getProperty(name, string(val));
}
return _properties->getProperty(name, defaultValue);
}
bool SystemConfigurationImpl::hasProperty(const string &key)
{
strncpy(_envParam.name,key.c_str(),key.length() + 1);
const char* val = envGetConfigParamPtr(&_envParam);
return (val != NULL) || _properties->hasProperty(key);
}
ConfigurationProviderImpl::ConfigurationProviderImpl()
{
}
ConfigurationProviderImpl::~ConfigurationProviderImpl()
{
}
void ConfigurationProviderImpl::registerConfiguration(const string &name, Configuration::shared_pointer const & configuration)
{
Lock guard(_mutex);
std::map<std::string,Configuration::shared_pointer>::iterator configsIter = _configs.find(name);
if(configsIter != _configs.end())
{
string msg = "configuration with name " + name + " already registered";
THROW_BASE_EXCEPTION(msg.c_str());
}
_configs[name] = configuration;
}
Configuration::shared_pointer ConfigurationProviderImpl::getConfiguration(const string &name)
{
std::map<std::string,Configuration::shared_pointer>::iterator configsIter = _configs.find(name);
if(configsIter != _configs.end())
{
return configsIter->second;
}
return Configuration::shared_pointer();
}
ConfigurationProvider::shared_pointer configurationProvider;
Mutex conf_factory_mutex;
ConfigurationProvider::shared_pointer ConfigurationFactory::getProvider()
{
Lock guard(conf_factory_mutex);
if(configurationProvider.get() == NULL)
{
configurationProvider.reset(new ConfigurationProviderImpl());
// default
Configuration::shared_pointer systemConfig(new SystemConfigurationImpl());
configurationProvider->registerConfiguration("system", systemConfig);
}
return configurationProvider;
}
}}