general indent beautification
This commit is contained in:
+35
-34
@@ -37,7 +37,7 @@ const std::string &Properties::getProperty(const string &key) const
|
||||
return propertiesIterator->second;
|
||||
} else {
|
||||
THROW_BASE_EXCEPTION(string("Property not found in the map: ") + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string &Properties::getProperty(const string &key, const string &defaultValue) const
|
||||
@@ -125,7 +125,7 @@ void Properties::store(const std::string& fname) const
|
||||
void Properties::store(std::ostream& strm) const
|
||||
{
|
||||
for(_properties_t::const_iterator it=_properties.begin(), end=_properties.end();
|
||||
it!=end && strm.good(); ++it)
|
||||
it!=end && strm.good(); ++it)
|
||||
{
|
||||
strm << it->first << " = " << it->second << "\n";
|
||||
}
|
||||
@@ -133,12 +133,12 @@ void Properties::store(std::ostream& strm) const
|
||||
|
||||
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;
|
||||
}
|
||||
for (std::map<std::string,std::string>::iterator propertiesIterator = _properties.begin() ;
|
||||
propertiesIterator != _properties.end();
|
||||
propertiesIterator++ )
|
||||
{
|
||||
cout << "Key:" << propertiesIterator->first << ",Value: " << propertiesIterator->second << endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool Configuration::getPropertyAsBoolean(const std::string &name, const bool defaultValue) const
|
||||
@@ -160,18 +160,18 @@ bool Configuration::getPropertyAsBoolean(const std::string &name, const bool def
|
||||
|
||||
epics::pvData::int32 Configuration::getPropertyAsInteger(const std::string &name, const epics::pvData::int32 defaultValue) const
|
||||
{
|
||||
try{
|
||||
try {
|
||||
return castUnsafe<epics::pvData::int32>(getPropertyAsString(name, ""));
|
||||
}catch(std::runtime_error&){
|
||||
} catch(std::runtime_error&) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
float Configuration::getPropertyAsFloat(const std::string &name, const float defaultValue) const
|
||||
{
|
||||
try{
|
||||
try {
|
||||
return castUnsafe<float>(getPropertyAsString(name, ""));
|
||||
}catch(std::runtime_error&){
|
||||
} catch(std::runtime_error&) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -180,7 +180,7 @@ double Configuration::getPropertyAsDouble(const std::string &name, const double
|
||||
{
|
||||
try {
|
||||
return castUnsafe<double>(getPropertyAsString(name, ""));
|
||||
}catch(std::runtime_error&){
|
||||
} catch(std::runtime_error&) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -238,7 +238,7 @@ bool ConfigurationEnviron::tryGetPropertyAsString(const std::string& name, std::
|
||||
bool ConfigurationStack::tryGetPropertyAsString(const std::string& name, std::string* val) const
|
||||
{
|
||||
for(confs_t::const_reverse_iterator it = confs.rbegin(), end = confs.rend();
|
||||
it!=end; ++it)
|
||||
it!=end; ++it)
|
||||
{
|
||||
Configuration& conf = **it;
|
||||
if(conf.tryGetPropertyAsString(name, val))
|
||||
@@ -295,24 +295,24 @@ Configuration::shared_pointer ConfigurationBuilder::build()
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
Lock guard(_mutex);
|
||||
std::map<std::string,Configuration::shared_pointer>::iterator configsIter = _configs.find(name);
|
||||
if(configsIter != _configs.end())
|
||||
{
|
||||
return configsIter->second;
|
||||
}
|
||||
if(configsIter != _configs.end())
|
||||
{
|
||||
return configsIter->second;
|
||||
}
|
||||
Configuration::shared_pointer env(new ConfigurationEnviron); // default to environment only
|
||||
_configs[name] = env; // ensure that a later attempt to define this config will fail
|
||||
return env;
|
||||
@@ -323,15 +323,16 @@ Mutex conf_factory_mutex;
|
||||
|
||||
ConfigurationProvider::shared_pointer ConfigurationFactory::getProvider()
|
||||
{
|
||||
Lock guard(conf_factory_mutex);
|
||||
if(configurationProvider.get() == NULL)
|
||||
{
|
||||
configurationProvider.reset(new ConfigurationProviderImpl());
|
||||
Lock guard(conf_factory_mutex);
|
||||
if(configurationProvider.get() == NULL)
|
||||
{
|
||||
configurationProvider.reset(new ConfigurationProviderImpl());
|
||||
Configuration::shared_pointer systemConfig(new ConfigurationEnviron);
|
||||
configurationProvider->registerConfiguration("system", systemConfig);
|
||||
}
|
||||
return configurationProvider;
|
||||
configurationProvider->registerConfiguration("system", systemConfig);
|
||||
}
|
||||
return configurationProvider;
|
||||
}
|
||||
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@ namespace pvAccess {
|
||||
|
||||
/// Byte to hexchar mapping.
|
||||
static const char lookup[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
/// Get hex representation of byte.
|
||||
string toHex(int8 b) {
|
||||
@@ -57,7 +58,7 @@ void hexDump(std::string const & name, const int8 *bs, int start, int len) {
|
||||
}
|
||||
|
||||
void hexDump(std::string const & prologue, string const & name, const int8 *bs,
|
||||
int start, int len) {
|
||||
int start, int len) {
|
||||
|
||||
stringstream header;
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ void addDefaultBroadcastAddress(InetAddrVector* v, unsigned short p) {
|
||||
v->push_back(pNewNode);
|
||||
}
|
||||
|
||||
InetAddrVector* getBroadcastAddresses(SOCKET sock,
|
||||
unsigned short defaultPort) {
|
||||
InetAddrVector* getBroadcastAddresses(SOCKET sock,
|
||||
unsigned short defaultPort) {
|
||||
ELLLIST as;
|
||||
ellInit(&as);
|
||||
osiSockAddr serverAddr;
|
||||
@@ -147,7 +147,7 @@ int32 parseInetAddress(const string & addr) {
|
||||
}
|
||||
|
||||
InetAddrVector* getSocketAddressList(const std::string & list, int defaultPort,
|
||||
const InetAddrVector* appendList) {
|
||||
const InetAddrVector* appendList) {
|
||||
InetAddrVector* iav = new InetAddrVector();
|
||||
|
||||
// skip leading spaces
|
||||
@@ -174,13 +174,13 @@ InetAddrVector* getSocketAddressList(const std::string & list, int defaultPort,
|
||||
|
||||
if(appendList!=NULL) {
|
||||
for(size_t i = 0; i<appendList->size(); i++)
|
||||
iav->push_back((*appendList)[i]);
|
||||
iav->push_back((*appendList)[i]);
|
||||
}
|
||||
return iav;
|
||||
}
|
||||
|
||||
string inetAddressToString(const osiSockAddr &addr,
|
||||
bool displayPort, bool displayHex) {
|
||||
bool displayPort, bool displayHex) {
|
||||
stringstream saddr;
|
||||
|
||||
int ipa = ntohl(addr.ia.sin_addr.s_addr);
|
||||
@@ -191,7 +191,7 @@ string inetAddressToString(const osiSockAddr &addr,
|
||||
saddr<<((int)ipa&0xFF);
|
||||
if(displayPort) saddr<<":"<<ntohs(addr.ia.sin_port);
|
||||
if(displayHex) saddr<<" ("<<hex<<ntohl(addr.ia.sin_addr.s_addr)
|
||||
<<")";
|
||||
<<")";
|
||||
|
||||
return saddr.str();
|
||||
}
|
||||
@@ -231,7 +231,7 @@ static size_t ifreqSize ( struct ifreq *pifreq )
|
||||
|
||||
size = ifreq_size ( pifreq );
|
||||
if ( size < sizeof ( *pifreq ) ) {
|
||||
size = sizeof ( *pifreq );
|
||||
size = sizeof ( *pifreq );
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@@ -305,8 +305,8 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
* If its not an internet interface then dont use it
|
||||
*/
|
||||
if ( pIfreqList->ifr_addr.sa_family != AF_INET ) {
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): interface \"%s\" was not AF_INET\n", pIfreqList->ifr_name) );*/
|
||||
continue;
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): interface \"%s\" was not AF_INET\n", pIfreqList->ifr_name) );*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -319,13 +319,13 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
continue;
|
||||
}
|
||||
if ( pMatchAddr->ia.sin_addr.s_addr != htonl (INADDR_ANY) ) {
|
||||
struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pIfreqList->ifr_addr;
|
||||
if ( pInetAddr->sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) {
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): net intf \"%s\" didnt match\n", pIfreqList->ifr_name) );*/
|
||||
continue;
|
||||
}
|
||||
else
|
||||
match = 1;
|
||||
struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pIfreqList->ifr_addr;
|
||||
if ( pInetAddr->sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) {
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): net intf \"%s\" didnt match\n", pIfreqList->ifr_name) );*/
|
||||
continue;
|
||||
}
|
||||
else
|
||||
match = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,8 +339,8 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
* dont bother with interfaces that have been disabled
|
||||
*/
|
||||
if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) {
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): net intf \"%s\" was down\n", pIfreqList->ifr_name) );*/
|
||||
continue;
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): net intf \"%s\" was down\n", pIfreqList->ifr_name) );*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -348,8 +348,8 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
*/
|
||||
if (!match) {
|
||||
if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) {
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): ignoring loopback interface: \"%s\"\n", pIfreqList->ifr_name) );*/
|
||||
continue;
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): ignoring loopback interface: \"%s\"\n", pIfreqList->ifr_name) );*/
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,16 +394,16 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
/*ifDepenDebugPrintf ( ( "discoverInterfaces(): net intf \"%s\": not point to point or bcast?\n", pIfreqList->ifr_name ) );*/
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): net intf \"%s\" found\n", pIfreqList->ifr_name) );*/
|
||||
/*ifDepenDebugPrintf ( ("discoverInterfaces(): net intf \"%s\" found\n", pIfreqList->ifr_name) );*/
|
||||
|
||||
list.push_back(node);
|
||||
}
|
||||
list.push_back(node);
|
||||
}
|
||||
|
||||
free ( pIfreqList );
|
||||
return 0;
|
||||
}
|
||||
free ( pIfreqList );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
@@ -423,7 +423,7 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
int match;
|
||||
|
||||
/* only valid for winsock 2 and above
|
||||
TODO resolve dllimport compilation problem and uncomment this check
|
||||
TODO resolve dllimport compilation problem and uncomment this check
|
||||
if (wsaMajorVersion() < 2 ) {
|
||||
fprintf(stderr, "Need to set EPICS_CA_AUTO_ADDR_LIST=NO for winsock 1\n");
|
||||
return -1;
|
||||
@@ -432,14 +432,14 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
|
||||
nelem = 100;
|
||||
pIfinfoList = (INTERFACE_INFO *) calloc(nelem, sizeof(INTERFACE_INFO));
|
||||
if(!pIfinfoList){
|
||||
if(!pIfinfoList) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = WSAIoctl (socket, SIO_GET_INTERFACE_LIST,
|
||||
NULL, 0,
|
||||
(LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO),
|
||||
&cbBytesReturned, NULL, NULL);
|
||||
NULL, 0,
|
||||
(LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO),
|
||||
&cbBytesReturned, NULL, NULL);
|
||||
|
||||
if (status != 0 || cbBytesReturned == 0) {
|
||||
fprintf(stderr, "WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError());
|
||||
@@ -448,7 +448,7 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
}
|
||||
|
||||
numifs = cbBytesReturned/sizeof(INTERFACE_INFO);
|
||||
for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){
|
||||
for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++) {
|
||||
|
||||
/*
|
||||
* dont bother with interfaces that have been disabled
|
||||
@@ -504,7 +504,7 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
|
||||
ifaceNode node;
|
||||
node.ifaceAddr.ia = pIfinfo->iiAddress.AddressIn;
|
||||
|
||||
|
||||
if (pIfinfo->iiFlags & IFF_BROADCAST) {
|
||||
const unsigned mask = pIfinfo->iiNetmask.AddressIn.sin_addr.s_addr;
|
||||
const unsigned bcast = pIfinfo->iiBroadcastAddress.AddressIn.sin_addr.s_addr;
|
||||
@@ -513,11 +513,11 @@ int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *
|
||||
node.ifaceBCast.ia.sin_family = AF_INET;
|
||||
node.ifaceBCast.ia.sin_addr.s_addr = result;
|
||||
node.ifaceBCast.ia.sin_port = htons ( 0 );
|
||||
}
|
||||
else {
|
||||
node.ifaceBCast.ia = pIfinfo->iiBroadcastAddress.AddressIn;
|
||||
}
|
||||
|
||||
else {
|
||||
node.ifaceBCast.ia = pIfinfo->iiBroadcastAddress.AddressIn;
|
||||
}
|
||||
|
||||
|
||||
list.push_back(node);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ FieldCreatePtr IntrospectionRegistry::_fieldCreate(getFieldCreate());
|
||||
|
||||
IntrospectionRegistry::IntrospectionRegistry()
|
||||
{
|
||||
reset();
|
||||
reset();
|
||||
}
|
||||
|
||||
IntrospectionRegistry::~IntrospectionRegistry()
|
||||
@@ -31,118 +31,119 @@ IntrospectionRegistry::~IntrospectionRegistry()
|
||||
|
||||
void IntrospectionRegistry::reset()
|
||||
{
|
||||
_pointer = 1;
|
||||
_registry.clear();
|
||||
_pointer = 1;
|
||||
_registry.clear();
|
||||
}
|
||||
|
||||
FieldConstPtr IntrospectionRegistry::getIntrospectionInterface(const int16 id)
|
||||
{
|
||||
registryMap_t::iterator registryIter = _registry.find(id);
|
||||
if(registryIter == _registry.end())
|
||||
{
|
||||
return FieldConstPtr();
|
||||
}
|
||||
return registryIter->second;
|
||||
registryMap_t::iterator registryIter = _registry.find(id);
|
||||
if(registryIter == _registry.end())
|
||||
{
|
||||
return FieldConstPtr();
|
||||
}
|
||||
return registryIter->second;
|
||||
}
|
||||
|
||||
void IntrospectionRegistry::registerIntrospectionInterface(const int16 id, FieldConstPtr const & field)
|
||||
{
|
||||
_registry[id] = field;
|
||||
_registry[id] = field;
|
||||
}
|
||||
|
||||
int16 IntrospectionRegistry::registerIntrospectionInterface(FieldConstPtr const & field, bool& existing)
|
||||
{
|
||||
int16 key;
|
||||
// TODO this is slow
|
||||
if(registryContainsValue(field, key))
|
||||
{
|
||||
existing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
existing = false;
|
||||
key = _pointer++;
|
||||
_registry[key] = field;
|
||||
}
|
||||
return key;
|
||||
int16 key;
|
||||
// TODO this is slow
|
||||
if(registryContainsValue(field, key))
|
||||
{
|
||||
existing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
existing = false;
|
||||
key = _pointer++;
|
||||
_registry[key] = field;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
// TODO slow !!!!
|
||||
bool IntrospectionRegistry::registryContainsValue(FieldConstPtr const & field, int16& key)
|
||||
{
|
||||
for(registryMap_t::reverse_iterator registryRIter = _registry.rbegin(); registryRIter != _registry.rend(); registryRIter++)
|
||||
{
|
||||
if(*(field.get()) == *(registryRIter->second))
|
||||
{
|
||||
key = registryRIter->first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
for(registryMap_t::reverse_iterator registryRIter = _registry.rbegin(); registryRIter != _registry.rend(); registryRIter++)
|
||||
{
|
||||
if(*(field.get()) == *(registryRIter->second))
|
||||
{
|
||||
key = registryRIter->first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void IntrospectionRegistry::serialize(FieldConstPtr const & field, ByteBuffer* buffer, SerializableControl* control)
|
||||
{
|
||||
if (field.get() == NULL)
|
||||
{
|
||||
SerializationHelper::serializeNullField(buffer, control);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (field.get() == NULL)
|
||||
{
|
||||
SerializationHelper::serializeNullField(buffer, control);
|
||||
}
|
||||
else
|
||||
{
|
||||
// do not cache scalars, scalarArrays
|
||||
// ... and (array of) variant unions - not worth the complex condition,
|
||||
// unless bool Field.cache() would exist
|
||||
if (field->getType() != scalar &&
|
||||
field->getType() != scalarArray)
|
||||
{
|
||||
bool existing;
|
||||
const int16 key = registerIntrospectionInterface(field, existing);
|
||||
if (existing) {
|
||||
control->ensureBuffer(3);
|
||||
buffer->putByte(ONLY_ID_TYPE_CODE);
|
||||
buffer->putShort(key);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
control->ensureBuffer(3);
|
||||
buffer->putByte(FULL_WITH_ID_TYPE_CODE); // could also be a mask
|
||||
buffer->putShort(key);
|
||||
}
|
||||
}
|
||||
field->getType() != scalarArray)
|
||||
{
|
||||
bool existing;
|
||||
const int16 key = registerIntrospectionInterface(field, existing);
|
||||
if (existing) {
|
||||
control->ensureBuffer(3);
|
||||
buffer->putByte(ONLY_ID_TYPE_CODE);
|
||||
buffer->putShort(key);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
control->ensureBuffer(3);
|
||||
buffer->putByte(FULL_WITH_ID_TYPE_CODE); // could also be a mask
|
||||
buffer->putShort(key);
|
||||
}
|
||||
}
|
||||
|
||||
field->serialize(buffer, control);
|
||||
}
|
||||
field->serialize(buffer, control);
|
||||
}
|
||||
}
|
||||
|
||||
FieldConstPtr IntrospectionRegistry::deserialize(ByteBuffer* buffer, DeserializableControl* control)
|
||||
{
|
||||
control->ensureData(1);
|
||||
size_t pos = buffer->getPosition();
|
||||
const int8 typeCode = buffer->getByte();
|
||||
control->ensureData(1);
|
||||
size_t pos = buffer->getPosition();
|
||||
const int8 typeCode = buffer->getByte();
|
||||
|
||||
if (typeCode == NULL_TYPE_CODE)
|
||||
{
|
||||
if (typeCode == NULL_TYPE_CODE)
|
||||
{
|
||||
return FieldConstPtr();
|
||||
}
|
||||
else if (typeCode == ONLY_ID_TYPE_CODE)
|
||||
{
|
||||
control->ensureData(sizeof(int16)/sizeof(int8));
|
||||
return getIntrospectionInterface(buffer->getShort());
|
||||
}
|
||||
// could also be a mask
|
||||
if(typeCode == IntrospectionRegistry::FULL_WITH_ID_TYPE_CODE)
|
||||
{
|
||||
control->ensureData(sizeof(int16)/sizeof(int8));
|
||||
const short key = buffer->getShort();
|
||||
FieldConstPtr field = _fieldCreate->deserialize(buffer, control);
|
||||
registerIntrospectionInterface(key, field);
|
||||
return field;
|
||||
}
|
||||
}
|
||||
else if (typeCode == ONLY_ID_TYPE_CODE)
|
||||
{
|
||||
control->ensureData(sizeof(int16)/sizeof(int8));
|
||||
return getIntrospectionInterface(buffer->getShort());
|
||||
}
|
||||
// could also be a mask
|
||||
if(typeCode == IntrospectionRegistry::FULL_WITH_ID_TYPE_CODE)
|
||||
{
|
||||
control->ensureData(sizeof(int16)/sizeof(int8));
|
||||
const short key = buffer->getShort();
|
||||
FieldConstPtr field = _fieldCreate->deserialize(buffer, control);
|
||||
registerIntrospectionInterface(key, field);
|
||||
return field;
|
||||
}
|
||||
|
||||
// return typeCode back
|
||||
// return typeCode back
|
||||
buffer->setPosition(pos);
|
||||
return _fieldCreate->deserialize(buffer, control);
|
||||
return _fieldCreate->deserialize(buffer, control);
|
||||
}
|
||||
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+78
-78
@@ -28,90 +28,90 @@ using std::ios;
|
||||
using std::endl;
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
#define TIMETEXTLEN 32
|
||||
|
||||
static pvAccessLogLevel g_pvAccessLogLevel = logLevelInfo;
|
||||
|
||||
void pvAccessLog(pvAccessLogLevel level, const char* format, ...)
|
||||
{
|
||||
// TODO lock
|
||||
if (level >= g_pvAccessLogLevel)
|
||||
{
|
||||
char timeText[TIMETEXTLEN];
|
||||
epicsTimeStamp tsNow;
|
||||
|
||||
epicsTimeGetCurrent(&tsNow);
|
||||
epicsTimeToStrftime(timeText, TIMETEXTLEN, "%Y-%m-%dT%H:%M:%S.%03f", &tsNow);
|
||||
|
||||
printf("%s ", timeText);
|
||||
namespace pvAccess {
|
||||
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
vprintf(format, arg);
|
||||
va_end(arg);
|
||||
#define TIMETEXTLEN 32
|
||||
|
||||
printf("\n");
|
||||
fflush(stdout); // needed for WIN32
|
||||
}
|
||||
}
|
||||
static pvAccessLogLevel g_pvAccessLogLevel = logLevelInfo;
|
||||
|
||||
void pvAccessSetLogLevel(pvAccessLogLevel level)
|
||||
{
|
||||
g_pvAccessLogLevel = level;
|
||||
}
|
||||
void pvAccessLog(pvAccessLogLevel level, const char* format, ...)
|
||||
{
|
||||
// TODO lock
|
||||
if (level >= g_pvAccessLogLevel)
|
||||
{
|
||||
char timeText[TIMETEXTLEN];
|
||||
epicsTimeStamp tsNow;
|
||||
|
||||
bool pvAccessIsLoggable(pvAccessLogLevel level)
|
||||
{
|
||||
return level >= g_pvAccessLogLevel;
|
||||
}
|
||||
epicsTimeGetCurrent(&tsNow);
|
||||
epicsTimeToStrftime(timeText, TIMETEXTLEN, "%Y-%m-%dT%H:%M:%S.%03f", &tsNow);
|
||||
|
||||
class FileLogger : public NoDefaultMethods {
|
||||
public:
|
||||
FileLogger(std::string const & name) {
|
||||
logFile.open(name.data(), ios::app);
|
||||
}
|
||||
printf("%s ", timeText);
|
||||
|
||||
~FileLogger() {
|
||||
logFile.close();
|
||||
}
|
||||
|
||||
void logMessage(const char* message) {
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
char* timeStr = ctime(&rawtime);
|
||||
timeStr[strlen(timeStr)-1]='\0'; // remove newline
|
||||
|
||||
logFile<<timeStr<<"\t"<<message; // the newline is added by the caller
|
||||
}
|
||||
private:
|
||||
ofstream logFile;
|
||||
|
||||
};
|
||||
|
||||
static FileLogger* fileLogger = NULL;
|
||||
|
||||
static void errLogFileListener(void* /*pPrivate*/, const char *message) {
|
||||
fileLogger->logMessage(message);
|
||||
}
|
||||
|
||||
static void exitFileLoggerHandler(void* /*pPrivate*/) {
|
||||
errlogFlush();
|
||||
delete fileLogger;
|
||||
}
|
||||
|
||||
void createFileLogger(std::string const & fname) {
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
|
||||
if(fileLogger==NULL) {
|
||||
fileLogger = new FileLogger(fname);
|
||||
errlogInit(2048);
|
||||
errlogAddListener(errLogFileListener, NULL);
|
||||
epicsAtExit(exitFileLoggerHandler, NULL);
|
||||
}
|
||||
}
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
vprintf(format, arg);
|
||||
va_end(arg);
|
||||
|
||||
printf("\n");
|
||||
fflush(stdout); // needed for WIN32
|
||||
}
|
||||
}
|
||||
|
||||
void pvAccessSetLogLevel(pvAccessLogLevel level)
|
||||
{
|
||||
g_pvAccessLogLevel = level;
|
||||
}
|
||||
|
||||
bool pvAccessIsLoggable(pvAccessLogLevel level)
|
||||
{
|
||||
return level >= g_pvAccessLogLevel;
|
||||
}
|
||||
|
||||
class FileLogger : public NoDefaultMethods {
|
||||
public:
|
||||
FileLogger(std::string const & name) {
|
||||
logFile.open(name.data(), ios::app);
|
||||
}
|
||||
|
||||
~FileLogger() {
|
||||
logFile.close();
|
||||
}
|
||||
|
||||
void logMessage(const char* message) {
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
char* timeStr = ctime(&rawtime);
|
||||
timeStr[strlen(timeStr)-1]='\0'; // remove newline
|
||||
|
||||
logFile<<timeStr<<"\t"<<message; // the newline is added by the caller
|
||||
}
|
||||
private:
|
||||
ofstream logFile;
|
||||
|
||||
};
|
||||
|
||||
static FileLogger* fileLogger = NULL;
|
||||
|
||||
static void errLogFileListener(void* /*pPrivate*/, const char *message) {
|
||||
fileLogger->logMessage(message);
|
||||
}
|
||||
|
||||
static void exitFileLoggerHandler(void* /*pPrivate*/) {
|
||||
errlogFlush();
|
||||
delete fileLogger;
|
||||
}
|
||||
|
||||
void createFileLogger(std::string const & fname) {
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
|
||||
if(fileLogger==NULL) {
|
||||
fileLogger = new FileLogger(fname);
|
||||
errlogInit(2048);
|
||||
errlogAddListener(errLogFileListener, NULL);
|
||||
epicsAtExit(exitFileLoggerHandler, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+119
-108
@@ -43,27 +43,35 @@ public:
|
||||
Properties(const std::string &fileName) EPICS_DEPRECATED;
|
||||
|
||||
inline void setProperty(const std::string &key,const std::string &value)
|
||||
{ _properties[key] = value; }
|
||||
{
|
||||
_properties[key] = value;
|
||||
}
|
||||
const std::string& getProperty(const std::string &key) const;
|
||||
const std::string& getProperty(const std::string &key, const std::string &defaultValue) const;
|
||||
inline bool hasProperty(const std::string &key) const
|
||||
{ return _properties.find(key) != _properties.end(); }
|
||||
{
|
||||
return _properties.find(key) != _properties.end();
|
||||
}
|
||||
|
||||
void store() const;
|
||||
void store(const std::string &fileName) const;
|
||||
void store(std::ostream& strm) const;
|
||||
void load();
|
||||
void load(const std::string &fileName);
|
||||
void load(const std::string &fileName);
|
||||
void load(std::istream& strm);
|
||||
void list();
|
||||
void list();
|
||||
|
||||
inline size_t size() const {return _properties.size();}
|
||||
inline size_t size() const {
|
||||
return _properties.size();
|
||||
}
|
||||
private:
|
||||
typedef std::map<std::string,std::string> _properties_t;
|
||||
_properties_t _properties;
|
||||
std::string _fileName;
|
||||
public:
|
||||
inline const _properties_t& map() const {return _properties;}
|
||||
inline const _properties_t& map() const {
|
||||
return _properties;
|
||||
}
|
||||
};
|
||||
|
||||
class ConfigurationStack;
|
||||
@@ -74,72 +82,72 @@ class ConfigurationStack;
|
||||
class epicsShareClass Configuration : private epics::pvData::NoDefaultMethods
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(Configuration);
|
||||
POINTER_DEFINITIONS(Configuration);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~Configuration() {};
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
bool getPropertyAsBoolean(const std::string &name, const bool defaultValue) const;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
epics::pvData::int32 getPropertyAsInteger(const std::string &name, const epics::pvData::int32 defaultValue) const;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
float getPropertyAsFloat(const std::string &name, const float defaultValue) const;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
double getPropertyAsDouble(const std::string &name, const double defaultValue) const;
|
||||
/**
|
||||
* 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 std::string or default value if it does not exist.
|
||||
*/
|
||||
std::string getPropertyAsString(const std::string &name, const std::string &defaultValue) const;
|
||||
/**
|
||||
* Fetch and parse as a socket address and port number (address family set accordingly).
|
||||
* At present only numeric addresses are parsed (eg. "127.0.0.1:4242").
|
||||
*
|
||||
* The storage pointed to be addr should be initialized with a default value, or zeroed.
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~Configuration() {};
|
||||
/**
|
||||
* 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.
|
||||
* @pram addr pointer to the address struct to be filled in
|
||||
* @return true if addr now contains an address, false otherwise
|
||||
* @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.
|
||||
*/
|
||||
bool getPropertyAsBoolean(const std::string &name, const bool defaultValue) const;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
epics::pvData::int32 getPropertyAsInteger(const std::string &name, const epics::pvData::int32 defaultValue) const;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
float getPropertyAsFloat(const std::string &name, const float defaultValue) const;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
double getPropertyAsDouble(const std::string &name, const double defaultValue) const;
|
||||
/**
|
||||
* 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 std::string or default value if it does not exist.
|
||||
*/
|
||||
std::string getPropertyAsString(const std::string &name, const std::string &defaultValue) const;
|
||||
/**
|
||||
* Fetch and parse as a socket address and port number (address family set accordingly).
|
||||
* At present only numeric addresses are parsed (eg. "127.0.0.1:4242").
|
||||
*
|
||||
* The storage pointed to be addr should be initialized with a default value, or zeroed.
|
||||
*
|
||||
* @param name name of the environment variable to return.
|
||||
* @pram addr pointer to the address struct to be filled in
|
||||
* @return true if addr now contains an address, false otherwise
|
||||
*/
|
||||
bool getPropertyAsAddress(const std::string& name, osiSockAddr* addr) const;
|
||||
|
||||
bool hasProperty(const std::string &name) const;
|
||||
@@ -188,7 +196,9 @@ public:
|
||||
confs.pop_back();
|
||||
return ret;
|
||||
}
|
||||
inline size_t size() const {return confs.size();}
|
||||
inline size_t size() const {
|
||||
return confs.size();
|
||||
}
|
||||
};
|
||||
|
||||
struct epicsShareClass ConfigurationBuilder
|
||||
@@ -218,41 +228,41 @@ private:
|
||||
class epicsShareClass ConfigurationProvider : private epics::pvData::NoDefaultMethods
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ConfigurationProvider);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~ConfigurationProvider() {};
|
||||
/**
|
||||
* 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::shared_pointer getConfiguration(const std::string &name) = 0;
|
||||
/**
|
||||
* Register configuration.
|
||||
*
|
||||
* @param name name of the configuration to register.
|
||||
* @param configuration configuration to register.
|
||||
*/
|
||||
virtual void registerConfiguration(const std::string &name, Configuration::shared_pointer const & configuration) = 0;
|
||||
POINTER_DEFINITIONS(ConfigurationProvider);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~ConfigurationProvider() {};
|
||||
/**
|
||||
* 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::shared_pointer getConfiguration(const std::string &name) = 0;
|
||||
/**
|
||||
* Register configuration.
|
||||
*
|
||||
* @param name name of the configuration to register.
|
||||
* @param configuration configuration to register.
|
||||
*/
|
||||
virtual void registerConfiguration(const std::string &name, Configuration::shared_pointer const & configuration) = 0;
|
||||
};
|
||||
|
||||
class ConfigurationProviderImpl: public ConfigurationProvider
|
||||
{
|
||||
public:
|
||||
ConfigurationProviderImpl() {}
|
||||
/**
|
||||
* Destructor. Note: Registered configurations will be deleted!!
|
||||
*/
|
||||
/**
|
||||
* Destructor. Note: Registered configurations will be deleted!!
|
||||
*/
|
||||
~ConfigurationProviderImpl() {}
|
||||
Configuration::shared_pointer getConfiguration(const std::string &name);
|
||||
void registerConfiguration(const std::string &name, Configuration::shared_pointer const & configuration);
|
||||
Configuration::shared_pointer getConfiguration(const std::string &name);
|
||||
void registerConfiguration(const std::string &name, Configuration::shared_pointer const & configuration);
|
||||
private:
|
||||
epics::pvData::Mutex _mutex;
|
||||
std::map<std::string,Configuration::shared_pointer> _configs;
|
||||
epics::pvData::Mutex _mutex;
|
||||
std::map<std::string,Configuration::shared_pointer> _configs;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -261,17 +271,17 @@ private:
|
||||
class epicsShareClass ConfigurationFactory : private epics::pvData::NoDefaultMethods
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ConfigurationFactory);
|
||||
POINTER_DEFINITIONS(ConfigurationFactory);
|
||||
|
||||
/**
|
||||
* Lazily creates configuration provider.
|
||||
*
|
||||
* @param name name of the configuration to register.
|
||||
* @param configuration configuration to register.
|
||||
*
|
||||
* @return configuration provider
|
||||
*/
|
||||
static ConfigurationProvider::shared_pointer getProvider();
|
||||
/**
|
||||
* Lazily creates configuration provider.
|
||||
*
|
||||
* @param name name of the configuration to register.
|
||||
* @param configuration configuration to register.
|
||||
*
|
||||
* @return configuration provider
|
||||
*/
|
||||
static ConfigurationProvider::shared_pointer getProvider();
|
||||
static void registerConfiguration(const std::string &name, Configuration::shared_pointer const & configuration)
|
||||
{
|
||||
getProvider()->registerConfiguration(name, configuration);
|
||||
@@ -282,9 +292,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
ConfigurationFactory() {};
|
||||
ConfigurationFactory() {};
|
||||
};
|
||||
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIGURATION_H */
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics {namespace pvAccess {
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
|
||||
/** @brief An intrusive, loss-less, unbounded, round-robin queue
|
||||
@@ -82,7 +83,7 @@ public:
|
||||
public:
|
||||
entry() :Qcnt(0), holder()
|
||||
#ifndef NDEBUG
|
||||
, owner(NULL)
|
||||
, owner(NULL)
|
||||
#endif
|
||||
{
|
||||
enode.node.next = enode.node.previous = NULL;
|
||||
@@ -196,6 +197,7 @@ private:
|
||||
mutable epicsEvent wakeup;
|
||||
};
|
||||
|
||||
}} // namespace
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#endif // FAIRQUEUE_H
|
||||
|
||||
+25
-25
@@ -24,33 +24,33 @@
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
/**
|
||||
* Output a buffer in hex format.
|
||||
* @param name name (description) of the message.
|
||||
* @param bs buffer to dump
|
||||
* @param len first bytes (length) to dump.
|
||||
*/
|
||||
epicsShareFunc void hexDump(std::string const & name, const epics::pvData::int8 *bs, int len);
|
||||
/**
|
||||
* Output a buffer in hex format.
|
||||
* @param name name (description) of the message.
|
||||
* @param bs buffer to dump
|
||||
* @param len first bytes (length) to dump.
|
||||
*/
|
||||
epicsShareFunc void hexDump(std::string const & name, const epics::pvData::int8 *bs, int len);
|
||||
|
||||
/**
|
||||
* Output a buffer in hex format.
|
||||
* @param[in] name name (description) of the message.
|
||||
* @param[in] bs buffer to dump
|
||||
* @param[in] start dump message using given offset.
|
||||
* @param[in] len first bytes (length) to dump.
|
||||
*/
|
||||
epicsShareFunc void hexDump(std::string const & name, const epics::pvData::int8 *bs, int start, int len);
|
||||
/**
|
||||
* Output a buffer in hex format.
|
||||
* @param[in] name name (description) of the message.
|
||||
* @param[in] bs buffer to dump
|
||||
* @param[in] start dump message using given offset.
|
||||
* @param[in] len first bytes (length) to dump.
|
||||
*/
|
||||
epicsShareFunc void hexDump(std::string const & name, const epics::pvData::int8 *bs, int start, int len);
|
||||
|
||||
/**
|
||||
* Output a buffer in hex format.
|
||||
* @param[in] prologue string to prefixed to debug output, can be <code>null</code>
|
||||
* @param[in] name name (description) of the message.
|
||||
* @param[in] bs buffer to dump
|
||||
* @param[in] start dump message using given offset.
|
||||
* @param[in] len first bytes (length) to dump.
|
||||
*/
|
||||
epicsShareFunc void hexDump(std::string const & prologue, std::string const & name,
|
||||
const epics::pvData::int8 *bs, int start, int len);
|
||||
/**
|
||||
* Output a buffer in hex format.
|
||||
* @param[in] prologue string to prefixed to debug output, can be <code>null</code>
|
||||
* @param[in] name name (description) of the message.
|
||||
* @param[in] bs buffer to dump
|
||||
* @param[in] start dump message using given offset.
|
||||
* @param[in] len first bytes (length) to dump.
|
||||
*/
|
||||
epicsShareFunc void hexDump(std::string const & prologue, std::string const & name,
|
||||
const epics::pvData::int8 *bs, int start, int len);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,118 +32,118 @@
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
typedef std::vector<osiSockAddr> InetAddrVector;
|
||||
typedef std::vector<osiSockAddr> InetAddrVector;
|
||||
|
||||
/**
|
||||
* Returns a vector containing all the IPv4 broadcast addresses on this machine.
|
||||
* IPv6 doesn't have a local broadcast address.
|
||||
* Conversion of the defaultPort to network byte order performed by
|
||||
* the function.
|
||||
*/
|
||||
epicsShareFunc InetAddrVector* getBroadcastAddresses(SOCKET sock, unsigned short defaultPort);
|
||||
/**
|
||||
* Returns a vector containing all the IPv4 broadcast addresses on this machine.
|
||||
* IPv6 doesn't have a local broadcast address.
|
||||
* Conversion of the defaultPort to network byte order performed by
|
||||
* the function.
|
||||
*/
|
||||
epicsShareFunc InetAddrVector* getBroadcastAddresses(SOCKET sock, unsigned short defaultPort);
|
||||
|
||||
struct ifaceNode {
|
||||
osiSockAddr ifaceAddr, ifaceBCast;
|
||||
};
|
||||
typedef std::vector<ifaceNode> IfaceNodeVector;
|
||||
epicsShareFunc int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *pMatchAddr = 0);
|
||||
struct ifaceNode {
|
||||
osiSockAddr ifaceAddr, ifaceBCast;
|
||||
};
|
||||
typedef std::vector<ifaceNode> IfaceNodeVector;
|
||||
epicsShareFunc int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *pMatchAddr = 0);
|
||||
|
||||
/**
|
||||
* Returns NIF index for given interface address, or -1 on failure.
|
||||
*/
|
||||
epicsShareFunc int discoverInterfaceIndex(SOCKET socket, const osiSockAddr *pMatchAddr);
|
||||
/**
|
||||
* Returns NIF index for given interface address, or -1 on failure.
|
||||
*/
|
||||
epicsShareFunc int discoverInterfaceIndex(SOCKET socket, const osiSockAddr *pMatchAddr);
|
||||
|
||||
/**
|
||||
* Encode IPv4 address as IPv6 address.
|
||||
* @param buffer byte-buffer where to put encoded data.
|
||||
* @param address address to encode.
|
||||
*/
|
||||
epicsShareFunc void encodeAsIPv6Address(epics::pvData::ByteBuffer* buffer, const osiSockAddr* address);
|
||||
/**
|
||||
* Encode IPv4 address as IPv6 address.
|
||||
* @param buffer byte-buffer where to put encoded data.
|
||||
* @param address address to encode.
|
||||
*/
|
||||
epicsShareFunc void encodeAsIPv6Address(epics::pvData::ByteBuffer* buffer, const osiSockAddr* address);
|
||||
|
||||
/**
|
||||
* Decode IPv6 address (as IPv4 address).
|
||||
* @param buffer byte-buffer where to get encoded data.
|
||||
* @param address address where to decode.
|
||||
* @return success status (true on success).
|
||||
*/
|
||||
epicsShareFunc bool decodeAsIPv6Address(epics::pvData::ByteBuffer* buffer, osiSockAddr* address);
|
||||
/**
|
||||
* Decode IPv6 address (as IPv4 address).
|
||||
* @param buffer byte-buffer where to get encoded data.
|
||||
* @param address address where to decode.
|
||||
* @return success status (true on success).
|
||||
*/
|
||||
epicsShareFunc bool decodeAsIPv6Address(epics::pvData::ByteBuffer* buffer, osiSockAddr* address);
|
||||
|
||||
/**
|
||||
* Check if an IPv4 address is a multicast address.
|
||||
* @param address IPv4 address to check.
|
||||
* @return true if the adress is a multicast address.
|
||||
*/
|
||||
epicsShareFunc bool isMulticastAddress(const osiSockAddr* address);
|
||||
/**
|
||||
* Check if an IPv4 address is a multicast address.
|
||||
* @param address IPv4 address to check.
|
||||
* @return true if the adress is a multicast address.
|
||||
*/
|
||||
epicsShareFunc bool isMulticastAddress(const osiSockAddr* address);
|
||||
|
||||
/**
|
||||
* Convert an integer into an IPv4 INET address.
|
||||
* @param addr integer representation of a given address.
|
||||
* @return IPv4 INET address.
|
||||
*/
|
||||
epicsShareFunc osiSockAddr* intToIPv4Address(epics::pvData::int32 addr);
|
||||
/**
|
||||
* Convert an integer into an IPv4 INET address.
|
||||
* @param addr integer representation of a given address.
|
||||
* @return IPv4 INET address.
|
||||
*/
|
||||
epicsShareFunc osiSockAddr* intToIPv4Address(epics::pvData::int32 addr);
|
||||
|
||||
/**
|
||||
* Convert an IPv4 INET address to an integer.
|
||||
* @param addr IPv4 INET address.
|
||||
* @return integer representation of a given address.
|
||||
*/
|
||||
epicsShareFunc epics::pvData::int32 ipv4AddressToInt(const osiSockAddr& addr);
|
||||
/**
|
||||
* Convert an IPv4 INET address to an integer.
|
||||
* @param addr IPv4 INET address.
|
||||
* @return integer representation of a given address.
|
||||
*/
|
||||
epicsShareFunc epics::pvData::int32 ipv4AddressToInt(const osiSockAddr& addr);
|
||||
|
||||
/**
|
||||
* Parse space delimited addresss[:port] string and return array of <code>InetSocketAddress</code>.
|
||||
* @param list space delimited addresss[:port] string.
|
||||
* @param defaultPort port take if not specified.
|
||||
* @param appendList list to be appended.
|
||||
* @return array of <code>InetSocketAddress</code>.
|
||||
*/
|
||||
epicsShareFunc InetAddrVector* getSocketAddressList(const std::string & list, int defaultPort,
|
||||
const InetAddrVector* appendList = NULL);
|
||||
/**
|
||||
* Parse space delimited addresss[:port] string and return array of <code>InetSocketAddress</code>.
|
||||
* @param list space delimited addresss[:port] string.
|
||||
* @param defaultPort port take if not specified.
|
||||
* @param appendList list to be appended.
|
||||
* @return array of <code>InetSocketAddress</code>.
|
||||
*/
|
||||
epicsShareFunc InetAddrVector* getSocketAddressList(const std::string & list, int defaultPort,
|
||||
const InetAddrVector* appendList = NULL);
|
||||
|
||||
epicsShareFunc std::string inetAddressToString(const osiSockAddr &addr,
|
||||
bool displayPort = true, bool displayHex = false);
|
||||
epicsShareFunc std::string inetAddressToString(const osiSockAddr &addr,
|
||||
bool displayPort = true, bool displayHex = false);
|
||||
|
||||
epicsShareFunc int getLoopbackNIF(osiSockAddr& loAddr, std::string const & localNIF, unsigned short port);
|
||||
epicsShareFunc int getLoopbackNIF(osiSockAddr& loAddr, std::string const & localNIF, unsigned short port);
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
// comparators for osiSockAddr
|
||||
// comparators for osiSockAddr
|
||||
|
||||
struct comp_osiSockAddrPtr {
|
||||
bool operator()(osiSockAddr const *a, osiSockAddr const *b) const {
|
||||
if(a->sa.sa_family<b->sa.sa_family) return true;
|
||||
if((a->sa.sa_family==b->sa.sa_family)&&(a->ia.sin_addr.s_addr
|
||||
<b->ia.sin_addr.s_addr)) return true;
|
||||
if((a->sa.sa_family==b->sa.sa_family)&&(a->ia.sin_addr.s_addr
|
||||
==b->ia.sin_addr.s_addr)&&(a->ia.sin_port
|
||||
<b->ia.sin_port)) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
struct comp_osiSockAddrPtr {
|
||||
bool operator()(osiSockAddr const *a, osiSockAddr const *b) const {
|
||||
if(a->sa.sa_family<b->sa.sa_family) return true;
|
||||
if((a->sa.sa_family==b->sa.sa_family)&&(a->ia.sin_addr.s_addr
|
||||
<b->ia.sin_addr.s_addr)) return true;
|
||||
if((a->sa.sa_family==b->sa.sa_family)&&(a->ia.sin_addr.s_addr
|
||||
==b->ia.sin_addr.s_addr)&&(a->ia.sin_port
|
||||
<b->ia.sin_port)) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct comp_osiSock_lt {
|
||||
bool operator()(const osiSockAddr& a, const osiSockAddr& b) const {
|
||||
if(a.sa.sa_family<b.sa.sa_family) return true;
|
||||
if((a.sa.sa_family==b.sa.sa_family)&&(a.ia.sin_addr.s_addr
|
||||
<b.ia.sin_addr.s_addr)) return true;
|
||||
if((a.sa.sa_family==b.sa.sa_family)&&(a.ia.sin_addr.s_addr
|
||||
==b.ia.sin_addr.s_addr)&&(a.ia.sin_port
|
||||
<b.ia.sin_port)) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
struct comp_osiSock_lt {
|
||||
bool operator()(const osiSockAddr& a, const osiSockAddr& b) const {
|
||||
if(a.sa.sa_family<b.sa.sa_family) return true;
|
||||
if((a.sa.sa_family==b.sa.sa_family)&&(a.ia.sin_addr.s_addr
|
||||
<b.ia.sin_addr.s_addr)) return true;
|
||||
if((a.sa.sa_family==b.sa.sa_family)&&(a.ia.sin_addr.s_addr
|
||||
==b.ia.sin_addr.s_addr)&&(a.ia.sin_port
|
||||
<b.ia.sin_port)) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//TODO if unordered map is used instead of map we can use sockAddrAreIdentical routine from osiSock.h
|
||||
struct comp_osiSockAddr {
|
||||
bool operator()(osiSockAddr const a, osiSockAddr const b) const {
|
||||
if(a.sa.sa_family<b.sa.sa_family) return true;
|
||||
if((a.sa.sa_family==b.sa.sa_family)&&(a.ia.sin_addr.s_addr
|
||||
<b.ia.sin_addr.s_addr)) return true;
|
||||
if((a.sa.sa_family==b.sa.sa_family)&&(a.ia.sin_addr.s_addr
|
||||
==b.ia.sin_addr.s_addr)&&(a.ia.sin_port
|
||||
<b.ia.sin_port)) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
//TODO if unordered map is used instead of map we can use sockAddrAreIdentical routine from osiSock.h
|
||||
struct comp_osiSockAddr {
|
||||
bool operator()(osiSockAddr const a, osiSockAddr const b) const {
|
||||
if(a.sa.sa_family<b.sa.sa_family) return true;
|
||||
if((a.sa.sa_family==b.sa.sa_family)&&(a.ia.sin_addr.s_addr
|
||||
<b.ia.sin_addr.s_addr)) return true;
|
||||
if((a.sa.sa_family==b.sa.sa_family)&&(a.ia.sin_addr.s_addr
|
||||
==b.ia.sin_addr.s_addr)&&(a.ia.sin_port
|
||||
<b.ia.sin_port)) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,97 +37,98 @@ namespace pvAccess {
|
||||
typedef std::map<const short,epics::pvData::FieldConstPtr> registryMap_t;
|
||||
|
||||
|
||||
/**
|
||||
* PVData Structure registry.
|
||||
* Registry is used to cache introspection interfaces to minimize network traffic.
|
||||
* @author gjansa
|
||||
*/
|
||||
class IntrospectionRegistry : public epics::pvData::NoDefaultMethods {
|
||||
public:
|
||||
IntrospectionRegistry();
|
||||
virtual ~IntrospectionRegistry();
|
||||
/**
|
||||
* PVData Structure registry.
|
||||
* Registry is used to cache introspection interfaces to minimize network traffic.
|
||||
* @author gjansa
|
||||
*/
|
||||
class IntrospectionRegistry : public epics::pvData::NoDefaultMethods {
|
||||
public:
|
||||
IntrospectionRegistry();
|
||||
virtual ~IntrospectionRegistry();
|
||||
|
||||
/**
|
||||
* Resets registry, i.e. must be done when transport is changed (server restarted).
|
||||
*/
|
||||
void reset();
|
||||
/**
|
||||
* Get introspection interface for given ID.
|
||||
*
|
||||
* @param id id of the introspection interface to get
|
||||
*
|
||||
* @return <code>Field</code> instance for given ID.
|
||||
*/
|
||||
epics::pvData::FieldConstPtr getIntrospectionInterface(const epics::pvData::int16 id);
|
||||
/**
|
||||
* Resets registry, i.e. must be done when transport is changed (server restarted).
|
||||
*/
|
||||
void reset();
|
||||
/**
|
||||
* Get introspection interface for given ID.
|
||||
*
|
||||
* @param id id of the introspection interface to get
|
||||
*
|
||||
* @return <code>Field</code> instance for given ID.
|
||||
*/
|
||||
epics::pvData::FieldConstPtr getIntrospectionInterface(const epics::pvData::int16 id);
|
||||
|
||||
/**
|
||||
* Registers introspection interface with given ID. Always INCOMING.
|
||||
*
|
||||
* @param id id of the introspection interface to register
|
||||
* @param field introspection interface to register
|
||||
*/
|
||||
void registerIntrospectionInterface(const epics::pvData::int16 id, epics::pvData::FieldConstPtr const & field);
|
||||
/**
|
||||
* Registers introspection interface with given ID. Always INCOMING.
|
||||
*
|
||||
* @param id id of the introspection interface to register
|
||||
* @param field introspection interface to register
|
||||
*/
|
||||
void registerIntrospectionInterface(const epics::pvData::int16 id, epics::pvData::FieldConstPtr const & field);
|
||||
|
||||
/**
|
||||
* Registers introspection interface and get it's ID. Always OUTGOING.
|
||||
* If it is already registered only preassigned ID is returned.
|
||||
*
|
||||
* TODO !!!!!!this can get very slow in large maps. We need to change this !!!!!!
|
||||
*
|
||||
* @param field introspection interface to register
|
||||
*
|
||||
* @return id of given introspection interface
|
||||
*/
|
||||
epics::pvData::int16 registerIntrospectionInterface(epics::pvData::FieldConstPtr const & field, bool& existing);
|
||||
/**
|
||||
* Registers introspection interface and get it's ID. Always OUTGOING.
|
||||
* If it is already registered only preassigned ID is returned.
|
||||
*
|
||||
* TODO !!!!!!this can get very slow in large maps. We need to change this !!!!!!
|
||||
*
|
||||
* @param field introspection interface to register
|
||||
*
|
||||
* @return id of given introspection interface
|
||||
*/
|
||||
epics::pvData::int16 registerIntrospectionInterface(epics::pvData::FieldConstPtr const & field, bool& existing);
|
||||
|
||||
/**
|
||||
* Serializes introspection interface
|
||||
*
|
||||
* @param field
|
||||
* @param buffer
|
||||
* @param control
|
||||
*/
|
||||
void serialize(epics::pvData::FieldConstPtr const & field, epics::pvData::ByteBuffer* buffer, epics::pvData::SerializableControl* control);
|
||||
/**
|
||||
* Serializes introspection interface
|
||||
*
|
||||
* @param field
|
||||
* @param buffer
|
||||
* @param control
|
||||
*/
|
||||
void serialize(epics::pvData::FieldConstPtr const & field, epics::pvData::ByteBuffer* buffer, epics::pvData::SerializableControl* control);
|
||||
|
||||
/**
|
||||
* Deserializes introspection interface
|
||||
*
|
||||
* TODO
|
||||
*
|
||||
* @param buffer
|
||||
* @param control
|
||||
*
|
||||
* @return <code>Field</code> deserialized from the buffer.
|
||||
*/
|
||||
epics::pvData::FieldConstPtr deserialize(epics::pvData::ByteBuffer* buffer, epics::pvData::DeserializableControl* control);
|
||||
/**
|
||||
* Deserializes introspection interface
|
||||
*
|
||||
* TODO
|
||||
*
|
||||
* @param buffer
|
||||
* @param control
|
||||
*
|
||||
* @return <code>Field</code> deserialized from the buffer.
|
||||
*/
|
||||
epics::pvData::FieldConstPtr deserialize(epics::pvData::ByteBuffer* buffer, epics::pvData::DeserializableControl* control);
|
||||
|
||||
/**
|
||||
* Null type.
|
||||
*/
|
||||
const static epics::pvData::int8 NULL_TYPE_CODE;
|
||||
/**
|
||||
* Null type.
|
||||
*/
|
||||
const static epics::pvData::int8 NULL_TYPE_CODE;
|
||||
|
||||
/**
|
||||
* Serialization contains only an ID (that was assigned by one of the previous <code>FULL_WITH_ID</code> descriptions).
|
||||
*/
|
||||
const static epics::pvData::int8 ONLY_ID_TYPE_CODE;
|
||||
/**
|
||||
* Serialization contains only an ID (that was assigned by one of the previous <code>FULL_WITH_ID</code> descriptions).
|
||||
*/
|
||||
const static epics::pvData::int8 ONLY_ID_TYPE_CODE;
|
||||
|
||||
/**
|
||||
* Serialization contains an ID (that can be used later, if cached) and full interface description.
|
||||
*/
|
||||
const static epics::pvData::int8 FULL_WITH_ID_TYPE_CODE;
|
||||
/**
|
||||
* Serialization contains an ID (that can be used later, if cached) and full interface description.
|
||||
*/
|
||||
const static epics::pvData::int8 FULL_WITH_ID_TYPE_CODE;
|
||||
|
||||
private:
|
||||
registryMap_t _registry;
|
||||
epics::pvData::int16 _pointer;
|
||||
private:
|
||||
registryMap_t _registry;
|
||||
epics::pvData::int16 _pointer;
|
||||
|
||||
/**
|
||||
* Field factory.
|
||||
*/
|
||||
static epics::pvData::FieldCreatePtr _fieldCreate;
|
||||
/**
|
||||
* Field factory.
|
||||
*/
|
||||
static epics::pvData::FieldCreatePtr _fieldCreate;
|
||||
|
||||
bool registryContainsValue(epics::pvData::FieldConstPtr const & field, epics::pvData::int16& key);
|
||||
};
|
||||
bool registryContainsValue(epics::pvData::FieldConstPtr const & field, epics::pvData::int16& key);
|
||||
};
|
||||
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* INTROSPECTIONREGISTRY_H */
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#define LIKELY_H_
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
#define likely(x) __builtin_expect (x, 1)
|
||||
#define unlikely(x) __builtin_expect (x, 0)
|
||||
#define likely(x) __builtin_expect (x, 1)
|
||||
#define unlikely(x) __builtin_expect (x, 0)
|
||||
#else
|
||||
#define likely(x) (x)
|
||||
#define unlikely(x) (x)
|
||||
#define likely(x) (x)
|
||||
#define unlikely(x) (x)
|
||||
#endif
|
||||
|
||||
#endif /* LIKELY_H_ */
|
||||
|
||||
+52
-51
@@ -24,58 +24,59 @@
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
typedef enum { logLevelAll = 0, logLevelTrace, logLevelDebug, logLevelInfo,
|
||||
logLevelWarn, logLevelError, logLevelFatal, logLevelOff } pvAccessLogLevel;
|
||||
/*
|
||||
ALL
|
||||
The ALL has the lowest possible rank and is intended to turn on all logging.
|
||||
TRACE
|
||||
The TRACE Level designates finer-grained informational events than the DEBUG
|
||||
DEBUG
|
||||
The DEBUG Level designates fine-grained informational events that are most useful to debug an application.
|
||||
INFO
|
||||
The INFO level designates informational messages that highlight the progress of the application at coarse-grained level.
|
||||
WARN
|
||||
The WARN level designates potentially harmful situations.
|
||||
ERROR
|
||||
The ERROR level designates error events that might still allow the application to continue running.
|
||||
FATAL
|
||||
The FATAL level designates very severe error events that will presumably lead the application to abort.
|
||||
OFF
|
||||
The OFF has the highest possible rank and is intended to turn off logging.
|
||||
|
||||
typedef enum { logLevelAll = 0, logLevelTrace, logLevelDebug, logLevelInfo,
|
||||
logLevelWarn, logLevelError, logLevelFatal, logLevelOff
|
||||
} pvAccessLogLevel;
|
||||
/*
|
||||
ALL
|
||||
The ALL has the lowest possible rank and is intended to turn on all logging.
|
||||
TRACE
|
||||
The TRACE Level designates finer-grained informational events than the DEBUG
|
||||
DEBUG
|
||||
The DEBUG Level designates fine-grained informational events that are most useful to debug an application.
|
||||
INFO
|
||||
The INFO level designates informational messages that highlight the progress of the application at coarse-grained level.
|
||||
WARN
|
||||
The WARN level designates potentially harmful situations.
|
||||
ERROR
|
||||
The ERROR level designates error events that might still allow the application to continue running.
|
||||
FATAL
|
||||
The FATAL level designates very severe error events that will presumably lead the application to abort.
|
||||
OFF
|
||||
The OFF has the highest possible rank and is intended to turn off logging.
|
||||
*/
|
||||
|
||||
|
||||
epicsShareExtern void pvAccessLog(pvAccessLogLevel level, const char* format, ...);
|
||||
epicsShareExtern void pvAccessSetLogLevel(pvAccessLogLevel level);
|
||||
epicsShareExtern bool pvAccessIsLoggable(pvAccessLogLevel level);
|
||||
|
||||
#if defined (__GNUC__) && __GNUC__ < 3
|
||||
#define LOG(level, format, ARGS...) pvAccessLog(level, format, ##ARGS)
|
||||
#else
|
||||
#define LOG(level, format, ...) pvAccessLog(level, format, ##__VA_ARGS__)
|
||||
#endif
|
||||
#define SET_LOG_LEVEL(level) pvAccessSetLogLevel(level)
|
||||
#define IS_LOGGABLE(level) pvAccessIsLoggable(level)
|
||||
|
||||
// EPICS errlog
|
||||
//#define LOG errlogSevPrintf
|
||||
//#define SET_LOG_LEVEL(level) errlogSetSevToLog(level)
|
||||
|
||||
// none
|
||||
//#define LOG(level, fmt, ...)
|
||||
//#define SET_LOG_LEVEL(level)
|
||||
|
||||
/**
|
||||
* Create a logger that will write to file indicated by the <tt>fname</tt>.
|
||||
* After creation you are free to use standard EPICSv3 functions from
|
||||
* <tt>errlog.h</tt>.
|
||||
*
|
||||
* @param[in] fname The file to write to. If the file exists, it
|
||||
* is opened for append.
|
||||
*/
|
||||
|
||||
|
||||
epicsShareExtern void pvAccessLog(pvAccessLogLevel level, const char* format, ...);
|
||||
epicsShareExtern void pvAccessSetLogLevel(pvAccessLogLevel level);
|
||||
epicsShareExtern bool pvAccessIsLoggable(pvAccessLogLevel level);
|
||||
|
||||
#if defined (__GNUC__) && __GNUC__ < 3
|
||||
#define LOG(level, format, ARGS...) pvAccessLog(level, format, ##ARGS)
|
||||
#else
|
||||
#define LOG(level, format, ...) pvAccessLog(level, format, ##__VA_ARGS__)
|
||||
#endif
|
||||
#define SET_LOG_LEVEL(level) pvAccessSetLogLevel(level)
|
||||
#define IS_LOGGABLE(level) pvAccessIsLoggable(level)
|
||||
|
||||
// EPICS errlog
|
||||
//#define LOG errlogSevPrintf
|
||||
//#define SET_LOG_LEVEL(level) errlogSetSevToLog(level)
|
||||
|
||||
// none
|
||||
//#define LOG(level, fmt, ...)
|
||||
//#define SET_LOG_LEVEL(level)
|
||||
|
||||
/**
|
||||
* Create a logger that will write to file indicated by the <tt>fname</tt>.
|
||||
* After creation you are free to use standard EPICSv3 functions from
|
||||
* <tt>errlog.h</tt>.
|
||||
*
|
||||
* @param[in] fname The file to write to. If the file exists, it
|
||||
* is opened for append.
|
||||
*/
|
||||
epicsShareExtern void createFileLogger( std::string const & fname );
|
||||
epicsShareExtern void createFileLogger( std::string const & fname );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
|
||||
// TODO implement using smart pointers
|
||||
|
||||
namespace epics { namespace pvAccess {
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
/**
|
||||
* NamedLockPattern
|
||||
@@ -37,125 +38,131 @@ template <class Key, class Compare = std::less<Key> >
|
||||
class NamedLockPattern
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
NamedLockPattern() {};
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~NamedLockPattern() {};
|
||||
/**
|
||||
* Acquire synchronization lock for named object.
|
||||
*
|
||||
* NOTE: Argument msecs is currently not supported due to
|
||||
* Darwin OS not supporting pthread_mutex_timedlock. May be changed in the future.
|
||||
*
|
||||
* @param name name of the object whose lock to acquire.
|
||||
* @param msec the number of milleseconds to wait.
|
||||
* An argument less than or equal to zero means not to wait at all.
|
||||
* @return <code>true</code> if acquired, <code>false</code> othwerwise.
|
||||
* NOTE: currently this routine always returns true. Look above for explanation.
|
||||
*/
|
||||
bool acquireSynchronizationObject(const Key& name, const epics::pvData::int64 msec);
|
||||
/**
|
||||
* Release synchronization lock for named object.
|
||||
* @param name name of the object whose lock to release.
|
||||
*/
|
||||
void releaseSynchronizationObject(const Key& name);
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
NamedLockPattern() {};
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~NamedLockPattern() {};
|
||||
/**
|
||||
* Acquire synchronization lock for named object.
|
||||
*
|
||||
* NOTE: Argument msecs is currently not supported due to
|
||||
* Darwin OS not supporting pthread_mutex_timedlock. May be changed in the future.
|
||||
*
|
||||
* @param name name of the object whose lock to acquire.
|
||||
* @param msec the number of milleseconds to wait.
|
||||
* An argument less than or equal to zero means not to wait at all.
|
||||
* @return <code>true</code> if acquired, <code>false</code> othwerwise.
|
||||
* NOTE: currently this routine always returns true. Look above for explanation.
|
||||
*/
|
||||
bool acquireSynchronizationObject(const Key& name, const epics::pvData::int64 msec);
|
||||
/**
|
||||
* Release synchronization lock for named object.
|
||||
* @param name name of the object whose lock to release.
|
||||
*/
|
||||
void releaseSynchronizationObject(const Key& name);
|
||||
private:
|
||||
epics::pvData::Mutex _mutex;
|
||||
std::map<const Key,ReferenceCountingLock::shared_pointer,Compare> _namedLocks;
|
||||
typename std::map<const Key,ReferenceCountingLock::shared_pointer,Compare>::iterator _namedLocksIter;
|
||||
epics::pvData::Mutex _mutex;
|
||||
std::map<const Key,ReferenceCountingLock::shared_pointer,Compare> _namedLocks;
|
||||
typename std::map<const Key,ReferenceCountingLock::shared_pointer,Compare>::iterator _namedLocksIter;
|
||||
|
||||
/**
|
||||
* Release synchronization lock for named object.
|
||||
* @param name name of the object whose lock to release.
|
||||
* @param release set to <code>false</code> if there is no need to call release
|
||||
* on synchronization lock.
|
||||
*/
|
||||
void releaseSynchronizationObject(const Key& name,const bool release);
|
||||
/**
|
||||
* Release synchronization lock for named object.
|
||||
* @param name name of the object whose lock to release.
|
||||
* @param release set to <code>false</code> if there is no need to call release
|
||||
* on synchronization lock.
|
||||
*/
|
||||
void releaseSynchronizationObject(const Key& name,const bool release);
|
||||
};
|
||||
|
||||
template <class Key, class Compare>
|
||||
bool NamedLockPattern<Key,Compare>::acquireSynchronizationObject(const Key& name, const epics::pvData::int64 msec)
|
||||
{
|
||||
ReferenceCountingLock::shared_pointer lock;
|
||||
{ //due to guard
|
||||
epics::pvData::Lock guard(_mutex);
|
||||
ReferenceCountingLock::shared_pointer lock;
|
||||
{ //due to guard
|
||||
epics::pvData::Lock guard(_mutex);
|
||||
|
||||
_namedLocksIter = _namedLocks.find(name);
|
||||
// get synchronization object
|
||||
_namedLocksIter = _namedLocks.find(name);
|
||||
// get synchronization object
|
||||
|
||||
// none is found, create and return new one
|
||||
// increment references
|
||||
if(_namedLocksIter == _namedLocks.end())
|
||||
{
|
||||
lock.reset(new ReferenceCountingLock());
|
||||
_namedLocks[name] = lock;
|
||||
}
|
||||
else
|
||||
{
|
||||
lock = _namedLocksIter->second;
|
||||
lock->increment();
|
||||
}
|
||||
} // end of guarded area
|
||||
// none is found, create and return new one
|
||||
// increment references
|
||||
if(_namedLocksIter == _namedLocks.end())
|
||||
{
|
||||
lock.reset(new ReferenceCountingLock());
|
||||
_namedLocks[name] = lock;
|
||||
}
|
||||
else
|
||||
{
|
||||
lock = _namedLocksIter->second;
|
||||
lock->increment();
|
||||
}
|
||||
} // end of guarded area
|
||||
|
||||
bool success = lock->acquire(msec);
|
||||
bool success = lock->acquire(msec);
|
||||
|
||||
if(!success)
|
||||
{
|
||||
releaseSynchronizationObject(name, false);
|
||||
}
|
||||
if(!success)
|
||||
{
|
||||
releaseSynchronizationObject(name, false);
|
||||
}
|
||||
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
template <class Key, class Compare>
|
||||
void NamedLockPattern<Key,Compare>::releaseSynchronizationObject(const Key& name)
|
||||
{
|
||||
releaseSynchronizationObject(name, true);
|
||||
releaseSynchronizationObject(name, true);
|
||||
}
|
||||
|
||||
template <class Key, class Compare>
|
||||
void NamedLockPattern<Key,Compare>::releaseSynchronizationObject(const Key& name,const bool release)
|
||||
{
|
||||
epics::pvData::Lock guard(_mutex);
|
||||
ReferenceCountingLock::shared_pointer lock;
|
||||
_namedLocksIter = _namedLocks.find(name);
|
||||
epics::pvData::Lock guard(_mutex);
|
||||
ReferenceCountingLock::shared_pointer lock;
|
||||
_namedLocksIter = _namedLocks.find(name);
|
||||
|
||||
// release lock
|
||||
if (_namedLocksIter != _namedLocks.end())
|
||||
{
|
||||
lock = _namedLocksIter->second;
|
||||
// release lock
|
||||
if (_namedLocksIter != _namedLocks.end())
|
||||
{
|
||||
lock = _namedLocksIter->second;
|
||||
|
||||
// release the lock
|
||||
if (release)
|
||||
{
|
||||
lock->release();
|
||||
}
|
||||
// release the lock
|
||||
if (release)
|
||||
{
|
||||
lock->release();
|
||||
}
|
||||
|
||||
// if there only one current lock exists
|
||||
// remove it from the map
|
||||
if (lock->decrement() <= 0)
|
||||
{
|
||||
_namedLocks.erase(_namedLocksIter);
|
||||
}
|
||||
}
|
||||
// if there only one current lock exists
|
||||
// remove it from the map
|
||||
if (lock->decrement() <= 0)
|
||||
{
|
||||
_namedLocks.erase(_namedLocksIter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Key, class Compare>
|
||||
class NamedLock : private epics::pvData::NoDefaultMethods
|
||||
{
|
||||
public:
|
||||
NamedLock(NamedLockPattern<Key,Compare>* namedLockPattern): _namedLockPattern(namedLockPattern) {}
|
||||
bool acquireSynchronizationObject(const Key& name, const epics::pvData::int64 msec) {_name = name; return _namedLockPattern->acquireSynchronizationObject(name,msec);}
|
||||
~NamedLock(){_namedLockPattern->releaseSynchronizationObject(_name);}
|
||||
NamedLock(NamedLockPattern<Key,Compare>* namedLockPattern): _namedLockPattern(namedLockPattern) {}
|
||||
bool acquireSynchronizationObject(const Key& name, const epics::pvData::int64 msec) {
|
||||
_name = name;
|
||||
return _namedLockPattern->acquireSynchronizationObject(name,msec);
|
||||
}
|
||||
~NamedLock() {
|
||||
_namedLockPattern->releaseSynchronizationObject(_name);
|
||||
}
|
||||
private:
|
||||
Key _name;
|
||||
NamedLockPattern<Key,Compare>* _namedLockPattern;
|
||||
Key _name;
|
||||
NamedLockPattern<Key,Compare>* _namedLockPattern;
|
||||
};
|
||||
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NAMEDLOCKPATTERN_H */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* pvAccessCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef REFERENCECOUNTINGLOCK_H
|
||||
#define REFERENCECOUNTINGLOCK_H
|
||||
|
||||
@@ -37,51 +37,52 @@ class ReferenceCountingLock
|
||||
public:
|
||||
POINTER_DEFINITIONS(ReferenceCountingLock);
|
||||
|
||||
/**
|
||||
* Constructor of <code>ReferenceCountingLock</code>.
|
||||
* After construction lock is free and reference count equals <code>1</code>.
|
||||
*/
|
||||
ReferenceCountingLock();
|
||||
/**
|
||||
* Destructor of <code>ReferenceCountingLock</code>.
|
||||
*/
|
||||
virtual ~ReferenceCountingLock();
|
||||
/**
|
||||
* Attempt to acquire lock.
|
||||
*
|
||||
* NOTE: Argument msecs is currently not supported due to
|
||||
* Darwin OS not supporting pthread_mutex_timedlock. May be changed in the future.
|
||||
*
|
||||
* @param msecs the number of milleseconds to wait.
|
||||
* An argument less than or equal to zero means not to wait at all.
|
||||
*
|
||||
* @return <code>true</code> if acquired, <code>false</code> otherwise.
|
||||
* NOTE: currently this routine always returns true. Look above for explanation.
|
||||
*
|
||||
*/
|
||||
bool acquire(epics::pvData::int64 msecs);
|
||||
/**
|
||||
* Release previously acquired lock.
|
||||
*/
|
||||
void release();
|
||||
/**
|
||||
* Increment number of references.
|
||||
*
|
||||
* @return number of references.
|
||||
*/
|
||||
int increment();
|
||||
/**
|
||||
* Decrement number of references.
|
||||
*
|
||||
* @return number of references.
|
||||
*/
|
||||
int decrement();
|
||||
/**
|
||||
* Constructor of <code>ReferenceCountingLock</code>.
|
||||
* After construction lock is free and reference count equals <code>1</code>.
|
||||
*/
|
||||
ReferenceCountingLock();
|
||||
/**
|
||||
* Destructor of <code>ReferenceCountingLock</code>.
|
||||
*/
|
||||
virtual ~ReferenceCountingLock();
|
||||
/**
|
||||
* Attempt to acquire lock.
|
||||
*
|
||||
* NOTE: Argument msecs is currently not supported due to
|
||||
* Darwin OS not supporting pthread_mutex_timedlock. May be changed in the future.
|
||||
*
|
||||
* @param msecs the number of milleseconds to wait.
|
||||
* An argument less than or equal to zero means not to wait at all.
|
||||
*
|
||||
* @return <code>true</code> if acquired, <code>false</code> otherwise.
|
||||
* NOTE: currently this routine always returns true. Look above for explanation.
|
||||
*
|
||||
*/
|
||||
bool acquire(epics::pvData::int64 msecs);
|
||||
/**
|
||||
* Release previously acquired lock.
|
||||
*/
|
||||
void release();
|
||||
/**
|
||||
* Increment number of references.
|
||||
*
|
||||
* @return number of references.
|
||||
*/
|
||||
int increment();
|
||||
/**
|
||||
* Decrement number of references.
|
||||
*
|
||||
* @return number of references.
|
||||
*/
|
||||
int decrement();
|
||||
private:
|
||||
int _references;
|
||||
epics::pvData::Mutex _mutex;
|
||||
epics::pvData::Mutex _countMutex;
|
||||
int _references;
|
||||
epics::pvData::Mutex _mutex;
|
||||
epics::pvData::Mutex _countMutex;
|
||||
};
|
||||
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* REFERENCECOUNTINGLOCK_H */
|
||||
|
||||
+12
-10
@@ -35,7 +35,8 @@
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
namespace epics { namespace pvAccess {
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
/**
|
||||
* Class which implements UNIX style wildcards and tests to see
|
||||
@@ -43,19 +44,19 @@ namespace epics { namespace pvAccess {
|
||||
*/
|
||||
class epicsShareClass Wildcard
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* This function implements the UN*X wildcards.
|
||||
* @param wildcard Wildcard to be used.
|
||||
* @param test Value which we want to see if it matches the wildcard.
|
||||
* @return 0 if wildcard does not match *test. 1 - if wildcard
|
||||
* @return 0 if wildcard does not match *test. 1 - if wildcard
|
||||
* matches test.
|
||||
*/
|
||||
static int wildcardfit (const char *wildcard, const char *test);
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
/**
|
||||
* Scans a set of characters and returns 0 if the set mismatches at this
|
||||
* position in the teststring and 1 if it is matching
|
||||
@@ -66,7 +67,7 @@ class epicsShareClass Wildcard
|
||||
* @return 0 if the set mismatches. 1 otherwise.
|
||||
*/
|
||||
static int set (const char **wildcard, const char **test);
|
||||
|
||||
|
||||
/**
|
||||
* Scans an asterisk.
|
||||
* @param wildcard UNIX style wildcard to be used
|
||||
@@ -76,7 +77,8 @@ class epicsShareClass Wildcard
|
||||
static int asterisk (const char **wildcard, const char **test);
|
||||
};
|
||||
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,30 +13,30 @@ using namespace epics::pvData;
|
||||
|
||||
ReferenceCountingLock::ReferenceCountingLock(): _references(1)
|
||||
{
|
||||
/* pthread_mutexattr_t mutexAttribute;
|
||||
int32 retval = pthread_mutexattr_init(&mutexAttribute);
|
||||
if(retval != 0)
|
||||
{
|
||||
//string errMsg = "Error: pthread_mutexattr_init failed: " + string(strerror(retval));
|
||||
assert(false);
|
||||
}
|
||||
retval = pthread_mutexattr_settype(&mutexAttribute, PTHREAD_MUTEX_RECURSIVE);
|
||||
if(retval == 0)
|
||||
{
|
||||
retval = pthread_mutex_init(_mutex, &mutexAttribute);
|
||||
if(retval != 0)
|
||||
{
|
||||
//string errMsg = "Error: pthread_mutex_init failed: " + string(strerror(retval));
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//string errMsg = "Error: pthread_mutexattr_settype failed: " + string(strerror(retval));
|
||||
assert(false);
|
||||
}
|
||||
/* pthread_mutexattr_t mutexAttribute;
|
||||
int32 retval = pthread_mutexattr_init(&mutexAttribute);
|
||||
if(retval != 0)
|
||||
{
|
||||
//string errMsg = "Error: pthread_mutexattr_init failed: " + string(strerror(retval));
|
||||
assert(false);
|
||||
}
|
||||
retval = pthread_mutexattr_settype(&mutexAttribute, PTHREAD_MUTEX_RECURSIVE);
|
||||
if(retval == 0)
|
||||
{
|
||||
retval = pthread_mutex_init(_mutex, &mutexAttribute);
|
||||
if(retval != 0)
|
||||
{
|
||||
//string errMsg = "Error: pthread_mutex_init failed: " + string(strerror(retval));
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//string errMsg = "Error: pthread_mutexattr_settype failed: " + string(strerror(retval));
|
||||
assert(false);
|
||||
}
|
||||
|
||||
pthread_mutexattr_destroy(&mutexAttribute);*/
|
||||
pthread_mutexattr_destroy(&mutexAttribute);*/
|
||||
}
|
||||
|
||||
ReferenceCountingLock::~ReferenceCountingLock()
|
||||
@@ -46,54 +46,55 @@ ReferenceCountingLock::~ReferenceCountingLock()
|
||||
|
||||
bool ReferenceCountingLock::acquire(int64 /*msecs*/)
|
||||
{
|
||||
_mutex.lock();
|
||||
return true;
|
||||
/* struct timespec deltatime;
|
||||
if(msecs > 0)
|
||||
{
|
||||
deltatime.tv_sec = msecs / 1000;
|
||||
deltatime.tv_nsec = (msecs % 1000) * 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
deltatime.tv_sec = 0;
|
||||
deltatime.tv_nsec = 0;
|
||||
}
|
||||
_mutex.lock();
|
||||
return true;
|
||||
/* struct timespec deltatime;
|
||||
if(msecs > 0)
|
||||
{
|
||||
deltatime.tv_sec = msecs / 1000;
|
||||
deltatime.tv_nsec = (msecs % 1000) * 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
deltatime.tv_sec = 0;
|
||||
deltatime.tv_nsec = 0;
|
||||
}
|
||||
|
||||
int32 retval = pthread_mutex_timedlock(_mutex, &deltatime);
|
||||
if(retval == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
*/
|
||||
int32 retval = pthread_mutex_timedlock(_mutex, &deltatime);
|
||||
if(retval == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
|
||||
void ReferenceCountingLock::release()
|
||||
{
|
||||
_mutex.unlock();
|
||||
/* int retval = pthread_mutex_unlock(_mutex);
|
||||
if(retval != 0)
|
||||
{
|
||||
//string errMsg = "Error: pthread_mutex_unlock failed: " + string(strerror(retval));
|
||||
//TODO do something?
|
||||
}*/
|
||||
_mutex.unlock();
|
||||
/* int retval = pthread_mutex_unlock(_mutex);
|
||||
if(retval != 0)
|
||||
{
|
||||
//string errMsg = "Error: pthread_mutex_unlock failed: " + string(strerror(retval));
|
||||
//TODO do something?
|
||||
}*/
|
||||
}
|
||||
|
||||
// TODO use atomic primitive impl.
|
||||
int ReferenceCountingLock::increment()
|
||||
{
|
||||
Lock guard(_countMutex);
|
||||
++_references;
|
||||
return _references;
|
||||
Lock guard(_countMutex);
|
||||
++_references;
|
||||
return _references;
|
||||
}
|
||||
|
||||
int ReferenceCountingLock::decrement()
|
||||
{
|
||||
Lock guard(_countMutex);
|
||||
--_references;
|
||||
return _references;
|
||||
Lock guard(_countMutex);
|
||||
--_references;
|
||||
return _references;
|
||||
}
|
||||
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+91
-91
@@ -38,131 +38,131 @@ using namespace epics::pvAccess;
|
||||
int
|
||||
Wildcard::wildcardfit (const char *wildcard, const char *test)
|
||||
{
|
||||
int fit = 1;
|
||||
|
||||
for (; ('\000' != *wildcard) && (1 == fit) && ('\000' != *test); wildcard++)
|
||||
int fit = 1;
|
||||
|
||||
for (; ('\000' != *wildcard) && (1 == fit) && ('\000' != *test); wildcard++)
|
||||
{
|
||||
switch (*wildcard)
|
||||
switch (*wildcard)
|
||||
{
|
||||
case '[':
|
||||
wildcard++; /* leave out the opening square bracket */
|
||||
fit = set (&wildcard, &test);
|
||||
/* we don't need to decrement the wildcard as in case */
|
||||
/* of asterisk because the closing ] is still there */
|
||||
break;
|
||||
wildcard++; /* leave out the opening square bracket */
|
||||
fit = set (&wildcard, &test);
|
||||
/* we don't need to decrement the wildcard as in case */
|
||||
/* of asterisk because the closing ] is still there */
|
||||
break;
|
||||
case '?':
|
||||
test++;
|
||||
break;
|
||||
test++;
|
||||
break;
|
||||
case '*':
|
||||
fit = asterisk (&wildcard, &test);
|
||||
/* the asterisk was skipped by asterisk() but the loop will */
|
||||
/* increment by itself. So we have to decrement */
|
||||
wildcard--;
|
||||
break;
|
||||
fit = asterisk (&wildcard, &test);
|
||||
/* the asterisk was skipped by asterisk() but the loop will */
|
||||
/* increment by itself. So we have to decrement */
|
||||
wildcard--;
|
||||
break;
|
||||
default:
|
||||
fit = (int) (*wildcard == *test);
|
||||
test++;
|
||||
fit = (int) (*wildcard == *test);
|
||||
test++;
|
||||
}
|
||||
}
|
||||
while ((*wildcard == '*') && (1 == fit))
|
||||
/* here the teststring is empty otherwise you cannot */
|
||||
/* leave the previous loop */
|
||||
wildcard++;
|
||||
return (int) ((1 == fit) && ('\0' == *test) && ('\0' == *wildcard));
|
||||
while ((*wildcard == '*') && (1 == fit))
|
||||
/* here the teststring is empty otherwise you cannot */
|
||||
/* leave the previous loop */
|
||||
wildcard++;
|
||||
return (int) ((1 == fit) && ('\0' == *test) && ('\0' == *wildcard));
|
||||
}
|
||||
|
||||
int
|
||||
Wildcard::set (const char **wildcard, const char **test)
|
||||
{
|
||||
int fit = 0;
|
||||
int negation = 0;
|
||||
int at_beginning = 1;
|
||||
int fit = 0;
|
||||
int negation = 0;
|
||||
int at_beginning = 1;
|
||||
|
||||
if ('!' == **wildcard)
|
||||
if ('!' == **wildcard)
|
||||
{
|
||||
negation = 1;
|
||||
(*wildcard)++;
|
||||
negation = 1;
|
||||
(*wildcard)++;
|
||||
}
|
||||
while ((']' != **wildcard) || (1 == at_beginning))
|
||||
while ((']' != **wildcard) || (1 == at_beginning))
|
||||
{
|
||||
if (0 == fit)
|
||||
if (0 == fit)
|
||||
{
|
||||
if (('-' == **wildcard)
|
||||
&& ((*(*wildcard - 1)) < (*(*wildcard + 1)))
|
||||
&& (']' != *(*wildcard + 1))
|
||||
&& (0 == at_beginning))
|
||||
if (('-' == **wildcard)
|
||||
&& ((*(*wildcard - 1)) < (*(*wildcard + 1)))
|
||||
&& (']' != *(*wildcard + 1))
|
||||
&& (0 == at_beginning))
|
||||
{
|
||||
if (((**test) >= (*(*wildcard - 1)))
|
||||
&& ((**test) <= (*(*wildcard + 1))))
|
||||
if (((**test) >= (*(*wildcard - 1)))
|
||||
&& ((**test) <= (*(*wildcard + 1))))
|
||||
{
|
||||
fit = 1;
|
||||
(*wildcard)++;
|
||||
fit = 1;
|
||||
(*wildcard)++;
|
||||
}
|
||||
}
|
||||
else if ((**wildcard) == (**test))
|
||||
else if ((**wildcard) == (**test))
|
||||
{
|
||||
fit = 1;
|
||||
fit = 1;
|
||||
}
|
||||
}
|
||||
(*wildcard)++;
|
||||
at_beginning = 0;
|
||||
(*wildcard)++;
|
||||
at_beginning = 0;
|
||||
}
|
||||
if (1 == negation)
|
||||
/* change from zero to one and vice versa */
|
||||
fit = 1 - fit;
|
||||
if (1 == fit)
|
||||
(*test)++;
|
||||
if (1 == negation)
|
||||
/* change from zero to one and vice versa */
|
||||
fit = 1 - fit;
|
||||
if (1 == fit)
|
||||
(*test)++;
|
||||
|
||||
return (fit);
|
||||
return (fit);
|
||||
}
|
||||
|
||||
int
|
||||
Wildcard::asterisk (const char **wildcard, const char **test)
|
||||
{
|
||||
/* Warning: uses multiple returns */
|
||||
int fit = 1;
|
||||
/* Warning: uses multiple returns */
|
||||
int fit = 1;
|
||||
|
||||
/* erase the leading asterisk */
|
||||
(*wildcard)++;
|
||||
while (('\000' != (**test))
|
||||
&& (('?' == **wildcard)
|
||||
|| ('*' == **wildcard)))
|
||||
{
|
||||
if ('?' == **wildcard)
|
||||
(*test)++;
|
||||
(*wildcard)++;
|
||||
}
|
||||
/* Now it could be that test is empty and wildcard contains */
|
||||
/* aterisks. Then we delete them to get a proper state */
|
||||
while ('*' == (**wildcard))
|
||||
/* erase the leading asterisk */
|
||||
(*wildcard)++;
|
||||
|
||||
if (('\0' == (**test)) && ('\0' != (**wildcard)))
|
||||
return (fit = 0);
|
||||
if (('\0' == (**test)) && ('\0' == (**wildcard)))
|
||||
return (fit = 1);
|
||||
else
|
||||
while (('\000' != (**test))
|
||||
&& (('?' == **wildcard)
|
||||
|| ('*' == **wildcard)))
|
||||
{
|
||||
/* Neither test nor wildcard are empty! */
|
||||
/* the first character of wildcard isn't in [*?] */
|
||||
if (0 == wildcardfit(*wildcard, (*test)))
|
||||
{
|
||||
do
|
||||
{
|
||||
(*test)++;
|
||||
/* skip as much characters as possible in the teststring */
|
||||
/* stop if a character match occurs */
|
||||
while (((**wildcard) != (**test))
|
||||
&& ('[' != (**wildcard))
|
||||
&& ('\0' != (**test)))
|
||||
(*test)++;
|
||||
}
|
||||
while ((('\0' != **test))?
|
||||
(0 == wildcardfit (*wildcard, (*test)))
|
||||
: (0 != (fit = 0)));
|
||||
}
|
||||
if (('\0' == **test) && ('\0' == **wildcard))
|
||||
fit = 1;
|
||||
return (fit);
|
||||
if ('?' == **wildcard)
|
||||
(*test)++;
|
||||
(*wildcard)++;
|
||||
}
|
||||
/* Now it could be that test is empty and wildcard contains */
|
||||
/* aterisks. Then we delete them to get a proper state */
|
||||
while ('*' == (**wildcard))
|
||||
(*wildcard)++;
|
||||
|
||||
if (('\0' == (**test)) && ('\0' != (**wildcard)))
|
||||
return (fit = 0);
|
||||
if (('\0' == (**test)) && ('\0' == (**wildcard)))
|
||||
return (fit = 1);
|
||||
else
|
||||
{
|
||||
/* Neither test nor wildcard are empty! */
|
||||
/* the first character of wildcard isn't in [*?] */
|
||||
if (0 == wildcardfit(*wildcard, (*test)))
|
||||
{
|
||||
do
|
||||
{
|
||||
(*test)++;
|
||||
/* skip as much characters as possible in the teststring */
|
||||
/* stop if a character match occurs */
|
||||
while (((**wildcard) != (**test))
|
||||
&& ('[' != (**wildcard))
|
||||
&& ('\0' != (**test)))
|
||||
(*test)++;
|
||||
}
|
||||
while ((('\0' != **test))?
|
||||
(0 == wildcardfit (*wildcard, (*test)))
|
||||
: (0 != (fit = 0)));
|
||||
}
|
||||
if (('\0' == **test) && ('\0' == **wildcard))
|
||||
fit = 1;
|
||||
return (fit);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user