/** * 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 #include #define epicsExportSharedSymbols #include #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::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::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::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::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::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::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::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; } }}