Files
pva2pva/testApp/check_consist.cpp
2017-07-11 16:00:44 +02:00

102 lines
3.7 KiB
C++

#include <pv/clientFactory.h>
#include "utilities.h"
namespace pvd = epics::pvData;
namespace pva = epics::pvAccess;
namespace {
struct Destroyer {
pvd::Destroyable::shared_pointer D;
Destroyer(const pvd::Destroyable::shared_pointer& d) : D(d) {}
~Destroyer() { if(D) D->destroy(); }
};
struct Releaser {
pva::Monitor::shared_pointer& mon;
pva::MonitorElementPtr& elem;
Releaser(pva::Monitor::shared_pointer& m, pva::MonitorElementPtr& e)
:mon(m), elem(e)
{}
~Releaser() { mon->release(elem); }
};
} // namespace
int main(int argc, char *argv[])
{
testPlan(0);
try {
if(argc<4) {
std::cerr<<"Usage: "<<argv[0]<<" <channel> <fld1> <fld2> ...";
return 1;
}
pvd::StructureConstPtr reqdesc(pvd::getFieldCreate()->createFieldBuilder()
->add("unused", pvd::pvBoolean)
->createStructure());
pvd::PVStructurePtr pvreq(pvd::getPVDataCreate()->createPVStructure(reqdesc));
pva::ClientFactory::start();
pva::ChannelProvider::shared_pointer prov(pva::ChannelProviderRegistry::clients()->getProvider("pva"));
if(!prov) throw std::runtime_error("No pva provider?!?");
Destroyer prov_d(prov);
TestChannelRequester::shared_pointer chreq(new TestChannelRequester);
pva::Channel::shared_pointer chan(prov->createChannel(argv[1], chreq));
Destroyer chan_d(chan);
if(!chan) throw std::runtime_error("Failed to create channel");
std::cout<<"Connecting...\n";
if(!chreq->waitForConnect())
throw std::runtime_error("Failed to connect channel");
TestChannelMonitorRequester::shared_pointer monreq(new TestChannelMonitorRequester);
pva::Monitor::shared_pointer mon(chan->createMonitor(monreq, pvreq));
Destroyer mon_d(mon);
if(!mon) throw std::runtime_error("Failed to create monitor");
if(!monreq->waitForConnect())
throw std::runtime_error("failed to connect monitor");
if(!mon->start().isSuccess())
throw std::runtime_error("failed to start monitor");
std::cout<<"Wait for initial event...\n";
while(monreq->waitForEvent()) {
pva::MonitorElementPtr elem;
while(!!(elem=mon->poll())) {
Releaser R(mon, elem);
pvd::PVStructurePtr A, B;
A = elem->pvStructurePtr->getSubField<pvd::PVStructure>("a");
B = elem->pvStructurePtr->getSubField<pvd::PVStructure>("b");
if(!A || !B)
throw std::runtime_error("unexpected types");
epicsUInt32 vA = A->getSubFieldT<pvd::PVScalar>("value")->getAs<pvd::uint32>(),
vB = B->getSubFieldT<pvd::PVScalar>("value")->getAs<pvd::uint32>();
epicsUInt64 tsA = A->getSubFieldT<pvd::PVScalar>("timeStamp.secondsPastEpoch")->getAs<pvd::uint64>(),
tsB = B->getSubFieldT<pvd::PVScalar>("timeStamp.secondsPastEpoch")->getAs<pvd::uint64>();
epicsUInt32 tnA = A->getSubFieldT<pvd::PVScalar>("timeStamp.nanoseconds")->getAs<pvd::uint32>(),
tnB = B->getSubFieldT<pvd::PVScalar>("timeStamp.nanoseconds")->getAs<pvd::uint32>();
if(vA==vB && tsA==tsB && tnA==tnB) {
std::cout<<".";
continue;
}
std::cout<<"\nMismatch:\nA:\n"<<*A<<"B:\n"<<*B<<"\n";
}
}
std::cout<<"Done\n";
return 0;
}catch(std::exception&e){
PRINT_EXCEPTION(e);
std::cerr<<"Error: "<<e.what()<<"\n";
return 1;
}
}