work in progress; simple easyGet worked!!!

This commit is contained in:
Marty Kraimer
2015-02-27 15:04:56 -05:00
commit f677e1a091
34 changed files with 5540 additions and 0 deletions

22
src/Makefile Normal file
View File

@@ -0,0 +1,22 @@
# This is a Makefile fragment, see ../Makefile
TOP = ..
include $(TOP)/configure/CONFIG
LIBRARY += easyPVA
INC += easyPVA.h
LIBSRCS += easyPVA.cpp
LIBSRCS += easyPVStructure.cpp
LIBSRCS += easyChannel.cpp
LIBSRCS += easyGet.cpp
#LIBSRCS += easyPut.cpp
#LIBSRCS += easyMonitor.cpp
#LIBSRCS += easyRPC.cpp
easyPVA_LIBS += pvAccess pvData Com
easyPVA_LIBS += $(EPICS_BASE_IOC_LIBS)
include $(TOP)/configure/RULES

420
src/easyChannel.cpp Normal file
View File

@@ -0,0 +1,420 @@
/* easyChannel.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/lock.h>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
class epicsShareClass EasyChannelImpl :
public EasyChannel,
public std::tr1::enable_shared_from_this<EasyChannelImpl>
{
public:
EasyChannelImpl(
EasyPVAPtr const &pva,
string const & channelName,
string const & providerName);
~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 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();
}
private:
enum ConnectState {connectIdle,connectActive,notConnected,connected};
EasyPVAPtr easyPVA;
string channelName;
string providerName;
ConnectState connectState;
bool isDestroyed;
CreateRequest::shared_pointer createRequest;
Status channelConnectStatus;
Mutex mutex;
Event waitForConnect;
Channel::shared_pointer channel;
ChannelRequester::shared_pointer channelRequester;
};
namespace easyChannel {
class ChannelRequesterImpl : public ChannelRequester
{
EasyChannelImpl *easyChannel;
public:
ChannelRequesterImpl(EasyChannelImpl *easyChannel)
: easyChannel(easyChannel) {}
virtual void channelCreated(
const Status& status,
Channel::shared_pointer const & channel)
{ easyChannel->channelCreated(status,channel); }
virtual 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()
{return easyChannel->getRequesterName();}
virtual void message(
string const & message,
MessageType messageType)
{ easyChannel->message(message,messageType); }
virtual void destroy() {easyChannel->destroy();}
};
} //end namespace easyChannel`
using namespace epics::easyPVA::easyChannel;
EasyChannelImpl::EasyChannelImpl(
EasyPVAPtr const &easyPVA,
string const & channelName,
string const & providerName)
: easyPVA(easyPVA),
channelName(channelName),
providerName(providerName),
connectState(connectIdle),
isDestroyed(false),
createRequest(CreateRequest::create())
{}
EasyChannelImpl::~EasyChannelImpl()
{
destroy();
}
void EasyChannelImpl::channelCreated(const Status& status, Channel::shared_pointer const & channel)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
channelConnectStatus = status;
this->channel = channel;
}
void EasyChannelImpl::channelStateChange(
Channel::shared_pointer const & channel,
Channel::ConnectionState connectionState)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
bool waitingForConnect = false;
if(connectState==connectActive) waitingForConnect = true;
if(connectionState!=Channel::CONNECTED) {
string mess(channelName + " connection state " + Channel::ConnectionStateNames[connectionState]);
message(mess,errorMessage);
channelConnectStatus = Status(Status::STATUSTYPE_ERROR,mess);
connectState = notConnected;
} else {
connectState = connected;
}
if(waitingForConnect) waitForConnect.signal();
}
tr1::shared_ptr<Channel> EasyChannelImpl::getChannel()
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
return channel;
}
string EasyChannelImpl::getRequesterName()
{
return easyPVA->getRequesterName();
}
void EasyChannelImpl::message(
string const & message,
MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
easyPVA->message(message, messageType);
}
void EasyChannelImpl::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channel) channel->destroy();
channel.reset();
}
string EasyChannelImpl::getChannelName()
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
return channelName;
}
void EasyChannelImpl::connect(double timeout)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
issueConnect();
Status status = waitConnect(timeout);
if(status.isOK()) return;
stringstream ss;
ss << "channel " << getChannelName() << " EasyChannel::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyChannelImpl::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
if(connectState!=connectIdle) {
throw std::runtime_error("easyChannel already connected");
}
channelRequester = ChannelRequester::shared_pointer(new ChannelRequesterImpl(this));
connectState = connectActive;
ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry();
ChannelProvider::shared_pointer provider = reg->getProvider(providerName);
channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT);
}
Status EasyChannelImpl::waitConnect(double timeout)
{
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
waitForConnect.wait(timeout);
if(connectState==connected) return Status::Ok;
return Status(Status::STATUSTYPE_ERROR,channelConnectStatus.getMessage());
}
EasyFieldPtr EasyChannelImpl::createField()
{
return createField("");
}
EasyFieldPtr EasyChannelImpl::createField(string const & subField)
{
throw std::runtime_error("EasyChannel::createField not implemented");
}
EasyProcessPtr EasyChannelImpl::createProcess()
{
return createProcess("");
}
EasyProcessPtr EasyChannelImpl::createProcess(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createProcess invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createProcess(pvRequest);
}
EasyProcessPtr EasyChannelImpl::createProcess(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createProcess not implemented");
}
EasyGetPtr EasyChannelImpl::createGet()
{
return EasyChannelImpl::createGet("value,alarm.timeStamp");
}
EasyGetPtr EasyChannelImpl::createGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createGet invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createGet(pvRequest);
}
EasyGetPtr EasyChannelImpl::createGet(PVStructurePtr const & pvRequest)
{
if(connectState!=connected) connect(5.0);
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatGet not connected");
return EasyGetFactory::createEasyGet(easyPVA,getPtrSelf(),channel,pvRequest);
}
EasyPutPtr EasyChannelImpl::createPut()
{
return createPut("value");
}
EasyPutPtr EasyChannelImpl::createPut(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createPut invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createPut(pvRequest);
}
EasyPutPtr EasyChannelImpl::createPut(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createPut not implemented");
}
EasyPutGetPtr EasyChannelImpl::createPutGet()
{
return createPutGet("putField(argument)getField(result)");
}
EasyPutGetPtr EasyChannelImpl::createPutGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createPutGet invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createPutGet(pvRequest);
}
EasyPutGetPtr EasyChannelImpl::createPutGet(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createPutGet not implemented");
}
EasyRPCPtr EasyChannelImpl::createRPC()
{
return createRPC("");
}
EasyRPCPtr EasyChannelImpl::createRPC(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createRPC invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createRPC(pvRequest);
}
EasyRPCPtr EasyChannelImpl::createRPC(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createRPC not implemented");
}
EasyArrayPtr EasyChannelImpl::createArray()
{
return createArray("value");
}
EasyArrayPtr EasyChannelImpl::createArray(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createArray invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createArray(pvRequest);
}
EasyArrayPtr EasyChannelImpl::createArray(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createArray not implemented");
}
EasyMonitorPtr EasyChannelImpl::createMonitor()
{
return createMonitor("value,alarm,timeStamp");
}
EasyMonitorPtr EasyChannelImpl::createMonitor(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
stringstream ss;
ss << "channel " << getChannelName();
ss << " EasyChannel::createMonitor invalid pvRequest: " + createRequest->getMessage();
throw std::runtime_error(ss.str());
}
return createMonitor(pvRequest);
}
EasyMonitorPtr EasyChannelImpl::createMonitor(PVStructurePtr const & pvRequest)
{
throw std::runtime_error("EasyChannel::createMonitor not implemented");
}
EasyChannelPtr EasyChannelFactory::createEasyChannel(
EasyPVAPtr const &easyPVA,
string const & channelName)
{
return EasyChannelFactory::createEasyChannel(easyPVA,channelName,"pva");
}
EasyChannelPtr EasyChannelFactory::createEasyChannel(
EasyPVAPtr const &easyPVA,
string const & channelName,
string const & providerName)
{
EasyChannelPtr channel(new EasyChannelImpl(easyPVA,channelName,providerName));
return channel;
}
}}

551
src/easyGet.cpp Normal file
View File

@@ -0,0 +1,551 @@
/* easyGet.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/lock.h>
#include <pv/easyPVA.h>
#include <pv/createRequest.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
class epicsShareClass EasyGetImpl :
public EasyGet,
public std::tr1::enable_shared_from_this<EasyGetImpl>
{
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);
void channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & 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:
enum GetConnectState {connectIdle,connectActive,connected};
EasyPVAPtr easyPVA;
EasyChannelPtr 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;
};
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(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
: easyPVA(pva),
easyChannel(easyChannel),
channel(channel),
pvRequest(pvRequest),
easyPVStructure(pva->createEasyPVStructure()),
isDestroyed(false),
connectState(connectIdle),
getState(getIdle)
{
easyPVStructure->setMessagePrefix("channel " + channel->getChannelName() + " EasyGet");
}
EasyGetImpl::~EasyGetImpl()
{
destroy();
}
// from ChannelGetRequester
string EasyGetImpl::getRequesterName()
{
return easyPVA->getRequesterName();
}
void EasyGetImpl::message(string const & message,MessageType messageType)
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
easyPVA->message(message, messageType);
}
void EasyGetImpl::channelGetConnect(
const Status& status,
ChannelGet::shared_pointer const & channelGet,
StructureConstPtr const & structure)
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
channelGetConnectStatus = status;
this->channelGet = channelGet;
if(status.isOK()) {
connectState = connected;
} else {
connectState = connectIdle;
}
waitForConnect.signal();
}
void EasyGetImpl::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;
}
waitForGet.signal();
}
// from EasyGet
void EasyGetImpl::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
if(channelGet) channelGet->destroy();
channelGet.reset();
}
void EasyGetImpl::connect()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyGet::connect " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyGetImpl::issueConnect()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState!=connectIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyGet already connected ";
throw std::runtime_error(ss.str());
}
getRequester = ChannelGetRequester::shared_pointer(new ChannelGetRequesterImpl(this));
connectState = connectActive;
channelGet = channel->createChannelGet(getRequester,pvRequest);
}
Status EasyGetImpl::waitConnect()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState!=connectActive) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " easyGet illegal connect state ";
throw std::runtime_error(ss.str());
}
waitForConnect.wait();
if(connectState==connected) return Status::Ok;
return Status(Status::STATUSTYPE_ERROR,channelGetConnectStatus.getMessage());
}
void EasyGetImpl::get()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
issueGet();
Status status = waitGet();
if(status.isOK()) return;
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyGet::get " << status.getMessage();
throw std::runtime_error(ss.str());
}
void EasyGetImpl::issueGet()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(connectState==connectIdle) connect();
if(getState!=getIdle) {
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyGet::issueGet get aleady active ";
throw std::runtime_error(ss.str());
}
getState = getActive;
channelGet->get();
}
Status EasyGetImpl::waitGet()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
if(getState!=getActive){
stringstream ss;
ss << "channel " << channel->getChannelName() << " EasyGet::waitGet llegal get state";
throw std::runtime_error(ss.str());
}
waitForGet.wait();
if(getState==getComplete) {
getState = getIdle;
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()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getAlarm();
}
TimeStamp EasyGetImpl::getTimeStamp()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getTimeStamp();
}
bool EasyGetImpl::hasValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->hasValue();
}
bool EasyGetImpl::isValueScalar()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->isValueScalar();
}
bool EasyGetImpl::isValueScalarArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->isValueScalarArray();
}
PVFieldPtr EasyGetImpl::getValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getValue();
}
PVScalarPtr EasyGetImpl::getScalarValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getScalarValue();
}
std::tr1::shared_ptr<PVArray> EasyGetImpl::getArrayValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getArrayValue();
}
std::tr1::shared_ptr<PVScalarArray> EasyGetImpl::getScalarArrayValue()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getScalarArrayValue();
}
bool EasyGetImpl::getBoolean()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getBoolean();
}
int8 EasyGetImpl::getByte()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getByte();
}
int16 EasyGetImpl::getShort()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getShort();
}
int32 EasyGetImpl::getInt()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getInt();
}
int64 EasyGetImpl::getLong()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getLong();
}
uint8 EasyGetImpl::getUByte()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUByte();
}
uint16 EasyGetImpl::getUShort()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUShort();
}
uint32 EasyGetImpl::getUInt()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUInt();
}
uint64 EasyGetImpl::getULong()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getULong();
}
float EasyGetImpl::getFloat()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getFloat();
}
double EasyGetImpl::getDouble()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->isValueScalar();
}
std::string EasyGetImpl::getString()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getString();
}
shared_vector<boolean> EasyGetImpl::getBooleanArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getBooleanArray();
}
shared_vector<int8> EasyGetImpl::getByteArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getByteArray();
}
shared_vector<int16> EasyGetImpl::getShortArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getShortArray();
}
shared_vector<int32> EasyGetImpl::getIntArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getIntArray();
}
shared_vector<int64> EasyGetImpl::getLongArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getLongArray();
}
shared_vector<uint8> EasyGetImpl::getUByteArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUByteArray();
}
shared_vector<uint16> EasyGetImpl::getUShortArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUShortArray();
}
shared_vector<uint32> EasyGetImpl::getUIntArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getUIntArray();
}
shared_vector<uint64> EasyGetImpl::getULongArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getULongArray();
}
shared_vector<float> EasyGetImpl::getFloatArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getFloatArray();
}
shared_vector<double> EasyGetImpl::getDoubleArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getDoubleArray();
}
shared_vector<std::string> EasyGetImpl::getStringArray()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getStringArray();
}
PVStructurePtr EasyGetImpl::getPVStructure()
{
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
return easyPVStructure->getPVStructure();
}
EasyGetPtr EasyGetFactory::createEasyGet(
EasyPVAPtr const &pva,
EasyChannelPtr const & easyChannel,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
{
EasyGetPtr epv(new EasyGetImpl(pva,easyChannel,channel,pvRequest));
return epv;
}
}}

105
src/easyPVA.cpp Normal file
View File

@@ -0,0 +1,105 @@
/* easyPVA.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 <pv/easyPVA.h>
#include <pv/createRequest.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace easyPVA {
static FieldCreatePtr fieldCreate = getFieldCreate();
static const string easyPVAName = "easyPVA";
static const string defaultProvider = "pva";
static UnionConstPtr variantUnion = fieldCreate->createVariantUnion();
EasyPVAPtr EasyPVA::create()
{
EasyPVAPtr xx(new EasyPVA());
return xx;
}
PVStructurePtr EasyPVA::createRequest(string const &request)
{
CreateRequest::shared_pointer createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
throw std::invalid_argument("invalid pvRequest: " + createRequest->getMessage());
}
return pvRequest;
}
EasyPVA::EasyPVA()
: isDestroyed(false)
{
}
EasyPVA::~EasyPVA() {destroy();}
void EasyPVA::destroy()
{
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
std::list<EasyChannelPtr>::iterator channelIter;
while(true) {
channelIter = channelList.begin();
if(channelIter==channelList.end()) break;
channelList.erase(channelIter);
(*channelIter)->destroy();
}
std::list<EasyMultiChannelPtr>::iterator multiChannelIter;
#ifdef NOTDONE
while(true) {
multiChannelIter = multiChannelList.begin();
if(multiChannelIter==multiChannelList.end()) break;
multiChannelList.erase(multiChannelIter);
(*multiChannelIter)->destroy();
}
#endif
}
string EasyPVA:: getRequesterName()
{
static string name("easyPVA");
return name;
}
void EasyPVA::message(
string const & message,
MessageType messageType)
{
cout << getMessageTypeName(messageType) << " " << message << endl;
}
EasyPVStructurePtr EasyPVA::createEasyPVStructure()
{
return EasyPVStructureFactory::createEasyPVStructure();
}
EasyChannelPtr EasyPVA::createChannel(string const & channelName)
{
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName);
}
EasyChannelPtr EasyPVA::createChannel(string const & channelName, string const & providerName)
{
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName,providerName);
}
}}

721
src/easyPVA.h Normal file
View File

@@ -0,0 +1,721 @@
/* easyPVA.h */
/**
* 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
*/
#ifndef EASYPVA_H
#define EASYPVA_H
#ifdef epicsExportSharedSymbols
# define easyPVAEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <list>
#include <pv/requester.h>
#include <pv/status.h>
#include <pv/pvData.h>
#include <pv/pvCopy.h>
#include <pv/pvTimeStamp.h>
#include <pv/timeStamp.h>
#include <pv/pvAlarm.h>
#include <pv/alarm.h>
#include <pv/pvAccess.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/createRequest.h>
#ifdef easyPVAEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef easyPVAEpicsExportSharedSymbols
#endif
#include <shareLib.h>
namespace epics { namespace easyPVA {
class EasyPVA;
typedef std::tr1::shared_ptr<EasyPVA> EasyPVAPtr;
class EasyPVStructure;
typedef std::tr1::shared_ptr<EasyPVStructure> EasyPVStructurePtr;
class EasyChannel;
typedef std::tr1::shared_ptr<EasyChannel> EasyChannelPtr;
class EasyField;
typedef std::tr1::shared_ptr<EasyField> EasyFieldPtr;
class EasyProcess;
typedef std::tr1::shared_ptr<EasyProcess> EasyProcessPtr;
class EasyGet;
typedef std::tr1::shared_ptr<EasyGet> EasyGetPtr;
class EasyPut;
typedef std::tr1::shared_ptr<EasyPut> EasyPutPtr;
class EasyPutGet;
typedef std::tr1::shared_ptr<EasyPutGet> EasyPutGetPtr;
class EasyMonitor;
typedef std::tr1::shared_ptr<EasyMonitor> EasyMonitorPtr;
class EasyArray;
typedef std::tr1::shared_ptr<EasyArray> EasyArrayPtr;
class EasyRPC;
typedef std::tr1::shared_ptr<EasyRPC> EasyRPCPtr;
class EasyMultiData;
typedef std::tr1::shared_ptr<EasyMultiData> EasyMultiDataPtr;
class EasyMultiChannel;
typedef std::tr1::shared_ptr<EasyMultiChannel> EasyMultiChannelPtr;
class EasyMultiGet;
typedef std::tr1::shared_ptr<EasyMultiGet> EasyMultiGetPtr;
class EasyMultiPut;
typedef std::tr1::shared_ptr<EasyMultiPut> EasyMultiPutPtr;
class EasyMultiMonitor;
typedef std::tr1::shared_ptr<EasyMultiMonitor> EasyMultiMonitorPtr;
/**
* @brief EasyPVA is an easy to use interface to pvAccess.
*
* @author mrk
*/
class epicsShareClass EasyPVA :
public epics::pvData::Requester,
public std::tr1::enable_shared_from_this<EasyPVA>
{
public:
POINTER_DEFINITIONS(EasyPVA);
/**
* Destructor
*/
~EasyPVA();
/**
* @brief Create an instance of EasyPVA
* @return shared_ptr to new instance.
*/
static EasyPVAPtr create();
/** @brief get the requester name.
* @return The name.
*/
virtual std::string getRequesterName();
/**
* @brief A new message.
* If a requester is set then it is called otherwise message is displayed
* on standard out.
* @param message The message.
* @param messageType The type.
*/
virtual void message(
std::string const & message,
epics::pvData::MessageType messageType);
/**
* @brief Destroy all the channels and multiChannels.
*/
void destroy();
/**
* @brief Create a EasyPVStructure.
* @return The interface to the EasyPVStructure.
*/
EasyPVStructurePtr createEasyPVStructure();
/**
* @brief Create an EasyChannel. The provider is pvAccess.
* @param channelName The channelName.
* @return The interface.
*/
EasyChannelPtr createChannel(std::string const & channelName);
/**
* @brief Create an EasyChannel with the specified provider.
* @param channelName The channelName.
* @param providerName The provider.
* @return The interface or null if the provider does not exist.
*/
EasyChannelPtr createChannel(
std::string const & channelName,
std::string const & providerName);
/**
* @brief Create an EasyMultiChannel. The provider is pvAccess.
* @param channelName The channelName array.
* @return The interface.
*/
EasyMultiChannelPtr createMultiChannel(epics::pvData::StringArray const & channelName);
/**
* @brief Create an EasyMultiChannel with the specified provider.
* @param channelName The channelName array.
* @param providerName The provider.
* @return The interface.
*/
EasyMultiChannelPtr createMultiChannel(
epics::pvData::StringArray const & channelName,
std::string const & providerName);
/**
* @brief Create an EasyMultiChannel with the specified provider.
* @param channelName The channelName.
* @param providerName The provider.
* @param union The union interface for the value field of each channel.
* @return The interface.
*/
EasyMultiChannelPtr createMultiChannel(
epics::pvData::StringArray const & channelName,
std::string const & providerName,
epics::pvData::UnionConstPtr const & u);
/**
* @brief Set a requester.
* The default is for EasyPVA to handle messages by printing to System.out.
* @param requester The requester.
*/
void setRequester(epics::pvData::RequesterPtr const & requester);
/**
* @brief Clear the requester. EasyPVA will handle messages.
*/
void clearRequester();
/**
* @brief get shared pointer to this
*/
EasyPVAPtr getPtrSelf()
{
return shared_from_this();
}
private:
EasyPVA();
epics::pvData::PVStructurePtr createRequest(std::string const &request);
std::list<EasyChannelPtr> channelList;
std::list<EasyMultiChannelPtr> multiChannelList;
epics::pvData::RequesterPtr requester;
bool isDestroyed;
epics::pvData::Mutex mutex;
};
/**
* @brief An easy to use alternative to directly calling the Channel methods of pvAccess.
*
* @author mrk
*/
class epicsShareClass EasyChannel
{
public:
POINTER_DEFINITIONS(EasyChannel);
/**
* @brief Destroy the pvAccess connection.
*/
virtual void destroy() = 0;
/**
* @brief Get the name of the channel to which EasyChannel is connected.
* @return The channel name.
*/
virtual std::string getChannelName() = 0;
/**
* @brief Connect to the channel.
* This calls issueConnect and waitConnect.
* An exception is thrown if connect fails.
* @param timeout The time to wait for connecting to the channel.
*/
virtual void connect(double timeout) = 0;
/**
* @brief Issue a connect request and return immediately.
*/
virtual void issueConnect() = 0;
/**
* @brief Wait until the connection completes or for timeout.
* @param timeout The time in second to wait.
* @return status.
*/
virtual epics::pvData::Status waitConnect(double timeout) = 0;
/**
* @brief Calls the next method with subField = "";
* @return The interface.
*/
virtual EasyFieldPtr createField() = 0;
/**
* @brief Create an EasyField for the specified subField.
* @param subField The syntax for subField is defined in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyFieldPtr createField(std::string const & subField) = 0;
/**
* @brief Calls the next method with request = "";
* @return The interface.
*/
virtual EasyProcessPtr createProcess() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyProcessPtr createProcess(std::string const & request) = 0;
/**
* @brief Creates an EasyProcess.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "field(value,alarm,timeStamp)"
* @return The interface.
*/
virtual EasyGetPtr createGet() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then call the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyGetPtr createGet(std::string const & request) = 0;
/**
* @brief Creates an EasyGet.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "field(value)"
* @return The interface.
*/
virtual EasyPutPtr createPut() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyPutPtr createPut(std::string const & request) = 0;
/**
* @brief Create an EasyPut.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "record[process=true]putField(argument)getField(result)".
* @return The interface.
*/
virtual EasyPutGetPtr createPutGet() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyPutGetPtr createPutGet(std::string const & request) = 0;
/**
* @brief Create an EasyPutGet.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call createRPC(PVStructure(null))
* @return The interface.
*/
virtual EasyRPCPtr createRPC() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyRPCPtr createRPC(std::string const & request) = 0;
/**
* @brief Create an EasyRPC.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyRPCPtr createRPC(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "field(value)";
* @return The interface.
*/
virtual EasyArrayPtr createArray() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyArrayPtr createArray(std::string const & request) = 0;
/**
* @brief Create an EasyArray.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyArrayPtr createArray(epics::pvData::PVStructurePtr const & pvRequest) = 0;
/**
* @brief Call the next method with request = "field(value.alarm,timeStamp)"
* @return The interface.
*/
virtual EasyMonitorPtr createMonitor() = 0;
/**
* @brief First call createRequest as implemented by pvDataJava and then calls the next method.
* @param request The request as described in package org.epics.pvdata.copy
* @return The interface.
*/
virtual EasyMonitorPtr createMonitor(std::string const & request) = 0;
/**
* @brief Create an EasyMonitor.
* @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy.
* @return The interface.
*/
virtual EasyMonitorPtr createMonitor(epics::pvData::PVStructurePtr const & pvRequest) = 0;
};
/**
* @brief This is a factory for creating an EasyChannel
*
* @author mrk
*/
class epicsShareClass EasyChannelFactory
{
public:
/**
* @brief Create a EasyPVAStructure.
* @param easyPVA Interface to EasyPVA
* @param channelName The name of the channel.
* @return The interface to the EasyPVAStructure.
*/
static EasyChannelPtr createEasyChannel(
EasyPVAPtr const &easyPVA,
std::string const & channelName);
/**
* @brief Create a EasyPVAStructure.
* @param channelName The name of the channel.
* @param providerName The name of the provider.
* @return The interface to the EasyPVAStructure.
*/
static EasyChannelPtr createEasyChannel(
EasyPVAPtr const &easyPVA,
std::string const & channelName,
std::string const & providerName);
};
/**
* @brief This is a convenience wrapper for a PVStructure.
*
* @author mrk
*/
class epicsShareClass EasyPVStructure
{
public:
POINTER_DEFINITIONS(EasyPVStructure);
/**
* @brief Set a prefix to be added to any messages generated by EasyPVStructure.
* @param value The prefix.
*/
virtual void setMessagePrefix(std::string const & value) = 0;
/**
* @brief Set the pvStructure on which the remaining methods operate.
* @param pvStructure The structure.
*/
virtual void setPVStructure(epics::pvData::PVStructurePtr const & pvStructure) = 0;
/**
* @brief Get the top level pvStructure.
* @return The pvStructure. An exception is thrown if pvStructure does not exist.
*/
virtual epics::pvData::PVStructurePtr getPVStructure() = 0;
/**
* @brief Get the alarm.
* If the pvStructure as an alarm field it's values are returned.
* If no then alarm shows that not alarm defined.
* @return The alarm.
*/
virtual epics::pvData::Alarm getAlarm() = 0;
/**
* @brief Get the timeStamp.
* If the pvStructure as a timeStamp field, it's values are returned.
* If no then all fields are 0.
* @return The timeStamp.
*/
virtual epics::pvData::TimeStamp getTimeStamp() = 0;
/**
* @brief Is there a top level field named value of the PVstructure returned by channelGet?
* @return The answer.
*/
virtual bool hasValue() = 0;
/**
* @brief Is the value field a scalar?
* @return The answer.
*/
virtual bool isValueScalar() = 0;
/**
* @brief Is the value field a scalar array?
* @return The answer.
*/
virtual bool isValueScalarArray() = 0;
/**
* @brief Return the interface to the value field.
* @return The interface. an excetion is thrown if a value field does not exist.
*/
virtual epics::pvData::PVFieldPtr getValue() = 0;
/**
* @brief Return the interface to a scalar value field.
* @return The interface for a scalar value field.
* An exception is thown if no scalar value field.
*/
virtual epics::pvData::PVScalarPtr getScalarValue() = 0;
/**
* @brief Return the interface to an array value field.
* @return The interface.
* An exception is thown if no array value field.
*/
virtual std::tr1::shared_ptr<epics::pvData::PVArray> getArrayValue() = 0;
/**
* @brief Return the interface to a scalar array value field.
* @return Return the interface.
* An exception is thown if no scalar array value field.
*/
virtual std::tr1::shared_ptr<epics::pvData::PVScalarArray> getScalarArrayValue() = 0;
/**
* @brief Get the boolean value. If value is not a boolean an exception is thrown
* @return true or false.
*/
virtual bool getBoolean() = 0;
/**
* @brief Get the value as a byte.
* If value is not a byte scalar an exception is thrown.
* @return The value.
*/
virtual epics::pvData::int8 getByte() = 0;
/**
* @brief Get the value as a short.
* If value is not a numeric scalar an exception is thrown
* @return The value.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::int16 getShort() = 0;
/**
* @brief Get the value as an int.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::int32 getInt() = 0;
/**
* @brief Get the value as a long.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::int64 getLong() = 0;
/**
* @brief Get the value as an unsigned byte.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::uint8 getUByte() = 0;
/**
* @brief Get the value as a short.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::uint16 getUShort() = 0;
/**
* @brief Get the value as an unsigned int.
* @return If value is not a numeric scalar an exception is thrown
*/
virtual epics::pvData::uint32 getUInt() = 0;
/**
* @brief Get the value as an unsigned long.
* If value is not a numeric scalar an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
*/
virtual epics::pvData::uint64 getULong() = 0;
/**
* @brief Get the value as a float.
* If value is not a numeric scalar an exception is thrown.
* @return The value.
*/
virtual float getFloat() = 0;
/**
* @brief Get the value as a double.
* If value is not a numeric scalar an exception is thrown.
* @return The value.
*/
virtual double getDouble() = 0;
/**
* @brief Get the value as a string.
* If value is not a string an exception is thrown
* @return The value.
*/
virtual std::string getString() = 0;
/**
* @brief Get the value as a boolean array.
* If the value is not a boolean array an exception is thrown
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::boolean> getBooleanArray() = 0;
/**
* @brief Get the value as a byte array.
* @return If the value is not a numeric array an exception is thrown
*/
virtual epics::pvData::shared_vector<epics::pvData::int8> getByteArray() = 0;
/**
* @brief Get the value as a short array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::int16> getShortArray() = 0;
/**
* @brief Get the value as an int array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::int32> getIntArray() = 0;
/**
* @brief Get the value as a long array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::int64> getLongArray() = 0;
/**
* @brief Get the value as an unsigned byte array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::uint8> getUByteArray() = 0;
/**
* @brief Get the value as an unsigned short array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::uint16> getUShortArray() = 0;
/**
* Get the value as an unsigned int array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::uint32> getUIntArray() = 0;
/**
* @brief Get the value as an unsigned long array.
* If the value is not a numeric array an exception is thrown.
* An exception is also thrown if the actualy type can cause an overflow.
* @return The value.
*/
virtual epics::pvData::shared_vector<epics::pvData::uint64> getULongArray() = 0;
/**
* @brief Get the value as a float array.
* If the value is not a numeric array an exception is thrown.
* @return The value.
*/
virtual epics::pvData::shared_vector<float> getFloatArray() = 0;
/**
* @brief Get the value as a double array.
* If the value is not a numeric array an exception is thrown.
* @return The value.
*/
virtual epics::pvData::shared_vector<double> getDoubleArray() = 0;
/**
* @brief Get the value as a string array.
* If the value is not a string array an exception is thrown.
* @return The value.
*/
virtual epics::pvData::shared_vector<std::string> getStringArray() = 0;
};
/**
* @brief This is a factory for creating an EasyPVStructure
*
* @author mrk
*/
class epicsShareClass EasyPVStructureFactory
{
public:
/**
* @brief Create a EasyPVAStructure.
* @return The interface to the EasyPVAStructure.
*/
static EasyPVStructurePtr createEasyPVStructure();
};
/**
* @brief An easy to use alternative to ChannelGet.
*
* @author mrk
*/
class epicsShareClass EasyGet :
public EasyPVStructure
{
public:
POINTER_DEFINITIONS(EasyGet);
/**
* @brief destructor
*/
virtual ~EasyGet(){}
/**
* @brief destroy an resources used.
*/
virtual void destroy() = 0;
/**
* @brief call issueConnect and then waitConnect.
* An exception is thrown if connect fails.
*/
virtual void connect() = 0;
/**
* @brief create the channelGet connection to the channel.
* This can only be called once.
* An exception is thrown if connect fails.
*/
virtual void issueConnect() = 0;
/**
* @brief wait until the channelGet connection to the channel is complete.
* @return status;
*/
virtual epics::pvData::Status waitConnect() = 0;
/**
* @brief Call issueGet and then waitGet.
* An exception is thrown if get fails.
*/
virtual void get() = 0;
/**
* @brief Issue a get and return immediately.
*/
virtual void issueGet() = 0;
/**
* @brief Wait until get completes.
* If failure getStatus can be called to get reason.
* @return (false,true) means (failure,success)
*/
virtual epics::pvData::Status waitGet() = 0;
/**
* @brief Get the bitSet for the top level structure.
* @return The bitSet.
*/
virtual epics::pvData::BitSetPtr getBitSet() = 0;
};
/**
* @brief This is a factory for creating an EasyGet.
*
* @author mrk
*/
class epicsShareClass EasyGetFactory
{
public:
/**
* @brief Create a EasyPVAStructure.
* @param &easyPVA Interface to EasyPVA
* @param easyChannel Interface to EasyChannel
* @param channel Interface to Channel
* @param pvRequest The request structure.
* @return The interface to the EasyPVAStructure.
*/
static EasyGetPtr createEasyGet(
EasyPVAPtr const &easyPVA,
EasyChannelPtr const & easyChannel,
epics::pvAccess::Channel::shared_pointer const & channel,
epics::pvData::PVStructurePtr const &pvRequest
);
};
}}
#endif /* EASYPVA_H */
/** @page Overview Documentation
*
* <a href = "easyPVA.html">easyPVA.html</a>
*
*/

597
src/easyPVStructure.cpp Normal file
View File

@@ -0,0 +1,597 @@
/* 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();
}
}}