From 5301a190860f92067350228a598d8ca091fcecfa Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Thu, 26 May 2011 09:18:34 +0200 Subject: [PATCH] completed --- testApp/remote/pvaget.cpp | 167 ++++++++++++++++++++++++++------------ 1 file changed, 116 insertions(+), 51 deletions(-) diff --git a/testApp/remote/pvaget.cpp b/testApp/remote/pvaget.cpp index c9a6eb2..11b314a 100644 --- a/testApp/remote/pvaget.cpp +++ b/testApp/remote/pvaget.cpp @@ -4,11 +4,13 @@ #include #include #include +#include #include #include using namespace std; +using namespace std::tr1; using namespace epics::pvData; using namespace epics::pvAccess; @@ -16,9 +18,9 @@ using namespace epics::pvAccess; -void convertStructure(StringBuilder buffer,PVStructure *data,int indentLevel); -void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel); -void convertStructureArray(StringBuilder buffer,PVStructureArray * pvdata,int indentLevel); +void convertStructure(StringBuilder buffer,PVStructure *data,int notFirst); +void convertArray(StringBuilder buffer,PVScalarArray * pv,int notFirst); +void convertStructureArray(StringBuilder buffer,PVStructureArray * pvdata,int notFirst); @@ -27,21 +29,22 @@ void convertStructureArray(StringBuilder buffer,PVStructureArray * pvdata,int in -void convertToString(StringBuilder buffer,PVField * pv,int indentLevel) +void convertToString(StringBuilder buffer,PVField * pv,int notFirst) { Type type = pv->getField()->getType(); if(type==structure) { - convertStructure(buffer,static_cast(pv),indentLevel); + convertStructure(buffer,static_cast(pv),notFirst); return; } - *buffer += "\t"; if(type==scalarArray) { - convertArray(buffer,static_cast(pv),indentLevel); + convertArray(buffer,static_cast(pv),notFirst); + *buffer += "\t"; return; } if(type==structureArray) { convertStructureArray( - buffer,static_cast(pv),indentLevel); + buffer,static_cast(pv),notFirst); + *buffer += "\t"; return; } PVScalar *pvScalar = static_cast(pv); @@ -57,72 +60,74 @@ void convertToString(StringBuilder buffer,PVField * pv,int indentLevel) *buffer += "false"; } } - return; + break; case pvByte: { PVByte *data = static_cast(pv); char xxx[30]; sprintf(xxx,"%d",(int)data->get()); *buffer += xxx; } - return; + break; case pvShort: { PVShort *data = static_cast(pv); char xxx[30]; sprintf(xxx,"%d",(int)data->get()); *buffer += xxx; } - return; + break; case pvInt: { PVInt *data = static_cast(pv); char xxx[30]; sprintf(xxx,"%d",(int)data->get()); *buffer += xxx; } - return; + break; case pvLong: { PVLong *data = static_cast(pv); char xxx[30]; sprintf(xxx,"%lld",(int64)data->get()); *buffer += xxx; } - return; + break; case pvFloat: { PVFloat *data = static_cast(pv); char xxx[30]; sprintf(xxx,"%g",data->get()); *buffer += xxx; } - return; + break; case pvDouble: { PVDouble *data = static_cast(pv); char xxx[30]; sprintf(xxx,"%lg",data->get()); *buffer += xxx; } - return; + break; case pvString: { PVString *data = static_cast(pv); *buffer += data->get(); } - return; + break; default: *buffer += "(unknown ScalarType)"; } + + *buffer += "\t"; } -void convertStructure(StringBuilder buffer,PVStructure *data,int indentLevel) +void convertStructure(StringBuilder buffer,PVStructure *data,int notFirst) { PVFieldPtrArray fieldsData = data->getPVFields(); if (fieldsData != 0) { int length = data->getStructure()->getNumberFields(); for(int i=0; igetScalarArray(); ScalarType type = array->getElementType(); @@ -289,7 +294,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel) } void convertStructureArray(StringBuilder buffer, - PVStructureArray * pvdata,int indentLevel) + PVStructureArray * pvdata,int notFirst) { int length = pvdata->getLength(); if(length<=0) { @@ -302,7 +307,7 @@ void convertStructureArray(StringBuilder buffer, if (pvStructure == 0) { *buffer += "null"; } else { - convertToString(buffer,pvStructure,indentLevel+1); + convertToString(buffer,pvStructure,notFirst+1); } } } @@ -328,8 +333,9 @@ void convertStructureArray(StringBuilder buffer, #define DEFAULT_TIMEOUT 3.0 #define DEFAULT_REQUEST "field(value)" -double caTimeout = DEFAULT_TIMEOUT; +double timeOut = DEFAULT_TIMEOUT; string request(DEFAULT_REQUEST); +bool terseMode = false; PVStructure::shared_pointer pvRequest; @@ -340,7 +346,8 @@ void usage (void) "options:\n" " -r : Request, specifies what fields to return and options, default is '%s'\n" " -w : Wait time, specifies timeout, default is %f second(s)\n" - "\nExample: pvaget my_channel \n\n" + " -t: Terse mode - print only value, without name" + "\nExample: pvaget example001 \n\n" , DEFAULT_REQUEST, DEFAULT_TIMEOUT); } @@ -348,13 +355,15 @@ void usage (void) class ChannelGetRequesterImpl : public ChannelGetRequester { private: - -ChannelGet::shared_pointer m_channelGet; - epics::pvData::PVStructure::shared_pointer m_pvStructure; - epics::pvData::BitSet::shared_pointer m_bitSet; + PVStructure::shared_pointer m_pvStructure; + BitSet::shared_pointer m_bitSet; + Event m_event; + String m_channelName; public: + ChannelGetRequesterImpl(String channelName) : m_channelName(channelName) {}; + virtual String getRequesterName() { return "ChannelGetRequesterImpl"; @@ -369,34 +378,66 @@ ChannelGet::shared_pointer m_channelGet; epics::pvData::PVStructure::shared_pointer const & pvStructure, epics::pvData::BitSet::shared_pointer const & bitSet) { - // TODO remove (cyclic shared_pointers) - m_channelGet = channelGet; - - m_pvStructure = pvStructure; - m_bitSet = bitSet; - channelGet->get(true); + if (status.isSuccess()) + { + // show warning + if (!status.isOK()) + { + std::cout << "[" << m_channelName << "] channel get create: " << status.toString() << std::endl; + } + + m_pvStructure = pvStructure; + m_bitSet = bitSet; + channelGet->get(true); + } + else + { + std::cout << "[" << m_channelName << "] failed to create channel get: " << status.toString() << std::endl; + } } virtual void getDone(const epics::pvData::Status& status) { - std::cout << "getDone(" << status.toString() << ")" << std::endl; - if (status.isSuccess()) { + // show warning + if (!status.isOK()) + { + std::cout << "[" << m_channelName << "] channel get: " << status.toString() << std::endl; + } + String str; - m_pvStructure->toString(&str); + if (terseMode) + convertToString(&str, m_pvStructure.get(), 0); + else + m_pvStructure->toString(&str); - //convertToString(&str, m_pvStructure.get(), 0); - std::cout << str; - std::cout << std::endl; + std::cout << str << std::endl; + + m_event.signal(); } + else + { + std::cout << "[" << m_channelName << "] failed to get: " << status.toString() << std::endl; + } + + } + + bool waitUntilGet(double timeOut) + { + return m_event.wait(timeOut); } }; class ChannelRequesterImpl : public ChannelRequester { +private: + Event m_event; + +public: + virtual String getRequesterName() { return "ChannelRequesterImpl"; @@ -414,12 +455,12 @@ class ChannelRequesterImpl : public ChannelRequester // show warning if (!status.isOK()) { - std::cout << "channel create: " << status.toString() << std::endl; + std::cout << "[" << channel->getChannelName() << "] channel create: " << status.toString() << std::endl; } } else { - std::cout << "failed to create a channel: " << status.toString() << std::endl; + std::cout << "[" << channel->getChannelName() << "] failed to create a channel: " << status.toString() << std::endl; } } @@ -427,16 +468,20 @@ class ChannelRequesterImpl : public ChannelRequester { if (connectionState == Channel::CONNECTED) { - ChannelGetRequester::shared_pointer getRequester(new ChannelGetRequesterImpl()); - channel->createChannelGet(getRequester, pvRequest); + m_event.signal(); } /* else if (connectionState != Channel::DESTROYED) { - std::cout << "channel state change: " << Channel::ConnectionStateNames[connectionState] << std::endl; + std::cout << "[" << channel->getChannelName() << "] channel state change: " << Channel::ConnectionStateNames[connectionState] << std::endl; } */ } + + bool waitUntilConnected(double timeOut) + { + return m_event.wait(timeOut); + } }; /*+************************************************************************** @@ -461,22 +506,25 @@ int main (int argc, char *argv[]) setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ - while ((opt = getopt(argc, argv, ":hr:w:")) != -1) { + while ((opt = getopt(argc, argv, ":hr:w:t")) != -1) { switch (opt) { case 'h': /* Print usage */ usage(); return 0; case 'w': /* Set CA timeout value */ - if(epicsScanDouble(optarg, &caTimeout) != 1) + if(epicsScanDouble(optarg, &timeOut) != 1) { fprintf(stderr, "'%s' is not a valid timeout value " "- ignored. ('cainfo -h' for help.)\n", optarg); - caTimeout = DEFAULT_TIMEOUT; + timeOut = DEFAULT_TIMEOUT; } break; case 'r': /* Set CA timeout value */ request = optarg; break; + case 't': /* Terse mode */ + terseMode = true; + break; case '?': fprintf(stderr, "Unrecognized option: '-%c'. ('pvaget -h' for help.)\n", @@ -511,16 +559,33 @@ int main (int argc, char *argv[]) return 1; } + // typedef enum {errlogInfo, errlogMinor, errlogMajor, errlogFatal} errlogSevEnum; + errlogSetSevToLog(errlogMajor); ClientFactory::start(); ChannelProvider::shared_pointer provider = getChannelAccess()->getProvider("pvAccess"); - ChannelRequester::shared_pointer channelRequester(new ChannelRequesterImpl()); - Channel::shared_pointer tmpChannel = provider->createChannel(pvs[0], channelRequester); // TODO + bool allOK = true; - epicsThreadSleep ( 3.0 ); - + // for now a simple iterating sync implementation, guarantees order + for (int n = 0; n < nPvs; n++) + { + shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); + Channel::shared_pointer channel = provider->createChannel(pvs[n], channelRequesterImpl); + if (channelRequesterImpl->waitUntilConnected(timeOut)) + { + shared_ptr getRequesterImpl(new ChannelGetRequesterImpl(channel->getChannelName())); + ChannelGet::shared_pointer channelGet = channel->createChannelGet(getRequesterImpl, pvRequest); + allOK &= getRequesterImpl->waitUntilGet(timeOut); + } + else + { + allOK = false; + channel->destroy(); + std::cout << "[" << channel->getChannelName() << "] connection timeout" << std::endl; + } + } ClientFactory::stop();