all EasyChannel methods are implemented except channelArray; EasyMultiChannel not started.

This commit is contained in:
Marty Kraimer
2015-03-13 15:09:55 -04:00
parent 5dc5e746f4
commit cdc72bc5ae
32 changed files with 4366 additions and 1747 deletions

View File

@@ -8,11 +8,15 @@ LIBRARY += easyPVA
INC += easyPVA.h
LIBSRCS += easyPVA.cpp
LIBSRCS += easyPVStructure.cpp
LIBSRCS += easyPutData.cpp
LIBSRCS += easyGetData.cpp
LIBSRCS += easyMonitorData.cpp
LIBSRCS += easyChannel.cpp
LIBSRCS += easyProcess.cpp
LIBSRCS += easyGet.cpp
#LIBSRCS += easyPut.cpp
#LIBSRCS += easyMonitor.cpp
LIBSRCS += easyPut.cpp
LIBSRCS += easyMonitor.cpp
LIBSRCS += easyPutGet.cpp
#LIBSRCS += easyRPC.cpp
easyPVA_LIBS += pvAccess pvData Com

View File

@@ -25,8 +25,6 @@ using namespace std;
namespace epics { namespace easyPVA {
class EasyGetCache;
typedef std::tr1::shared_ptr<EasyGetCache> EasyGetCachePtr;
class EasyGetCache
{
@@ -60,109 +58,65 @@ void EasyGetCache::addGet(string const & request,EasyGetPtr const & easyGet)
request,easyGet));
}
class epicsShareClass EasyChannelImpl :
public EasyChannel,
public std::tr1::enable_shared_from_this<EasyChannelImpl>
class EasyPutCache
{
public:
EasyChannelImpl(
EasyPVAPtr const &pva,
string const & channelName,
string const & providerName);
virtual ~EasyChannelImpl();
// from EasyChannel
void channelCreated(const Status& status, Channel::shared_pointer const & channel);
void channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState);
tr1::shared_ptr<Channel> getChannel();
string getRequesterName();
void message(
string const & message,
MessageType messageType);
virtual void destroy();
virtual string getChannelName();
virtual void connect(double timeout);
virtual void issueConnect();
virtual Status waitConnect(double timeout);
virtual EasyFieldPtr createField();
virtual EasyFieldPtr createField(string const & subField);
virtual EasyProcessPtr createProcess();
virtual EasyProcessPtr createProcess(string const & request);
virtual EasyProcessPtr createProcess(PVStructurePtr const & pvRequest);
virtual EasyGetPtr get() {return get("value,alarm,timeStamp");}
virtual EasyGetPtr get(string const & request);
virtual EasyGetPtr createGet();
virtual EasyGetPtr createGet(string const & request);
virtual EasyGetPtr createGet(PVStructurePtr const & pvRequest);
virtual EasyPutPtr createPut();
virtual EasyPutPtr createPut(string const & request);
virtual EasyPutPtr createPut(PVStructurePtr const & pvRequest);
virtual EasyPutGetPtr createPutGet();
virtual EasyPutGetPtr createPutGet(string const & request);
virtual EasyPutGetPtr createPutGet(PVStructurePtr const & pvRequest);
virtual EasyRPCPtr createRPC();
virtual EasyRPCPtr createRPC(string const & request);
virtual EasyRPCPtr createRPC(PVStructurePtr const & pvRequest);
virtual EasyArrayPtr createArray();
virtual EasyArrayPtr createArray(string const & request);
virtual EasyArrayPtr createArray(PVStructurePtr const & pvRequest);
virtual EasyMonitorPtr createMonitor();
virtual EasyMonitorPtr createMonitor(string const & request);
virtual EasyMonitorPtr createMonitor(PVStructurePtr const & pvRequest);
EasyChannelPtr getPtrSelf()
{
return shared_from_this();
EasyPutCache(){}
~EasyPutCache();
void destroy() {
easyPutMap.clear();
}
EasyPutPtr getPut(string const & request);
void addPut(string const & request,EasyPutPtr const & easyPut);
private:
enum ConnectState {connectIdle,connectActive,notConnected,connected};
EasyPVA::weak_pointer easyPVA;
string channelName;
string providerName;
ConnectState connectState;
bool isDestroyed;
CreateRequest::shared_pointer createRequest;
EasyGetCachePtr easyGetCache;
Status channelConnectStatus;
Mutex mutex;
Event waitForConnect;
Channel::shared_pointer channel;
ChannelRequester::shared_pointer channelRequester;
map<string,EasyPutPtr> easyPutMap;
};
namespace easyChannel {
EasyPutCache::~EasyPutCache()
{
destroy();
}
EasyPutPtr EasyPutCache::getPut(string const & request)
{
map<string,EasyPutPtr>::iterator iter = easyPutMap.find(request);
if(iter!=easyPutMap.end()) return iter->second;
return EasyPutPtr();
}
void EasyPutCache::addPut(string const & request,EasyPutPtr const & easyPut)
{
easyPutMap.insert(std::pair<string,EasyPutPtr>(
request,easyPut));
}
class ChannelRequesterImpl : public ChannelRequester
{
EasyChannelImpl *easyChannel;
EasyChannel *easyChannel;
public:
ChannelRequesterImpl(EasyChannelImpl *easyChannel)
ChannelRequesterImpl(EasyChannel *easyChannel)
: easyChannel(easyChannel) {}
virtual void channelCreated(
void channelCreated(
const Status& status,
Channel::shared_pointer const & channel)
{ easyChannel->channelCreated(status,channel); }
virtual void channelStateChange(
void channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState)
{easyChannel->channelStateChange(channel,connectionState);}
virtual tr1::shared_ptr<Channel> getChannel() {return easyChannel->getChannel();}
virtual string getRequesterName()
tr1::shared_ptr<Channel> getChannel() {return easyChannel->getChannel();}
string getRequesterName()
{return easyChannel->getRequesterName();}
virtual void message(
void message(
string const & message,
MessageType messageType)
{ easyChannel->message(message,messageType); }
virtual void destroy() {easyChannel->destroy();}
void destroy() {easyChannel->destroy();}
};
} //end namespace easyChannel`
using namespace epics::easyPVA::easyChannel;
EasyChannelImpl::EasyChannelImpl(
EasyChannel::EasyChannel(
EasyPVAPtr const &easyPVA,
string const & channelName,
string const & providerName)
@@ -172,25 +126,26 @@ EasyChannelImpl::EasyChannelImpl(
connectState(connectIdle),
isDestroyed(false),
createRequest(CreateRequest::create()),
easyGetCache(new EasyGetCache())
easyGetCache(new EasyGetCache()),
easyPutCache(new EasyPutCache())
{}
EasyChannelImpl::~EasyChannelImpl()
EasyChannel::~EasyChannel()
{
destroy();
}
void EasyChannelImpl::channelCreated(const Status& status, Channel::shared_pointer const & channel)
void EasyChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
if(status.isOK()) {
this->channel = channel;
return;
}
cout << "EasyChannelImpl::channelCreated status " << status.getMessage() << " why??\n";
cout << "EasyChannel::channelCreated status " << status.getMessage() << " why??\n";
}
void EasyChannelImpl::channelStateChange(
void EasyChannel::channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState)
{
@@ -209,20 +164,20 @@ void EasyChannelImpl::channelStateChange(
if(waitingForConnect) waitForConnect.signal();
}
tr1::shared_ptr<Channel> EasyChannelImpl::getChannel()
tr1::shared_ptr<Channel> EasyChannel::getChannel()
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
return channel;
}
string EasyChannelImpl::getRequesterName()
string EasyChannel::getRequesterName()
{
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
return yyy->getRequesterName();
}
void EasyChannelImpl::message(
void EasyChannel::message(
string const & message,
MessageType messageType)
{
@@ -232,7 +187,7 @@ void EasyChannelImpl::message(
yyy->message(message, messageType);
}
void EasyChannelImpl::destroy()
void EasyChannel::destroy()
{
{
Lock xx(mutex);
@@ -242,15 +197,16 @@ void EasyChannelImpl::destroy()
if(channel) channel->destroy();
channel.reset();
easyGetCache.reset();
easyPutCache.reset();
}
string EasyChannelImpl::getChannelName()
string EasyChannel::getChannelName()
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
return channelName;
}
void EasyChannelImpl::connect(double timeout)
void EasyChannel::connect(double timeout)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
issueConnect();
@@ -261,7 +217,7 @@ void EasyChannelImpl::connect(double timeout)
throw std::runtime_error(ss.str());
}
void EasyChannelImpl::issueConnect()
void EasyChannel::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
if(connectState!=connectIdle) {
@@ -279,7 +235,7 @@ void EasyChannelImpl::issueConnect()
}
}
Status EasyChannelImpl::waitConnect(double timeout)
Status EasyChannel::waitConnect(double timeout)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
waitForConnect.wait(timeout);
@@ -287,22 +243,22 @@ Status EasyChannelImpl::waitConnect(double timeout)
return Status(Status::STATUSTYPE_ERROR,channelConnectStatus.getMessage());
}
EasyFieldPtr EasyChannelImpl::createField()
EasyFieldPtr EasyChannel::createField()
{
return createField("");
}
EasyFieldPtr EasyChannelImpl::createField(string const & subField)
EasyFieldPtr EasyChannel::createField(string const & subField)
{
throw std::runtime_error("EasyChannel::createField not implemented");
}
EasyProcessPtr EasyChannelImpl::createProcess()
EasyProcessPtr EasyChannel::createProcess()
{
return createProcess("");
}
EasyProcessPtr EasyChannelImpl::createProcess(string const & request)
EasyProcessPtr EasyChannel::createProcess(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
@@ -314,28 +270,33 @@ EasyProcessPtr EasyChannelImpl::createProcess(string const & request)
return createProcess(pvRequest);
}
EasyProcessPtr EasyChannelImpl::createProcess(PVStructurePtr const & pvRequest)
EasyProcessPtr EasyChannel::createProcess(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createProcess not implemented");
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatProcess not connected");
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
return EasyProcess::create(yyy,getPtrSelf(),channel,pvRequest);
}
EasyGetPtr EasyChannelImpl::get(string const & request)
EasyGetPtr EasyChannel::get() {return get("value,alarm,timeStamp");}
EasyGetPtr EasyChannel::get(string const & request)
{
EasyGetPtr easyGet = easyGetCache->getGet(request);
if(easyGet) return easyGet;
easyGet = createGet(request);
easyGet->connect();
easyGet->get();
easyGetCache->addGet(request,easyGet);
return easyGet;
}
EasyGetPtr EasyChannelImpl::createGet()
EasyGetPtr EasyChannel::createGet()
{
return EasyChannelImpl::createGet("value,alarm,timeStamp");
return EasyChannel::createGet("value,alarm,timeStamp");
}
EasyGetPtr EasyChannelImpl::createGet(string const & request)
EasyGetPtr EasyChannel::createGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
@@ -347,21 +308,34 @@ EasyGetPtr EasyChannelImpl::createGet(string const & request)
return createGet(pvRequest);
}
EasyGetPtr EasyChannelImpl::createGet(PVStructurePtr const & pvRequest)
EasyGetPtr EasyChannel::createGet(PVStructurePtr const & pvRequest)
{
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatGet not connected");
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
return EasyGetFactory::createEasyGet(yyy,getPtrSelf(),channel,pvRequest);
return EasyGet::create(yyy,getPtrSelf(),channel,pvRequest);
}
EasyPutPtr EasyChannelImpl::createPut()
EasyPutPtr EasyChannel::put() {return put("value");}
EasyPutPtr EasyChannel::put(string const & request)
{
EasyPutPtr easyPut = easyPutCache->getPut(request);
if(easyPut) return easyPut;
easyPut = createPut(request);
easyPut->connect();
easyPut->get();
easyPutCache->addPut(request,easyPut);
return easyPut;
}
EasyPutPtr EasyChannel::createPut()
{
return createPut("value");
}
EasyPutPtr EasyChannelImpl::createPut(string const & request)
EasyPutPtr EasyChannel::createPut(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
@@ -373,17 +347,21 @@ EasyPutPtr EasyChannelImpl::createPut(string const & request)
return createPut(pvRequest);
}
EasyPutPtr EasyChannelImpl::createPut(PVStructurePtr const & pvRequest)
EasyPutPtr EasyChannel::createPut(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createPut not implemented");
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatPut not connected");
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
return EasyPut::create(yyy,getPtrSelf(),channel,pvRequest);
}
EasyPutGetPtr EasyChannelImpl::createPutGet()
EasyPutGetPtr EasyChannel::createPutGet()
{
return createPutGet("putField(argument)getField(result)");
}
EasyPutGetPtr EasyChannelImpl::createPutGet(string const & request)
EasyPutGetPtr EasyChannel::createPutGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
@@ -395,17 +373,21 @@ EasyPutGetPtr EasyChannelImpl::createPutGet(string const & request)
return createPutGet(pvRequest);
}
EasyPutGetPtr EasyChannelImpl::createPutGet(PVStructurePtr const & pvRequest)
EasyPutGetPtr EasyChannel::createPutGet(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createPutGet not implemented");
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatPutGet not connected");
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
return EasyPutGet::create(yyy,getPtrSelf(),channel,pvRequest);
}
EasyRPCPtr EasyChannelImpl::createRPC()
EasyRPCPtr EasyChannel::createRPC()
{
return createRPC("");
}
EasyRPCPtr EasyChannelImpl::createRPC(string const & request)
EasyRPCPtr EasyChannel::createRPC(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
@@ -417,17 +399,17 @@ EasyRPCPtr EasyChannelImpl::createRPC(string const & request)
return createRPC(pvRequest);
}
EasyRPCPtr EasyChannelImpl::createRPC(PVStructurePtr const & pvRequest)
EasyRPCPtr EasyChannel::createRPC(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createRPC not implemented");
}
EasyArrayPtr EasyChannelImpl::createArray()
EasyArrayPtr EasyChannel::createArray()
{
return createArray("value");
}
EasyArrayPtr EasyChannelImpl::createArray(string const & request)
EasyArrayPtr EasyChannel::createArray(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
@@ -439,17 +421,42 @@ EasyArrayPtr EasyChannelImpl::createArray(string const & request)
return createArray(pvRequest);
}
EasyArrayPtr EasyChannelImpl::createArray(PVStructurePtr const & pvRequest)
EasyArrayPtr EasyChannel::createArray(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createArray not implemented");
}
EasyMonitorPtr EasyChannelImpl::createMonitor()
EasyMonitorPtr EasyChannel::monitor() {return monitor("value,alarm,timeStamp");}
EasyMonitorPtr EasyChannel::monitor(string const & request)
{
EasyMonitorPtr easyMonitor = createMonitor(request);
easyMonitor->connect();
easyMonitor->start();
return easyMonitor;
}
EasyMonitorPtr EasyChannel::monitor(EasyMonitorRequesterPtr const & easyMonitorRequester)
{ return monitor("value,alarm,timeStamp",easyMonitorRequester);
}
EasyMonitorPtr EasyChannel::monitor(string const & request,
EasyMonitorRequesterPtr const & easyMonitorRequester)
{
EasyMonitorPtr easyMonitor = createMonitor(request);
easyMonitor->connect();
easyMonitor->setRequester(easyMonitorRequester);
easyMonitor->start();
return easyMonitor;
}
EasyMonitorPtr EasyChannel::createMonitor()
{
return createMonitor("value,alarm,timeStamp");
}
EasyMonitorPtr EasyChannelImpl::createMonitor(string const & request)
EasyMonitorPtr EasyChannel::createMonitor(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
@@ -461,25 +468,22 @@ EasyMonitorPtr EasyChannelImpl::createMonitor(string const & request)
return createMonitor(pvRequest);
}
EasyMonitorPtr EasyChannelImpl::createMonitor(PVStructurePtr const & pvRequest)
EasyMonitorPtr EasyChannel::createMonitor(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createMonitor not implemented");
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("EasyChannel::createMonitor not connected");
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
return EasyMonitor::create(yyy,getPtrSelf(),channel,pvRequest);
}
EasyChannelPtr EasyChannelFactory::createEasyChannel(
EasyPVAPtr const &easyPVA,
string const & channelName)
{
return EasyChannelFactory::createEasyChannel(easyPVA,channelName,"pva");
}
EasyChannelPtr EasyChannelFactory::createEasyChannel(
EasyChannelPtr EasyChannel::create(
EasyPVAPtr const &easyPVA,
string const & channelName,
string const & providerName)
{
EasyChannelPtr channel(new EasyChannelImpl(easyPVA,channelName,providerName));
EasyChannelPtr channel(new EasyChannel(easyPVA,channelName,providerName));
return channel;
}

View File

@@ -12,9 +12,7 @@
#include <sstream>
#include <pv/event.h>
#include <pv/lock.h>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
@@ -23,139 +21,31 @@ using namespace std;
namespace epics { namespace easyPVA {
class epicsShareClass EasyGetImpl :
public EasyGet,
public std::tr1::enable_shared_from_this<EasyGetImpl>
class ChannelGetRequesterImpl : public ChannelGetRequester
{
EasyGet * easyGet;
public:
EasyGetImpl(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest);
~EasyGetImpl();
// from ChannelGetRequester
string getRequesterName();
void message(string const & message,MessageType messageType);
ChannelGetRequesterImpl(EasyGet * easyGet)
: easyGet(easyGet) {}
string getRequesterName()
{return easyGet->getRequesterName();}
void message(string const & message,MessageType messageType)
{easyGet->message(message,messageType);}
void channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & structure);
StructureConstPtr const & structure)
{easyGet->channelGetConnect(status,channelGet,structure);}
void getDone(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet);
// from EasyGet
virtual void destroy();
virtual void connect();
virtual void issueConnect();
virtual Status waitConnect();
virtual void get();
virtual void issueGet();
virtual Status waitGet();
virtual BitSetPtr getBitSet();
// from EasyPVStructure
virtual void setMessagePrefix(std::string const & value);
virtual void setPVStructure(epics::pvData::PVStructurePtr const & pvStructure);
virtual Alarm getAlarm();
virtual TimeStamp getTimeStamp();
virtual bool hasValue();
virtual bool isValueScalar();
virtual bool isValueScalarArray();
virtual PVFieldPtr getValue();
virtual PVScalarPtr getScalarValue();
virtual std::tr1::shared_ptr<PVArray> getArrayValue();
virtual std::tr1::shared_ptr<PVScalarArray> getScalarArrayValue();
virtual bool getBoolean();
virtual int8 getByte();
virtual int16 getShort();
virtual int32 getInt();
virtual int64 getLong();
virtual uint8 getUByte();
virtual uint16 getUShort();
virtual uint32 getUInt();
virtual uint64 getULong();
virtual float getFloat();
virtual double getDouble();
virtual std::string getString();
virtual shared_vector<boolean> getBooleanArray();
virtual shared_vector<int8> getByteArray();
virtual shared_vector<int16> getShortArray();
virtual shared_vector<int32> getIntArray();
virtual shared_vector<int64> getLongArray();
virtual shared_vector<uint8> getUByteArray();
virtual shared_vector<uint16> getUShortArray();
virtual shared_vector<uint32> getUIntArray();
virtual shared_vector<uint64> getULongArray();
virtual shared_vector<float> getFloatArray();
virtual shared_vector<double> getDoubleArray();
virtual shared_vector<std::string> getStringArray();
virtual PVStructurePtr getPVStructure();
EasyGetPtr getPtrSelf()
{
return shared_from_this();
}
private:
void checkGetState();
enum GetConnectState {connectIdle,connectActive,connected};
EasyPVA::weak_pointer easyPVA;
EasyChannel::weak_pointer easyChannel;
Channel::shared_pointer channel;
ChannelGetRequester::shared_pointer getRequester;
PVStructurePtr pvRequest;
Mutex mutex;
Event waitForConnect;
Event waitForGet;
EasyPVStructurePtr easyPVStructure;
string messagePrefix;
bool isDestroyed;
Status channelGetConnectStatus;
Status channelGetStatus;
ChannelGet::shared_pointer channelGet;
BitSet::shared_pointer bitSet;
GetConnectState connectState;
enum GetState {getIdle,getActive,getComplete};
GetState getState;
bool getSuccess;
BitSetPtr const & bitSet)
{easyGet->getDone(status,channelGet,pvStructure,bitSet);}
};
namespace easyGet {
class ChannelGetRequesterImpl : public ChannelGetRequester
{
EasyGetImpl * easyGet;
public:
ChannelGetRequesterImpl(EasyGetImpl * easyGet)
: easyGet(easyGet) {}
virtual string getRequesterName()
{return easyGet->getRequesterName();}
virtual void message(string const & message,MessageType messageType)
{easyGet->message(message,messageType);}
virtual void channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & structure)
{easyGet->channelGetConnect(status,channelGet,structure);}
virtual void getDone(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{easyGet->getDone(status,channelGet,pvStructure,bitSet);}
};
} // namespace easyGet
using namespace epics::easyPVA::easyGet;
EasyGetImpl::EasyGetImpl(
EasyGet::EasyGet(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
@@ -164,20 +54,18 @@ EasyGetImpl::EasyGetImpl(
easyChannel(easyChannel),
channel(channel),
pvRequest(pvRequest),
easyPVStructure(pva->createEasyPVStructure()),
isDestroyed(false),
connectState(connectIdle),
getState(getIdle)
{
easyPVStructure->setMessagePrefix("channel " + channel->getChannelName() + " EasyGet");
}
EasyGetImpl::~EasyGetImpl()
EasyGet::~EasyGet()
{
destroy();
}
void EasyGetImpl::checkGetState()
void EasyGet::checkGetState()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState==connectIdle) connect();
@@ -185,14 +73,14 @@ void EasyGetImpl::checkGetState()
}
// from ChannelGetRequester
string EasyGetImpl::getRequesterName()
string EasyGet::getRequesterName()
{
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
return yyy->getRequesterName();
}
void EasyGetImpl::message(string const & message,MessageType messageType)
void EasyGet::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
EasyPVAPtr yyy = easyPVA.lock();
@@ -200,7 +88,7 @@ void EasyGetImpl::message(string const & message,MessageType messageType)
yyy->message(message, messageType);
}
void EasyGetImpl::channelGetConnect(
void EasyGet::channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & structure)
@@ -209,35 +97,30 @@ void EasyGetImpl::channelGetConnect(
channelGetConnectStatus = status;
this->channelGet = channelGet;
if(status.isOK()) {
connectState = connected;
} else {
connectState = connectIdle;
easyData = EasyGetData::create(structure);
easyData->setMessagePrefix(channel->getChannelName());
}
waitForConnect.signal();
}
void EasyGetImpl::getDone(
void EasyGet::getDone(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
easyPVStructure->setPVStructure(pvStructure);
this->bitSet = bitSet;
channelGetStatus = status;
if(status.isOK()) {
getState = getComplete;
} else {
getState = getIdle;
easyData->setData(pvStructure,bitSet);
}
waitForGet.signal();
}
// from EasyGet
void EasyGetImpl::destroy()
void EasyGet::destroy()
{
{
Lock xx(mutex);
@@ -248,7 +131,7 @@ void EasyGetImpl::destroy()
channelGet.reset();
}
void EasyGetImpl::connect()
void EasyGet::connect()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
issueConnect();
@@ -259,7 +142,7 @@ void EasyGetImpl::connect()
throw std::runtime_error(ss.str());
}
void EasyGetImpl::issueConnect()
void EasyGet::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState!=connectIdle) {
@@ -272,7 +155,7 @@ void EasyGetImpl::issueConnect()
channelGet = channel->createChannelGet(getRequester,pvRequest);
}
Status EasyGetImpl::waitConnect()
Status EasyGet::waitConnect()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState!=connectActive) {
@@ -281,11 +164,15 @@ Status EasyGetImpl::waitConnect()
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(connectState==connected) return Status::Ok;
if(channelGetConnectStatus.isOK()){
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,channelGetConnectStatus.getMessage());
}
void EasyGetImpl::get()
void EasyGet::get()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
issueGet();
@@ -296,7 +183,7 @@ void EasyGetImpl::get()
throw std::runtime_error(ss.str());
}
void EasyGetImpl::issueGet()
void EasyGet::issueGet()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState==connectIdle) connect();
@@ -309,7 +196,7 @@ void EasyGetImpl::issueGet()
channelGet->get();
}
Status EasyGetImpl::waitGet()
Status EasyGet::waitGet()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(getState!=getActive){
@@ -318,243 +205,25 @@ Status EasyGetImpl::waitGet()
throw std::runtime_error(ss.str());
}
waitForGet.wait();
if(getState==getComplete) {
getState = getIdle;
getState = getIdle;
if(channelGetStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetStatus.getMessage());
}
BitSetPtr EasyGetImpl::getBitSet()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return bitSet;
}
void EasyGetImpl::setMessagePrefix(string const & value)
{
messagePrefix = value;
if(value.size()>0) messagePrefix += " ";
}
void EasyGetImpl::setPVStructure(epics::pvData::PVStructurePtr const & pvStructure)
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
throw std::runtime_error("easyGet does not implement setPVStructure");
}
Alarm EasyGetImpl::getAlarm()
EasyGetDataPtr EasyGet::getData()
{
checkGetState();
return easyPVStructure->getAlarm();
return easyData;
}
TimeStamp EasyGetImpl::getTimeStamp()
{
checkGetState();
return easyPVStructure->getTimeStamp();
}
bool EasyGetImpl::hasValue()
{
checkGetState();
return easyPVStructure->hasValue();
}
bool EasyGetImpl::isValueScalar()
{
checkGetState();
return easyPVStructure->isValueScalar();
}
bool EasyGetImpl::isValueScalarArray()
{
checkGetState();
return easyPVStructure->isValueScalarArray();
}
PVFieldPtr EasyGetImpl::getValue()
{
checkGetState();
return easyPVStructure->getValue();
}
PVScalarPtr EasyGetImpl::getScalarValue()
{
checkGetState();
return easyPVStructure->getScalarValue();
}
std::tr1::shared_ptr<PVArray> EasyGetImpl::getArrayValue()
{
checkGetState();
return easyPVStructure->getArrayValue();
}
std::tr1::shared_ptr<PVScalarArray> EasyGetImpl::getScalarArrayValue()
{
checkGetState();
return easyPVStructure->getScalarArrayValue();
}
bool EasyGetImpl::getBoolean()
{
checkGetState();
return easyPVStructure->getBoolean();
}
int8 EasyGetImpl::getByte()
{
checkGetState();
return easyPVStructure->getByte();
}
int16 EasyGetImpl::getShort()
{
checkGetState();
return easyPVStructure->getShort();
}
int32 EasyGetImpl::getInt()
{
checkGetState();
return easyPVStructure->getInt();
}
int64 EasyGetImpl::getLong()
{
checkGetState();
return easyPVStructure->getLong();
}
uint8 EasyGetImpl::getUByte()
{
checkGetState();
return easyPVStructure->getUByte();
}
uint16 EasyGetImpl::getUShort()
{
checkGetState();
return easyPVStructure->getUShort();
}
uint32 EasyGetImpl::getUInt()
{
checkGetState();
return easyPVStructure->getUInt();
}
uint64 EasyGetImpl::getULong()
{
checkGetState();
return easyPVStructure->getULong();
}
float EasyGetImpl::getFloat()
{
checkGetState();
return easyPVStructure->getFloat();
}
double EasyGetImpl::getDouble()
{
checkGetState();
return easyPVStructure->getDouble();
}
std::string EasyGetImpl::getString()
{
checkGetState();
return easyPVStructure->getString();
}
shared_vector<boolean> EasyGetImpl::getBooleanArray()
{
checkGetState();
return easyPVStructure->getBooleanArray();
}
shared_vector<int8> EasyGetImpl::getByteArray()
{
checkGetState();
return easyPVStructure->getByteArray();
}
shared_vector<int16> EasyGetImpl::getShortArray()
{
checkGetState();
return easyPVStructure->getShortArray();
}
shared_vector<int32> EasyGetImpl::getIntArray()
{
checkGetState();
return easyPVStructure->getIntArray();
}
shared_vector<int64> EasyGetImpl::getLongArray()
{
checkGetState();
return easyPVStructure->getLongArray();
}
shared_vector<uint8> EasyGetImpl::getUByteArray()
{
checkGetState();
return easyPVStructure->getUByteArray();
}
shared_vector<uint16> EasyGetImpl::getUShortArray()
{
checkGetState();
return easyPVStructure->getUShortArray();
}
shared_vector<uint32> EasyGetImpl::getUIntArray()
{
checkGetState();
return easyPVStructure->getUIntArray();
}
shared_vector<uint64> EasyGetImpl::getULongArray()
{
checkGetState();
return easyPVStructure->getULongArray();
}
shared_vector<float> EasyGetImpl::getFloatArray()
{
checkGetState();
return easyPVStructure->getFloatArray();
}
shared_vector<double> EasyGetImpl::getDoubleArray()
{
checkGetState();
return easyPVStructure->getDoubleArray();
}
shared_vector<std::string> EasyGetImpl::getStringArray()
{
checkGetState();
return easyPVStructure->getStringArray();
}
PVStructurePtr EasyGetImpl::getPVStructure()
{
checkGetState();
return easyPVStructure->getPVStructure();
}
EasyGetPtr EasyGetFactory::createEasyGet(
EasyGetPtr EasyGet::create(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
EasyGetPtr epv(new EasyGetImpl(pva,easyChannel,channel,pvRequest));
EasyGetPtr epv(new EasyGet(pva,easyChannel,channel,pvRequest));
return epv;
}

200
src/easyGetData.cpp Normal file
View File

@@ -0,0 +1,200 @@
/* easyGetData.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <typeinfo>
#include <sstream>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
#include <pv/convert.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noStructure("no pvStructure ");
static string noValue("no value field");
static string noScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string noArray("value is not an array");
static string noScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
EasyGetDataPtr EasyGetData::create(StructureConstPtr const & structure)
{
EasyGetDataPtr epv(new EasyGetData(structure));
return epv;
}
EasyGetData::EasyGetData(StructureConstPtr const & structure)
: structure(structure)
{}
void EasyGetData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void EasyGetData::setMessagePrefix(std::string const & value)
{
messagePrefix = value;
}
StructureConstPtr EasyGetData::getStructure()
{return structure;}
PVStructurePtr EasyGetData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr EasyGetData::getBitSet()
{
if(bitSet)return bitSet;
throw std::runtime_error(messagePrefix + noStructure);
}
std::ostream & EasyGetData::showChanged(std::ostream & out)
{
if(!bitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
void EasyGetData::setData(
PVStructurePtr const & pvStructureFrom,
BitSetPtr const & bitSetFrom)
{
pvStructure = pvStructureFrom;
bitSet = bitSetFrom;
pvValue = pvStructure->getSubField("value");
}
bool EasyGetData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool EasyGetData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool EasyGetData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr EasyGetData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr EasyGetData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalar);
}
return pv;
}
PVArrayPtr EasyGetData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noArray);
}
return pv;
}
PVScalarArrayPtr EasyGetData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalarArray);
}
return pv;
}
double EasyGetData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string EasyGetData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> EasyGetData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> EasyGetData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
}}

250
src/easyMonitor.cpp Normal file
View File

@@ -0,0 +1,250 @@
/* easyMonitor.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.03
*/
#define epicsExportSharedSymbols
#include <sstream>
#include <pv/event.h>
#include <pv/easyPVA.h>
#include <pv/bitSetUtil.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
class ChannelMonitorRequester : public MonitorRequester
{
EasyMonitor * easyMonitor;
public:
ChannelMonitorRequester(EasyMonitor * easyMonitor)
: easyMonitor(easyMonitor) {}
string getRequesterName()
{return easyMonitor->getRequesterName();}
void message(string const & message,MessageType messageType)
{easyMonitor->message(message,messageType);}
void monitorConnect(
const Status& status,
Monitor::shared_pointer const & monitor,
StructureConstPtr const & structure)
{easyMonitor->monitorConnect(status,monitor,structure);}
void monitorEvent(MonitorPtr const & monitor)
{
easyMonitor->monitorEvent(monitor);
}
void unlisten(MonitorPtr const & monitor)
{easyMonitor->unlisten();}
};
EasyMonitor::EasyMonitor(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: easyPVA(pva),
easyChannel(easyChannel),
channel(channel),
pvRequest(pvRequest),
isDestroyed(false),
connectState(connectIdle),
userPoll(false),
userWait(false)
{
}
EasyMonitor::~EasyMonitor()
{
destroy();
}
void EasyMonitor::checkMonitorState()
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
if(connectState==connectIdle) connect();
if(connectState==connected) start();
}
// from MonitorRequester
string EasyMonitor::getRequesterName()
{
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
return yyy->getRequesterName();
}
void EasyMonitor::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
yyy->message(message, messageType);
}
void EasyMonitor::monitorConnect(
const Status& status,
Monitor::shared_pointer const & monitor,
StructureConstPtr const & structure)
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
connectStatus = status;
this->monitor = monitor;
if(status.isOK()) {
easyData = EasyMonitorData::create(structure);
easyData->setMessagePrefix(channel->getChannelName());
}
waitForConnect.signal();
}
void EasyMonitor::monitorEvent(MonitorPtr const & monitor)
{
EasyMonitorRequesterPtr req = easyMonitorRequester.lock();
if(req) req->event(getPtrSelf());
if(userWait) waitForEvent.signal();
}
void EasyMonitor::unlisten()
{
destroy();
}
// from EasyMonitor
void EasyMonitor::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(monitor) monitor->destroy();
monitor.reset();
}
void EasyMonitor::connect()
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyMonitor::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyMonitor::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyMonitor already connected ";
throw std::runtime_error(ss.str());
}
monitorRequester = ChannelMonitorRequester::shared_pointer(new ChannelMonitorRequester(this));
connectState = connectActive;
monitor = channel->createMonitor(monitorRequester,pvRequest);
}
Status EasyMonitor::waitConnect()
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyMonitor illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(connectStatus.isOK()){
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,connectStatus.getMessage());
}
void EasyMonitor::setRequester(EasyMonitorRequesterPtr const & easyMonitorrRequester)
{
this->easyMonitorRequester = easyMonitorrRequester;
}
void EasyMonitor::start()
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
if(connectState==monitorStarted) return;
if(connectState==connectIdle) connect();
if(connectState!=connected) throw std::runtime_error("EasyMonitor::start illegal state");
connectState = monitorStarted;
monitor->start();
}
void EasyMonitor::stop()
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
if(connectState!=monitorStarted) return;
connectState = connected;
monitor->stop();
}
bool EasyMonitor::poll()
{
checkMonitorState();
if(connectState!=monitorStarted) throw std::runtime_error("EasyMonitor::poll illegal state");
if(userPoll) throw std::runtime_error("EasyMonitor::poll did not release last");
monitorElement = monitor->poll();
if(!monitorElement) return false;
userPoll = true;
easyData->setData(monitorElement);
return true;
}
bool EasyMonitor::waitEvent(double secondsToWait)
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
if(connectState!=monitorStarted) throw std::runtime_error("EasyMonitor::poll illegal state");
if(poll()) return true;
userWait = true;
if(secondsToWait==0.0) {
waitForEvent.wait();
} else {
waitForEvent.wait(secondsToWait);
}
userWait = false;
return poll();
}
void EasyMonitor::releaseEvent()
{
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
if(connectState!=monitorStarted) throw std::runtime_error("EasyMonitor::poll illegal state");
if(!userPoll) throw std::runtime_error("EasyMonitor::releaseEvent did not call poll");
userPoll = false;
monitor->release(monitorElement);
}
EasyMonitorDataPtr EasyMonitor::getData()
{
checkMonitorState();
return easyData;
}
EasyMonitorPtr EasyMonitor::create(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
EasyMonitorPtr epv(new EasyMonitor(pva,easyChannel,channel,pvRequest));
return epv;
}
}}

226
src/easyMonitorData.cpp Normal file
View File

@@ -0,0 +1,226 @@
/* easyMonitorData.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <typeinfo>
#include <sstream>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
#include <pv/convert.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static StructureConstPtr nullStructure;
static PVStructurePtr nullPVStructure;
static ConvertPtr convert = getConvert();
static string noStructure("no pvStructure ");
static string noValue("no value field");
static string noScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string noArray("value is not an array");
static string noScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
EasyMonitorDataPtr EasyMonitorData::create(StructureConstPtr const & structure)
{
EasyMonitorDataPtr epv(new EasyMonitorData(structure));
return epv;
}
EasyMonitorData::EasyMonitorData(StructureConstPtr const & structure)
: structure(structure)
{}
void EasyMonitorData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void EasyMonitorData::setMessagePrefix(std::string const & value)
{
messagePrefix = value;
}
StructureConstPtr EasyMonitorData::getStructure()
{return structure;}
PVStructurePtr EasyMonitorData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr EasyMonitorData::getChangedBitSet()
{
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
return changedBitSet;
}
BitSetPtr EasyMonitorData::getOverrunBitSet()
{
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
return overrunBitSet;
}
std::ostream & EasyMonitorData::showChanged(std::ostream & out)
{
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = changedBitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = changedBitSet->nextSetBit(nextSet+1);
}
return out;
}
std::ostream & EasyMonitorData::showOverrun(std::ostream & out)
{
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = overrunBitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = overrunBitSet->nextSetBit(nextSet+1);
}
return out;
}
void EasyMonitorData::setData(MonitorElementPtr const & monitorElement)
{
pvStructure = monitorElement->pvStructurePtr;
changedBitSet = monitorElement->changedBitSet;
overrunBitSet = monitorElement->overrunBitSet;
pvValue = pvStructure->getSubField("value");
}
bool EasyMonitorData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool EasyMonitorData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool EasyMonitorData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr EasyMonitorData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr EasyMonitorData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalar);
}
return pv;
}
PVArrayPtr EasyMonitorData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noArray);
}
return pv;
}
PVScalarArrayPtr EasyMonitorData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalarArray);
}
return pv;
}
double EasyMonitorData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string EasyMonitorData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> EasyMonitorData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> EasyMonitorData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
}}

View File

@@ -98,7 +98,6 @@ void EasyChannelCache::removeChannel(string const & channelName)
using namespace epics::easyPVA::easyPVAPvt;
EasyPVAPtr EasyPVA::create()
{
EasyPVAPtr xx(new EasyPVA());
@@ -152,11 +151,6 @@ void EasyPVA::message(
cout << getMessageTypeName(messageType) << " " << message << endl;
}
EasyPVStructurePtr EasyPVA::createEasyPVStructure()
{
return EasyPVStructureFactory::createEasyPVStructure();
}
EasyChannelPtr EasyPVA::channel(
std::string const & channelName,
std::string const & providerName,
@@ -172,12 +166,12 @@ EasyChannelPtr EasyPVA::channel(
EasyChannelPtr EasyPVA::createChannel(string const & channelName)
{
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName);
return EasyChannel::create(getPtrSelf(),channelName);
}
EasyChannelPtr EasyPVA::createChannel(string const & channelName, string const & providerName)
{
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName,providerName);
return EasyChannel::create(getPtrSelf(),channelName,providerName);
}
}}

File diff suppressed because it is too large Load Diff

View File

@@ -1,597 +0,0 @@
/* easyPVStructure.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <typeinfo>
#include <sstream>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
#include <pv/convert.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
typedef std::tr1::shared_ptr<epics::pvData::PVArray> PVArrayPtr;
static StructureConstPtr nullStructure;
static PVStructurePtr nullPVStructure;
static ConvertPtr convert = getConvert();
static Status statusOK(Status::Ok);
static Status statusDestroyed(Status::STATUSTYPE_ERROR,"was destroyed");
static Status statusNoPVStructure(Status::STATUSTYPE_ERROR,"setPVStructure not called");
static Status statusNoValue(Status::STATUSTYPE_ERROR,"no value field");
static Status statusNoScalar(Status::STATUSTYPE_ERROR,"value is not a scalar");
static Status statusMismatchedScalar(Status::STATUSTYPE_ERROR,"value is not a compatible scalar");
static Status statusNoArray(Status::STATUSTYPE_ERROR,"value is not a array");
static Status statusNoScalarArray(Status::STATUSTYPE_ERROR,"value is not a scalarArray");
static Status statusMismatchedScalarArray(Status::STATUSTYPE_ERROR,"value is not a compatible scalarArray");
static Status statusNoAlarm(Status::STATUSTYPE_ERROR,"no alarm field");
static Status statusNoTimeStamp(Status::STATUSTYPE_ERROR,"no timeStamp field");
class epicsShareClass EasyPVStructureImpl :
public EasyPVStructure,
public std::tr1::enable_shared_from_this<EasyPVStructureImpl>
{
public:
EasyPVStructureImpl();
~EasyPVStructureImpl(){}
virtual void setMessagePrefix(std::string const & value);
virtual void setPVStructure(PVStructurePtr const & pvStructure);
virtual PVStructurePtr getPVStructure();
virtual Alarm getAlarm();
virtual TimeStamp getTimeStamp();
virtual bool hasValue();
virtual bool isValueScalar();
virtual bool isValueScalarArray() ;
virtual PVFieldPtr getValue();
virtual PVScalarPtr getScalarValue();
virtual std::tr1::shared_ptr<PVArray> getArrayValue();
virtual std::tr1::shared_ptr<PVScalarArray> getScalarArrayValue();
virtual bool getBoolean();
virtual int8 getByte();
virtual int16 getShort();
virtual int32 getInt();
virtual int64 getLong();
virtual uint8 getUByte();
virtual uint16 getUShort();
virtual uint32 getUInt();
virtual uint64 getULong();
virtual float getFloat();
virtual double getDouble();
virtual std::string getString();
virtual shared_vector<boolean> getBooleanArray();
virtual shared_vector<int8> getByteArray();
virtual shared_vector<int16> getShortArray();
virtual shared_vector<int32> getIntArray();
virtual shared_vector<int64> getLongArray();
virtual shared_vector<uint8> getUByteArray();
virtual shared_vector<uint16> getUShortArray();
virtual shared_vector<uint32> getUIntArray();
virtual shared_vector<uint64> getULongArray();
virtual shared_vector<float> getFloatArray();
virtual shared_vector<double> getDoubleArray();
virtual shared_vector<string> getStringArray();
EasyPVStructurePtr getPtrSelf()
{
return shared_from_this();
}
private:
void checkPVStructure();
void checkValue();
bool checkOverflow(ScalarType source,ScalarType dest);
PVScalarPtr checkScalar(ScalarType scalarType);
PVScalarArrayPtr checkScalarArray(ScalarType elementType);
string messagePrefix;
PVStructurePtr pvStructure;
PVFieldPtr pvValue;
PVAlarm pvAlarm;
Alarm alarm;
PVTimeStamp pvTimeStamp;
TimeStamp timeStamp;
};
EasyPVStructureImpl::EasyPVStructureImpl()
{}
EasyPVStructurePtr EasyPVStructureFactory::createEasyPVStructure()
{
EasyPVStructurePtr epv(new EasyPVStructureImpl());
return epv;
}
void EasyPVStructureImpl::checkPVStructure()
{
if(pvStructure) return;
throw std::runtime_error(messagePrefix + statusNoPVStructure.getMessage());
}
void EasyPVStructureImpl::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + statusNoValue.getMessage());
}
bool EasyPVStructureImpl::checkOverflow(ScalarType source,ScalarType dest)
{
if(dest==pvFloat||dest==pvDouble) return true;
if(!ScalarTypeFunc::isInteger(source) && !ScalarTypeFunc::isUInteger(source)) return false;
if(ScalarTypeFunc::isUInteger(dest)) {
if(ScalarTypeFunc::isUInteger(source)) {
if(dest>=source) return true;
return false;
}
if(ScalarTypeFunc::isInteger(source)) {
if(dest>=(source+4)) return true;
return false;
}
return false;
}
if(ScalarTypeFunc::isInteger(dest)) {
if(ScalarTypeFunc::isUInteger(source)) {
if(dest>(source-4)) return true;
return false;
}
if(ScalarTypeFunc::isInteger(source)) {
if(dest>=source) return true;
return false;
}
return false;
}
return false;
}
PVScalarPtr EasyPVStructureImpl::checkScalar(ScalarType scalarType)
{
checkPVStructure();
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoScalar.getMessage());
}
ScalarType type = pv->getScalar()->getScalarType();
if((scalarType==pvBoolean && type==pvBoolean)
|| (scalarType==pvString && type==pvString)) return pv;
if((ScalarTypeFunc::isNumeric(type) && ScalarTypeFunc::isNumeric(scalarType))
&& checkOverflow(type,scalarType)) return pv;
stringstream ss;
ss << messagePrefix << statusMismatchedScalar.getMessage();
ss << " source " << type << " dest " << scalarType;
throw std::runtime_error(ss.str());
}
PVScalarArrayPtr EasyPVStructureImpl::checkScalarArray(ScalarType elementType)
{
checkPVStructure();
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoScalarArray.getMessage());
}
ScalarType type = pv->getScalarArray()->getElementType();
if((elementType==pvBoolean && type==pvBoolean)
|| (elementType==pvBoolean && type==pvBoolean)) return pv;
if((ScalarTypeFunc::isNumeric(type) && ScalarTypeFunc::isNumeric(elementType))
&& checkOverflow(type,elementType)) return pv;
throw std::runtime_error(messagePrefix + statusMismatchedScalarArray.getMessage());
}
void EasyPVStructureImpl::setMessagePrefix(string const & value)
{
messagePrefix = value;
if(value.size()>0) messagePrefix += " ";
}
void EasyPVStructureImpl::setPVStructure(PVStructurePtr const & pvStructure)
{
this->pvStructure = pvStructure;
pvValue = pvStructure->getSubField("value");
}
PVStructurePtr EasyPVStructureImpl::getPVStructure()
{
checkPVStructure();
return pvStructure;
}
PVFieldPtr EasyPVStructureImpl::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr EasyPVStructureImpl::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoScalar.getMessage());
}
return pv;
}
PVArrayPtr EasyPVStructureImpl::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoArray.getMessage());
}
return pv;
}
PVScalarArrayPtr EasyPVStructureImpl::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + statusNoScalarArray.getMessage());
}
return pv;
}
Alarm EasyPVStructureImpl::getAlarm()
{
Alarm alarm;
alarm.setSeverity(undefinedAlarm);
alarm.setStatus(undefinedStatus);
alarm.setMessage("no alarm field");
if(!pvStructure) return alarm;
PVStructurePtr xxx = pvStructure->getSubField<PVStructure>("alarm");
if(xxx) {
pvAlarm.attach(xxx);
if(pvAlarm.isAttached()) {
pvAlarm.get(alarm);
pvAlarm.detach();
}
}
return alarm;;
}
TimeStamp EasyPVStructureImpl::getTimeStamp()
{
TimeStamp timeStamp;
if(!pvStructure) return timeStamp;
PVStructurePtr xxx = pvStructure->getSubField<PVStructure>("timeStamp");
if(xxx) {
pvTimeStamp.attach(xxx);
if(pvTimeStamp.isAttached()) {
pvTimeStamp.get(timeStamp);
pvTimeStamp.detach();
}
}
return timeStamp;;
}
bool EasyPVStructureImpl::hasValue()
{
if(!pvValue) return false;
return true;
}
bool EasyPVStructureImpl::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool EasyPVStructureImpl::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
bool EasyPVStructureImpl::getBoolean()
{
PVScalarPtr pvScalar = checkScalar(pvBoolean);
PVBooleanPtr pv = static_pointer_cast<PVBoolean>(pvScalar);
return pv->get();
}
int8 EasyPVStructureImpl::getByte()
{
PVScalarPtr pvScalar = checkScalar(pvByte);
return convert->toByte(pvScalar);
}
uint8 EasyPVStructureImpl::getUByte()
{
PVScalarPtr pvScalar = checkScalar(pvUByte);
return convert->toUByte(pvScalar);
}
int16 EasyPVStructureImpl::getShort()
{
PVScalarPtr pvScalar = checkScalar(pvShort);
return convert->toShort(pvScalar);
}
uint16 EasyPVStructureImpl::getUShort()
{
PVScalarPtr pvScalar = checkScalar(pvUShort);
return convert->toUShort(pvScalar);
}
int32 EasyPVStructureImpl::getInt()
{
PVScalarPtr pvScalar = checkScalar(pvInt);
return convert->toInt(pvScalar);
}
uint32 EasyPVStructureImpl::getUInt()
{
PVScalarPtr pvScalar = checkScalar(pvUInt);
return convert->toUInt(pvScalar);
}
int64 EasyPVStructureImpl::getLong()
{
PVScalarPtr pvScalar = checkScalar(pvLong);
return convert->toLong(pvScalar);
}
uint64 EasyPVStructureImpl::getULong()
{
PVScalarPtr pvScalar = checkScalar(pvULong);
return convert->toULong(pvScalar);
}
float EasyPVStructureImpl::getFloat()
{
PVScalarPtr pvScalar = checkScalar(pvFloat);
return convert->toFloat(pvScalar);
}
double EasyPVStructureImpl::getDouble()
{
PVScalarPtr pvScalar = checkScalar(pvDouble);
return convert->toDouble(pvScalar);
}
string EasyPVStructureImpl::getString()
{
PVScalarPtr pvScalar = checkScalar(pvString);
PVStringPtr pv = static_pointer_cast<PVString>(pvScalar);
return pv->get();
}
shared_vector<boolean> EasyPVStructureImpl::getBooleanArray()
{
checkScalarArray(pvBoolean);
PVBooleanArrayPtr pv = static_pointer_cast<PVBooleanArray>(pvValue);
return pv->reuse();
}
template <typename T>
shared_vector<T> copy(PVScalarArrayPtr const & pvScalarArray)
{
ScalarType elementType = pvScalarArray->getScalarArray()->getElementType();
switch(elementType) {
case pvBoolean :
break;
case pvByte :
{
PVByteArrayPtr pv = static_pointer_cast<PVByteArray>(pvScalarArray);
shared_vector<int8> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,int8>(data);
return to;
}
case pvShort :
{
PVShortArrayPtr pv = static_pointer_cast<PVShortArray>(pvScalarArray);
shared_vector<int16> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,int16>(data);
return to;
}
case pvInt :
{
PVIntArrayPtr pv = static_pointer_cast<PVIntArray>(pvScalarArray);
shared_vector<int32> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,int32>(data);
return to;
}
case pvLong :
{
PVLongArrayPtr pv = static_pointer_cast<PVLongArray>(pvScalarArray);
shared_vector<int64> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,int64>(data);
return to;
}
case pvUByte :
{
PVUByteArrayPtr pv = static_pointer_cast<PVUByteArray>(pvScalarArray);
shared_vector<uint8> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,uint8>(data);
return to;
}
case pvUShort :
{
PVUShortArrayPtr pv = static_pointer_cast<PVUShortArray>(pvScalarArray);
shared_vector<uint16> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,uint16>(data);
return to;
}
case pvUInt :
{
PVUIntArrayPtr pv = static_pointer_cast<PVUIntArray>(pvScalarArray);
shared_vector<uint32> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,uint32>(data);
return to;
}
case pvULong :
{
PVULongArrayPtr pv = static_pointer_cast<PVULongArray>(pvScalarArray);
shared_vector<uint64> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,uint64>(data);
return to;
}
case pvFloat :
{
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvScalarArray);
shared_vector<float> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,float>(data);
return to;
}
case pvDouble :
{
PVDoubleArrayPtr pv = static_pointer_cast<PVDoubleArray>(pvScalarArray);
shared_vector<double> data = pv->reuse();
shared_vector<T> to = shared_vector_convert<T,double>(data);
return to;
}
case pvString :
break;
}
return shared_vector<T>();
}
shared_vector<int8> EasyPVStructureImpl::getByteArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvByte);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvByte) {
PVByteArrayPtr pv = static_pointer_cast<PVByteArray>(pvValue);
return pv->reuse();
}
shared_vector<int8> xx = copy<int8>(pvScalarArray);
return xx;
}
shared_vector<int16> EasyPVStructureImpl::getShortArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvShort);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvShort) {
PVShortArrayPtr pv = static_pointer_cast<PVShortArray>(pvValue);
return pv->reuse();
}
shared_vector<int16> xx = copy<int16>(pvScalarArray);
return xx;
}
shared_vector<int32> EasyPVStructureImpl::getIntArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvInt);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvInt) {
PVIntArrayPtr pv = static_pointer_cast<PVIntArray>(pvValue);
return pv->reuse();
}
shared_vector<int32> xx = copy<int32>(pvScalarArray);
return xx;
}
shared_vector<int64> EasyPVStructureImpl::getLongArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvLong);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvLong) {
PVLongArrayPtr pv = static_pointer_cast<PVLongArray>(pvValue);
return pv->reuse();
}
shared_vector<int64> xx = copy<int64>(pvScalarArray);
return xx;
}
shared_vector<uint8> EasyPVStructureImpl::getUByteArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUByte);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvUByte) {
PVUByteArrayPtr pv = static_pointer_cast<PVUByteArray>(pvValue);
return pv->reuse();
}
shared_vector<uint8> xx = copy<uint8>(pvScalarArray);
return xx;
}
shared_vector<uint16> EasyPVStructureImpl::getUShortArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUShort);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvUShort) {
PVUShortArrayPtr pv = static_pointer_cast<PVUShortArray>(pvValue);
return pv->reuse();
}
shared_vector<uint16> xx = copy<uint16>(pvScalarArray);
return xx;
}
shared_vector<uint32> EasyPVStructureImpl::getUIntArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUInt);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvUInt) {
PVUIntArrayPtr pv = static_pointer_cast<PVUIntArray>(pvValue);
return pv->reuse();
}
shared_vector<uint32> xx = copy<uint32>(pvScalarArray);
return xx;
}
shared_vector<uint64> EasyPVStructureImpl::getULongArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvULong);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvULong) {
PVULongArrayPtr pv = static_pointer_cast<PVULongArray>(pvValue);
return pv->reuse();
}
shared_vector<uint64> xx = copy<uint64>(pvScalarArray);
return xx;
}
shared_vector<float> EasyPVStructureImpl::getFloatArray()
{
checkScalarArray(pvFloat);
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvValue);
return pv->reuse();
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvFloat);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvFloat) {
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvValue);
return pv->reuse();
}
shared_vector<float> xx = copy<float>(pvScalarArray);
return xx;
}
shared_vector<double> EasyPVStructureImpl::getDoubleArray()
{
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvDouble);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(scalarType==pvDouble) {
PVDoubleArrayPtr pv = static_pointer_cast<PVDoubleArray>(pvValue);
return pv->reuse();
}
shared_vector<double> xx = copy<double>(pvScalarArray);
return xx;
}
shared_vector<string> EasyPVStructureImpl::getStringArray()
{
checkScalarArray(pvString);
PVStringArrayPtr pv = static_pointer_cast<PVStringArray>(pvValue);
return pv->reuse();
}
}}

212
src/easyProcess.cpp Normal file
View File

@@ -0,0 +1,212 @@
/* easyProcess.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <sstream>
#include <pv/event.h>
#include <pv/easyPVA.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
class ChannelProcessRequesterImpl : public ChannelProcessRequester
{
EasyProcess * easyProcess;
public:
ChannelProcessRequesterImpl(EasyProcess * easyProcess)
: easyProcess(easyProcess) {}
string getRequesterName()
{return easyProcess->getRequesterName();}
void message(string const & message,MessageType messageType)
{easyProcess->message(message,messageType);}
void channelProcessConnect(
const Status& status,
ChannelProcess::shared_pointer const & channelProcess)
{easyProcess->channelProcessConnect(status,channelProcess);}
void processDone(
const Status& status,
ChannelProcess::shared_pointer const & channelProcess)
{easyProcess->processDone(status,channelProcess);}
};
EasyProcess::EasyProcess(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: easyPVA(pva),
easyChannel(easyChannel),
channel(channel),
pvRequest(pvRequest),
isDestroyed(false),
connectState(connectIdle),
processState(processIdle)
{
}
EasyProcess::~EasyProcess()
{
destroy();
}
void EasyProcess::checkProcessState()
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
if(connectState==connectIdle) connect();
if(processState==processIdle) process();
}
// from ChannelProcessRequester
string EasyProcess::getRequesterName()
{
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
return yyy->getRequesterName();
}
void EasyProcess::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
yyy->message(message, messageType);
}
void EasyProcess::channelProcessConnect(
const Status& status,
ChannelProcess::shared_pointer const & channelProcess)
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
channelProcessConnectStatus = status;
this->channelProcess = channelProcess;
waitForConnect.signal();
}
void EasyProcess::processDone(
const Status& status,
ChannelProcess::shared_pointer const & channelProcess)
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
channelProcessStatus = status;
waitForProcess.signal();
}
// from EasyProcess
void EasyProcess::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channelProcess) channelProcess->destroy();
channelProcess.reset();
}
void EasyProcess::connect()
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyProcess::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyProcess::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyProcess already connected ";
throw std::runtime_error(ss.str());
}
processRequester = ChannelProcessRequester::shared_pointer(new ChannelProcessRequesterImpl(this));
connectState = connectActive;
channelProcess = channel->createChannelProcess(processRequester,pvRequest);
}
Status EasyProcess::waitConnect()
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyProcess illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(channelProcessConnectStatus.isOK()){
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,channelProcessConnectStatus.getMessage());
}
void EasyProcess::process()
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
issueProcess();
Status status = waitProcess();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyProcess::process " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyProcess::issueProcess()
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
if(connectState==connectIdle) connect();
if(processState!=processIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyProcess::issueProcess process aleady active ";
throw std::runtime_error(ss.str());
}
processState = processActive;
channelProcess->process();
}
Status EasyProcess::waitProcess()
{
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
if(processState!=processActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyProcess::waitProcess llegal process state";
throw std::runtime_error(ss.str());
}
waitForProcess.wait();
processState = processIdle;
if(channelProcessStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelProcessStatus.getMessage());
}
EasyProcessPtr EasyProcess::create(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
EasyProcessPtr epv(new EasyProcess(pva,easyChannel,channel,pvRequest));
return epv;
}
}}

292
src/easyPut.cpp Normal file
View File

@@ -0,0 +1,292 @@
/* easyPut.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <sstream>
#include <pv/event.h>
#include <pv/easyPVA.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
class ChannelPutRequesterImpl : public ChannelPutRequester
{
EasyPut * easyPut;
public:
ChannelPutRequesterImpl(EasyPut * easyPut)
: easyPut(easyPut) {}
string getRequesterName()
{return easyPut->getRequesterName();}
void message(string const & message,MessageType messageType)
{easyPut->message(message,messageType);}
void channelPutConnect(
const Status& status,
ChannelPut::shared_pointer const & channelPut,
StructureConstPtr const & structure)
{easyPut->channelPutConnect(status,channelPut,structure);}
void getDone(
const Status& status,
ChannelPut::shared_pointer const & channelPut,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{easyPut->getDone(status,channelPut,pvStructure,bitSet);}
void putDone(
const Status& status,
ChannelPut::shared_pointer const & channelPut)
{easyPut->putDone(status,channelPut);}
};
EasyPut::EasyPut(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: easyPVA(pva),
easyChannel(easyChannel),
channel(channel),
pvRequest(pvRequest),
isDestroyed(false),
connectState(connectIdle),
putState(putIdle)
{
}
EasyPut::~EasyPut()
{
destroy();
}
void EasyPut::checkPutState()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
if(connectState==connectIdle){
connect();
get();
}
}
// from ChannelPutRequester
string EasyPut::getRequesterName()
{
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
return yyy->getRequesterName();
}
void EasyPut::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
yyy->message(message, messageType);
}
void EasyPut::channelPutConnect(
const Status& status,
ChannelPut::shared_pointer const & channelPut,
StructureConstPtr const & structure)
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
channelPutConnectStatus = status;
this->channelPut = channelPut;
if(status.isOK()) {
easyData = EasyPutData::create(structure);
easyData->setMessagePrefix(easyChannel.lock()->getChannelName());
}
waitForConnect.signal();
}
void EasyPut::getDone(
const Status& status,
ChannelPut::shared_pointer const & channelPut,
PVStructurePtr const & pvStructure,
BitSetPtr const & bitSet)
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
channelGetPutStatus = status;
if(status.isOK()) {
PVStructurePtr pvs = easyData->getPVStructure();
pvs->copyUnchecked(*pvStructure,*bitSet);
BitSetPtr bs = easyData->getBitSet();
bs->clear();
*bs |= *bitSet;
}
waitForGetPut.signal();
}
void EasyPut::putDone(
const Status& status,
ChannelPut::shared_pointer const & channelPut)
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
channelGetPutStatus = status;
waitForGetPut.signal();
}
// from EasyPut
void EasyPut::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channelPut) channelPut->destroy();
channelPut.reset();
}
void EasyPut::connect()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPut::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyPut::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyPut already connected ";
throw std::runtime_error(ss.str());
}
putRequester = ChannelPutRequester::shared_pointer(new ChannelPutRequesterImpl(this));
connectState = connectActive;
channelPut = channel->createChannelPut(putRequester,pvRequest);
}
Status EasyPut::waitConnect()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyPut illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(channelPutConnectStatus.isOK()) {
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,channelPutConnectStatus.getMessage());
}
void EasyPut::get()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
issueGet();
Status status = waitGet();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPut::get " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyPut::issueGet()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
if(connectState==connectIdle) connect();
if(putState!=putIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPut::issueGet get or put aleady active ";
throw std::runtime_error(ss.str());
}
putState = getActive;
easyData->getBitSet()->clear();
channelPut->get();
}
Status EasyPut::waitGet()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
if(putState!=getActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPut::waitGet llegal put state";
throw std::runtime_error(ss.str());
}
waitForGetPut.wait();
putState = putIdle;
if(channelGetPutStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutStatus.getMessage());
}
void EasyPut::put()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
issuePut();
Status status = waitPut();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPut::put " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyPut::issuePut()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
if(connectState==connectIdle) connect();
if(putState!=putIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPut::issueGet get or put aleady active ";
throw std::runtime_error(ss.str());
}
putState = putActive;
channelPut->put(easyData->getPVStructure(),easyData->getBitSet());
}
Status EasyPut::waitPut()
{
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
if(putState!=putActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPut::waitPut llegal put state";
throw std::runtime_error(ss.str());
}
waitForGetPut.wait();
putState = putIdle;
if(channelGetPutStatus.isOK()) {
easyData->getBitSet()->clear();
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutStatus.getMessage());
}
EasyPutDataPtr EasyPut::getData()
{
checkPutState();
return easyData;
}
EasyPutPtr EasyPut::create(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
EasyPutPtr epv(new EasyPut(pva,easyChannel,channel,pvRequest));
return epv;
}
}}

257
src/easyPutData.cpp Normal file
View File

@@ -0,0 +1,257 @@
/* easyPutData.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <typeinfo>
#include <sstream>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
#include <pv/convert.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
class EasyPostHandlerPvt: public PostHandler
{
EasyPutData * easyData;
size_t fieldNumber;
public:
EasyPostHandlerPvt(EasyPutData *easyData,size_t fieldNumber)
: easyData(easyData),fieldNumber(fieldNumber){}
void postPut() { easyData->postPut(fieldNumber);}
};
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noValue("no value field");
static string noScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string noArray("value is not an array");
static string noScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
EasyPutDataPtr EasyPutData::create(StructureConstPtr const & structure)
{
EasyPutDataPtr epv(new EasyPutData(structure));
return epv;
}
EasyPutData::EasyPutData(StructureConstPtr const & structure)
: structure(structure),
pvStructure(getPVDataCreate()->createPVStructure(structure)),
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
{
size_t nfields = pvStructure->getNumberFields();
postHandler.resize(nfields);
PVFieldPtr pvField;
for(size_t i =0; i<nfields; ++i)
{
postHandler[i] = PostHandlerPtr(new EasyPostHandlerPvt(this, i));
if(i==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(i);
}
pvField->setPostHandler(postHandler[i]);
}
pvValue = pvStructure->getSubField("value");
}
void EasyPutData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void EasyPutData::postPut(size_t fieldNumber)
{
bitSet->set(fieldNumber);
}
void EasyPutData::setMessagePrefix(std::string const & value)
{
messagePrefix = value;
}
StructureConstPtr EasyPutData::getStructure()
{return structure;}
PVStructurePtr EasyPutData::getPVStructure()
{return pvStructure;}
BitSetPtr EasyPutData::getBitSet()
{return bitSet;}
std::ostream & EasyPutData::showChanged(std::ostream & out)
{
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
bool EasyPutData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool EasyPutData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool EasyPutData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr EasyPutData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr EasyPutData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalar);
}
return pv;
}
PVArrayPtr EasyPutData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noArray);
}
return pv;
}
PVScalarArrayPtr EasyPutData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalarArray);
}
return pv;
}
double EasyPutData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string EasyPutData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> EasyPutData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> EasyPutData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
void EasyPutData::putDouble(double value)
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
pvDouble->put(value);
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(notCompatibleScalar);
}
convert->fromDouble(pvScalar,value);
}
void EasyPutData::putString(std::string const & value)
{
PVScalarPtr pvScalar = getScalarValue();
convert->fromString(pvScalar,value);
}
void EasyPutData::putDoubleArray(shared_vector<const double> const & value)
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
pv->replace(value);
}
void EasyPutData::putStringArray(shared_vector<const std::string> const & value)
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
pv->replace(value);
}
}}

378
src/easyPutGet.cpp Normal file
View File

@@ -0,0 +1,378 @@
/* easyPutGet.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2015.02
*/
#define epicsExportSharedSymbols
#include <sstream>
#include <pv/event.h>
#include <pv/easyPVA.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
class ChannelPutGetRequesterImpl : public ChannelPutGetRequester
{
EasyPutGet * easyPutGet;
public:
ChannelPutGetRequesterImpl(EasyPutGet * easyPutGet)
: easyPutGet(easyPutGet) {}
string getRequesterName()
{return easyPutGet->getRequesterName();}
void message(string const & message,MessageType messageType)
{easyPutGet->message(message,messageType);}
void channelPutGetConnect(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
epics::pvData::StructureConstPtr const & putStructure,
epics::pvData::StructureConstPtr const & getStructure)
{
easyPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure);
}
void putGetDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
epics::pvData::PVStructurePtr const & getPVStructure,
epics::pvData::BitSetPtr const & getBitSet)
{
easyPutGet->putGetDone(status,channelPutGet,getPVStructure,getBitSet);
}
void getPutDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
epics::pvData::PVStructurePtr const & putPVStructure,
epics::pvData::BitSet::shared_pointer const & putBitSet)
{
easyPutGet->getPutDone(status,channelPutGet,putPVStructure,putBitSet);
}
void getGetDone(
const epics::pvData::Status& status,
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
epics::pvData::PVStructurePtr const & getPVStructure,
epics::pvData::BitSet::shared_pointer const & getBitSet)
{
easyPutGet->getGetDone(status,channelPutGet,getPVStructure,getBitSet);
}
};
EasyPutGet::EasyPutGet(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: easyPVA(pva),
easyChannel(easyChannel),
channel(channel),
pvRequest(pvRequest),
isDestroyed(false),
connectState(connectIdle),
putGetState(putGetIdle)
{
}
EasyPutGet::~EasyPutGet()
{
destroy();
}
void EasyPutGet::checkPutGetState()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
if(connectState==connectIdle){
connect();
getPut();
}
}
// from ChannelPutGetRequester
string EasyPutGet::getRequesterName()
{
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
return yyy->getRequesterName();
}
void EasyPutGet::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
EasyPVAPtr yyy = easyPVA.lock();
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
yyy->message(message, messageType);
}
void EasyPutGet::channelPutGetConnect(
const Status& status,
ChannelPutGet::shared_pointer const & channelPutGet,
StructureConstPtr const & putStructure,
StructureConstPtr const & getStructure)
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
channelPutGetConnectStatus = status;
this->channelPutGet = channelPutGet;
if(status.isOK()) {
easyPutData = EasyPutData::create(putStructure);
easyPutData->setMessagePrefix(easyChannel.lock()->getChannelName());
easyGetData = EasyGetData::create(getStructure);
easyGetData->setMessagePrefix(easyChannel.lock()->getChannelName());
}
waitForConnect.signal();
}
void EasyPutGet::putGetDone(
const Status& status,
ChannelPutGet::shared_pointer const & channelPutGet,
PVStructurePtr const & getPVStructure,
BitSetPtr const & getBitSet)
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
channelPutGetStatus = status;
if(status.isOK()) {
easyGetData->setData(getPVStructure,getBitSet);
}
waitForPutGet.signal();
}
void EasyPutGet::getPutDone(
const Status& status,
ChannelPutGet::shared_pointer const & channelPutGet,
PVStructurePtr const & putPVStructure,
BitSetPtr const & putBitSet)
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
channelGetPutGetStatus = status;
if(status.isOK()) {
PVStructurePtr pvs = easyPutData->getPVStructure();
pvs->copyUnchecked(*putPVStructure,*putBitSet);
BitSetPtr bs = easyPutData->getBitSet();
bs->clear();
*bs |= *putBitSet;
}
waitForPutGet.signal();
}
void EasyPutGet::getGetDone(
const Status& status,
ChannelPutGet::shared_pointer const & channelPutGet,
PVStructurePtr const & getPVStructure,
BitSetPtr const & getBitSet)
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
channelPutGetStatus = status;
if(status.isOK()) {
easyGetData->setData(getPVStructure,getBitSet);
}
waitForPutGet.signal();
}
// from EasyPutGet
void EasyPutGet::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channelPutGet) channelPutGet->destroy();
channelPutGet.reset();
}
void EasyPutGet::connect()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyPutGet::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyPutGet already connected ";
throw std::runtime_error(ss.str());
}
putGetRequester = ChannelPutGetRequester::shared_pointer(new ChannelPutGetRequesterImpl(this));
connectState = connectActive;
channelPutGet = channel->createChannelPutGet(putGetRequester,pvRequest);
}
Status EasyPutGet::waitConnect()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyPutGet illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(channelPutGetConnectStatus.isOK()) {
connectState = connected;
return Status::Ok;
}
connectState = connectIdle;
return Status(Status::STATUSTYPE_ERROR,channelPutGetConnectStatus.getMessage());
}
void EasyPutGet::putGet()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
issuePutGet();
Status status = waitPutGet();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::putGet " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyPutGet::issuePutGet()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
if(connectState==connectIdle) connect();
if(putGetState!=putGetIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::issueGet get or put aleady active ";
throw std::runtime_error(ss.str());
}
putGetState = putGetActive;
channelPutGet->putGet(easyPutData->getPVStructure(),easyPutData->getBitSet());
}
Status EasyPutGet::waitPutGet()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
if(putGetState!=putGetActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::waitPutGet llegal put state";
throw std::runtime_error(ss.str());
}
waitForPutGet.wait();
putGetState = putGetIdle;
if(channelGetPutGetStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutGetStatus.getMessage());
}
void EasyPutGet::getGet()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
issueGetGet();
Status status = waitGetGet();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::getGet " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyPutGet::issueGetGet()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
if(connectState==connectIdle) connect();
if(putGetState!=putGetIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::issueGetGet aleady active ";
throw std::runtime_error(ss.str());
}
putGetState = putGetActive;
channelPutGet->getGet();
}
Status EasyPutGet::waitGetGet()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
if(putGetState!=putGetActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::waitGetGet illegal state";
throw std::runtime_error(ss.str());
}
waitForPutGet.wait();
putGetState = putGetIdle;
if(channelGetPutGetStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutGetStatus.getMessage());
}
void EasyPutGet::getPut()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
issueGetPut();
Status status = waitGetPut();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::getPut " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyPutGet::issueGetPut()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
if(connectState==connectIdle) connect();
if(putGetState!=putGetIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::issueGetPut aleady active ";
throw std::runtime_error(ss.str());
}
putGetState = putGetActive;
channelPutGet->getPut();
}
Status EasyPutGet::waitGetPut()
{
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
if(putGetState!=putGetActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyPutGet::waitGetPut illegal state";
throw std::runtime_error(ss.str());
}
waitForPutGet.wait();
putGetState = putGetIdle;
if(channelGetPutGetStatus.isOK()) {
return Status::Ok;
}
return Status(Status::STATUSTYPE_ERROR,channelGetPutGetStatus.getMessage());
}
EasyGetDataPtr EasyPutGet::getGetData()
{
checkPutGetState();
return easyGetData;
}
EasyPutDataPtr EasyPutGet::getPutData()
{
checkPutGetState();
return easyPutData;
}
EasyPutGetPtr EasyPutGet::create(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
EasyPutGetPtr epv(new EasyPutGet(pva,easyChannel,channel,pvRequest));
return epv;
}
}}