Initial commit

This commit is contained in:
2017-09-19 08:27:10 +02:00
commit 3b2e49f7b7
138 changed files with 199299 additions and 0 deletions

1
src/PyCafe.cpp Symbolic link
View File

@@ -0,0 +1 @@
PyCafe3.cpp

119252
src/PyCafe3.cpp Normal file

File diff suppressed because it is too large Load Diff

3919
src/cafe.cpp Normal file

File diff suppressed because it is too large Load Diff

1873
src/cafeCache.cpp Normal file

File diff suppressed because it is too large Load Diff

38
src/cafeEnumStrings.cpp Normal file
View File

@@ -0,0 +1,38 @@
///
/// \file cafeEnumStrings.h
/// \author Jan Chrin, PSI
/// \date Release: February 2015
/// \version CAFE 1.0.0
///
#include "cafeEnum.h"
#include "enumStrings.h"
template<> char const * enumStrings<CAFENUM::ChannelWaitForResponsePolicyKind>::data[]
= {"CAFENUM::WAIT", "CAFENUM::NO_WAIT"};
template<> char const * enumStrings<CAFENUM::ChannelRequestDataTypePolicyKind>::data[]
= {"CAFENUM::NATIVE_DATATYPE", "CAFENUM::LOWEST_DATATYPE"};
template<> char const * enumStrings<CAFENUM::ChannelFlushSendBufferPolicyKind>::data[]
= {"CAFENUM::WITH_FLUSH_IO","CAFENUM::WITH_PEND_IO","CAFENUM::WITH_PEND_EVENT", "CAFENUM::WITH_POLL"};
template<> char const * enumStrings<CAFENUM::ChannelWhenToFlushSendBufferPolicyKind>::data[]
= {"CAFENUM::FLUSH_AFTER_EACH_MESSAGE","CAFENUM::FLUSH_DESIGNATED_TO_CLIENT"};
template<> char const * enumStrings<CAFENUM::ChannelRequestPolicyKind>::data[]
= {"CAFENUM::WITHOUT_CALLBACK","CAFENUM::WITH_CALLBACK_DEFAULT","CAFENUM::WITH_CALLBACK_USER_SUPPLIED"};
template<> char const * enumStrings<CAFENUM::DBR_TYPE>::data[]
= {"CAFENUM::DBR_PRIMITIVE","CAFENUM::DBR_STS","CAFENUM::DBR_TIME", "CAFENUM::DBR_GR",
"CAFENUM::DBR_CTRL","CAFENUM::DBR_PUT", "CAFENUM::DBR_STSACK","CAFENUM::DBR_CLASS",
"CAFENUM::DBR_OTHER"};
template<> char const * enumStrings<CAFENUM::StatusMessageKind>::data[]
= {"CAFENUM::NO_MESSAGE","CAFENUM::PRE_REQUEST","CAFENUM::FROM_REQUEST","CAFENUM::FROM_PEND",
"CAFENUM::FROM_CALLBACK"};
template<> char const * enumStrings<CAFENUM::CallbackProgressKind>::data[]
= {"CAFENUM::NOT_INITIATED","CAFENUM::PENDING","CAFENUM::COMPLETE"};

1528
src/cafeGroup.cpp Normal file

File diff suppressed because it is too large Load Diff

383
src/cafeService.cpp Normal file
View File

@@ -0,0 +1,383 @@
///
/// \file cafeService.cpp
/// \author Jan Chrin, PSI
/// \date Release July: 2017
/// \version CAFE 1.3.0
///
#include <cafe.h>
#if HAVE_ZEROMQ
#include <zhelpers.h>
#endif
string globalZmqStream="";
string contentsS="";
unsigned long nCBs=0;
int CAFE::calcDBPMStatus(int statusDATA, int statusVALID, string valueVALID) {
if (statusDATA != ICAFE_NORMAL) {
return statusDATA;
}
else if (statusVALID != ICAFE_NORMAL) {
return statusVALID;
}
else if ( valueVALID.compare("VALID")!=0) {
//cout << "calcDBPMStatus " << valueVALID << endl;
return ECAFE_BPM_DATA_IS_INVALID;
}
return ICAFE_NORMAL;
}
int CAFE::prepareDBPM(vector<string> &_glist, vector<unsigned int> &_hV, std::vector<std::string> &dev, std::vector<float> &pos ) {
int localStatus=ICAFE_NORMAL;
if (!CAFE::isCollection("cDBPM")) {
localStatus=CAFE::loadCollectionsFromXML("cNodes.xml");
if (localStatus != ICAFE_NORMAL) {return localStatus;}
}
if (!CAFE::isGroup("gDBPM")) {
localStatus=CAFE::loadGroupsFromXML("gDBPM.xml");
if (localStatus != ICAFE_NORMAL) {return localStatus;}
}
CAFE::groupMemberList("gDBPM", _glist);
CAFE::devicePositionV("cDBPM", dev, pos);
/*
std::map<float, std::string>::iterator iter;
std::map<float, std::string> posDev;
CAFE::devicePositionMap("cDBPM", posDev);
for (iter =posDev.begin(); iter != posDev.end(); ++iter) {
//cout << "position= " << iter->first << " Dev " << iter->second << endl;
pos.push_back(iter->first) ;
dev.push_back(iter->second) ;
}
*/
CAFE::openPrepare();
CAFE::open(_glist, _hV);
CAFE::openNowAndWait(2.0); //wait for specified time, here 2.0 seconds
//CAFE::printDisconnectedHandles();
/*
for (int ij=0; ij<5; ++ij) {
if (!initCallbackComplete(_hV) ) {
cout << "Will wait for " << 1+ij << " SECONDS " << endl;
CAFE::openNowAndWait(1+ij);
}
}
*/
std::size_t found;
std::string attribute;
vector<int> statusV;
//CAFE::get(_hV, statusV); // do Get just to warm up
//CAFE::flushNow();
CAFE::openMonitorPrepare();
for (std::size_t i=0; i < _hV.size(); ++i) {
handleHelper.getChannelAttribute(_hV[i], attribute);
found=attribute.find("VALID");
//if (found != std::string::npos) {
if (handleHelper.getNmonitorData(_hV[i])==0) {
CAFE::monitorStart(_hV[i]);
}
//}
}
//Give plenty of time for all callback functions to report
CAFE::openMonitorNowAndWait(1.0);
return localStatus;
}
int CAFE::prepareDBPM(vector<string> &_glist, vector<unsigned int> &_hV, std::map<float, std::string> &posDev) {
int localStatus=ICAFE_NORMAL;
if (!CAFE::isCollection("cDBPM")) {
localStatus=CAFE::loadCollectionsFromXML("cNodes.xml");
if (localStatus != ICAFE_NORMAL) {return localStatus;}
}
if (!CAFE::isGroup("gDBPM")) {
localStatus=CAFE::loadGroupsFromXML("gDBPM.xml");
if (localStatus != ICAFE_NORMAL) {return localStatus;}
}
CAFE::groupMemberList("gDBPM", _glist);
CAFE::openPrepare();
CAFE::open(_glist, _hV);
//open BPM Reference
CAFE::openNowAndWait(1.5); //wait for specified time, here 1.5 seconds
std::size_t found;
std::string attribute;
CAFE::openMonitorPrepare();
for (std::size_t i=0; i < _hV.size(); ++i) {
handleHelper.getChannelAttribute(_hV[i], attribute);
found=attribute.find("VALID");
//if (found != std::string::npos) {
if (handleHelper.getNmonitorData(_hV[i])==0) {
CAFE::monitorStart(_hV[i]);
}
//}
}
CAFE::openMonitorNowAndWait(1.5);
std::map<float, std::string>::iterator pos;
CAFE::devicePositionMap("cDBPM", posDev);
//for (pos =posDev.begin(); pos != posDev.end(); ++pos) {
// cout << "position= " << pos->first << " Dev " << pos->second << endl;
//}
// cout << " END " << endl;
return localStatus;
}
int CAFE::readDBPMOffsets(DBPMKeeper &dbpm) {
vector<unsigned int> hx;
vector<unsigned int> hy;
vector<string> devOffsetX;
vector<string> devOffsetY;
devOffsetX.clear();
devOffsetY.clear();
devOffsetX.reserve(dbpm.device.size());
devOffsetY.reserve(dbpm.device.size());
string devOffx="";
string devOffy="";
for (size_t i=0; i<dbpm.device.size(); ++i) {
devOffx=dbpm.device[i];
devOffx.append(":OFFS-X");
devOffy=dbpm.device[i];
devOffy.append(":OFFS-Y");
devOffsetX.push_back(devOffx);
devOffsetY.push_back(devOffy);
}
CAFE::openPrepare();
CAFE::open(devOffsetX, hx);
CAFE::open(devOffsetY, hy);
CAFE::openNowAndWait(1.0);
vector<int> statusV;
int status1=CAFE::getScalars(hx, dbpm.offs_x, statusV);
statusV.clear();
int status2=CAFE::getScalars(hy, dbpm.offs_y, statusV);
CAFE::closeHandles(hx);
CAFE::closeHandles(hy);
return max(status1, status2);
}
int CAFE::getDBPM(DBPMKeeper &dbpm) {
if(MUTEX){cafeMutex.lock();}
cout << "-------------------------------------------MUTEX LOCKED " << endl;
dbpm.x.clear();
dbpm.y.clear();
dbpm.q.clear();
dbpm.energy.clear();
dbpm.x.reserve(dbpm.nDBPM);
dbpm.y.reserve(dbpm.nDBPM);
dbpm.q.reserve(dbpm.nDBPM);
dbpm.energy.reserve(dbpm.nDBPM);
for (size_t i=0; i<dbpm.nDBPM; ++i) {
dbpm.pvd[dbpm.xIdx+i].set(0);
dbpm.pvd[dbpm.yIdx+i].set(0);
dbpm.pvd[dbpm.qIdx+i].set(0);
dbpm.pvd[dbpm.xValidIdx+i].set((std::string) "INVALID");
dbpm.pvd[dbpm.yValidIdx+i].set((std::string) "INVALID");
dbpm.pvd[dbpm.qValidIdx+i].set((std::string) "INVALID");
}
if (!dbpm.isBS){
//From Channel Access:
dbpm.status=CAFE::getCachePVArray(dbpm.handle, dbpm.pvd);
}
else {
#if HAVE_ZEROMQ
s_dump(dbpm);
if (dbpm.status > ICAFE_LINUX_ERROR) {
cout << "status from cafeService.cpp -------------------------------------------------> " << dbpm.status << endl;
}
#endif
}
dbpm.isAllXOK=true;
dbpm.isAllYOK=true;
dbpm.isAllQOK=true;
dbpm.isAllEOK=true;
dbpm.isAllOK =true;
DBPMData ddx, ddy, ddq, dde;
for (size_t i=0; i<dbpm.nDBPM; ++i) {
ddx.val=dbpm.pvd[dbpm.xIdx+i].getAsDouble();
ddx.ets=dbpm.pvd[dbpm.xIdx+i].getEpicsTimeStamp();
if (!dbpm.isBS) {
ddx.status=CAFE::calcDBPMStatus(dbpm.pvd[dbpm.xIdx+i].getStatus(), dbpm.pvd[dbpm.xValidIdx+i].getStatus(), dbpm.pvd[dbpm.xValidIdx+i].getAsString());
}
else {
ddx.status=CAFE::calcDBPMStatus(ICAFE_NORMAL, ICAFE_NORMAL, dbpm.pvd[dbpm.xValidIdx+i].getAsString());
//cout << " IDX " << dbpm.xValidIdx+i << "STATUS " << dbpm.pvd[dbpm.xValidIdx+i].getAsString() << endl;
//cout << "ddx.status " << ddx.status << endl;
}
if (dbpm.isAllXOK && ddx.status != ICAFE_NORMAL) {
dbpm.isAllXOK=false;
dbpm.isAllOK=false;
}
ddy.val=dbpm.pvd[dbpm.yIdx+i].getAsDouble();
ddy.ets=dbpm.pvd[dbpm.yIdx+i].getEpicsTimeStamp();
if (!dbpm.isBS) {
ddy.status=CAFE::calcDBPMStatus(dbpm.pvd[dbpm.yIdx+i].getStatus(), dbpm.pvd[dbpm.yValidIdx+i].getStatus(), dbpm.pvd[dbpm.yValidIdx+i].getAsString()) ;
}
else {
ddy.status=CAFE::calcDBPMStatus(ICAFE_NORMAL, ICAFE_NORMAL, dbpm.pvd[dbpm.yValidIdx+i].getAsString()) ;
}
if (dbpm.isAllYOK && ddy.status != ICAFE_NORMAL) {
dbpm.isAllYOK=false;
dbpm.isAllOK=false;
}
ddq.val=dbpm.pvd[dbpm.qIdx+i].getAsDouble();
ddq.ets=dbpm.pvd[dbpm.qIdx+i].getEpicsTimeStamp();
if (!dbpm.isBS) {
ddq.status=CAFE::calcDBPMStatus(dbpm.pvd[dbpm.qIdx+i].getStatus(), dbpm.pvd[dbpm.qValidIdx+i].getStatus(), dbpm.pvd[dbpm.qValidIdx+i].getAsString());
}
else {
ddq.status=CAFE::calcDBPMStatus(ICAFE_NORMAL, ICAFE_NORMAL,dbpm.pvd[dbpm.qValidIdx+i].getAsString());
}
if (dbpm.isAllQOK && ddq.status != ICAFE_NORMAL) {
dbpm.isAllQOK=false;
dbpm.isAllOK =false;
}
dde.val =dbpm.pvd[dbpm.energyIdx+i].getAsDouble();
dde.ets =dbpm.pvd[dbpm.energyIdx+i].getEpicsTimeStamp();
dde.status=dbpm.pvd[dbpm.energyIdx+i].getStatus();
if (dbpm.isAllEOK && dbpm.status != ICAFE_NORMAL) {
dbpm.isAllEOK=false;
dbpm.isAllOK=false;
}
dbpm.x.push_back(ddx);
dbpm.y.push_back(ddy);
dbpm.q.push_back(ddq);
dbpm.energy.push_back(dde);
//}
}
if(MUTEX){cafeMutex.unlock();}
cout << "-------------------------------------------MUTEX UNLOCKED " << endl;
return dbpm.status;
}

3066
src/cafeVectors.cpp Normal file

File diff suppressed because it is too large Load Diff

536
src/cafeXML.cpp Normal file
View File

@@ -0,0 +1,536 @@
///
/// \file cafeXML.cc
/// \author Jan Chrin, PSI
/// \date November 2014
/// \version CAFE 1.0.0
///
#include <iostream>
#include <fstream>
#include <ctime>
#include "cafe.h"
#include <boost/date_time/posix_time/posix_time.hpp>
#include "loadCollectionXMLParser.h"
#include "loadGroupXMLParser.h"
#include "restorePVGroupXMLParser.h"
#if HAVE_LIBQTXML
using namespace boost::posix_time;
/**
* \brief loadCollections from XML \n
* Routine first searches the given directory before CAFE_XML_PATH environment variable
* \param collectionFile input: name of collection file
* \return ICAFE_NORMAL if OK else ECAFE_LOAD_COLLECTION;
*/
int CAFE::loadCollectionsFromXML(const char * collectionFile) {
#define __METHOD__ "CAFE::loadCollectionsFromXML(char * collectionFile)"
//First check for existence of file in current directory
//before searching in CAFE_XML_PATH
QFile * file;
file = new QFile(collectionFile);
if (!file->exists()) {
std::string envS;
char * env = getenv("CAFE_XML_PATH");
env == NULL ? envS=std::string(".") : envS=std::string(env);
envS.append("/"); //("/Collections/");
envS.append(collectionFile);
file = new QFile(envS.c_str());
if (!file->exists()) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "envS=" << envS << endl;
cout << "COLLECTION FILE " << collectionFile << " NOT FOUND " << endl;
cout << "IN THE CURRENT (OR GIVEN) DIRECTORY" << endl;
if (env != NULL) {
cout << "NOR IN CAFE_XML_PATH/=" << endl;
cout << env << endl;
}
else {
cout << "OPTIONAL ENVIRONMENT VARIABLE CAFE_XML_PATH IS UNDEFINED" << endl;
}
delete file;
return ECAFE_LOAD_COLLECTION;
}
}
else {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << " COLLECTION LOADED FROM CURRENT (OR GIVEN) DIRECTORY" << endl;
}
loadCollectionXMLParser handler;
QXmlInputSource source(file);
QXmlSimpleReader reader;
reader.setContentHandler(&handler);
reader.setFeature("http://trolltech.com/xml/features/report-whitespace-only-CharData", false);
bool isOK = reader.parse(source);
if (!isOK) {
return ECAFE_LOAD_COLLECTION;
}
deviceCollectionV=handler.deviceCollectionV;
//cout << deviceCollectionV[0].getCMembers()[0].devicePosition << endl;
//cout << deviceCollectionV[1].getCMembers()[0].devicePosition << endl;
return ICAFE_NORMAL;
#undef __METHOD__
}
/**
* \brief loadGroups from XML \n
* Routine first searches the given directory before CAFE_XML_PATH environment variable
* \param groupFile input: name of group file
* \return ICAFE_NORMAL if OK else ECAFE_LOAD_GROUP;
*/
int CAFE::loadGroupsFromXML (const char * groupFile) {
#define __METHOD__ "CAFE::loadGroupsFromXML(char * groupFile)"
int localStatus=ICAFE_NORMAL;
QFile * file;
file = new QFile(groupFile);
if (!file->exists()) {
std::string envS;
char * env = getenv("CAFE_XML_PATH");
env == NULL ? envS=std::string(".") : envS=std::string(env);
envS.append("/"); //envS.append("/Groups/");
envS.append(groupFile);
file = new QFile(envS.c_str());
if (!file->exists()) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "GROUP FILE " << groupFile << " NOT FOUND " << endl;
cout << "NEITHER IN THE CURRENT (OR GIVEN) DIRECTORY" << endl;
if (env != NULL) {
cout << "NOR IN CAFE_XML_PATH/=" << endl;
cout << env << endl;
}
else {
cout << "OPTIONAL ENVIRONMENT VARIABLE CAFE_XML_PATH IS UNDEFINED" << endl;
}
delete file;
return ECAFE_LOAD_GROUP;
}
}
else {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << " GROUPS LOADED FROM CURRENT (OR GIVEN) DIRECTORY" << endl;
}
loadGroupXMLParser handler;
QXmlInputSource source(file);
QXmlSimpleReader reader;
reader.setContentHandler(&handler);
reader.setFeature("http://trolltech.com/xml/features/report-whitespace-only-CharData", false);
bool isOK = reader.parse(source);
if (!isOK) {
return ECAFE_LOAD_GROUP;
}
for (std::vector<deviceGroup>::const_iterator group=handler.groups.begin();
group!=handler.groups.end();++group) {
if(isGroup((char *)(*group).getName().c_str())) {
localStatus=ECAFE_GROUP_PREV_DEF;
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
std::cout << "FAILED TO LOAD GROUP WITH NAME(ID) " << (*group).getName() << std::endl;
std::cout << "AS GROUP WITH THIS NAME ALREADY EXISTS " << std::endl;
cafeStatus.report(ECAFE_GROUP_PREV_DEF);
std::cout << "WE CONTINUE WITH LOADING ANY REMAINING GROUPS " << std::endl;
continue;
}
PVGroup pg;
vector<std::string> pvList; pvList.clear();
strcpy(pg.name,(*group).getName().c_str());
//Loop round all collections;
vector<collectionInGroup> cg; cg.clear();
cg=(*group).getCollections();
for (size_t i=0; i <cg.size(); ++i) {
//cout << cg[i].id << " " << cg[i].attrib << " " << endl; //cg[i].collectiveType << endl;
if(!isCollection((char *)cg[i].id.c_str())) {
localStatus=ECAFE_UNKNOWN_COLLECTION;
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
std::cout << "FAILED TO LOAD COLLECTION WITH NAME(ID) " << cg[i].id << std::endl;
std::cout << "AS COLLECTION WITH THIS NAME DOES NOT EXIST " << std::endl;
cafeStatus.report(ECAFE_UNKNOWN_COLLECTION);
std::cout << "WE CONTINUE LOADING GROUP WITH ANY REMAINING COLLECTIONS " << std::endl;
continue;
}
// Fill Group
vector<string> members;
collectionFetch((char *)cg[i].id.c_str(),members);
for(size_t j=0; j<members.size(); ++j) {
string da=members[j] + deviceAttributeDeliminator + cg[i].attrib;
pvList.push_back(da);
}
}
//Loop round all members
vector<string> cm= (*group).getXMLMembers();
for (size_t i=0; i <cm.size(); ++i) {
pvList.push_back(cm[i]);
}
if (pvList.size()>0 ) {
groupDefine((const char *) (*group).getName().c_str(), pvList);
}
else {
cout << "GROUP " << (*group).getName().c_str()
<< " NOT DEFINED AS IT HAS NO MEMBERS! " << endl;
}
}
return ICAFE_NORMAL;
#undef __METHOD__
}
/**
* \brief restoreFromXML \n
* Reads a PVGroup XML file and writes values to EPICS variables \n
* from the directory defined the by CAFE_SAR_PATH environment variable
* \param snapshotFile input: char * snapshotFile
* \return ICAFE_NORMAL if OK else first ECAFE/ICAFE error encountered
*/
int CAFE::restoreFromXML (const char * snapshotFile) {
#define __METHOD__ "CAFE::restoreFromXML(char * snapshotFile)"
int localStatus=ICAFE_NORMAL;
unsigned int gh;
string ssf=snapshotFile;
QFile * file;
file = new QFile(snapshotFile);
if (!file->exists()) {
std::string envS;
char * env = getenv("CAFE_SAR_PATH");
env == NULL ? envS=std::string(".") : envS=std::string(env);
envS.append("/");
envS.append(snapshotFile);
file = new QFile(envS.c_str());
if (!file->exists()) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "PVGROUP FILE " << snapshotFile << " NOT FOUND " << endl;
cout << "NEITHER IN THE CURRENT (OR GIVEN) DIRECTORY NOR IN CAFE_SAR_PATH=" << envS << endl;
return ECAFE_LOAD_GROUP;
}
ssf=envS;
}
else {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << " PVGROUP LOADED FROM CURRENT (OR GIVEN) DIRECTORY" << endl;
}
QXmlInputSource source(file);
restorePVGroupXMLParser handler;
QXmlSimpleReader reader;
reader.setContentHandler(&handler);
reader.setFeature("http://trolltech.com/xml/features/report-whitespace-only-CharData", false);
bool isOK = reader.parse(source);
if (!isOK) {
return ECAFE_LOAD_GROUP;
}
PVGroup pvg = handler.group;
string gNameNew= pvg.name;
gNameNew.append("Restore");
strcpy(pvg.name,gNameNew.c_str());
PVGroupV.push_back(pvg);
localStatus=groupOpen(pvg, gh);
if (localStatus != ICAFE_NORMAL) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "GROUP OPEN REPORTS FOLLOWING ERROR " << endl;
for (unsigned int i=0; i<pvg.npv; ++i ) {
if(pvg.pvdata[i].status !=ICAFE_NORMAL) {
pvg.pvdata[i].print();
}
}
}
//Now parse a second time to read in values!
restorePVGroupXMLParser handler2;
QXmlSimpleReader reader2;
reader2.setContentHandler(&handler2);
reader2.setFeature("http://trolltech.com/xml/features/report-whitespace-only-CharData", false);
QFile file2(ssf.c_str());
QXmlInputSource source2(&file2);
isOK = reader2.parse(source2);
if (!isOK) {
return ECAFE_LOAD_GROUP;
}
pvg =handler2.group;
pvg.groupHandle=gh;
strcpy(pvg.name,gNameNew.c_str());
localStatus=groupSet(gh, pvg);
if (localStatus != ICAFE_NORMAL) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "GROUP SET REPORTS FOLLOWING ERROR " << endl;
for (unsigned int i=0; i<pvg.npv; ++i ) {
if(pvg.pvdata[i].status !=ICAFE_NORMAL) {
pvg.pvdata[i].print();
}
}
}
groupClose(gh);
return localStatus;
#undef __METHOD__
}
#endif
/**
* \brief snapshot2XML \n
* Takes a PVGroup snapshot and writes data to a timestamped file \n
* in the directory defined the by CAFE_SAR_PATH environment variable
* \param pg input: PVGroup pg
* \return ICAFE_NORMAL if OK else first ECAFE/ICAFE error encountered
*/
int CAFE::snapshot2XML (PVGroup pg) {
#define __METHOD__ "CAFE::snapshot2XML(PVGroup pg)"
std::string s="<cafe:config>\n";
s.append("<cafe:group id=\"");
std::string gname=pg.getName();
s.append(gname);
s.append("\">\n");
char sBuffer[60]; char sBufferNPV[60];
int overallStatus=groupGet(pg.getGroupHandle(),pg);
PVDataHolder * pvd = pg.getPVData();
unsigned int hl=0;
s.append("<cafe:npv> ");
sprintf(sBufferNPV,"%d", pg.npv);
s.append(sBufferNPV);
s.append(" </cafe:npv>\n");
//First determine maximum pv size
unsigned short maxL=0; string sn="";
for (unsigned int j=0; j<pg.getNPV(); ++j) {
sn=pvd[j].getPV();
if(sn.size() > maxL) maxL=sn.size()+0;
}
for (unsigned int j=0; j<pg.getNPV(); ++j) {
s.append("<cafe:member><cafe:name> ");
s.append(pvd[j].getPV());
sn=pvd[j].getPV();
s.append((maxL-sn.size()),' ');
s.append(" </cafe:name><cafe:nelem> ");
sprintf(sBuffer,"%d", pvd[j].getNelem());
s.append(sBuffer);
s.append(" </cafe:nelem><cafe:val> ");
for (unsigned int i=0; i<pvd[j].getNelem(); ++i) {
s.append(pvd[j].getAsString(i)); s.append(" ");
}
s.append("</cafe:val><cafe:settable> ");
hl=getHandleHelper().getHandleFromPVWithinGroup(pvd[j].getPV(), pg.getGroupHandle() );
ChannelRegalia cr;
getInfo().getChannelRegalia(hl, cr);
if ( cr.getWriteAccess() ) {
s.append("true");} else {
s.append("false");
}
s.append(" </cafe:settable><cafe:status> ");
sprintf(sBuffer,"%d", pvd[j].getStatus());
s.append(sBuffer);
s.append(" </cafe:status>");
s.append("</cafe:member>\n");
}
s.append("</cafe:group>\n</cafe:config>");
time_t now = time(0);
tm *ltm = localtime(&now);
std::string envS;
char * env = getenv("CAFE_SAR_PATH");
env == NULL ? envS=std::string(".") : envS=std::string(env);
envS.append("/");
std::string fsname=envS;
fsname.append(pg.getName());
char s1[255];
sprintf(s1,"_%d_%d_%d_%d:%d:%d", (1900 + ltm->tm_year),(1+ltm->tm_mon),
ltm->tm_mday,ltm->tm_hour,ltm->tm_min,ltm->tm_sec );
fsname.append(s1);
fsname.append(".xml");
ofstream myfile;
myfile.open (fsname.c_str(), ios::out);
myfile << s;
myfile.close();
return overallStatus;
#undef __METHOD__
}
/**
* \brief openGroupXMLFile \n
* Open file given by fileName for writing XML data\n
* \param fileName input: filename to which PVGroup data is written
* \return ICAFE_NORMAL if OK else first ECAFE/ICAFE error encountered
*/
void CAFE::openGroupXMLFile(string fileName) {
ofstream myfile;
myfile.open (fileName.c_str(), ios::out);
std::string s="<cafe:config>\n";
myfile << s;
return myfile.close();
}
/**
* \brief closeGroupXMLFile \n
* Close file given by fileName for writing XML data\n
* \param fileName input: filename to which PVGroup data is written
* \return ICAFE_NORMAL if OK else first ECAFE/ICAFE error encountered
*/
void CAFE::closeGroupXMLFile(string fileName) {
ofstream myfile;
myfile.open (fileName.c_str(), ios::app);
std::string s="</cafe:config>\n";
myfile << s;
return myfile.close();
}
/**
* \brief group2XML \n
* Takes a PVGroup and writes its members to a file \n
* in the directory defined the by CAFE_SAR_PATH environment variable
* \param grpName input: PVGroup
* \param fileName input: filename to which PVGroup data is written
* \return ICAFE_NORMAL if OK else first ECAFE/ICAFE error encountered
*/
int CAFE::group2XML (const char * grpName, string fileName) {
#define __METHOD__ "CAFE::group2XML(const char *grpName, ofstream myfile)"
ofstream myfile;
myfile.open (fileName.c_str(), ios::app);
std::string s= "\n <cafe:group id=\"" ;
std::string gname=grpName;
s.append(gname); s.append("\">\n");
vector<string> lg;
lg.clear();
int status=CAFE::groupMemberList(grpName, lg);
for (int j=0; j<lg.size(); ++j) {
s.append(" <cafe:member> <cafe:name> ");
s.append(lg[j]);
s.append(" </cafe:name> </cafe:member>\n");
}
s.append(" </cafe:group>\n");
myfile << s;
myfile.close();
return status;
#undef __METHOD__
}

View File

@@ -0,0 +1,259 @@
///
/// \file callbackHandlerCreate.cc
/// \author Jan Chrin, PSI
/// \date Release: February 2015
/// \version CAFE 1.0.0
///
#include <cadef.h>
#include <global.h>
#include <policies.h>
#include <conduitFriends.h>
#include <conduitConnectionHandlerArgs.h>
//include <methodCallbacks.h>
#include <granules.h>
#include <handleHelper.h>
using namespace std;
/**
* \brief Callback function for ca_create_channel.
* Modifies Conduit object accordingly
* \param args returns connection handler parameters \n
* i.e. args.chid, args.op{CA_OP_CONN_UP, CA_OP_CONN_DOWN}
*/
void ChannelCreatePolicy::callbackHandlerCreate(struct connection_handler_args args) {
#define __METHOD__ "ChannelCreatePolicy::callbackHandlerCreate"
//Use for debugging
//cout << __METHOD__ << endl;
unsigned int _handle = (unsigned long) ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int)_handle);
if (it_handle != handle_index.end()) {
//cout << (*it_handle).pv << endl;
//cout << "handle= " << (*it_handle).getHandle() << endl; cout << endl;
//Modifies corresponding local variables
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_connectionHandlerArgs(args));
if(MUTEX){cafeMutex.unlock();}
if (args.op == CA_OP_CONN_UP) {
chtype buffer_TIME_Type = dbf_type_to_DBR_TIME(ca_field_type(args.chid)); //DBF_STRING
chtype buffer_CTRL_Type = dbf_type_to_DBR_CTRL(ca_field_type(args.chid));
chtype buffer_PRIMITIVE_TYPE = dbf_type_to_DBR (ca_field_type(args.chid));
//BUFFER FOR GET has DBR_TIME size
//BUFFER FOR PUT has DBR size
//BUFFER FOR CTRL has DBR_CTRL size
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_dataBufferSize_PRIMITIVE(buffer_PRIMITIVE_TYPE));
handle_index.modify(it_handle, change_dataBufferSize_CTRL (buffer_CTRL_Type));
handle_index.modify(it_handle, change_dataBufferSize_TIME (buffer_TIME_Type));
handle_index.modify(it_handle, change_dataBufferSize_STSACK ()); //fixed size DBR_STSACK_STRING
if ( (*it_handle).getAccessRead() != ca_read_access(args.chid) ) {
//cout << " This will only occur if CAFE's access right handler is not used " << endl;
//cout << " accessRightsEventHandler not called BEFORE channelEventHandler! " << endl;
//cout << " FORCING MODIFICATION IN HASH TABLE FOR READ ACCESS=" << ca_read_access(args.chid) << endl;
handle_index.modify(it_handle, change_accessRead(ca_read_access(args.chid)));
}
if ( (*it_handle).getAccessWrite() != ca_write_access(args.chid) ) {
//cout << " This will only occur if CAFE's access right handler is not used " << endl;
//cout << " accessRightsEventHandler not called BEFORE channelEventHandler! " << endl;
//cout << " FORCING MODIFICATION IN HASH TABLE FOR WRITE ACCESS=" << ca_write_access(args.chid) << endl;
handle_index.modify(it_handle, change_accessWrite(ca_write_access(args.chid)));
}
if(MUTEX){cafeMutex.unlock();}
//Set prerequestStatus
ChannelRequestStatus channelRequestStatusGet; int status;
//Call callback methods for all types!!
status=(*it_handle).getCtrlWithCallback(CALLBACK_CAFE::handlerGetCtrl);
channelRequestStatusGet = (*it_handle).getChannelRequestStatusGetCtrl();
channelRequestStatusGet.setRequestStatus (status);
if (status != ECA_NORMAL) {
channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_status(status));
if(MUTEX){cafeMutex.unlock();}
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "getCtrlWithCallback(CALLBACK_CAFE::handlerGetCtrl) reported error:" << endl;
CAFEStatus cafeStatus; cafeStatus.report(status);
}
else {
channelRequestStatusGet.setCallbackKind(true, false); //PENDING NOT_TRIGGERED
}
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_channelRequestStatusGetCtrl(channelRequestStatusGet));
if(MUTEX){cafeMutex.unlock();}
//ca_flush_io();
status=(*it_handle).getSTSACKWithCallback(CALLBACK_CAFE::handlerGetSTSACK);
channelRequestStatusGet = (*it_handle).getChannelRequestStatusGetSTSACK();
channelRequestStatusGet.setRequestStatus (status);
if (status != ECA_NORMAL) {
channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_status(status));
if(MUTEX){cafeMutex.unlock();}
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "getSTSACKWithCallback(CALLBACK_CAFE::handlerGetSTSACK) reported error:" << endl;
CAFEStatus cafeStatus; cafeStatus.report(status);
}
else {
channelRequestStatusGet.setCallbackKind(true, false); //PENDING NOT_TRIGGERED
}
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_channelRequestStatusGetSTSACK(channelRequestStatusGet));
if(MUTEX){cafeMutex.unlock();}
//ca_flush_io();
status=(*it_handle).getClassNameWithCallback(CALLBACK_CAFE::handlerGetClassName);
if ( status != ECA_NORMAL) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "getClassNameWithCallback(CALLBACK_CAFE::handlerGetClassName) reported error:" << endl;
CAFEStatus cafeStatus; cafeStatus.report(status);
}
status=(*it_handle).getWithCallback(CALLBACK_CAFE::handlerGet);
channelRequestStatusGet = (*it_handle).getChannelRequestStatusGet();
channelRequestStatusGet.setRequestStatus (status);
if (status != ECA_NORMAL) {
channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_status(status));
if(MUTEX){cafeMutex.unlock();}
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "getWithCallback(CALLBACK_CAFE::handlerGet) reported error:" << endl;
CAFEStatus cafeStatus; cafeStatus.report(status);
}
else {
channelRequestStatusGet.setCallbackKind(true, false); //PENDING NOT_TRIGGERED
}
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_channelRequestStatusGet(channelRequestStatusGet));
if(MUTEX){cafeMutex.unlock();}
//ca_flush_io();
// Check if any monitors for this channel are to be started.....
// If monitors are to be started, then start the monitors
// pass on handler functions
//
// Loop thru monitor waiting list
// monitor in waiting
vector<MonitorPolicy> mpInWaitingV =(*it_handle).getMonitorPolicyInWaitingVector();
vector<MonitorPolicy>::iterator it;
//Iterate
for (it = mpInWaitingV.begin(); it != mpInWaitingV.end(); ++it) {
//Check start values;
if ((*it).getNelem()==0) {
(*it).setNelem((*it_handle).getChannelRegalia().getNelem());
}
//Check start values;
if ((*it).getDataType()==CAFE_NOT_REQUESTED) {
(*it).setDataType((*it_handle).getChannelRegalia().getDataType());
}
//Check setMask if MASK_CTRL!
status=(*it_handle).monitorStart((*it));
(*it).setStatus(status);
//Add to vector
//check in to vector<monitorMap>
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_monitorPolicyInsert((*it)));
if(MUTEX){cafeMutex.unlock();}
}
//loop
for (it = mpInWaitingV.begin(); it != mpInWaitingV.end(); ++it) {
unsigned int ID=(*it).getID();
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_monitorPolicyInWaitingErase(ID));
if(MUTEX){cafeMutex.unlock();}
}
//loop
} else {
// DIS-CONNECTION (i.e. from a previously connected state)
// Setting Access Rights to boolean false. These will in any
// case be overwritten to false by the access_rights_event_handler
/*
if ( (*it_handle).getAccessRead() != 0 ) {
handle_index.modify(it_handle, change_accessRead(0));
}
if ( (*it_handle).getAccessWrite() != 0 ) {
handle_index.modify(it_handle, change_accessWrite(0));
}
*/
// On disconnection invoke PyCafe Monitor callback
#if HAVE_PYTHON_H
// monitors
vector<MonitorPolicy> mpV =(*it_handle).getMonitorPolicyVector();
vector<MonitorPolicy>::iterator itmp;
//Iterate
for (itmp = mpV.begin(); itmp != mpV.end(); ++itmp) {
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_usrArgs( (unsigned long) (*itmp).getMonitorID() ));
if(MUTEX){cafeMutex.unlock();}
//Add datatypes etc...
//cout << "(*it_handle).PyEventHandler(); " << (*itmp).getMonitorID() << endl;
(*it_handle).PyEventHandler((*itmp).getMonitorID() );
}
#endif
}
}
else {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__
<< " called with an invalid CAFE handle:" << _handle << endl;
cout << "Actually this should not happen and this line should never appear!! " << endl;
}
return;
#undef __METHOD__
}

View File

@@ -0,0 +1,179 @@
//
/// \file callbackHandlerMonitor.cc
/// \author Jan Chrin, PSI
/// \date Release: February 2015
/// \version CAFE 1.0.0
///
#include <cadef.h>
#include "global.h"
#include "policies.h"
#include "conduitFriends.h"
#include "conduitConnectionHandlerArgs.h"
#include "conduitEventHandlerArgs.h"
#include "methodCallbacks.h"
#include "granules.h"
using namespace std;
/**
* \brief Callback function for monitor method is invoked
* with a pointer to the retrieved value
* \param args input: event handler arguments
*/
void MonitorPolicy::callbackHandlerMonitor( struct event_handler_args args) {
#define __METHOD__ "MonitorPolicy::callbackHandlerMonitor"
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) ca_puser(args.chid);// args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int)_handle);
if (it_handle != handle_index.end()) {
//cout << (*it_handle).getPV() << " " << (*it_handle).getHandle() << endl;
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX){cafeMutex.unlock();}
/*
if (args.type < DBR_GR_STRING) {
PVDataHolder pvd(args.count);
(*it_handle).getPVDataHolder(pvd);
//// pvd.print();
cout << "val/D//= " << pvd.getAsString(0) << endl;
}
else if (args.type < DBR_PUT_ACKT) {
PVCtrlHolder pvc(args.count);
(*it_handle).getPVCtrlHolder(pvc);
////pvc.print();
cout << "val/C/= " << pvc.getAsString(0) << endl;
}
*/
}
else {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
return;
#undef __METHOD__
};
/**
* \brief Callback function for monitor method is invoked
* with a pointer to the retrieved value; also fires a user supplied Python callback.
* \param args input: event handler arguments
*/
void MonitorPolicy::PyCallbackHandlerMonitorData (struct event_handler_args args) {
#define __METHOD__ "MonbitorPolicy::PyCallbackHandlerMonitorData"
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) ca_puser(args.chid);// args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int)_handle);
if (it_handle != handle_index.end()) {
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX){cafeMutex.unlock();}
#if HAVE_PYTHON_H
if (args.type < DBR_GR_STRING) {
(*it_handle).PyDataEventHandler();
}
else if (args.type < DBR_PUT_ACKT) {
(*it_handle).PyCtrlEventHandler();
}
#endif
}
else {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
return;
#undef __METHOD__
};
/**
* \brief Callback function for monitor method is invoked
* with a pointer to the retrieved value; also fires a user supplied Python callback.
* \param args input: event handler arguments
*/
void MonitorPolicy::PyCallbackHandlerMonitor (struct event_handler_args args) {
#define __METHOD__ "MonitorPolicy::PyCallbackHandlerMonitor"
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) ca_puser(args.chid);// args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int)_handle);
if (it_handle != handle_index.end()) {
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX){cafeMutex.unlock();}
#if HAVE_PYTHON_H
(*it_handle).PyEventHandler();
#endif
}
else {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
return;
#undef __METHOD__
}

918
src/conduit.cpp Normal file
View File

@@ -0,0 +1,918 @@
///
/// \file conduit.cc
/// \author Jan Chrin, PSI
/// \date Release: September 2015
/// \version CAFE 1.1.0
///
#include "conduit.h"
#include "helper.h"
unsigned int Conduit::handleNext=0; //4294967295;
unsigned int MonitorPolicy::idNext=0xfff; //4095
Conduit::Conduit( ){};
/**
* CAFEConduit destructor \n
* Good place to clean up!
*/
Conduit::~Conduit(){};
/*
Conduit::Conduit(const char * _pv, ca_client_context *_ccc, bool _pyCafeFlag) {
//Define default policies
channelRequestPolicyPut.setPolicy(_channelRequestPolicy.getWhenToFlushSendBuffer(),
_channelRequestPolicy.getWaitKind(), _channelRequestPolicy.getMethodKind());
cout << "when " << _channelRequestPolicy.getWhenToFlushSendBuffer() << endl;
cout << "wait " << _channelRequestPolicy.getWaitKind() << endl;
cout << "method " << _channelRequestPolicy.getMethodKind() << endl;
Conduit::Conduit(_pv, _ccc, _pyCafeFlag);
cout << "when " << _channelRequestPolicy.getWhenToFlushSendBuffer() << endl;
cout << "wait " << _channelRequestPolicy.getWaitKind() << endl;
cout << "method " << _channelRequestPolicy.getMethodKind() << endl;
}
*/
/**
* \brief Conduit constructor with flag for PyCafe API \n
* \param _pv input: process variable
* \param _ccc input: ca_client_context
* \param _pyCafeFlag input: bool
*/
Conduit::Conduit(const char * _pv, ca_client_context *_ccc,
ChannelRequestPolicy _channelRequestPolicyPut, ChannelRequestPolicy _channelRequestPolicyGet,
ChannelGetActionWhenMonitorPolicy _channelGetActionWhenMonitorPolicy,
bool _pyCafeFlag) {
// To avoid the following compilation error
// conduit.cpp:41: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
//epicsAlarmSeverityStrings= {"NO_ALARM","MINOR","MAJOR","INVALID"};
epicsAlarmSeverityStrings[0]=(const char *) "NO_ALARM";
epicsAlarmSeverityStrings[1]=(const char *) "MINOR";
epicsAlarmSeverityStrings[2]=(const char *) "MAJOR";
epicsAlarmSeverityStrings[3]=(const char *) "INVALID";
//epicsAlarmConditionStrings = {"NO_ALARM","READ","WRITE","HIHI","HIGH",
//"LOLO","LOW","STATE","COS", "COMM","TIMEOUT","HWLIMIT","CALC","SCAN","LINK",
//"SOFT","BAD_SUB","UDF","DISABLE","SIMM","READ_ACCESS", "WRITE_ACCESS"};
epicsAlarmConditionStrings[0]= (const char *) "NO_ALARM";
epicsAlarmConditionStrings[1]= (const char *) "READ";
epicsAlarmConditionStrings[2]= (const char *) "WRITE";
epicsAlarmConditionStrings[3]= (const char *) "HIHI";
epicsAlarmConditionStrings[4]= (const char *) "HIGH";
epicsAlarmConditionStrings[5]= (const char *) "LOLO";
epicsAlarmConditionStrings[6]= (const char *) "LOW";
epicsAlarmConditionStrings[7]= (const char *) "STATE";
epicsAlarmConditionStrings[8]= (const char *) "COS";
epicsAlarmConditionStrings[9]= (const char *) "COMM";
epicsAlarmConditionStrings[10]= (const char *) "TIMEOUT";
epicsAlarmConditionStrings[11]= (const char *) "HWLIMIT";
epicsAlarmConditionStrings[12]= (const char *) "CALC";
epicsAlarmConditionStrings[13]= (const char *) "SCAN";
epicsAlarmConditionStrings[14]= (const char *) "LINK";
epicsAlarmConditionStrings[15]= (const char *) "SOFT";
epicsAlarmConditionStrings[16]= (const char *) "BAD_SUB";
epicsAlarmConditionStrings[17]= (const char *) "UDF";
epicsAlarmConditionStrings[18]= (const char *) "DISABLE";
epicsAlarmConditionStrings[19]= (const char *) "SIMM";
epicsAlarmConditionStrings[20]= (const char *) "READ_ACCESS";
epicsAlarmConditionStrings[21]= (const char *) "WRITE_ACCESS";
ccc = _ccc;
pvAlias = _pv;
pv = _pv;
++handleNext;
if(handleNext==0) { // In case we loop round 4294967295(!)
++handleNext; // 0 reserved for handle not found
}
pyCafeFlag=_pyCafeFlag;
handle = handleNext;
groupHandle= 0;
channelID=NULL;
alarmStatus=-1;
alarmSeverity=-1;
ts.secPastEpoch=0;
ts.nsec=0;
usrArgs= (unsigned long) 0;
dataType= NULL; //(chtype) NULL;
dbrDataType= NULL; //(chtype) NULL;
cafeDbrType=CAFENUM::DBR_NONE;
beamEventNo=0;
dataBuffer = NULL;
ctrlBuffer = NULL;
putBuffer = NULL;
stsackBuffer= NULL;
status=ICAFE_CS_NEVER_CONN;
//Default - we will let the user methods take control of this
channelRequestMetaDataClient.cafeDbrType = CAFENUM::DBR_TIME; //PLAIN;
channelRequestMetaData.cafeDbrType = CAFENUM::DBR_TIME;
channelRequestMetaPrimitive.cafeDbrType = CAFENUM::DBR_PRIMITIVE;
channelRequestMetaCtrlClient.cafeDbrType = CAFENUM::DBR_CTRL;
channelRequestMetaCtrl.cafeDbrType = CAFENUM::DBR_CTRL;
//channelRequestMetaCtrlRepository.cafeDbrType = CAFENUM::DBR_CTRL;
deviceAttributeDeliminator=DEFAULT_DEVICE_ATTRIBUTE_DELIMINATOR;
channelDeviceAttribute.init(pv,deviceAttributeDeliminator);
mpV.reserve(2);
monitorAction.reserve(2);
hasNewData=true; // used by HandleHelper.getMonitorAction(); start with true
//channelRequestPolicyPut
channelRequestPolicyPut.setPolicy(_channelRequestPolicyPut.getWhenToFlushSendBuffer(),
_channelRequestPolicyPut.getWaitKind(), _channelRequestPolicyPut.getMethodKind());
channelRequestPolicyGet.setPolicy(_channelRequestPolicyGet.getWhenToFlushSendBuffer(),
_channelRequestPolicyGet.getWaitKind(), _channelRequestPolicyGet.getMethodKind());
//Use same policy for get ctrl
channelRequestPolicyGetCtrl.setPolicy(_channelRequestPolicyGet.getWhenToFlushSendBuffer(),
_channelRequestPolicyGet.getWaitKind(), _channelRequestPolicyGet.getMethodKind());
channelGetActionWhenMonitorPolicy.setActionKind(_channelGetActionWhenMonitorPolicy.getActionKind());
//cout << "when /" << channelRequestPolicyMaster.getWhenToFlushSendBuffer() << endl;
//cout << "wait /" << channelRequestPolicyMaster.getWaitKind() << endl;
//cout << "method /" << channelRequestPolicyMaster.getMethodKind() << endl;
//Define default policies
//channelRequestPolicyPut.setPolicy(CAFENUM::FLUSH_AFTER_EACH_MESSAGE,
//CAFENUM::NO_WAIT, CAFENUM::WITH_CALLBACK_DEFAULT);
//channelRequestPolicyGet.setPolicy(CAFENUM::FLUSH_AFTER_EACH_MESSAGE,
// CAFENUM::WAIT, CAFENUM::WITH_CALLBACK_DEFAULT); //WITHOUT_CALLBACK);
//channelRequestPolicyGetCtrl.setPolicy(CAFENUM::FLUSH_AFTER_EACH_MESSAGE,
// CAFENUM::WAIT, CAFENUM::WITHOUT_CALLBACK); //WITH_CALLBACK_DEFAULT);
#if HAVE_PYTHON_H
#if HAVE_PYCAFE_EXT
//Do nothing as PyCafe_ext is compiled
#else
//Give non Python APIs (e.g. MATLAB) a chance to turn this off
//MATLAB needs to turn this off
if (pyCafeFlag) {
//Py_Initialize();
import_PyCafe(); // Use PyCafe_api.h
}
#endif
#endif
}
#if HAVE_PYTHON_H
void * Conduit::PyGetHandler() const {
py_cb_handle_get_wrapper(handle);
return (void *) 0;
}
void * Conduit::PyPutHandler() const {
py_cb_handle_put_wrapper(handle);
return (void *) 0;
}
void * Conduit::PyEventHandler() const {
//py_cb_handle_wrapper(handle);
py_cb_handle_monid_wrapper(handle, (unsigned long) usrArgs);
return (void *) 0;
}
void * Conduit::PyEventHandler(unsigned int monid) const {
//py_cb_handle_wrapper(handle);
py_cb_handle_monid_wrapper(handle, monid);
return (void *) 0;
}
void * Conduit::PyDataEventHandler() const{
PVDataHolder pvd(channelRequestMetaData.nelem);
//size is set in conduitEventHandlerArgs.h
getPVDataHolder(pvd);
py_cb_wrapper(pvd, handle, pv);
return (void *) 0;
}
void * Conduit::PyCtrlEventHandler() const{
PVCtrlHolder pvc(channelRequestMetaCtrl.nelem);
//size is set in conduitEventHandlerArgs.h
getPVCtrlHolder(pvc);
py_cb_ctrl_wrapper(pvc, handle, pv);
return (void *) 0;
}
#endif
/**
* \brief Called from Granules.cc \n
* Sends data from the Conduit::putBuffer to the process variable.
* It does not wait to determine if the data was actually written or not.
* \return ECA_NORMAL - Normal successful completion
* \return ECA_BADCHID - Corrupted Channel Identifier (chid)
* \return ECA_BADTYPE - Invalid DBR_XXX type
* \return ECA_BADCOUNT - Requested count larger than native element count
* \return ECA_NOWTACCESS - Write access denied
* \return ECA_ALLOCMEM - Unable to allocate memory
* \return ECA_DISCONN - Channel is disconnected
*/
int Conduit::put(void) const {
#define __METHOD__ "Conduit::put()"
return ca_array_put(channelRequestMetaPrimitive.dbrDataType, channelRequestMetaPrimitive.nelem,
channelRegalia.channelID, putBuffer);
#undef __METHOD__
};
/**
* \brief Called from Granules.cc \n
* Sends data from the Conduit::putBuffer to the process variable.
* It does not wait to determine if the data was actually written or not.
* \param callbackHandlerPut input: pCallback
* \return ECA_NORMAL if OK else ECA error
*/
int Conduit::putWithCallback(pCallback callbackHandlerPut) const {
#define __METHOD__ "Conduit::putWithCallback(pCallback callbackHandlerPut) "
//cout << "channelRequestMetaPrimitive.nelem: " << channelRequestMetaPrimitive.nelem << endl;
//for (int i=0; i< channelRequestMetaPrimitive.nelem; ++i) {
// cout << (*(&((putBuffer)->fltval)+i)) << " [" << i << "] " << endl;
//}
return ca_array_put_callback(channelRequestMetaPrimitive.dbrDataType, channelRequestMetaPrimitive.nelem,
channelRegalia.channelID, putBuffer, callbackHandlerPut,(void *) (long long) handle );
#undef __METHOD__
};
/**
* \brief Called from Granules.cc \n
* Retrieves PV data through channel access into the Conduit::dataBuffer
* \return ECA_NORMAL if OK else ECA error
*/
int Conduit::get(void) const {
#define __METHOD__ "Conduit::get(void) "
return ca_array_get(channelRequestMetaData.dbrDataType, channelRequestMetaData.nelem,
channelRegalia.channelID, dataBuffer);
#undef __METHOD__
};
/**
* \brief Called from Granules.cc \n
* Retrieves PV data through channel access into the Conduit::dataBuffer thru callbackHandlerGet
* \param callbackHandlerGet input: pCallback
* \return ECA_NORMAL if OK else ECA error
*/
int Conduit::getWithCallback(pCallback callbackHandlerGet) const {
#define __METHOD__ "Conduit::getCallback(pCallback callbackHandlerGet) "
return ca_array_get_callback(channelRequestMetaData.dbrDataType, channelRequestMetaData.nelem,
channelRegalia.channelID,callbackHandlerGet,(void *) (long long) handle );
#undef __METHOD__
};
/**
* \brief Called from Granules.cc \n
* Retrieves Ctrl data through channel access into the Conduit::ctrlBuffer
* \return ECA_NORMAL if OK else ECA error
*/
int Conduit::getCtrl(void) const {
#define __METHOD__ "Conduit::getCtrl(void) "
return ca_array_get(channelRequestMetaCtrl.dbrDataType, channelRequestMetaCtrl.nelem,
channelRegalia.channelID, ctrlBuffer);
#undef __METHOD__
};
/**
* \brief Called from granules.cc and conduitConnectionHandersArgs.h \n
* Retrieves Ctrl data through channel access into the Conduit::ctrlBuffer thru callbackHandlerCtrl
* \param callbackHandlerCtrl input: pCallback
* \return ECA_NORMAL if OK else ECA error
*/
int Conduit::getCtrlWithCallback(pCallback callbackHandlerCtrl) const {
#define __METHOD__ "Conduit::getCtrlCallback(pCallback callbackHandlerCtrl) "
return ca_array_get_callback(channelRequestMetaCtrl.dbrDataType,
channelRequestMetaCtrl.nelem,
//min(channelRequestMetaCtrl.nelem,max_nelem_for_ctrl_buffer),
channelRegalia.channelID, callbackHandlerCtrl, (void *) (long long) handle);
#undef __METHOD__
};
/**
* \brief Called from Granules.cc and conduitConnectionHandersArgs.h \n
* Retrieves STSACK data through channel access into the Conduit::STSACKBuffer thru callbackHandlerSTSACK
* \param callbackHandlerSTSACK input: pCallback
* \return ECA_NORMAL if OK else ECA error
*/
int Conduit::getSTSACKWithCallback(pCallback callbackHandlerSTSACK) const {
#define __METHOD__ "Conduit::getSTSACKWithCallback(pCallback callbackHandlerSTSACK) "
return ca_array_get_callback(DBR_STSACK_STRING, channelRequestMetaSTSACK.nelem,
channelRegalia.channelID, callbackHandlerSTSACK, (void *) (long long) handle);
#undef __METHOD__
};
/**
* \brief Called from Granules.cc and conduitConnectionHandersArgs.h \n
* Retrieves ClassName data through channel access into the Conduit::ClassNameBuffer thru callbackHandlerClassName
* \param callbackHandlerClassName input: pCallback
* \return ECA_NORMAL if OK else ECA error
*/
int Conduit::getClassNameWithCallback(pCallback callbackHandlerClassName) const {
#define __METHOD__ "Conduit::getClassNameWithCallback(pCallback callbackHandlerClassName) "
return ca_array_get_callback(DBR_CLASS_NAME, 1,
channelRegalia.channelID, callbackHandlerClassName, (void *)(long long) handle);
#undef __METHOD__
};
/**
* \brief Called from cafe.cc
* \param _pvd output: PVDataHolder
* \return ECA_NORMAL if OK else ECA error
*/
int Conduit::getPVDataHolder(PVDataHolder & _pvd) const {
#define __METHOD__ "Conduit::getPVDataHolder(PVDataHolder & _pvd) "
Helper helper;
//Check on the datatype transferred
chtype channelType = channelRequestMetaData.getDbrDataType();
CAFENUM::DBR_TYPE dbrTypeClass=helper.convertToCAFEDbrTypeClass(channelType);
if ( channelRegalia.getCafeConnectionState() != ICAFE_CS_NEVER_CONN ) {
switch(dbrTypeClass)
{
case CAFENUM::DBR_PRIMITIVE:
case CAFENUM::DBR_STS:
case CAFENUM::DBR_TIME:
break;
default:
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "CAFE INTERNAL FUNNY: dbrTypeClass = " << dbrTypeClass <<
" is NOT appropriate for this method" << endl;
cout << "Method does not deal with this DBR_TYPE: "
<< dbr_type_to_text(channelType) << endl;
break;
}
} //if
unsigned int offset = channelRequestMetaData.getOffset(); //channelRequestMetaDataClient.getOffset();
unsigned int nelem = channelRequestMetaData.getNelem()-offset;
nelem=min(_pvd.nelem,nelem); // Add this for getCache method
_pvd.alarmStatus = -1;//alarmStatus;
_pvd.alarmSeverity = -1;//alarmSeverity;
_pvd.ts.nsec = 0;//ts;
_pvd.ts.secPastEpoch= 0;
_pvd.nelem = min(_pvd.size,nelem); //channelRequestMetaData.getNelem();
_pvd.beamEventNo = beamEventNo;
_pvd.status = status;
_pvd.dataTypeNative = (CAFE_DATATYPE) channelRegalia.getDataType();
_pvd.dataType = (CAFE_DATATYPE) channelRequestMetaData.getDataType();//dataTypeRequest;
_pvd.dbrDataType = channelRequestMetaData.getDbrDataType();
strcpy(_pvd.pv, pv.c_str());
strcpy(_pvd.pvAlias, pvAlias.c_str());
strcpy(_pvd.device, channelDeviceAttribute.getDevice());
strcpy(_pvd.attrib, channelDeviceAttribute.getAttribute());
if (_pvd.dataTypeNative==DBR_ENUM) {
_pvd.noStr = ((struct dbr_ctrl_enum *) ctrlBuffer)->no_str;
memcpy( _pvd.strs, &(((struct dbr_ctrl_enum *) ctrlBuffer)->strs), sizeof(_pvd.strs)) ;
//for (int i=0; i<_pvd.noStr; ++i) cout << __METHOD__ << i << " " << _pvd.strs[i] << endl;
}
switch (channelType)
{
case DBR_TIME_DOUBLE:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].d = (*(&((dataBuffer)->tdblval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_double *) dataBuffer)->stamp;
_pvd.alarmStatus = ((struct dbr_time_double *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_time_double *) dataBuffer)->severity;
break;
case DBR_TIME_FLOAT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].f = (*(&((dataBuffer)->tfltval.value)+i+offset));
}
_pvd.ts = (epicsTimeStamp) ((struct dbr_time_float *) dataBuffer)->stamp;
_pvd.alarmStatus = ((struct dbr_time_float *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_time_float *) dataBuffer)->severity;
break;
case DBR_TIME_LONG:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].l = (*(&((dataBuffer)->tlngval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_long *) dataBuffer)->stamp;
_pvd.alarmStatus = ((struct dbr_time_long *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_time_long *) dataBuffer)->severity;
break;
case DBR_TIME_SHORT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].s = (*(&((dataBuffer)->tshrtval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_short *) dataBuffer)->stamp;
_pvd.alarmStatus = ((struct dbr_time_short *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_time_short *) dataBuffer)->severity;
break;
case DBR_TIME_ENUM:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].us = (*(&((dataBuffer)->tenmval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_enum *) dataBuffer)->stamp;
_pvd.alarmStatus = ((struct dbr_time_enum *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_time_enum *) dataBuffer)->severity;
break;
case DBR_TIME_CHAR:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].ch = (*(&((dataBuffer)->tchrval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_char *) dataBuffer)->stamp;
_pvd.alarmStatus = ((struct dbr_time_char *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_time_char *) dataBuffer)->severity;
break;
case DBR_TIME_STRING:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
strcpy(_pvd.val[i].str, (*(&((dataBuffer)->tstrval.value)+i+offset)));
}
_pvd.ts = ((struct dbr_time_string *) dataBuffer)->stamp;
_pvd.alarmStatus = ((struct dbr_time_string *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_time_string *) dataBuffer)->severity;
break;
case DBR_STS_DOUBLE:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].d = (*(&((dataBuffer)->sdblval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_double *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_sts_double *) dataBuffer)->severity;
break;
case DBR_STS_FLOAT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].f = (*(&((dataBuffer)->sfltval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_float *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_sts_float *) dataBuffer)->severity;
break;
case DBR_STS_LONG:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].l = (*(&((dataBuffer)->slngval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_int *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_sts_int *) dataBuffer)->severity;
break;
case DBR_STS_SHORT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].s = (*(&((dataBuffer)->sshrtval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_short *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_sts_short *) dataBuffer)->severity;
break;
case DBR_STS_ENUM:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].us = (*(&((dataBuffer)->senmval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_enum *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_sts_enum *) dataBuffer)->severity;
break;
case DBR_STS_CHAR:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].ch = (*(&((dataBuffer)->schrval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_char *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_sts_char *) dataBuffer)->severity;
break;
case DBR_STS_STRING:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
strcpy(_pvd.val[i].str, (*(&((dataBuffer)->sstrval.value)+i+offset)));
}
_pvd.alarmStatus = ((struct dbr_sts_string *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_sts_string *) dataBuffer)->severity;
break;
case DBR_DOUBLE:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].d = (*(&((dataBuffer)->doubleval)+i+offset));
}
break;
case DBR_FLOAT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].f = (*(&((dataBuffer)->fltval)+i+offset));
}
break;
case DBR_LONG:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].l = (*(&((dataBuffer)->longval)+i+offset));
}
break;
case DBR_SHORT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].s = (*(&((dataBuffer)->shrtval)+i+offset));
}
break;
case DBR_ENUM:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].us = (*(&((dataBuffer)->enmval)+i+offset));
}
break;
case DBR_CHAR:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
_pvd.val[i].ch = (*(&((dataBuffer)->charval)+i+offset));
}
break;
case DBR_STRING:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
strcpy(_pvd.val[i].str, (*(&((dataBuffer)->strval)+i+offset)));
}
break;
case TYPENOTCONN:
if ( channelRegalia.getCafeConnectionState() != ICAFE_CS_NEVER_CONN ) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "ERROR CAFE_TYPENOTCONN: dataType: "
<< channelType << " : " << dbr_type_to_text(channelType) << endl;
}
break;
default:
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "The switch case does not support this channelType: "
<< channelType << " : " << dbr_type_to_text(channelType) << endl;
break;
}
//Do this to prevent overflow error in epicsTime time(ts) routines!
//This bad number can occur in timeouts
if(_pvd.ts.nsec>1000000000) {_pvd.ts.nsec=0;}
return ICAFE_NORMAL;
#undef __METHOD__
};
/**
* \brief Called from cafe.cc
* \param _pvc output: PVCtrlHolder
* \return ICAFE_NORMAL if OK else ICAFE error
*/
int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const {
#define __METHOD__ " Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) "
Helper helper;
int channelType=channelRequestMetaCtrl.getDbrDataType();
CAFENUM::DBR_TYPE dbrTypeClass=helper.convertToCAFEDbrTypeClass(channelType);
if ( channelRegalia.getCafeConnectionState() != ICAFE_CS_NEVER_CONN ) {
switch(dbrTypeClass)
{
case CAFENUM::DBR_GR:
case CAFENUM::DBR_CTRL:
break;
default:
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "CAFE INTERNAL FUNNY: dbrTypeClass = " << dbrTypeClass <<
" is NOT appropriate for this method" << endl;
cout << "Method does not deal with this DBR_TYPE: "
<< dbr_type_to_text(channelType) << endl;
break;
}
}
unsigned int offset = channelRequestMetaCtrlClient.getOffset();
unsigned int nelem = channelRequestMetaCtrl.getNelem()-offset;
nelem=min(_pvc.nelem,nelem); // Add this for getCache method
//
_pvc.alarmStatus = -1;//alarmStatus;
_pvc.alarmSeverity = -1;//alarmSeverity;
_pvc.nelem = min(_pvc.size,nelem);
//Default from constructor if not connected
_pvc.dataType = (CAFE_DATATYPE) channelRequestMetaCtrl.getDataType(); // dataTypeRequest;
_pvc.dataTypeNative = (CAFE_DATATYPE) channelRegalia.getDataType(); // dataTypeRequest;
_pvc.dbrDataType = channelRequestMetaCtrl.getDbrDataType();
_pvc.status = status;
strcpy(_pvc.pv, pv.c_str());
strcpy(_pvc.pvAlias, pvAlias.c_str());
strcpy(_pvc.device,channelDeviceAttribute.getDevice());
strcpy(_pvc.attrib,channelDeviceAttribute.getAttribute());
if (_pvc.dataTypeNative==DBR_ENUM) {
_pvc.noStr = ((struct dbr_ctrl_enum *) ctrlBuffer)->no_str;
memcpy( _pvc.strs, &(((struct dbr_ctrl_enum *) ctrlBuffer)->strs), sizeof(_pvc.strs)) ;
//for (int i=0; i<_pvc.noStr; ++i) cout << __METHOD__ << i << " " << _pvc.strs[i] << endl;
}
switch (channelType)
{
case DBR_CTRL_CHAR:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
_pvc.val[i].ch = (*(&((ctrlBuffer)->cchrval.value)+i+offset));
}
_pvc.precision = 0; // struct dbr_ctrl_char does not have the precision member
_pvc.RISC_pad.ch = ((struct dbr_ctrl_char *) ctrlBuffer)->RISC_pad;
_pvc.alarmStatus = ((struct dbr_ctrl_char *) ctrlBuffer)->status;
_pvc.alarmSeverity = ((struct dbr_ctrl_char *) ctrlBuffer)->severity;
memcpy(_pvc.units, &(((struct dbr_ctrl_char *) ctrlBuffer)->units), sizeof(char[MAX_UNITS_SIZE]));
_pvc.upperDispLimit.ch = (dbr_char_t) ((struct dbr_ctrl_char *) ctrlBuffer)->upper_disp_limit;
_pvc.lowerDispLimit.ch = (dbr_char_t) ((struct dbr_ctrl_char *) ctrlBuffer)->lower_disp_limit;
_pvc.upperAlarmLimit.ch = (dbr_char_t) ((struct dbr_ctrl_char *) ctrlBuffer)->upper_alarm_limit;
_pvc.upperWarningLimit.ch = (dbr_char_t) ((struct dbr_ctrl_char *) ctrlBuffer)->upper_warning_limit;
_pvc.lowerWarningLimit.ch = (dbr_char_t) ((struct dbr_ctrl_char *) ctrlBuffer)->lower_warning_limit;
_pvc.lowerAlarmLimit.ch = (dbr_char_t) ((struct dbr_ctrl_char *) ctrlBuffer)->lower_alarm_limit;
_pvc.upperCtrlLimit.ch = (dbr_char_t) ((struct dbr_ctrl_char *) ctrlBuffer)->upper_ctrl_limit;
_pvc.lowerCtrlLimit.ch = (dbr_char_t) ((struct dbr_ctrl_char *) ctrlBuffer)->lower_ctrl_limit;
break;
case DBR_CTRL_FLOAT:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
_pvc.val[i].f = (*(&((ctrlBuffer)->cfltval.value)+i+offset));
}
_pvc.precision = ((struct dbr_ctrl_float *) ctrlBuffer)->precision;
_pvc.RISC_pad.s = ((struct dbr_ctrl_float *) ctrlBuffer)->RISC_pad;
_pvc.alarmStatus = ((struct dbr_ctrl_float *) ctrlBuffer)->status;
_pvc.alarmSeverity = ((struct dbr_ctrl_float *) ctrlBuffer)->severity;
memcpy(_pvc.units, &(((struct dbr_ctrl_float *) ctrlBuffer)->units), sizeof(char[MAX_UNITS_SIZE]));
_pvc.upperDispLimit.f = (dbr_float_t) ((struct dbr_ctrl_float *) ctrlBuffer)->upper_disp_limit;
_pvc.lowerDispLimit.f = (dbr_float_t) ((struct dbr_ctrl_float *) ctrlBuffer)->lower_disp_limit;
_pvc.upperAlarmLimit.f = (dbr_float_t) ((struct dbr_ctrl_float *) ctrlBuffer)->upper_alarm_limit;
_pvc.upperWarningLimit.f = (dbr_float_t) ((struct dbr_ctrl_float *) ctrlBuffer)->upper_warning_limit;
_pvc.lowerWarningLimit.f = (dbr_float_t) ((struct dbr_ctrl_float *) ctrlBuffer)->lower_warning_limit;
_pvc.lowerAlarmLimit.f = (dbr_float_t) ((struct dbr_ctrl_float *) ctrlBuffer)->lower_alarm_limit;
_pvc.upperCtrlLimit.f = (dbr_float_t) ((struct dbr_ctrl_float *) ctrlBuffer)->upper_ctrl_limit;
_pvc.lowerCtrlLimit.f = (dbr_float_t) ((struct dbr_ctrl_float *) ctrlBuffer)->lower_ctrl_limit;
break;
case DBR_CTRL_DOUBLE:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
_pvc.val[i].d = (*(&((ctrlBuffer)->cdblval.value)+i+offset));
}
_pvc.precision = ((struct dbr_ctrl_double *) ctrlBuffer)->precision;
_pvc.RISC_pad.s = ((struct dbr_ctrl_double *) ctrlBuffer)->RISC_pad0;
_pvc.alarmStatus = ((struct dbr_ctrl_double *) ctrlBuffer)->status;
_pvc.alarmSeverity = ((struct dbr_ctrl_double *) ctrlBuffer)->severity;
memcpy(_pvc.units, &(((struct dbr_ctrl_double *) ctrlBuffer)->units), sizeof(char[MAX_UNITS_SIZE]));
_pvc.upperDispLimit.d = (dbr_double_t) ((struct dbr_ctrl_double *) ctrlBuffer)->upper_disp_limit;
_pvc.lowerDispLimit.d = (dbr_double_t) ((struct dbr_ctrl_double *) ctrlBuffer)->lower_disp_limit;
_pvc.upperAlarmLimit.d = (dbr_double_t) ((struct dbr_ctrl_double *) ctrlBuffer)->upper_alarm_limit;
_pvc.upperWarningLimit.d = (dbr_double_t) ((struct dbr_ctrl_double *) ctrlBuffer)->upper_warning_limit;
_pvc.lowerWarningLimit.d = (dbr_double_t) ((struct dbr_ctrl_double *) ctrlBuffer)->lower_warning_limit;
_pvc.lowerAlarmLimit.d = (dbr_double_t) ((struct dbr_ctrl_double *) ctrlBuffer)->lower_alarm_limit;
_pvc.upperCtrlLimit.d = (dbr_double_t) ((struct dbr_ctrl_double *) ctrlBuffer)->upper_ctrl_limit;
_pvc.lowerCtrlLimit.d = (dbr_double_t) ((struct dbr_ctrl_double *) ctrlBuffer)->lower_ctrl_limit;
break;
case DBR_CTRL_SHORT:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
_pvc.val[i].s = (*(&((ctrlBuffer)->cshrtval.value)+i+offset));
}
_pvc.precision = 0;
_pvc.RISC_pad.s = 0;
_pvc.alarmStatus = ((struct dbr_ctrl_short *) ctrlBuffer)->status;
_pvc.alarmSeverity = ((struct dbr_ctrl_short *) ctrlBuffer)->severity;
memcpy(_pvc.units, &(((struct dbr_ctrl_short *) ctrlBuffer)->units), sizeof(char[MAX_UNITS_SIZE]));
_pvc.upperDispLimit.s = (dbr_short_t) ((struct dbr_ctrl_short *) ctrlBuffer)->upper_disp_limit;
_pvc.lowerDispLimit.s = (dbr_short_t) ((struct dbr_ctrl_short *) ctrlBuffer)->lower_disp_limit;
_pvc.upperAlarmLimit.s = (dbr_short_t) ((struct dbr_ctrl_short *) ctrlBuffer)->upper_alarm_limit;
_pvc.upperWarningLimit.s = (dbr_short_t) ((struct dbr_ctrl_short *) ctrlBuffer)->upper_warning_limit;
_pvc.lowerWarningLimit.s = (dbr_short_t) ((struct dbr_ctrl_short *) ctrlBuffer)->lower_warning_limit;
_pvc.lowerAlarmLimit.s = (dbr_short_t) ((struct dbr_ctrl_short *) ctrlBuffer)->lower_alarm_limit;
_pvc.upperCtrlLimit.s = (dbr_short_t) ((struct dbr_ctrl_short *) ctrlBuffer)->upper_ctrl_limit;
_pvc.lowerCtrlLimit.s = (dbr_short_t) ((struct dbr_ctrl_short *) ctrlBuffer)->lower_ctrl_limit;
break;
case DBR_CTRL_LONG:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
_pvc.val[i].l = (*(&((ctrlBuffer)->clngval.value)+i+offset));
}
_pvc.precision = 0;
_pvc.RISC_pad.s = 0;
_pvc.alarmStatus = ((struct dbr_ctrl_int *) ctrlBuffer)->status;
_pvc.alarmSeverity = ((struct dbr_ctrl_int *) ctrlBuffer)->severity;
memcpy(_pvc.units, &(((struct dbr_ctrl_int *) ctrlBuffer)->units), sizeof(char[MAX_UNITS_SIZE]));
_pvc.upperDispLimit.l = (dbr_long_t) ((struct dbr_ctrl_int *) ctrlBuffer)->upper_disp_limit;
_pvc.lowerDispLimit.l = (dbr_long_t) ((struct dbr_ctrl_int *) ctrlBuffer)->lower_disp_limit;
_pvc.upperAlarmLimit.l = (dbr_long_t) ((struct dbr_ctrl_int *) ctrlBuffer)->upper_alarm_limit;
_pvc.upperWarningLimit.l = (dbr_long_t) ((struct dbr_ctrl_int *) ctrlBuffer)->upper_warning_limit;
_pvc.lowerWarningLimit.l = (dbr_long_t) ((struct dbr_ctrl_int *) ctrlBuffer)->lower_warning_limit;
_pvc.lowerAlarmLimit.l = (dbr_long_t) ((struct dbr_ctrl_int *) ctrlBuffer)->lower_alarm_limit;
_pvc.upperCtrlLimit.l = (dbr_long_t) ((struct dbr_ctrl_int *) ctrlBuffer)->upper_ctrl_limit;
_pvc.lowerCtrlLimit.l = (dbr_long_t) ((struct dbr_ctrl_int *) ctrlBuffer)->lower_ctrl_limit;
break;
case DBR_CTRL_ENUM:
memcpy(_pvc.val.get(), &(&((ctrlBuffer)->cenmval.value))[offset], sizeof(dbr_short_t)*_pvc.nelem);
_pvc.precision = 0;
_pvc.RISC_pad.s = 0;
_pvc.alarmStatus = ((struct dbr_ctrl_enum *) ctrlBuffer)->status;
_pvc.alarmSeverity = ((struct dbr_ctrl_enum *) ctrlBuffer)->severity;
_pvc.noStr = ((struct dbr_ctrl_enum *) ctrlBuffer)->no_str;
memcpy(_pvc.strs , &(((struct dbr_ctrl_enum *) ctrlBuffer)->strs),
sizeof(char)*MAX_ENUM_STRING_SIZE*MAX_ENUM_STATES);
//no units
memcpy(_pvc.units,"",sizeof(char[MAX_UNITS_SIZE]));
_pvc.upperDispLimit.us = 0;
_pvc.lowerDispLimit.us = 0;
_pvc.upperAlarmLimit.us = 0;
_pvc.upperWarningLimit.us = 0;
_pvc.lowerWarningLimit.us = 0;
_pvc.lowerAlarmLimit.us = 0;
_pvc.upperCtrlLimit.us = 0;
_pvc.lowerCtrlLimit.us = 0;
break;
case DBR_CTRL_STRING:
memcpy(_pvc.val.get(), &(&((ctrlBuffer)->cstrval.value))[offset], sizeof(dbr_string_t)*_pvc.nelem);
_pvc.alarmStatus = ((struct dbr_sts_string *) ctrlBuffer)->status;
_pvc.alarmSeverity = ((struct dbr_sts_string *) ctrlBuffer)->severity;
memcpy(_pvc.units,"",sizeof(char[MAX_UNITS_SIZE]));
_pvc.upperDispLimit.us = 0;
_pvc.lowerDispLimit.us = 0;
_pvc.upperAlarmLimit.us = 0;
_pvc.upperWarningLimit.us = 0;
_pvc.lowerWarningLimit.us = 0;
_pvc.lowerAlarmLimit.us = 0;
_pvc.upperCtrlLimit.us = 0;
_pvc.lowerCtrlLimit.us = 0;
break;
default:
break;
}
return ICAFE_NORMAL;
#undef __METHOD__
};
////////////////////////////////////// Monitors //////////////////////////////////////////
/**
* \brief Starts a monitor on the epics channel
* \param mp input: MonitorPolicy class \n
* mp.eventID output: evid identifying the monitor subscription
* \return ECA_NORMAL - normal sucessful completiom
* \return ECA_BADCHID - corrupted chid
* \return ECA_BADTYPE - invalid DBR_XXXX type
* \return ECA_ALLOCMEM - a local database event add failed
*/
int Conduit::monitorStart(MonitorPolicy &mp) const {
#define __METHOD__ "Conduit::monitorStart(MonitorPolicy mp)"
//cout << __METHOD__ << " mp.getDbrDataType()= " << mp.getDbrDataType() << endl;
evid eventID;
int status = ca_create_subscription(mp.getDbrDataType(), mp.getNelem(), channelRegalia.channelID, mp.getMask(),
mp.getHandler(), (void *) mp.getUserArgs(), &eventID);
mp.setEventID(eventID);
return status;
#undef __METHOD__
};
/**
* \brief Stops a monitor on the epics channel
* \param eventID input: evid
* \return ECA_NORMAL if OK else ECA_BADCHID (corrupted CHID)
*/
int Conduit::monitorStop(evid eventID) const {
#define __METHOD__ "Conduit::monitorStop(evid eventID)"
return ca_clear_subscription(eventID);
#undef __METHOD__
};

204
src/conduitGroup.cpp Normal file
View File

@@ -0,0 +1,204 @@
///
/// \file conduitGroup.cc
/// \author Jan Chrin, PSI
/// \date November 2014
/// \version CAFE 1.0.0
#include <conduitGroup.h>
#include <hashConduitGroup.h>
#include <global.h>
#include <cadef.h>
//include <oldAccess.h>
//include <Python.h>
unsigned int ConduitGroup::groupHandleNext=0;
/**
* ConduitGroup destructor \n
* Good place to clean up!
*/
ConduitGroup::~ConduitGroup(void){
};
/**
* ConduitGroup constructor \n
*
*/
ConduitGroup::ConduitGroup(void){
};
/**
* ConduitGroup constructor has:\n
* \param _groupName assigned group name
* \param _ccc ca_client_context
* \param _groupID unique group identifier (CA_SYNC_GID)
* \param _nMember number of members in group
* \param _mHandle handlt to Conduit object
*/
ConduitGroup::ConduitGroup(const char * _groupName, ca_client_context * _ccc, CA_SYNC_GID _groupID,
unsigned int _nMember, unsigned int * _mHandle){
ccc = _ccc;
groupName = _groupName;
groupID = _groupID;
nMember = _nMember;
mHandle = _mHandle;
timeout_sg_pend_io = DEFAULT_TIMEOUT_SG_PEND_IO;
channelTimeoutPolicySGGet.setTimeout(DEFAULT_TIMEOUT_SG_PEND_IO);
channelTimeoutPolicySGPut.setTimeout(DEFAULT_TIMEOUT_SG_PEND_IO);
channelTimeoutPolicySGGet.setDefaultTimeout(DEFAULT_TIMEOUT_SG_PEND_IO);
channelTimeoutPolicySGPut.setDefaultTimeout(DEFAULT_TIMEOUT_SG_PEND_IO);
++groupHandleNext;
groupHandle = groupHandleNext;
mStatus = new int [nMember];
mRule = new bool[nMember];
for (unsigned int i=0; i<nMember; ++i) {
mRule[i]="true";
mStatus[i]=ICAFE_NORMAL;
}
};
/**
* Retrieves PV data through channel access into the CAFEConduit::dataBuffer
* \return ICAFE_NORMAL if OK
*/
int ConduitGroup::get(void) const{
#define __METHOD__ "ConduitGroup::get(void) const"
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
for (unsigned int i=0; i<nMember; ++i) {
it_handle = handle_index.find(mHandle[i]);
if (it_handle != handle_index.end()) {
if (mStatus[i]==ICAFE_NORMAL) {
//Returns ECA_NORMAL, ECA_BADSYNCGRP, ECA_BADCHID, ECA_BADCOUNT,
//ECA_BADTYPE, ECA_GETFAIL, or 192 if not connected!
mStatus[i]=ca_sg_array_get (groupID,
(*it_handle).channelRequestMetaData.dbrDataType,
(*it_handle).channelRequestMetaData.nelem,
(*it_handle).channelRegalia.channelID,
(*it_handle).dataBuffer);
}
}
} //for
//returns ECA_NORMAL, ECA_TIMEOUT, ECA_EVDISALLOW, ECA_BADSYNCGRP
int groupStatus=ECA_NORMAL;
groupStatus=ca_sg_block(groupID, channelTimeoutPolicySGGet.getTimeout() ); //timeout_sg_pend_io );
//Withdraw this test for now; not required
//while ( (ca_sg_test((*it_groupHandle).getGroupID()) == ECA_IOINPROGRESS
// || gStatus == ECA_TIMEOUT) && channelTimeoutPolicySGGet.getSelfGoverningTimeout()
// && ntries<channelTimeoutPolicySGGet.getNtries()
//)
if (groupStatus== ECA_TIMEOUT) {
CAFEStatus cafeStatus;
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cafeStatus.report(ECA_TIMEOUT);
}
else if (groupStatus!= ECA_NORMAL) {
CAFEStatus cafeStatus;
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "groupID = " << groupID << " groupName = " << groupName << endl;
cafeStatus.report(groupStatus);
}
return groupStatus;
#undef __METHOD__
};
/**
* Sets PV data from the Conduit::dataBuffer through channel access
* \return ICAFE_NORMAL if OK
*/
int ConduitGroup::put(void) const {
#define __METHOD__ "ConduitGroup::put(void) const"
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
for (unsigned int i=0; i<nMember; ++i) {
it_handle = handle_index.find(mHandle[i]);
if (it_handle != handle_index.end()) {
if (mStatus[i]==ICAFE_NORMAL) {
//Returns ECA_NORMAL, ECA_BADSYNCGRP, ECA_BADCHID, ECA_BADCOUNT,
//ECA_BADTYPE, ECA_GETFAIL, or 192 if not connected!
mStatus[i]=ca_sg_array_put (groupID,
(*it_handle).channelRequestMetaPrimitive.dbrDataType,
(*it_handle).channelRequestMetaPrimitive.nelem,
(*it_handle).channelRegalia.channelID,
(*it_handle).putBuffer);
}
}
} //for
//returns ECA_NORMAL, ECA_TIMEOUT, ECA_EVDISALLOW, ECA-BADSYNCGRP
int groupStatus=ECA_NORMAL;
groupStatus=ca_sg_block(groupID, channelTimeoutPolicySGPut.getTimeout() ); // timeout_sg_pend_io );
// epics code for ca_sg_block
/*
ca_client_context *pcac;
int status = fetchClientContext ( &pcac );
if ( status == ECA_NORMAL ) {
CASG * pcasg;
{
epicsGuard < epicsMutex > guard ( pcac->mutex );
pcasg = pcac->lookupCASG ( guard, groupID );
if ( pcasg ) {
status = pcasg->block (
pcac->pCallbackGuard.get (), guard, channelTimeoutPolicySGPut.getTimeout() );
}
else {
status = ECA_BADSYNCGRP;
}
}
if ( pcasg ) {
sync_group_reset ( *pcac, *pcasg );
}
}
*/
//ca_poll();
//ca_sg_test(groupID);
//sleep(1);
if (groupStatus== ECA_TIMEOUT) {
CAFEStatus cafeStatus;
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cafeStatus.report(ECA_TIMEOUT);
}
//groupStatus is ECA_NORMAL even if one of the channels is disconnected
return groupStatus;
#undef __METHOD__
};

2470
src/connect.cpp Normal file

File diff suppressed because it is too large Load Diff

98
src/connectCallbacks.cpp Normal file
View File

@@ -0,0 +1,98 @@
///
/// \file connectCallbacks.cc
/// \author Jan Chrin, PSI
/// \date Release: February 2015
/// \version CAFE 1.0.0
///
#include "connect.h"
#include "conduitFriends.h"
extern cafeConduit_set cs;
extern bool MUTEX;
extern epicsMutex cafeMutex;
/**
* Callback function for callbackHandlerAccessRights \n
* Modifies Conduit object accordingly \n
* Callback handler for the event of a change of R/W access rights \n
* R3.14 documentation states that the callback handler is called \n
* - whenever CA connects the channel, immediately BEFORE the channel's
* connection handler is called \n
* - whenever CA disconnects the channel, immediately AFTER the channel's
* disconnect callback handler is called \n
* - once immediately after installation if the channel is connected \n
* - whenever the access rights of a connected channel changes \n
* \param args output: access_rights_handler_args parameters \n
*/
void Connect::callbackHandlerAccessRights(struct access_rights_handler_args args) {
#define __METHOD__ "Connect::callbackHandlerAccessRights"
//Note: At first connection the no of elements is unknown!
//Therefore we cannot allocate memory for data buffers here!
//cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
unsigned int _handle = (unsigned long) ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int) _handle);
if (it_handle != handle_index.end()) {
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_accessRightsHandlerArgs(args));
if(MUTEX){cafeMutex.unlock();}
}
return;
#undef __METHOD__
}
/**
* Callback function for callbackHandlerException
* Modifies CAFEConduit object accordingly
* \param args output: exception_handler_args parameters \n
*
*/
void Connect::callbackHandlerException(struct exception_handler_args args) {
#define __METHOD__ "Connect::callbackHandlerException"
// This routine is called on disconnect before the connection handler
// cout << "-------------------------------------------------------------" << endl;
// cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
// cout << "Warning: Virtual circuit disconnect" << endl;
// cout << "Exception Handler Args has status = " << args.stat << endl;
unsigned int _handle=0;
char buf[512];
char pName[PVNAME_SIZE];
if (args.chid) {
strcpy(pName , ca_name(args.chid));
_handle = (unsigned long) ca_puser(args.chid);
sprintf(buf,
"%s with request handle=%d, channel=%s, op=%ld, datatype=%s, count=%ld. %s",
args.ctx, (unsigned int) _handle, pName, args.op, dbr_type_to_text (args.type), args.count,
"Possibly an IOC has been switched off or is rebooting.");
}
// This case is more usual(!)
else {
strcpy(pName , "unknown");
sprintf(buf,
"%s with channel=%s, op=%ld, datatype=%s, count=%ld. %s",
args.ctx, pName, args.op, dbr_type_to_text (args.type), args.count,
"Possibly an IOC has been switched off or is rebooting.\n");
}
ca_signal (args.stat, buf);
return;
#undef __METHOD__
}

1830
src/connectGroup.cpp Normal file

File diff suppressed because it is too large Load Diff

92
src/enumStrings.cpp Normal file
View File

@@ -0,0 +1,92 @@
///
/// \file enumStrings.cc
/// \author Modified by Jan Chrin, PSI from Astari's C++11 version \n
/// Using boost::begin() boost::end() for C++
/// \date Release, February 2015
/// \version CAFE 1.0.0
#include "enumStrings.h"
#include "defines.h"
#include "policies.h"
#include "cafeEnum.h"
template<typename T>
struct enumStrings
{
static char const* data[];
};
template<typename T>
struct enumRefHolder
{
T& enumVal;
enumRefHolder(T& enumVal): enumVal(enumVal) {}
};
template<typename T>
struct enumConstRefHolder
{
T const& enumVal;
enumConstRefHolder(T const& enumVal): enumVal(enumVal) {}
};
template<typename T>
std::ostream& operator<<(std::ostream& str, enumConstRefHolder<T> const& data)
{
//Add check on enumStrings<T>::data size to ensure correspondence with entries in cafeEnumEpics.h
if ( boost::size( enumStrings<T>::data) > (unsigned int) data.enumVal) {
return str << enumStrings<T>::data[data.enumVal];
}
else {
return str << "ERROR: enumStrings.h reports data.enumVal= " << data.enumVal
<< " DOES NOT HAVE A STRING EQUIVALENT!";
}
}
template<typename T>
std::istream& operator>>(std::istream& str, enumRefHolder<T> const& data)
{
std::string value;
str >> value;
// These two can be made easier to read in C++11
// using std::begin() and std::end()
//static auto begin = std::begin(enumStrings<T>::data);
//static auto end = std::end(enumStrings<T>::data);
//auto find = std::find(begin, end, value);
//if (find != end)
if ( std::find( boost::begin(enumStrings<T>::data), boost::end( enumStrings<T>::data), value) !=
boost::end( enumStrings<T>::data))
{
//data.enumVal = static_cast<T>(std::distance(begin, find));
data.enumVal = static_cast<T>(std::distance(boost::begin(enumStrings<T>::data),
std::find (boost::begin(enumStrings<T>::data), boost::end(enumStrings<T>::data), value ) ));
}
if (data.enumVal > boost::size( enumStrings<T>::data) ) {
std::cout << "ERROR: enumStrings.h reports data.enumVal = " << data.enumVal
<< " is out of enum range = " << boost::size( enumStrings<T>::data) << std::endl;
}
return str;
}
template<typename T>
enumConstRefHolder<T> enumToString(T const& e) {return enumConstRefHolder<T>(e);}
template<typename T>
enumRefHolder<T> enumFromString(T& e) {return enumRefHolder<T>(e);}

125
src/exceptionsHelper.cpp Normal file
View File

@@ -0,0 +1,125 @@
///
/// \file exceptionsHelper.cc
/// \author Jan Chrin, PSI
/// \date Release, February 2015
/// \version CAFE 1.0.0
///
#include "exceptionsHelper.h"
/**
* \brief Populates the CAFEException_pv struct; precedes throw(e)
* \param pv input: process variable
* \param pvAlias input: process variable alias
* \param handle input: handle to reference object
* \param pCh input: channel identifier (chid)
* \param status input: the error/status code
* \param source input: method name
* \param ln input: line number of file from where the error originates
* \return struct CAFEException_pv
*/
CAFEException_pv ExceptionsHelper::prepareCAFEException_pv(const char *pv, const char *pvAlias,
unsigned int handle, chid pCh, int status,
const char * source, unsigned int ln) {
#define __METHOD__ "Connect::prepareCAFEException_pv"
CAFEException_pv e;
// handle, pv, pvAlias
e.handle=handle;
if (pv!=NULL) {
strcpy(e.pv, (char *) pv);
}
else {
strcpy(e.pv, "");
}
if (pvAlias!=NULL) {
strcpy(e.pvAlias, (char *) pvAlias);
}
else {
strcpy(e.pvAlias, "");
}
// native datatype
if (pCh == NULL) {
e.dataTypeNative = (CAFE_DATATYPE) CAFE_NO_ACCESS;
}
else if (status == ECAFE_RULE_FALSE || status == ICAFE_RULE_FALSE) {
e.dataTypeNative = (CAFE_DATATYPE) CAFE_NOT_REQUESTED;
}
else {
e.dataTypeNative = (CAFE_DATATYPE) dbf_type_to_DBR(ca_field_type(pCh));
}
e.dataTypeNativeText = cafeDataTypeCode.message(e.dataTypeNative).c_str();
// status code, message, description
e.statusCode = status;
e.statusCodeText = (const char *) cafeStatus.csc.message(status).c_str();
e.statusMessage = (const char *) cafeStatus.csi.message(status).c_str();
// method and line no of error source
e.source = (const char *) source;
e.ln = ln;
return e;
#undef __METHOD__
}
/**
* \brief Prints CAFEException_pv to std out
* \param e input: struct CAFEException
*/
void ExceptionsHelper::printCAFEException_pv(CAFEException_pv & e) {
#define __METHOD__ "ExceptionsHelper::printCAFEException_pv"
cout << "------------------------------------" << endl;
cout << __METHOD__ << endl;
cout << "------------------------------------" << endl;
cout << "Handle : " << e.handle << endl;
cout << "Process Variable (PV): " << e.pv << endl;
if ( strcmp(e.pv,e.pvAlias) ) {
cout << "PV Alias : " << e.pvAlias << endl;
}
cout << "PV Native Type : " << e.dataTypeNative << " ("
<< e.dataTypeNativeText << ") " << endl;
cout << "Status Code : " << e.statusCode << endl;
cout << "Status Message : " << e.statusCodeText << endl;
cout << "Error Description : " << e.statusMessage << endl;
cout << "Source Method/Line : " << e.source << "/" << e.ln << endl;
cout << "------------------------------------" << endl;
return;
#undef __METHOD__
}
/**
* \brief Populates the CAFEException_group struct; precedes throw(e)
* \param groupName input: name of group
* \param ghandle input: group handle to reference object
* \param status input: the error/status code
* \param source input: method name
* \param ln input: line number of file from where the error originates
* \return struct CAFEException_group
*/
CAFEException_group ExceptionsHelper::prepareCAFEException_group(char groupName[PVNAME_SIZE],
unsigned int ghandle, int status,
const char * source, unsigned int ln) {
#define __METHOD__ "Connect::prepareCAFEExceptionGroup"
CAFEException_group e;
// handle, pv, pvAlias
e.groupHandle=ghandle;
if (groupName!=NULL) {
strcpy(e.groupName, groupName);
}
else {
strcpy(e.groupName, "");
}
e.statusCode = status;
e.statusCodeText = (const char *) cafeStatus.csc.message(status).c_str();
e.statusMessage = (const char *) cafeStatus.csi.message(status).c_str();
// method and line no of error source
e.source = (const char *) source;
e.ln = ln;
return e;
#undef __METHOD__
}

2359
src/granules.cpp Normal file

File diff suppressed because it is too large Load Diff

3372
src/handleHelper.cpp Normal file

File diff suppressed because it is too large Load Diff

272
src/helper.cpp Normal file
View File

@@ -0,0 +1,272 @@
///
/// \file helper.cc
/// \author Jan Chrin, PSI
/// \date Release: February 2015
/// \version CAFE 1.0.0
//include "connect.h"
//include "conduit.h"
//#include "cafeConduitFriends.h"
#include "helper.h"
using namespace std;
/**
* \brief Removes leading and trailing blanks
* \param pv input: process variable name
* \param pvStripped output: process variable name stripped of forward and trailing spaces
*/
void Helper::removeLeadingAndTrailingSpacesDbrString(const char * pv, char pvStripped[MAX_STRING_SIZE]) {
#define __METHOD__ "Helper::removeLeadingAndTrailingSpacesDbrString(const char * pv, char[MAX_STRING_SIZE])"
// Remove leading and trailing blanks
std::string pvS=pv;
size_t found1 = pvS.find_first_not_of(" ");
size_t found2 = pvS.find_last_not_of (" ");
if (found1!=std::string::npos && found2 !=std::string::npos) {
size_t found21 = std::min((int)((found2+1)-found1), (int) (MAX_STRING_SIZE-1));
size_t length = pvS.copy(pvStripped,found21,found1);
pvStripped[length]='\0'; //required
}
else {
std::strcpy(pvStripped,"");
}
return;
#undef __METHOD__
}
/**
* \brief Removes leading and trailing blanks
* \param pv input: process variable name
* \param pvStripped output: process variable name stripped of forward and trailing spaces
*/
void Helper::removeLeadingAndTrailingSpacesPseudo(const char * pv, char pvStripped[PVGROUP_PSEUDO_SIZE]) {
#define __METHOD__ "Helper::removeLeadingAndTrailingSpacesPseudo(const char * pv, char[PVGROUP_PSEUDO_SIZE])"
// Remove leading and trailing blanks
std::string pvS=pv;
size_t found1 = pvS.find_first_not_of(" ");
size_t found2 = pvS.find_last_not_of (" ");
if (found1!=std::string::npos && found2 !=std::string::npos) {
size_t found21 = std::min((int)((found2+1)-found1), (int) (PVGROUP_PSEUDO_SIZE-1));
size_t length = pvS.copy(pvStripped,found21,found1);
pvStripped[length]='\0'; //required
}
else {
std::strcpy(pvStripped,"isEmpty");
}
return;
#undef __METHOD__
}
/**
* \brief Removes leading and trailing blanks
* \param pv input: process variable name
* \param pvStripped output: process variable name stripped of forward and trailing spaces
*/
void Helper::removeLeadingAndTrailingSpaces(const char * pv, char pvStripped[PVNAME_SIZE]) {
#define __METHOD__ "Helper::removeLeadingAndTrailingSpaces(const char * pv, char[PVNAME_SIZE])"
// Remove leading and trailing blanks
std::string pvS=pv;
size_t found1 = pvS.find_first_not_of(" ");
size_t found2 = pvS.find_last_not_of (" ");
if (found1!=std::string::npos && found2 !=std::string::npos) {
size_t found21 = std::min((int)((found2+1)-found1), (int) (PVNAME_SIZE-1));
size_t length = pvS.copy(pvStripped,found21,found1);
pvStripped[length]='\0'; //required
}
else {
std::strcpy(pvStripped,"isEmpty");
}
return;
#undef __METHOD__
}
/**
* \brief Produces a unique identifier from the pvName, ca_client_context, group handle size \n
* for entry into hash table
* \param pv input: process variable name
* \param ccc input: current context
* \param ghs input: size of gs (group handle set)
* \return unique identifier
*/
unsigned int Helper::convertToUniqueNumber(const char * pv, ca_client_context * ccc, unsigned int ghs) {
#define __METHOD__ "Helper::convertToUniqueNumber(const char * pv, ca_client_context * ccc, unsigned int ghs)"
std::string myString=pv;
char s[12];
sprintf(s,"%ld", (unsigned long) ccc);
unsigned int numberPV = 0;
unsigned int numberContext =0 ;
double dpow=0;
unsigned int ld=0;
numberContext = atoi(s);
unsigned int intValueIs=0;
unsigned int iL=0;
for (unsigned int i=0; i< myString.size(); i++) {
intValueIs= (unsigned int) myString[i];
ld=1;
if ( (intValueIs >47 && intValueIs < 58) ||
(intValueIs >64 && intValueIs < 91) ||
(intValueIs >97 && intValueIs < 123) ) {
dpow=pow((float) 42, (int) iL%4);
ld = static_cast<unsigned int>(dpow);
++iL;
}
else {
iL=0;
}
numberPV += (intValueIs*ld*(i+1));
}
unsigned int final=(numberPV+numberContext+((ghs+1)*10000+ghs));
return final;
#undef __METHOD__
}
/**
* \brief Produces a unique identifier from the pvName and ca_client_context for entry into hash table
* \param pv input: process variable name
* \param ccc input: current context
* \return unique identifier
*/
unsigned int Helper::convertToUniqueNumber(const char * pv, ca_client_context * ccc) {
#define __METHOD__ "Helper::convertToUniqueNumber(const char * pv, ca_client_context * ccc)"
std::string myString=pv;
char s[12];
sprintf(s,"%ld", (unsigned long) ccc);
unsigned int numberPV = 0;
unsigned int numberContext =0 ;
double dpow=0;
unsigned int ld=0;
numberContext = atoi(s);
unsigned int intValueIs=0;
unsigned int iL=0;
for (unsigned int i=0; i< myString.size(); i++) {
intValueIs= (unsigned int) myString[i];
ld=1;
if ( (intValueIs >47 && intValueIs < 58) ||
(intValueIs >64 && intValueIs < 91) ||
(intValueIs >97 && intValueIs < 123) ) {
dpow=pow((float)42, (int)iL%4);
ld = static_cast<unsigned int>(dpow);
++iL;
}
else {
iL=0;
}
numberPV += (intValueIs*ld*(i+1));
}
return (numberPV+numberContext);
#undef __METHOD__
}
/**
* \brief enum CAFENUM::DBR_TYPE {DBR_PRIMITIVE=333,DBR_STS,DBR_TIME,
* DBR_GR,DBR_CTRL,DBR_NONE}; \n
* Extracts the CAFENUM::DBR_TYPE from the channel type
* \param _chtype input: channel type
* \return CAFENUM::DBR_TYPE
*/
CAFENUM::DBR_TYPE Helper::convertToCAFEDbrTypeClass(const chtype _chtype) const {
#define __METHOD__ "Helper::convertToCAFEDbrTypeClass(const chtype _chtype)"
if (_chtype>=DBR_STRING && _chtype <= DBR_DOUBLE) {
return CAFENUM::DBR_PRIMITIVE;
}
else if (_chtype>=DBR_STS_STRING && _chtype <= DBR_STS_DOUBLE) {
return CAFENUM::DBR_STS;
}
else if (_chtype>=DBR_TIME_STRING && _chtype <= DBR_TIME_DOUBLE) {
return CAFENUM::DBR_TIME;
}
else if (_chtype>=DBR_GR_STRING && _chtype <= DBR_GR_DOUBLE) {
return CAFENUM::DBR_GR;
}
else if (_chtype>=DBR_CTRL_STRING && _chtype <= DBR_CTRL_DOUBLE) {
return CAFENUM::DBR_CTRL;
}
else if (_chtype==DBR_PUT_ACKT || _chtype==DBR_PUT_ACKS) {
return CAFENUM::DBR_PUT;
}
else if (_chtype==DBR_STSACK_STRING) {
return CAFENUM::DBR_STSACK;
}
else if (_chtype==DBR_CLASS_NAME) {
return CAFENUM::DBR_CLASS;
}
else {
return CAFENUM::DBR_NONE;
}
#undef __METHOD__
}
/**
* \brief Concatinates dbr_char_t(unsigned char) into a string
* \param inpChar input: Array of dbr_char_t data types
* \param nChar input: size of array
* \return std:string The concatinated string
*/
std::string Helper::concatToString(dbr_char_t * inpChar, unsigned int nChar){
std::string psWF = "";
for (unsigned int i=0; i<nChar; ++i) {
if (inpChar[i] != '\0') {
psWF.append(1, inpChar[i]);
}
}
return psWF;
}

View File

@@ -0,0 +1,98 @@
///
/// \file loadCollectionXMLParser.cc
/// \author Jan Chrin, G. Prekas, PSI
/// \date Release: February 2015
/// \version CAFE 1.0.0
///
#include "loadCollectionXMLParser.h"
#if HAVE_LIBQTXML
const QString& loadCollectionXMLParser::tagConfig = "config";
const QString& loadCollectionXMLParser::tagGroup = "collection";
const QString& loadCollectionXMLParser::tagDescription = "description";
const QString& loadCollectionXMLParser::tagAttributes = "attributes";
const QString& loadCollectionXMLParser::tagAttribute = "attribute";
const QString& loadCollectionXMLParser::tagMember = "member";
const QString& loadCollectionXMLParser::tagDevice = "device";
loadCollectionXMLParser::loadCollectionXMLParser() {
}
loadCollectionXMLParser::~loadCollectionXMLParser() {
}
bool loadCollectionXMLParser::startElement(const QString& namespaceURI, const QString& localName,
const QString& qName, const QXmlAttributes& atts) {
bool error = false;
if (localName.compare(tagConfig, Qt::CaseInsensitive) == 0) {
}
else if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
devCollection = deviceCollection();
devCollection.name = atts.value("id").toAscii().constData();
state=NotWaiting;
} else if (localName.compare(tagDescription, Qt::CaseInsensitive) == 0) {
state = WaitingForDescription;
} else if (localName.compare(tagAttributes, Qt::CaseInsensitive) == 0) {
state=NotWaiting;
} else if (localName.compare(tagAttribute, Qt::CaseInsensitive) == 0) {
state=WaitingForAttribute;
} else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
cMember=collectionMember();
cMember.devicePosition = atts.value("pos").toFloat();
state=NotWaiting;
} else if (localName.compare(tagDevice, Qt::CaseInsensitive) == 0) {
state = WaitingForDevice;
} else {
error = true;
}
return !error;
}
bool loadCollectionXMLParser::endElement(const QString& namespaceURI, const QString& localName,
const QString& qName) {
if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
deviceCollectionV.push_back(devCollection);
} else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
devCollection.cMembers.push_back(cMember);
} else if (localName.compare(tagAttribute, Qt::CaseInsensitive) == 0) {
devCollection.attributes.push_back(attributeName);
}
return true;
}
bool loadCollectionXMLParser::characters(const QString& ch) {
bool error = false;
std::string data = ch.trimmed().toAscii().constData();;
switch (state) {
case WaitingForDevice:
cMember.deviceName = data;
//printf( "Waiting for Device %s \n", data.c_str());
break;
case WaitingForDescription:
//printf( "Waiting for Description %s \n", data.c_str());
devCollection.description = data;
break;
case WaitingForAttribute:
//printf( "Waiting for Attribute %s \n", data.c_str());
attributeName = data;
break;
case NotWaiting:
break;
default:
error = true;
printf("Unexpected state in loadCollectionXMLParser::characters : '%s'\n", data.c_str());
break;
}
return !error;
}
#endif

135
src/loadGroupXMLParser.cpp Normal file
View File

@@ -0,0 +1,135 @@
///
/// \file loadGroupXMLParser.cc
/// \author Jan Chrin, G. Prekas, PSI
/// \date Release: February 2015
/// \version CAFE 1.0.0
///
#include "loadGroupXMLParser.h"
#if HAVE_LIBQTXML
#include <stdio.h>
#include <stdlib.h>
const QString&loadGroupXMLParser::tagCollection_list = "config";
const QString&loadGroupXMLParser::tagGroup = "group";
const QString&loadGroupXMLParser::tagDescription = "description";
const QString&loadGroupXMLParser::tagStatusGroup = "statusGroup";
const QString&loadGroupXMLParser::tagMember = "member";
const QString&loadGroupXMLParser::tagName = "name";
const QString&loadGroupXMLParser::tagNelem = "nelem";
const QString&loadGroupXMLParser::tagStatus = "status";
const QString&loadGroupXMLParser::tagRule = "rule";
const QString&loadGroupXMLParser::tagDataType = "datatype";
const QString&loadGroupXMLParser::tagCollection = "collection";
const QString&loadGroupXMLParser::tagId = "id";
const QString&loadGroupXMLParser::tagAttrib = "attribute";
const QString&loadGroupXMLParser::tagCollectiveType = "collectivetype";
loadGroupXMLParser::loadGroupXMLParser() {
}
loadGroupXMLParser::~loadGroupXMLParser() {
}
bool loadGroupXMLParser::startElement(const QString& namespaceURI, const QString& localName,
const QString& qName, const QXmlAttributes& atts) {
bool error = false;
if (localName.compare(tagCollection_list, Qt::CaseInsensitive) == 0) {
}else if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
group = deviceGroup();
group.id = atts.value("id").toAscii().constData();
} else if (localName.compare(tagDescription, Qt::CaseInsensitive) == 0) {
state = WaitingForDescription;
} else if (localName.compare(tagStatusGroup, Qt::CaseInsensitive) == 0) {
state = WaitingForStatusGroup;
} else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
state = WaitingForMember;
} else if (localName.compare(tagName, Qt::CaseInsensitive) == 0) {
state = WaitingForName;
} else if (localName.compare(tagNelem, Qt::CaseInsensitive) == 0) {
state = WaitingForNelem;
} else if (localName.compare(tagStatus, Qt::CaseInsensitive) == 0) {
state = WaitingForStatus;
} else if (localName.compare(tagRule, Qt::CaseInsensitive) == 0) {
state = WaitingForRule;
} else if (localName.compare(tagDataType, Qt::CaseInsensitive) == 0) {
state = WaitingForDataType;
} else if (localName.compare(tagCollection, Qt::CaseInsensitive) == 0) {
collection = collectionInGroup();
} else if (localName.compare(tagId, Qt::CaseInsensitive) == 0) {
state = WaitingForId;
} else if (localName.compare(tagAttrib, Qt::CaseInsensitive) == 0) {
state = WaitingForAttrib;
} else if (localName.compare(tagCollectiveType, Qt::CaseInsensitive) == 0) {
state = WaitingForCollectiveType;
} else {
error = true;
}
return !error;
}
bool loadGroupXMLParser::endElement(const QString& namespaceURI,
const QString& localName, const QString& qName) {
if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
groups.push_back(group);
} else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
group.xmlMembers.push_back(xmlMem);
} else if (localName.compare(tagCollection, Qt::CaseInsensitive) == 0) {
group.collections.push_back(collection);
}
return true;
}
bool loadGroupXMLParser::characters(const QString& ch) {
bool error = false;
std::string data = ch.trimmed().toAscii().constData();
switch (state) {
case WaitingForDescription:
group.description = data;
break;
case WaitingForStatusGroup:
case WaitingForMember:
break;
case WaitingForName:
xmlMem=data;
break;
case WaitingForNelem:
break;
case WaitingForStatus:
break;
case WaitingForRule:
break;
case WaitingForDataType:
break;
case WaitingForId:
collection.id = data;
break;
case WaitingForAttrib:
collection.attrib = data;
break;
case WaitingForCollectiveType:
break;
default:
error = true;
printf("Unexpected state in loadGroupXMLParser::characters: '%s'\n", data.c_str());
break;
}
return !error;
}
#endif

27
src/makeManualWin.make Normal file
View File

@@ -0,0 +1,27 @@
INCLUDES = -Ic:\CAFE\CAFE\cpp\include -Ic:\CAFE\CAFE\cpp -Ic:\local\boost_1_62_0\boost \
-Ic:\local\boost_1_62_0 -Ic:\epics\base-3.14.12.5\include -Ic:\epics\base-3.14.12.5\include\os\WIN32 \
-Ic:\Qt\4.8.4\include
CXX=cl
CXXFLAGS = /W4 /EHsc /c
OUTPUT_OPTION = /o $@
LIB_LOCAL = C:\epics\base-3.14.12.5\lib\windows-x64\Com.lib C:\epics\base-3.14.12.5\lib\windows-x64\ca.lib \
C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_thread-vc100-mt-s-1_62.lib \
C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_system-vc100-mt-s-1_62.lib \
C:\Qt\4.8.4\lib\QtCore4.lib C:\Qt\4.8.4\lib\QtXml4.lib
LIBS = -lca -lCom
OBJS= src\cafeCache.obj src\cafeGroup.obj src\cafe.obj src\cafeVectors.obj \
src\cafeXML.obj src\callbackHandlerCreate.obj src\callbackHandlerMonitor.obj src\conduitGroup.obj src\conduit.obj \
src\connectCallbacks.obj src\connectGroup.obj \
src\connect.obj src\exceptionsHelper.obj src\granules.obj src\handleHelper.obj src\helper.obj \
src\loadCollectionXMLParser.obj src\loadGroupXMLParser.obj src\methodCallbacks.obj src\policyHelper.obj \
src\restorePVGroupXMLParser.obj src\transpose.obj $(LIB_LOCAL)
cafe.lib: $(OBJS)
LIB $(OBJS) /out:cafe.lib
%.obj: %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) $<

568
src/makefile Normal file
View File

@@ -0,0 +1,568 @@
# makefile.in generated by automake 1.11.1 from makefile.am.
# src/makefile. Generated from makefile.in by configure.
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
pkgdatadir = $(datadir)/cafe
pkgincludedir = $(includedir)/cafe
pkglibdir = $(libdir)/cafe
pkglibexecdir = $(libexecdir)/cafe
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-unknown-linux-gnu
host_triplet = x86_64-unknown-linux-gnu
#am__append_1 = PyCafe.cpp
subdir = src
DIST_COMMON = $(srcdir)/makefile.am $(srcdir)/makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/./include/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libcafe_la_LIBADD =
am__libcafe_la_SOURCES_DIST = cafe.cpp cafeCache.cpp cafeGroup.cpp \
cafeVectors.cpp cafeXML.cpp callbackHandlerCreate.cpp \
callbackHandlerMonitor.cpp conduit.cpp connect.cpp \
connectCallbacks.cpp exceptionsHelper.cpp granules.cpp \
handleHelper.cpp loadCollectionXMLParser.cpp \
loadGroupXMLParser.cpp methodCallbacks.cpp helper.cpp \
policyHelper.cpp conduitGroup.cpp connectGroup.cpp \
transpose.cpp restorePVGroupXMLParser.cpp PyCafe.cpp
#am__objects_1 = PyCafe.lo
am_libcafe_la_OBJECTS = cafe.lo cafeCache.lo cafeGroup.lo \
cafeVectors.lo cafeXML.lo callbackHandlerCreate.lo \
callbackHandlerMonitor.lo conduit.lo connect.lo \
connectCallbacks.lo exceptionsHelper.lo granules.lo \
handleHelper.lo loadCollectionXMLParser.lo \
loadGroupXMLParser.lo methodCallbacks.lo helper.lo \
policyHelper.lo conduitGroup.lo connectGroup.lo transpose.lo \
restorePVGroupXMLParser.lo $(am__objects_1)
libcafe_la_OBJECTS = $(am_libcafe_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(top_builddir)/./include
depcomp = $(SHELL) $(top_srcdir)/./depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libcafe_la_SOURCES)
DIST_SOURCES = $(am__libcafe_la_SOURCES_DIST)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run aclocal-1.11
AMTAR = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run tar
#if HAVE_ZEROMQ
#libcafe_la_SOURCES += cafeService.cpp
#endif
AM_CPPFLAGS = -fexceptions -fPIC -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/usr/include/QtCore -I/usr/include/QtXml -I$(top_srcdir)/include
AM_LDFLAGS = -L/usr/local/epics/base/lib/SL6-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/SL6-x86_64 -L/usr/lib64 -Wl,-rpath,/usr/lib64
AR = ar
AUTOCONF = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run autoconf
AUTOHEADER = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run autoheader
AUTOMAKE = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run automake-1.11
AWK = gawk
CAFE_CPPFLAGS = -I$(top_srcdir)/include
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = gcc -E
CPPFLAGS = -fexceptions -fPIC -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/usr/include/QtCore -I/usr/include/QtXml
CXX = g++
CXXCPP = g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DSYMUTIL =
DUMPBIN =
ECHO_C =
ECHO_N = -n
ECHO_T =
EGREP = /bin/grep -E
EXEEXT =
FGREP = /bin/grep -F
GREP = /bin/grep
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = -L/usr/local/epics/base/lib/SL6-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/SL6-x86_64 -L/usr/lib64 -Wl,-rpath,/usr/lib64
LIBOBJS =
LIBS = -lQtXml -lQtCore
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO =
LN_S = ln -s
LTLIBOBJS =
MAKEINFO = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run makeinfo
MKDIR_P = /bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT =
OBJDUMP = objdump
OBJEXT = o
OTOOL =
OTOOL64 =
PACKAGE = cafe
PACKAGE_BUGREPORT = Bug reports to: jan.chrin@psi.ch
PACKAGE_NAME = CAFE
PACKAGE_STRING = CAFE 1.0.0
PACKAGE_TARNAME = cafe
PACKAGE_VERSION = 1.0.0
PATH_SEPARATOR = :
RANLIB = ranlib
SED = /bin/sed
SET_MAKE =
SHELL = /bin/sh
STRIP = strip
VERSION = 1.0.0
abs_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/src
abs_srcdir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/src
abs_top_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp
abs_top_srcdir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_DUMPBIN =
am__include = include
am__leading_dot = .
am__quote =
am__tar = ${AMTAR} chof - "$$tardir"
am__untar = ${AMTAR} xf -
bindir = ${exec_prefix}/bin
build = x86_64-unknown-linux-gnu
build_alias =
build_cpu = x86_64
build_os = linux-gnu
build_vendor = unknown
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host = x86_64-unknown-linux-gnu
host_alias =
host_cpu = x86_64
host_os = linux-gnu
host_vendor = unknown
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/install-sh
libdir = /opt/gfa/cafe/cpp/cafe-1.3.0-final-1/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
lt_ECHO = echo
mandir = ${datarootdir}/man
mkdir_p = /bin/mkdir -p
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /opt/gfa/cafe/cpp/cafe-1.3.0-final-1
program_transform_name = s,x,x,
psdir = ${docdir}
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
sysconfdir = ${prefix}/etc
target_alias =
top_build_prefix = ../
top_builddir = ..
top_srcdir = ..
lib_LTLIBRARIES = libcafe.la
libcafe_la_SOURCES = cafe.cpp cafeCache.cpp cafeGroup.cpp \
cafeVectors.cpp cafeXML.cpp callbackHandlerCreate.cpp \
callbackHandlerMonitor.cpp conduit.cpp connect.cpp \
connectCallbacks.cpp exceptionsHelper.cpp granules.cpp \
handleHelper.cpp loadCollectionXMLParser.cpp \
loadGroupXMLParser.cpp methodCallbacks.cpp helper.cpp \
policyHelper.cpp conduitGroup.cpp connectGroup.cpp \
transpose.cpp restorePVGroupXMLParser.cpp $(am__append_1)
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/makefile.in: $(srcdir)/makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu src/makefile
.PRECIOUS: makefile
makefile: $(srcdir)/makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libcafe.la: $(libcafe_la_OBJECTS) $(libcafe_la_DEPENDENCIES)
$(CXXLINK) -rpath $(libdir) $(libcafe_la_OBJECTS) $(libcafe_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
include ./$(DEPDIR)/PyCafe.Plo
include ./$(DEPDIR)/cafe.Plo
include ./$(DEPDIR)/cafeCache.Plo
include ./$(DEPDIR)/cafeGroup.Plo
include ./$(DEPDIR)/cafeVectors.Plo
include ./$(DEPDIR)/cafeXML.Plo
include ./$(DEPDIR)/callbackHandlerCreate.Plo
include ./$(DEPDIR)/callbackHandlerMonitor.Plo
include ./$(DEPDIR)/conduit.Plo
include ./$(DEPDIR)/conduitGroup.Plo
include ./$(DEPDIR)/connect.Plo
include ./$(DEPDIR)/connectCallbacks.Plo
include ./$(DEPDIR)/connectGroup.Plo
include ./$(DEPDIR)/exceptionsHelper.Plo
include ./$(DEPDIR)/granules.Plo
include ./$(DEPDIR)/handleHelper.Plo
include ./$(DEPDIR)/helper.Plo
include ./$(DEPDIR)/loadCollectionXMLParser.Plo
include ./$(DEPDIR)/loadGroupXMLParser.Plo
include ./$(DEPDIR)/methodCallbacks.Plo
include ./$(DEPDIR)/policyHelper.Plo
include ./$(DEPDIR)/restorePVGroupXMLParser.Plo
include ./$(DEPDIR)/transpose.Plo
.cpp.o:
$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
# source='$<' object='$@' libtool=yes \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: makefile $(LTLIBRARIES)
installdirs:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

24
src/makefile.am Normal file
View File

@@ -0,0 +1,24 @@
## makefile.am - processed by automake to produce makefile.in
##
## input file for production of cafe library
##
lib_LTLIBRARIES = libcafe.la
libcafe_la_SOURCES = cafe.cpp cafeCache.cpp cafeGroup.cpp cafeVectors.cpp cafeXML.cpp \
callbackHandlerCreate.cpp callbackHandlerMonitor.cpp conduit.cpp connect.cpp connectCallbacks.cpp \
exceptionsHelper.cpp granules.cpp handleHelper.cpp loadCollectionXMLParser.cpp \
loadGroupXMLParser.cpp methodCallbacks.cpp helper.cpp policyHelper.cpp \
conduitGroup.cpp connectGroup.cpp transpose.cpp restorePVGroupXMLParser.cpp
if HAVE_PYCAFE_EXT
libcafe_la_SOURCES += PyCafe.cpp
endif
#if HAVE_ZEROMQ
#libcafe_la_SOURCES += cafeService.cpp
#endif
AM_CPPFLAGS = @AM_CPPFLAGS@ @CAFE_CPPFLAGS@
AM_LDFLAGS= @AM_LDFLAGS@

570
src/methodCallbacks.cpp Normal file
View File

@@ -0,0 +1,570 @@
///
/// \file methodCallbacks.cc
/// \author Jan Chrin, PSI
/// \date Release: February 2015
/// \version CAFE 1.0.0
#include "conduitEventHandlerArgs.h"
#include "methodCallbacks.h"
#include "connect.h"
//in methodCallbacks.h
//include <config.h>
//#if HAVE_PYTHON_H
//#include <PyCafe_api.h>
//#endif
#if HAVE_PYTHON_H
/**
* Callback function for when putWithCallback method is invoked
* \param args input: event handler_args structure
*/
void CALLBACK_CAFE::PyHandlerPut( struct event_handler_args args) {
#define __METHOD__ "CALLBACK_CAFE::PyHandlerPut"
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
// cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
unsigned int _handle = (unsigned long) args.usr;
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int) _handle);
if (it_handle != handle_index.end()) {
if(MUTEX)cafeMutex.lock();
//Change Channel Policy to NO_WAIT(?)
ChannelRequestStatus channelRequestStatusPut=(*it_handle).getChannelRequestStatusPut();
channelRequestStatusPut.setCallbackKind(false, true);
handle_index.modify(it_handle, change_channelRequestStatusPut(channelRequestStatusPut));
if(MUTEX)cafeMutex.unlock();
//if HAVE_PYTHON_H
(*it_handle).PyPutHandler();
//endif
}
else {
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
if ( (*itcs).getHandle()==_handle) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through itcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX)cafeMutex.lock();
ChannelRequestStatus channelRequestStatusPut=(*itcs).getChannelRequestStatusPut();
channelRequestStatusPut.setCallbackKind(false, true);
handle_index.modify(itcs, change_channelRequestStatusPut(channelRequestStatusPut));
if(MUTEX)cafeMutex.unlock();
//if HAVE_PYTHON_H
(*it_handle).PyPutHandler();
//endif
internalFlag=true;
break;
}
}
if (!internalFlag) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
return;
#undef __METHOD__
};
//#endif
//#if HAVE_PYTHON_H
/**
* Callback function for getCallback method is invoked
* with a pointer to the retrieved value
* \param args input: event handler arguments
*/
void CALLBACK_CAFE::PyHandlerGet( struct event_handler_args args) {
#define __METHOD__ "CALLBACK_CAFE::PyHandlerGet"
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
ChannelRequestStatus channelRequestStatusGet=(*it_handle).getChannelRequestStatusGet();
channelRequestStatusGet.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
handle_index.modify(it_handle, change_channelRequestStatusGet(channelRequestStatusGet));
//cout << __METHOD__ << " CALLBACK DONE " << (*it_handle).getChannelRequestStatusGet().getCallbackProgressKind() << endl;
if(MUTEX){cafeMutex.unlock();}
//if HAVE_PYTHON_H
(*it_handle).PyGetHandler();
//endif
}
else {
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
if ( (*itcs).getHandle()==_handle) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through tcs::iterator, since the by_handle::iterator was NOT found! " << endl;
ChannelRequestStatus channelRequestStatusGet=(*itcs).getChannelRequestStatusGet();
channelRequestStatusGet.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(itcs, change_eventHandlerArgs (args));
handle_index.modify(itcs, change_channelRequestStatusGet(channelRequestStatusGet));
if(MUTEX){cafeMutex.unlock();}
//if HAVE_PYTHON_H
(*it_handle).PyGetHandler();
//endif
internalFlag=true;
break;
}
}
if (!internalFlag) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
return;
#undef __METHOD__
};
#endif
/**
* Callback function for when putWithCallback method is invoked
* \param args input: event handler_args structure
*/
void CALLBACK_CAFE::handlerPut( struct event_handler_args args) {
#define __METHOD__ "CALLBACK_CAFE::handlerPut"
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr;
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int) _handle);
if (it_handle != handle_index.end()) {
if(MUTEX)cafeMutex.lock();
//Change Channel Policy to NO_WAIT(?)
ChannelRequestStatus channelRequestStatusPut=(*it_handle).getChannelRequestStatusPut();
channelRequestStatusPut.setCallbackKind(false, true);
handle_index.modify(it_handle, change_channelRequestStatusPut(channelRequestStatusPut));
if(MUTEX)cafeMutex.unlock();
}
else {
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
if ( (*itcs).getHandle()==_handle) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through itcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX)cafeMutex.lock();
ChannelRequestStatus channelRequestStatusPut=(*itcs).getChannelRequestStatusPut();
channelRequestStatusPut.setCallbackKind(false, true);
handle_index.modify(itcs, change_channelRequestStatusPut(channelRequestStatusPut));
if(MUTEX)cafeMutex.unlock();
internalFlag=true;
break;
}
}
if (!internalFlag) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
return;
#undef __METHOD__
};
/**
* Callback function for getCallback method is invoked
* with a pointer to the retrieved value
* \param args input: event handler arguments
*/
void CALLBACK_CAFE::handlerGet( struct event_handler_args args) {
#define __METHOD__ "CALLBACK_CAFE::handlerGet"
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
ChannelRequestStatus channelRequestStatusGet=(*it_handle).getChannelRequestStatusGet();
channelRequestStatusGet.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
handle_index.modify(it_handle, change_channelRequestStatusGet(channelRequestStatusGet));
//cout << __METHOD__ << " CALLBACK DONE " << (*it_handle).getChannelRequestStatusGet().getCallbackProgressKind() << endl;
if(MUTEX){cafeMutex.unlock();}
}
else {
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
if ( (*itcs).getHandle()==_handle) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through tcs::iterator, since the by_handle::iterator was NOT found! " << endl;
ChannelRequestStatus channelRequestStatusGet=(*itcs).getChannelRequestStatusGet();
channelRequestStatusGet.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(itcs, change_eventHandlerArgs (args));
handle_index.modify(itcs, change_channelRequestStatusGet(channelRequestStatusGet));
if(MUTEX){cafeMutex.unlock();}
internalFlag=true;
break;
}
}
if (!internalFlag) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
return;
#undef __METHOD__
};
/**
* Callback function for handlerGetCtrl method is invoked
* with a pointer to the retrieved value
* \param args input: event handler arguments
*/
void CALLBACK_CAFE::handlerGetCtrl( struct event_handler_args args) {
#define __METHOD__ "CALLBACK_CAFE::handlerGetCtrl "
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX){cafeMutex.unlock();}
ChannelRequestStatus channelRequestStatusGetCtrl=(*it_handle).getChannelRequestStatusGetCtrl();
channelRequestStatusGetCtrl.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_channelRequestStatusGetCtrl(channelRequestStatusGetCtrl));
if(MUTEX){cafeMutex.unlock();}
}
else {
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
if ( (*itcs).getHandle()==_handle) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through itcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX){cafeMutex.lock();}
handle_index.modify(itcs, change_eventHandlerArgs (args));
if(MUTEX){cafeMutex.unlock();}
ChannelRequestStatus channelRequestStatusGetCtrl=(*itcs).getChannelRequestStatusGetCtrl();
channelRequestStatusGetCtrl.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(itcs, change_channelRequestStatusGetCtrl(channelRequestStatusGetCtrl));
if(MUTEX){cafeMutex.unlock();}
internalFlag=true;
break;
}
}
if (!internalFlag) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
return;
#undef __METHOD__
};
/**
* Callback function for handlerSTSACK method is invoked
* with a pointer to the retrieved value
* \param args input: event handler arguments
*/
void CALLBACK_CAFE::handlerGetSTSACK( struct event_handler_args args) {
#define __METHOD__ "CALLBACK_CAFE::handlerGetSTSACK "
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX){cafeMutex.unlock();}
ChannelRequestStatus channelRequestStatusGetSTSACK=(*it_handle).getChannelRequestStatusGetSTSACK();
channelRequestStatusGetSTSACK.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_channelRequestStatusGetSTSACK(channelRequestStatusGetSTSACK));
if(MUTEX){cafeMutex.unlock();}
}
else {
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
if ( (*itcs).getHandle()==_handle) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through itcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX){cafeMutex.lock();}
handle_index.modify(itcs, change_eventHandlerArgs (args));
if(MUTEX){cafeMutex.unlock();}
ChannelRequestStatus channelRequestStatusGetSTSACK=(*itcs).getChannelRequestStatusGetSTSACK();
channelRequestStatusGetSTSACK.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(itcs, change_channelRequestStatusGetSTSACK(channelRequestStatusGetSTSACK));
if(MUTEX){cafeMutex.unlock();}
internalFlag=true;
break;
}
}
if (!internalFlag) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
return;
#undef __METHOD__
};
/**
* Callback function for handlerClassName method is invoked
* with a pointer to the retrieved value
* \param args input: event handler arguments
*/
void CALLBACK_CAFE::handlerGetClassName( struct event_handler_args args) {
#define __METHOD__ "CALLBACK_CAFE::handlerGetClassName "
if (args.status !=ECA_NORMAL) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX){cafeMutex.unlock();}
ChannelRequestStatus channelRequestStatusGetClassName=(*it_handle).getChannelRequestStatusGetClassName();
channelRequestStatusGetClassName.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_channelRequestStatusGetClassName(channelRequestStatusGetClassName));
if(MUTEX){cafeMutex.unlock();}
}
else {
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
if ( (*itcs).getHandle()==_handle) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through tcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX){cafeMutex.lock();}
handle_index.modify(itcs, change_eventHandlerArgs (args));
if(MUTEX){cafeMutex.unlock();}
ChannelRequestStatus channelRequestStatusGetClassName=(*it_handle).getChannelRequestStatusGetClassName();
channelRequestStatusGetClassName.setCallbackKind(false, true);
if(MUTEX){cafeMutex.lock();}
handle_index.modify(itcs, change_channelRequestStatusGetClassName(channelRequestStatusGetClassName));
if(MUTEX){cafeMutex.unlock();}
internalFlag=true;
break;
}
}
if (!internalFlag) {
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
return;
#undef __METHOD__
};

1640
src/policyHelper.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,185 @@
///
/// \file restorePVGroupXMLParser.cc
/// \author Jan Chrin, PSI
/// \date Release: February 2015
/// \version CAFE 1.0.0
///
#include "restorePVGroupXMLParser.h"
#if HAVE_LIBQTXML
#include <stdio.h>
#include <stdlib.h>
#include <vector>
vector<string> SplitString(const char *str, char c)
{
vector<string> result;
do {
const char *begin = str;
while(*str != c && *str) {
str++;
}
result.push_back(string(begin, str));
} while (0 != *str++);
return result;
}
const QString&restorePVGroupXMLParser::tagConfig = "config";
const QString&restorePVGroupXMLParser::tagGroup = "group";
const QString&restorePVGroupXMLParser::tagNPV = "npv";
const QString&restorePVGroupXMLParser::tagDescription = "description";
const QString&restorePVGroupXMLParser::tagStatusGroup = "statusGroup";
const QString&restorePVGroupXMLParser::tagMember = "member";
const QString&restorePVGroupXMLParser::tagName = "name";
const QString&restorePVGroupXMLParser::tagNelem = "nelem";
const QString&restorePVGroupXMLParser::tagStatus = "status";
const QString&restorePVGroupXMLParser::tagRule = "rule";
const QString&restorePVGroupXMLParser::tagVal = "val";
const QString&restorePVGroupXMLParser::tagSettable = "settable";
restorePVGroupXMLParser::restorePVGroupXMLParser() { icount=0;
}
restorePVGroupXMLParser::~restorePVGroupXMLParser() {
}
bool restorePVGroupXMLParser::startElement(const QString& namespaceURI, const QString& localName,
const QString& qName, const QXmlAttributes& atts) {
bool error = false;
if (localName.compare(tagConfig, Qt::CaseInsensitive) == 0) {
state = WaitingForConfig;
} else if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
group = PVGroup();
group.setName ( atts.value("id").toAscii().constData() );
pvd = new PVDataHolder[500]; //read in npv
state = WaitingForGroup;
} else if (localName.compare(tagNPV, Qt::CaseInsensitive) == 0) {
state = WaitingForNPV;
} else if (localName.compare(tagDescription, Qt::CaseInsensitive) == 0) {
state = WaitingForDescription;
} else if (localName.compare(tagStatusGroup, Qt::CaseInsensitive) == 0) {
state = WaitingForStatusGroup;
} else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
state = WaitingForMember;
} else if (localName.compare(tagName, Qt::CaseInsensitive) == 0) {
state = WaitingForName;
} else if (localName.compare(tagNelem, Qt::CaseInsensitive) == 0) {
state = WaitingForNelem;
} else if (localName.compare(tagStatus, Qt::CaseInsensitive) == 0) {
state = WaitingForStatus;
} else if (localName.compare(tagRule, Qt::CaseInsensitive) == 0) {
state = WaitingForRule;
} else if (localName.compare(tagVal, Qt::CaseInsensitive) == 0) {
state = WaitingForVal;
} else if (localName.compare(tagSettable, Qt::CaseInsensitive) == 0) {
state = WaitingForSettable;
} else {
error = true;
}
return !error;
}
bool restorePVGroupXMLParser::endElement(const QString& namespaceURI,
const QString& localName, const QString& qName) {
if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
group.setPVData(pvd);
group.npv=icount;
} else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
if(settable)++icount;
} else if (localName.compare(tagNPV, Qt::CaseInsensitive) == 0) {
}
return true;
}
bool restorePVGroupXMLParser::characters(const QString& ch) {
bool error = false;
std::string data = ch.trimmed().toAscii().constData();
switch (state) {
case WaitingForDescription:
case WaitingForGroup:
case WaitingForConfig:
case WaitingForStatusGroup:
case WaitingForMember:
break;
case WaitingForNPV:
break;
case WaitingForName:
strcpy(pvd[icount].pv,data.c_str());
break;
case WaitingForNelem:
pvd[icount].setNelem ( strtol(data.c_str(), NULL, 10) );
break;
case WaitingForStatus:
break;
case WaitingForRule:
break;
case WaitingForVal:
//if elements > 1, then break up string
//read no of elements and break up with space as deliminater!
if ( pvd[icount].getNelem() >1) {
//parse string
vector<string> v; v.clear(); v.reserve(pvd[icount].getNelem());
v = SplitString(data.c_str(), ' ');
dbr_string_t * arr = new dbr_string_t[ pvd[icount].getNelem()];
for (size_t i=0; i<v.size(); ++i) {
strcpy(arr[i], v[i].c_str());
}
pvd[icount].set(arr);
}
else {
pvd[icount].set(data);
}
break;
case WaitingForSettable:
if ( strcmp(data.c_str(),"true")==0) {
settable = true;
} else {
settable=false;
}
break;
default:
error = true;
printf("Unexpected: '%s'\n", data.c_str());
break;
}
return !error;
}
#endif

1305
src/transpose.cpp Normal file

File diff suppressed because it is too large Load Diff