added JSON support

This commit is contained in:
mrkraimer
2019-07-16 09:42:08 -04:00
parent 4c56116827
commit 9153036ccc
2 changed files with 106 additions and 1 deletions

View File

@ -613,6 +613,14 @@ public:
void setData(
epics::pvData::PVStructurePtr const & pvStructureFrom,
epics::pvData::BitSetPtr const & bitSetFrom);
/** @brief parse from input stream
*
* Accepts arguments of the form field='value' where value is json syntax.
* field is name.name...
* @parm args The arguments
* @throw runtime_error if failure.
*/
void parse(const std::vector<std::string> &args);
/** @brief Is there a top level field named value.
* @return The answer.
*/
@ -691,12 +699,18 @@ protected:
void checkValue();
std::string messagePrefix;
private:
void parse(
const std::string &arg,
const epics::pvData::PVFieldPtr &dest,
epics::pvData::BitSetPtr &bitSet);
void parse(
const std::string &arg,
const epics::pvData::PVUnionPtr &dest);
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr bitSet;
epics::pvData::PVFieldPtr pvValue;
epics::pvData::PVAlarm pvAlarm;
epics::pvData::PVTimeStamp pvTimeStamp;

View File

@ -11,9 +11,16 @@
#include <typeinfo>
#include <sstream>
#include <istream>
#include <pv/createRequest.h>
#include <pv/convert.h>
#include <pv/pvEnumerated.h>
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
# include <pv/json.h>
# define USE_JSON
#endif
#define epicsExportSharedSymbols
@ -106,6 +113,90 @@ void PvaClientData::setData(
pvValue = pvStructure->getSubField("value");
}
void PvaClientData::parse(
const std::string &arg,const PVFieldPtr &dest,BitSetPtr & bitSet)
{
#ifdef USE_JSON
std::istringstream strm(arg);
parseJSON(strm, dest,&(*bitSet));
#else
throw std::runtime_error("JSON support not built");
#endif
}
void PvaClientData::parse(
const std::string &arg,const PVUnionPtr &pvUnion)
{
if(pvUnion->getUnion()->isVariant()) {
throw std::runtime_error(messagePrefix + "varient union not implemented");
}
size_t iequals = arg.find_first_of('=');
string field;
string rest;
if(iequals==std::string::npos) {
string mess(arg);
mess += " was expected to start with field=";
throw std::runtime_error(messagePrefix + mess);
}
field = arg.substr(0,iequals);
rest = arg.substr(iequals+1);
PVFieldPtr pvField(pvUnion->select(field));
if(pvField->getField()->getType()==epics::pvData::union_) {
PVUnionPtr pvu = static_pointer_cast<PVUnion>(pvField);
parse(rest,pvu);
return;
}
BitSetPtr bs;
parse(rest,pvField,bs);
return;
}
void PvaClientData::parse(const std::vector<std::string> &args)
{
if(!pvStructure) throw std::runtime_error(messagePrefix + noStructure);
if(!bitSet) throw std::runtime_error(messagePrefix + noStructure);
bitSet->clear();
size_t num = args.size();
for(size_t i=0; i<num; ++i)
{
string val = args[i];
size_t iequals = val.find_first_of('=');
string field;
string rest(val);
if(iequals!=std::string::npos) {
field = val.substr(0,iequals);
rest = val.substr(iequals+1);
}
if(field.size()==std::string::npos) {
parse(rest,pvStructure,bitSet);
return;
}
PVFieldPtr pvField(pvStructure->getSubField(field));
// look for enumerated structure
PVEnumerated pvEnumerated;
bool result = pvEnumerated.attach(pvField);
if(result) {
PVStringArray::const_svector choices(pvEnumerated.getChoices());
for(size_t i=0; i<choices.size(); ++i) {
if(choices[i]==rest) {
pvEnumerated.setIndex(i);
return;
}
}
}
// look for union
PVUnionPtr pvUnion(pvStructure->getSubField<PVUnion>(field));
if(pvUnion) {
parse(rest,pvUnion);
bitSet->set(pvUnion->getFieldOffset());
return;
}
PVScalarArrayPtr pvScalarArray(pvStructure->getSubField<PVScalarArray>(field));
if(pvScalarArray) pvScalarArray->setLength(0);
parse(rest,pvField,bitSet);
}
}
bool PvaClientData::hasValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::hasValue\n";