17 #include <pv/createRequest.h> 18 #include <pv/convert.h> 19 #include <pv/pvEnumerated.h> 21 #if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1) 26 #define epicsExportSharedSymbols 30 using std::tr1::static_pointer_cast;
35 namespace epics {
namespace pvaClient {
39 static ConvertPtr convert = getConvert();
40 static string noStructure(
"no pvStructure ");
41 static string noValue(
"no value field");
42 static string noScalar(
"value is not a scalar");
43 static string noArray(
"value is not an array");
44 static string noScalarArray(
"value is not a scalarArray");
45 static string noAlarm(
"no alarm");
46 static string noTimeStamp(
"no timeStamp");
50 if(PvaClient::getDebug()) cout <<
"PvaClientData::create\n";
55 PvaClientData::PvaClientData(StructureConstPtr
const & structure)
56 : structure(structure)
65 const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
66 if(fieldPtrArray.size()==0) {
67 throw std::logic_error(
"PvaClientData::getSinglePVField() pvRequest for empty structure");
69 if(fieldPtrArray.size()!=1) {
70 PVFieldPtr pvValue = pvStructure->getSubField(
"value");
72 Type type = pvValue->getField()->getType();
73 if(type!=epics::pvData::structure)
return pvValue;
75 throw std::logic_error(
"PvaClientData::getSinglePVField() pvRequest for multiple fields");
77 PVFieldPtr pvField(fieldPtrArray[0]);
78 Type type = pvField->getField()->getType();
79 if(type!=epics::pvData::structure)
return pvField;
80 pvStructure = static_pointer_cast<PVStructure>(pvField);
103 if(pvStructure)
return pvStructure;
109 if(bitSet)
return bitSet;
115 if(!bitSet)
throw std::runtime_error(
messagePrefix + noStructure);
116 size_t nextSet = bitSet->nextSetBit(0);
118 while(nextSet!=string::npos) {
120 pvField = pvStructure;
122 pvField = pvStructure->getSubField(nextSet);
124 string name = pvField->getFullName();
125 out << name <<
" = " << pvField << endl;
126 nextSet = bitSet->nextSetBit(nextSet+1);
132 PVStructurePtr
const & pvStructureFrom,
133 BitSetPtr
const & bitSetFrom)
136 pvStructure = pvStructureFrom;
138 pvValue = pvStructure->getSubField(
"value");
145 if(!pvValue)
return false;
152 if(!pvValue)
return false;
153 if(pvValue->getField()->getType()==scalar)
return true;
160 if(!pvValue)
return false;
161 if(pvValue->getField()->getType()==scalarArray)
return true;
176 if(pvValue->getField()->getType()!=scalar) {
179 return pvStructure->getSubField<PVScalar>(
"value");
186 Type type = pvValue->getField()->getType();
187 if(type!=scalarArray && type!=structureArray && type!=unionArray) {
190 return pvStructure->getSubField<PVArray>(
"value");
197 Type type = pvValue->getField()->getType();
198 if(type!=scalarArray) {
201 return pvStructure->getSubField<PVScalarArray>(
"value");
208 Type type = pvField->getField()->getType();
210 throw std::logic_error(
"PvaClientData::getDouble() did not find a scalar field");
212 PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
213 ScalarType scalarType = pvScalar->getScalar()->getScalarType();
214 if(scalarType==pvDouble) {
215 PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
216 return pvDouble->get();
218 if(!ScalarTypeFunc::isNumeric(scalarType)) {
219 throw std::logic_error(
220 "PvaClientData::getDouble() did not find a numeric scalar field");
222 return convert->toDouble(pvScalar);
229 Type type = pvField->getField()->getType();
231 throw std::logic_error(
"PvaClientData::getString() did not find a scalar field");
233 PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
234 return convert->toString(pvScalar);
241 Type type = pvField->getField()->getType();
242 if(type!=scalarArray) {
243 throw std::logic_error(
"PvaClientData::getDoubleArray() did not find a scalarArray field");
245 PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
246 ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
247 if(!ScalarTypeFunc::isNumeric(scalarType)) {
248 throw std::logic_error(
249 "PvaClientData::getDoubleArray() did not find a numeric scalarArray field");
251 shared_vector<const double> retValue;
252 pvScalarArray->getAs<
const double>(retValue);
260 Type type = pvField->getField()->getType();
261 if(type!=scalarArray) {
262 throw std::logic_error(
"PvaClientData::getStringArray() did not find a scalarArray field");
264 PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
265 shared_vector<const string> retValue;
266 pvScalarArray->getAs<
const string>(retValue);
273 if(!pvStructure)
throw new std::runtime_error(
messagePrefix + noStructure);
274 PVStructurePtr pvs = pvStructure->getSubField<PVStructure>(
"alarm");
277 if(pvAlarm.isAttached()) {
289 if(!pvStructure)
throw new std::runtime_error(
messagePrefix + noStructure);
290 PVStructurePtr pvs = pvStructure->getSubField<PVStructure>(
"timeStamp");
291 if(!pvs)
throw std::runtime_error(
messagePrefix + noTimeStamp);
292 pvTimeStamp.attach(pvs);
293 if(pvTimeStamp.isAttached()) {
295 pvTimeStamp.get(timeStamp);
296 pvTimeStamp.detach();
304 if(!pvStructure)
throw new std::runtime_error(
messagePrefix + noStructure);
308 const std::string &arg,
const PVFieldPtr &dest,BitSetPtr & bitSet)
311 std::istringstream strm(arg);
312 parseJSON(strm, dest,&(*bitSet));
314 throw std::runtime_error(
"JSON support not built");
319 const std::string &arg,
const PVUnionPtr &pvUnion)
321 if(pvUnion->getUnion()->isVariant()) {
322 throw std::runtime_error(
messagePrefix +
"varient union not implemented");
324 size_t iequals = arg.find_first_of(
'=');
327 if(iequals==std::string::npos) {
329 mess +=
" was expected to start with field=";
332 field = arg.substr(0,iequals);
333 rest = arg.substr(iequals+1);
334 PVFieldPtr pvField(pvUnion->select(field));
335 if(pvField->getField()->getType()==epics::pvData::union_) {
336 PVUnionPtr pvu = static_pointer_cast<PVUnion>(pvField);
341 parse(rest,pvField,bs);
347 if(!pvStructure)
throw std::runtime_error(
messagePrefix + noStructure);
348 if(!bitSet)
throw std::runtime_error(
messagePrefix + noStructure);
349 size_t num = args.size();
350 if(num<1)
throw std::runtime_error(
messagePrefix +
" no arguments");
351 for(
size_t i=0; i<num; ++i)
353 string val = args[i];
354 size_t iequals = val.find_first_of(
'=');
357 if(iequals==std::string::npos) {
358 parse(rest,pvStructure,bitSet);
361 field = val.substr(0,iequals);
362 rest = val.substr(iequals+1);
363 if(field.size()==std::string::npos) {
364 parse(rest,pvStructure,bitSet);
367 PVFieldPtr pvField(pvStructure->getSubField(field));
368 if(!pvField)
throw std::runtime_error(
messagePrefix + field +
" does not exist");
370 PVEnumerated pvEnumerated;
371 bool result = pvEnumerated.attach(pvField);
373 PVStringArray::const_svector choices(pvEnumerated.getChoices());
374 for(
size_t i=0; i<choices.size(); ++i) {
375 if(choices[i]==rest) {
376 pvEnumerated.setIndex(i);
382 PVUnionPtr pvUnion(pvStructure->getSubField<PVUnion>(field));
385 bitSet->set(pvUnion->getFieldOffset());
388 parse(rest,pvField,bitSet);
394 bool ignoreUnprintable,
398 JSONPrintOptions opts;
399 opts.ignoreUnprintable = ignoreUnprintable;
400 opts.multiLine = multiLine;
401 printJSON(strm,*pvStructure,*bitSet,opts);
403 throw std::runtime_error(
"JSON support not built");
410 const PVFieldPtrArray pvFields(pvStructure->getPVFields());
411 for(
size_t i=0; i<pvFields.size(); ++i) {
412 PVFieldPtr pvField = pvFields[i];
413 Type type(pvField->getField()->getType());
417 PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
418 pvScalarArray->setLength(0);
423 PVStructureArrayPtr pvStructureArray = static_pointer_cast<PVStructureArray>(pvField);
424 pvStructureArray->setLength(0);
427 case epics::pvData::structure:
429 PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
epics::pvData::Alarm getAlarm()
Get the alarm. If the pvStructure has an alarm field it's values are returned. Otherwise an exception...
double getDouble()
Get the value as a double.
void parse(const std::vector< std::string > &args)
parse from args
std::tr1::shared_ptr< epics::pvData::PVArray > getArrayValue()
Get the interface to an array value field.
bool isValueScalar()
Is the value field a scalar?
std::tr1::shared_ptr< PVArray > PVArrayPtr
epics::pvData::PVScalarPtr getScalarValue()
Return the interface to a scalar value field.
epics::pvData::BitSetPtr getChangedBitSet()
Get the changed BitSet for the pvStructure.
epics::pvData::shared_vector< const std::string > getStringArray()
Get the value as a string array.
epics::pvData::PVFieldPtr getSinglePVField()
A base class for PvaClientGetData, PvaClientPutData, and PvaClientMonitorData.
void streamJSON(std::ostream &strm, bool ignoreUnprintable=true, bool multiLine=false)
generate JSON output from the current PVStructure and displays it on the output stream.
void zeroArrayLength()
set length of all array fields to 0
bool hasValue()
Is there a top level field named value.
std::ostream & showChanged(std::ostream &out)
Show the fields that have changed value since the last get.
epics::pvData::PVFieldPtr getValue()
Get the interface to the value field.
epics::pvData::shared_vector< const double > getDoubleArray()
Get the value as a double array.
std::tr1::shared_ptr< epics::pvData::PVScalarArray > getScalarArrayValue()
Get the interface to a scalar array value field.
std::string messagePrefix
void setMessagePrefix(std::string const &value)
Set a prefix for throw messages.
epics::pvData::PVStructurePtr getPVStructure()
Get the pvStructure.
epics::pvData::TimeStamp getTimeStamp()
Get the timeStamp. If the pvStructure has a timeStamp field, it's values are returned. Otherwise an exception is thrown.
static bool getDebug()
Is debug set?
epics::pvData::StructureConstPtr getStructure()
Get the structure.
void setData(epics::pvData::PVStructurePtr const &pvStructureFrom, epics::pvData::BitSetPtr const &bitSetFrom)
New data is present.
bool isValueScalarArray()
Is the value field a scalar array?
std::tr1::shared_ptr< PvaClientData > PvaClientDataPtr