This commit is contained in:
Matej Sekoranja
2011-01-09 20:08:34 +01:00
6 changed files with 647 additions and 2 deletions

View File

@@ -21,6 +21,7 @@ INC += introspectionRegistry.h
INC += transportRegistry.h
INC += namedLockPattern.h
INC += referenceCountingLock.h
INC += configuration.h
LIBSRCS += hexDump.cpp
LIBSRCS += wildcharMatcher.cpp
LIBSRCS += inetAddressUtil.cpp
@@ -29,6 +30,7 @@ LIBSRCS += introspectionRegistry.cpp
LIBSRCS += transportRegistry.cpp
LIBSRCS += namedLockPattern.cpp
LIBSRCS += referenceCountingLock.cpp
LIBSRCS += configuration.cpp
SRC_DIRS += $(PVACCESS)/client

View File

@@ -435,7 +435,7 @@ ChannelSearchManager::ChannelSearchManager(ClientContextImpl* context):
// create timers
_timers = new SearchTimer*[numberOfTimers];
for(int i = 0; i < numberOfTimers; i++)
for(int32 i = 0; i < numberOfTimers; i++)
{
_timers[i] = new SearchTimer(this, i, i > _beaconAnomalyTimerIndex, i != (numberOfTimers-1));
}
@@ -446,7 +446,7 @@ ChannelSearchManager::ChannelSearchManager(ClientContextImpl* context):
ChannelSearchManager::~ChannelSearchManager()
{
for(int i = 0; i < _numberOfTimers; i++)
for(int32 i = 0; i < _numberOfTimers; i++)
{
if(_timers[i]) delete _timers[i];
}

View File

@@ -0,0 +1,348 @@
/*
* configuration.cpp
*/
#include "configuration.h"
namespace epics { namespace pvAccess {
Properties::Properties()
{
_fileName = "";
_infile = new ifstream();
_infile->exceptions (ifstream::failbit | ifstream::badbit );
_outfile = new ofstream();
_outfile->exceptions (ofstream::failbit | ofstream::badbit );
}
Properties::Properties(const string fileName)
{
_fileName = fileName;
_infile = new ifstream();
_infile->exceptions (ifstream::failbit | ifstream::badbit );
_outfile = new ofstream();
_outfile->exceptions (ofstream::failbit | ofstream::badbit );
}
Properties::~Properties()
{
delete _infile;
delete _outfile;
//clear map
for(_propertiesIterator = _properties.begin() ;
_propertiesIterator != _properties.end();
_propertiesIterator++ )
{
delete [] _propertiesIterator->first;
delete [] _propertiesIterator->second;
}
_properties.clear();
}
void Properties::setProperty(const string key,const string value)
{
string oldValue;
_propertiesIterator = _properties.find(key.c_str());
if(_propertiesIterator != _properties.end()) //found in map
{
delete[] _propertiesIterator->first;
delete[] _propertiesIterator->second;
_properties.erase(_propertiesIterator);
}
char* chKey = new char[key.length() + 1];
strncpy(chKey,key.c_str(),key.length()+ 1);
char* chValue = new char[value.length() + 1];
strncpy(chValue,value.c_str(),value.length() + 1);
_properties[chKey] = chValue;
}
string Properties::getProperty(const string key)
{
_propertiesIterator = _properties.find(key.c_str());
if(_propertiesIterator != _properties.end()) //found in map
{
return string(_propertiesIterator->second);
}
else
{
string errMsg = "Property not found in the map: " + key;
throw BaseException(errMsg.c_str(), __FILE__, __LINE__);
}
}
string Properties::getProperty(const string key, const string defaultValue)
{
_propertiesIterator = _properties.find(key.c_str());
if(_propertiesIterator != _properties.end()) //found in map
{
return string(_propertiesIterator->second);
}
char* chKey = new char[key.length() + 1];
strncpy(chKey,key.c_str(),key.length()+ 1);
char* chValue = new char[defaultValue.length() + 1];
strncpy(chValue,defaultValue.c_str(),defaultValue.length() + 1);
_properties[chKey] = chValue;
return defaultValue;
}
void Properties::load()
{
for (_propertiesIterator = _properties.begin() ;
_propertiesIterator != _properties.end();
_propertiesIterator++ )
{
delete [] _propertiesIterator->first;
delete [] _propertiesIterator->second;
}
_properties.clear();
try
{
_infile->open(_fileName.c_str(),ifstream::in);
}
catch (ifstream::failure& e) {
string errMsg = "Error opening file: " + string(_fileName.c_str());
throw BaseException(errMsg.c_str(), __FILE__, __LINE__);
}
string line;
string property;
string key;
try
{
while(!_infile->eof())
{
line.clear();
std::getline(*_infile,line);
//remove trailing spaces
truncate(line);
//empty line
if(line.length() == 0)
{
continue;
}
// comment
if(line.at(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 BaseException(errMsg.c_str(), __FILE__, __LINE__);
}
key = line.substr(0,pos);
truncate(key);
property = line.substr(pos + 1,line.length());
truncate(property);
char* chKey = new char[key.length() + 1];
strncpy(chKey,key.c_str(),key.length()+ 1);
char* chProperty = new char[property.length() +1];
strncpy(chProperty,property.c_str(),property.length() + 1);
_properties[chKey] = chProperty;
}
}
catch (ifstream::failure& e)
{
_infile->close();
if(_infile->eof())
{
return; //end of file
}
string errMsg = "Error reading file: " + _fileName;
throw BaseException(errMsg.c_str(), __FILE__, __LINE__);
}
_infile->close();
}
void Properties::load(const string fileName)
{
_fileName = fileName;
load();
}
void Properties::store()
{
try
{
_outfile->open(_fileName.c_str(),ifstream::trunc);
}
catch (ofstream::failure& e) {
string errMsg = "Error opening file: " + string(_fileName.c_str());
throw BaseException(errMsg.c_str(), __FILE__, __LINE__);
}
for (_propertiesIterator = _properties.begin() ;
_propertiesIterator != _properties.end();
_propertiesIterator++ )
{
try
{
string line = string(_propertiesIterator->first) + string("=") + string(_propertiesIterator->second) + string("\n");
_outfile->write(line.c_str(),line.length());
}
catch (ofstream::failure& e) {
_outfile->close();
string errMsg = "Error writing to file: " + string(_fileName.c_str());
throw BaseException(errMsg.c_str(), __FILE__, __LINE__);
}
}
_outfile->close();
}
void Properties::store(const string fileName)
{
_fileName = fileName;
store();
}
void Properties::list()
{
for (_propertiesIterator = _properties.begin() ;
_propertiesIterator != _properties.end();
_propertiesIterator++ )
{
cout << "Key:" << _propertiesIterator->first << ",Value: " << _propertiesIterator->second << endl;
}
}
SystemConfigurationImpl::SystemConfigurationImpl()
{
_envParam.name = new char[MAX_NAME_LENGHT];
_envParam.pdflt = NULL;
_ibuffer.exceptions ( ifstream::failbit | ifstream::badbit );
_obuffer.exceptions ( ifstream::failbit | ifstream::badbit );
_properties = new Properties();
}
SystemConfigurationImpl::~SystemConfigurationImpl()
{
if(_envParam.name) delete[] _envParam.name;
if(_properties) delete _properties;
}
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;
return retval;
}
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;
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;
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;
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);
}
ConfigurationProviderImpl::ConfigurationProviderImpl()
{
}
ConfigurationProviderImpl::~ConfigurationProviderImpl()
{
for(_configsIter = _configs.begin() ;
_configsIter != _configs.end();
_configsIter++ )
{
delete [] _configsIter->first;
}
_configs.clear();
}
void ConfigurationProviderImpl::registerConfiguration(const string name, const Configuration* configuration)
{
Lock guard(&_mutex);
_configsIter = _configs.find(name.c_str());
if(_configsIter != _configs.end())
{
string msg = "configuration with name " + name + " already registered";
throw BaseException(msg.c_str(), __FILE__, __LINE__);
}
char* chKey = new char[name.length() + 1];
strncpy(chKey,name.c_str(),name.length()+ 1);
_configs[chKey] = configuration;
}
Configuration* ConfigurationProviderImpl::getConfiguration(const string name)
{
_configsIter = _configs.find(name.c_str());
if(_configsIter != _configs.end())
{
return const_cast<Configuration*>(_configsIter->second);
}
return NULL;
}
ConfigurationProviderImpl* ConfigurationFactory::_configurationProvider = NULL;
Mutex ConfigurationFactory::_conf_factory_mutex = Mutex();
ConfigurationProviderImpl* ConfigurationFactory::getProvider()
{
Lock guard(&_conf_factory_mutex);
if(_configurationProvider == NULL)
{
_configurationProvider = new ConfigurationProviderImpl();
}
return _configurationProvider;
}
}}

View File

@@ -0,0 +1,216 @@
/*
* configuration.h
*/
#ifndef CONFIGURATION_H
#define CONFIGURATION_H
#include "pvType.h"
#include "noDefaultMethods.h"
#include "lock.h"
#include "epicsException.h"
#include "envDefs.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <string.h>
#include <map>
using namespace epics::pvData;
using namespace std;
namespace epics { namespace pvAccess {
#define MAX_NAME_LENGHT 300
struct conf_cmp_str
{
bool operator()(char const *a, char const *b)
{
return strcmp(a, b) < 0;
}
};
/**
* Properties
*/
class Properties
{
public:
Properties();
Properties(const string fileName);
virtual ~Properties();
void setProperty(const string key,const string value);
string getProperty(const string key);
string getProperty(const string key, const string defaultValue);
void store();
void store(const string fileName);
void load();
void load(const string fileName);
void list();
private:
map<const char*,const char* , conf_cmp_str> _properties;
map<const char*,const char* , conf_cmp_str>::iterator _propertiesIterator;
ifstream* _infile;
ofstream* _outfile;
string _fileName;
inline void truncate(string& str)
{
while(str.length() != 0 && (str.at(0) == ' ' || str.at(0) == '\t'))
{
str.erase(0,1);
}
while(str.length() != 0 && (str.at(str.length()-1) == ' ' || str.at(str.length()-1) == '\t'))
{
str.erase(str.length()-1,1);
}
}
};
/**
* Configuration
*/
class Configuration : private NoDefaultMethods
{
public:
/*
* Get the environment variable specified by name or return default value
* if it does not exist.
*
* @param name name of the environment variable to return.
* @param defualtValue default value to return if environment variable does not exists.
*
* @return environment variable value as bool or default value if it does not exist.
*/
virtual bool getPropertyAsBoolean(const string name, const bool defaultValue) = 0;
/*
* Get the environment variable specified by name or return default value
* if it does not exist.
*
* @param name name of the environment variable to return.
* @param defualtValue default value to return if environment variable does not exists.
*
* @return environment variable value as int32 or default value if it does not exist.
*/
virtual int32 getPropertyAsInteger(const string name, const int32 defaultValue) = 0;
/*
* Get the environment variable specified by name or return default value
* if it does not exist.
*
* @param name name of the environment variable to return.
* @param defualtValue default value to return if environment variable does not exists.
*
* @return environment variable value as float or default value if it does not exist.
*/
virtual float getPropertyAsFloat(const string name, const float defaultValue) = 0;
/*
* Get the environment variable specified by name or return default value
* if it does not exist.
*
* @param name name of the environment variable to return.
* @param defualtValue default value to return if environment variable does not exists.
*
* @return environment variable value as double or default value if it does not exist.
*/
virtual float getPropertyAsDouble(const string name, const double defaultValue) = 0;
/*
* Get the environment variable specified by name or return default value
* if it does not exist.
*
* @param name name of the environment variable to return.
* @param defualtValue default value to return if environment variable does not exists.
*
* @return environment variable value as string or default value if it does not exist.
*/
virtual string getPropertyAsString(const string name, const string defaultValue) = 0;
};
class SystemConfigurationImpl: public Configuration
{
public:
SystemConfigurationImpl();
virtual ~SystemConfigurationImpl();
bool getPropertyAsBoolean(const string name, const bool defaultValue);
int32 getPropertyAsInteger(const string name, const int32 defaultValue);
float getPropertyAsFloat(const string name, const float defaultValue);
float getPropertyAsDouble(const string name, const double defaultValue);
string getPropertyAsString(const string name, string defaultValue);
Properties* _properties;
private:
ENV_PARAM _envParam;
istringstream _ibuffer;
ostringstream _obuffer;
};
/**
* Configuration provider.
*/
class ConfigurationProvider : private NoDefaultMethods
{
public:
/*
* Return configuration specified by name.
*
* @param name name of the configuration to return.
*
* @return configuration specified by name or NULL if it does not exists.
*/
virtual Configuration* getConfiguration(const string name) = 0;
/*
* Register configuration.
*
* @param name name of the configuration to register.
* @param configuration configuration to register.
*/
virtual void registerConfiguration(const string name, const Configuration* configuration) = 0;
};
class ConfigurationProviderImpl: public ConfigurationProvider
{
public:
ConfigurationProviderImpl();
virtual ~ConfigurationProviderImpl();
Configuration* getConfiguration(const string name);
void registerConfiguration(const string name, const Configuration* configuration);
private:
Mutex _mutex;
map<const char*,const Configuration*, conf_cmp_str> _configs;
map<const char*,const Configuration*, conf_cmp_str>::iterator _configsIter;
};
/**
* Configuration factory.
*/
class ConfigurationFactory : private NoDefaultMethods
{
public:
/*
* Lazily creates configuration provider.
*
* @param name name of the configuration to register.
* @param configuration configuration to register.
*
* @return configuration provider
*/
static ConfigurationProviderImpl* getProvider();
private:
ConfigurationFactory() {};
static ConfigurationProviderImpl* _configurationProvider;
static Mutex _conf_factory_mutex;
};
}}
#endif /* CONFIGURATION_H */

View File

@@ -38,6 +38,10 @@ PROD_HOST += namedLockPatternTest
namedLockPatternTest_SRCS += namedLockPatternTest.cpp
namedLockPatternTest_LIBS += pvAccess Com pvData
PROD_HOST += configurationTest
configurationTest_SRCS += configurationTest.cpp
configurationTest_LIBS += pvAccess Com pvData
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE

View File

@@ -0,0 +1,75 @@
/*
* configurationTest.cpp
*
*/
#include "configuration.h"
#include "showConstructDestruct.h"
#include <epicsAssert.h>
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace epics::pvAccess;
using namespace std;
int main(int argc, char *argv[])
{
SystemConfigurationImpl* configuration = new SystemConfigurationImpl();
bool boolProperty = configuration->getPropertyAsBoolean("boolProperty", true);
assert(boolProperty == true);
int32 intProperty = configuration->getPropertyAsInteger("intProperty", 1);
assert(intProperty == 1);
float floatProperty = configuration->getPropertyAsFloat("floatProperty", 3);
assert(floatProperty == 3);
double doubleProperty = configuration->getPropertyAsDouble("doubleProperty", -3);
assert(doubleProperty == -3);
string stringProperty = configuration->getPropertyAsString("stringProperty", "string");
assert(stringProperty == string("string"));
ConfigurationProviderImpl* configProvider = ConfigurationFactory::getProvider();
configProvider->registerConfiguration("conf1",static_cast<Configuration*>(configuration));
SystemConfigurationImpl* configurationOut = static_cast<SystemConfigurationImpl*>(configProvider->getConfiguration("conf1"));
assert(configurationOut == configuration);
intProperty = configuration->getPropertyAsInteger("intProperty", 2);
assert(intProperty == 1);
floatProperty = configuration->getPropertyAsFloat("floatProperty", 4);
assert(floatProperty == 3);
doubleProperty = configuration->getPropertyAsDouble("doubleProperty", -4);
assert(doubleProperty == -3);
stringProperty = configuration->getPropertyAsString("stringProperty", "string1");
assert(stringProperty == string("string"));
setenv("boolProperty1", "1", 1);
boolProperty = configuration->getPropertyAsInteger("boolProperty1", 0);
assert(boolProperty == true);
setenv("intProperty1", "45", 1);
intProperty = configuration->getPropertyAsInteger("intProperty1", 2);
assert(intProperty == 45);
setenv("floatProperty1", "22", 1);
floatProperty = configuration->getPropertyAsFloat("floatProperty1", 3);
assert(floatProperty == 22);
setenv("dobuleProperty1", "42", 1);
doubleProperty = configuration->getPropertyAsDouble("dobuleProperty1", -3);
assert(doubleProperty == 42);
if(configuration) delete configuration;
getShowConstructDestruct()->constuctDestructTotals(stdout);
return 0;
}