241 lines
6.4 KiB
C++
241 lines
6.4 KiB
C++
/* pvaClientGetData.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
|
|
*/
|
|
|
|
#include <typeinfo>
|
|
#include <sstream>
|
|
|
|
#include <pv/createRequest.h>
|
|
#include <pv/convert.h>
|
|
|
|
#define epicsExportSharedSymbols
|
|
|
|
#include <pv/pvaClient.h>
|
|
|
|
using std::tr1::static_pointer_cast;
|
|
using namespace epics::pvData;
|
|
using namespace epics::pvAccess;
|
|
using namespace std;
|
|
|
|
namespace epics { namespace pvaClient {
|
|
|
|
|
|
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");
|
|
static string noAlarm("no alarm");
|
|
static string noTimeStamp("no timeStamp");
|
|
|
|
PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure)
|
|
{
|
|
if(PvaClient::getDebug()) {
|
|
cout << "PvaClientGetData::create"
|
|
<< endl;
|
|
}
|
|
PvaClientGetDataPtr epv(new PvaClientGetData(structure));
|
|
return epv;
|
|
}
|
|
|
|
PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure)
|
|
: structure(structure),
|
|
pvStructure(getPVDataCreate()->createPVStructure(structure)),
|
|
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
|
|
{
|
|
messagePrefix = "";
|
|
pvValue = pvStructure->getSubField("value");
|
|
}
|
|
|
|
void PvaClientGetData::checkValue()
|
|
{
|
|
if(PvaClient::getDebug()) {
|
|
cout << "PvaClientGetData::checkValue"
|
|
<< endl;
|
|
}
|
|
if(pvValue) return;
|
|
throw std::runtime_error(messagePrefix + noValue);
|
|
}
|
|
|
|
void PvaClientGetData::setMessagePrefix(std::string const & value)
|
|
{
|
|
messagePrefix = value + " ";
|
|
}
|
|
|
|
StructureConstPtr PvaClientGetData::getStructure()
|
|
{return structure;}
|
|
|
|
PVStructurePtr PvaClientGetData::getPVStructure()
|
|
{
|
|
if(pvStructure) return pvStructure;
|
|
throw std::runtime_error(messagePrefix + noStructure);
|
|
}
|
|
|
|
BitSetPtr PvaClientGetData::getChangedBitSet()
|
|
{
|
|
if(bitSet)return bitSet;
|
|
throw std::runtime_error(messagePrefix + noStructure);
|
|
}
|
|
|
|
std::ostream & PvaClientGetData::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 PvaClientGetData::setData(
|
|
PVStructurePtr const & pvStructureFrom,
|
|
BitSetPtr const & bitSetFrom)
|
|
{
|
|
if(PvaClient::getDebug()) {
|
|
cout << "PvaClientGetData::setData"
|
|
<< endl;
|
|
}
|
|
pvStructure = pvStructureFrom;
|
|
bitSet = bitSetFrom;
|
|
pvValue = pvStructure->getSubField("value");
|
|
}
|
|
|
|
bool PvaClientGetData::hasValue()
|
|
{
|
|
if(!pvValue) return false;
|
|
return true;
|
|
}
|
|
|
|
bool PvaClientGetData::isValueScalar()
|
|
{
|
|
if(!pvValue) return false;
|
|
if(pvValue->getField()->getType()==scalar) return true;
|
|
return false;
|
|
}
|
|
|
|
bool PvaClientGetData::isValueScalarArray()
|
|
{
|
|
if(!pvValue) return false;
|
|
if(pvValue->getField()->getType()==scalarArray) return true;
|
|
return false;
|
|
}
|
|
|
|
PVFieldPtr PvaClientGetData::getValue()
|
|
{
|
|
checkValue();
|
|
return pvValue;
|
|
}
|
|
|
|
PVScalarPtr PvaClientGetData::getScalarValue()
|
|
{
|
|
checkValue();
|
|
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
|
if(!pv) throw std::runtime_error(messagePrefix + noScalar);
|
|
return pv;
|
|
}
|
|
|
|
PVArrayPtr PvaClientGetData::getArrayValue()
|
|
{
|
|
checkValue();
|
|
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
|
|
if(!pv) throw std::runtime_error(messagePrefix + noArray);
|
|
return pv;
|
|
}
|
|
|
|
PVScalarArrayPtr PvaClientGetData::getScalarArrayValue()
|
|
{
|
|
checkValue();
|
|
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
|
if(!pv) throw std::runtime_error(messagePrefix + noScalarArray);
|
|
return pv;
|
|
}
|
|
|
|
double PvaClientGetData::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(messagePrefix + notCompatibleScalar);
|
|
}
|
|
return convert->toDouble(pvScalar);
|
|
}
|
|
|
|
string PvaClientGetData::getString()
|
|
{
|
|
PVScalarPtr pvScalar = getScalarValue();
|
|
return convert->toString(pvScalar);
|
|
}
|
|
|
|
shared_vector<const double> PvaClientGetData::getDoubleArray()
|
|
{
|
|
checkValue();
|
|
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
|
|
if(!pv) throw std::runtime_error(messagePrefix + notDoubleArray);
|
|
return pv->view();
|
|
}
|
|
|
|
shared_vector<const string> PvaClientGetData::getStringArray()
|
|
{
|
|
checkValue();
|
|
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
|
|
if(!pv) throw std::runtime_error(messagePrefix + notStringArray);
|
|
return pv->view();
|
|
}
|
|
|
|
|
|
Alarm PvaClientGetData::getAlarm()
|
|
{
|
|
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
|
|
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("alarm");
|
|
if(!pvs) throw std::runtime_error(messagePrefix + noAlarm);
|
|
pvAlarm.attach(pvs);
|
|
if(pvAlarm.isAttached()) {
|
|
Alarm alarm;
|
|
pvAlarm.get(alarm);
|
|
pvAlarm.detach();
|
|
return alarm;
|
|
}
|
|
throw std::runtime_error(messagePrefix + noAlarm);
|
|
}
|
|
|
|
TimeStamp PvaClientGetData::getTimeStamp()
|
|
{
|
|
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
|
|
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("timeStamp");
|
|
if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp);
|
|
pvTimeStamp.attach(pvs);
|
|
if(pvTimeStamp.isAttached()) {
|
|
TimeStamp timeStamp;
|
|
pvTimeStamp.get(timeStamp);
|
|
pvTimeStamp.detach();
|
|
return timeStamp;
|
|
}
|
|
throw std::runtime_error(messagePrefix + noTimeStamp);
|
|
}
|
|
|
|
}}
|