NTNDArray mapping
This commit is contained in:
@ -59,9 +59,6 @@ struct context {
|
||||
} else if(key=="+trigger") {
|
||||
fld.trigger = value.ref<std::string>();
|
||||
|
||||
} else if(key=="+predef") {
|
||||
fld.predef = value.ref<std::string>();
|
||||
|
||||
} else if(key=="+putorder") {
|
||||
fld.putorder = value.as<pvd::int32>();
|
||||
|
||||
|
@ -44,14 +44,6 @@ struct Splitter {
|
||||
}
|
||||
};
|
||||
|
||||
pvd::StructureConstPtr NTNDArray(pvd::getFieldCreate()->createFieldBuilder()
|
||||
->setId("epics:nt/NTNDArray:1.0")
|
||||
//->add("value", pvd::getFieldCreate()->createVariantUnion())
|
||||
->addNestedStructureArray("dimension")
|
||||
->add("size", pvd::pvInt)
|
||||
->endNested()
|
||||
->createStructure());
|
||||
|
||||
struct GroupMemberInfo {
|
||||
// consumes builder
|
||||
GroupMemberInfo(const std::string& a, const std::string& b, p2p::auto_ptr<PVIFBuilder>& builder)
|
||||
@ -80,9 +72,6 @@ struct GroupInfo {
|
||||
|
||||
enum tribool {Unset,True,False} atomic;
|
||||
bool hastriggers;
|
||||
|
||||
typedef std::map<std::string, pvd::StructureConstPtr> predefs_t;
|
||||
predefs_t predefs;
|
||||
};
|
||||
|
||||
// Iterates all PDB records and gathers info() to construct PDB groups
|
||||
@ -199,18 +188,6 @@ struct PDBProcessor
|
||||
const std::string& fldname = fit->first;
|
||||
const GroupConfig::Field& fld = fit->second;
|
||||
|
||||
if(!fld.predef.empty()) {
|
||||
if(fld.predef=="epics:nt/NTNDArray:1.0") {
|
||||
curgroup->predefs[fldname] = NTNDArray;
|
||||
} else {
|
||||
fprintf(stderr, "%s.%s : unknown pre-defined type \"%s\"\n",
|
||||
grpname.c_str(), fldname.c_str(), fld.predef.c_str());
|
||||
}
|
||||
// allow pre-defined fields to skip a channel mapping
|
||||
if(fld.channel.empty())
|
||||
continue;
|
||||
}
|
||||
|
||||
if(fld.channel.empty())
|
||||
throw std::runtime_error("Missing required +channel");
|
||||
|
||||
@ -322,31 +299,6 @@ PDBProvider::PDBProvider(const epics::pvAccess::Configuration::shared_pointer &)
|
||||
pvd::FieldBuilderPtr builder(fcreate->createFieldBuilder());
|
||||
builder->add("record", _options);
|
||||
|
||||
for(GroupInfo::predefs_t::const_iterator it=info.predefs.begin(), end=info.predefs.end();
|
||||
it!=end; ++it)
|
||||
{
|
||||
if(PDBProviderDebug>2)
|
||||
fprintf(stderr, "%s.%s add pre-defined %s\n",
|
||||
info.name.c_str(), it->first.c_str(), it->second->getID().c_str());
|
||||
|
||||
std::vector<std::string> parts;
|
||||
{
|
||||
Splitter S(it->first.c_str(), '.');
|
||||
std::string part;
|
||||
while(S.snip(part))
|
||||
parts.push_back(part);
|
||||
}
|
||||
assert(!parts.empty());
|
||||
|
||||
for(size_t j=0; j<parts.size()-1; j++)
|
||||
builder = builder->addNestedStructure(parts[j]);
|
||||
|
||||
builder->add(parts.back(), it->second);
|
||||
|
||||
for(size_t j=0; j<parts.size()-1; j++)
|
||||
builder = builder->endNested();
|
||||
}
|
||||
|
||||
for(size_t i=0; i<nchans; i++)
|
||||
{
|
||||
GroupMemberInfo &mem = info.members[i];
|
||||
@ -357,22 +309,25 @@ PDBProvider::PDBProvider(const epics::pvAccess::Configuration::shared_pointer &)
|
||||
info.builder = PTRMOVE(mem.builder);
|
||||
assert(info.builder.get());
|
||||
|
||||
std::vector<std::string> parts;
|
||||
{
|
||||
Splitter S(mem.pvfldname.c_str(), '.');
|
||||
std::string part;
|
||||
while(S.snip(part))
|
||||
parts.push_back(part);
|
||||
if(info.builder->buildsType) {
|
||||
|
||||
std::vector<std::string> parts;
|
||||
{
|
||||
Splitter S(mem.pvfldname.c_str(), '.');
|
||||
std::string part;
|
||||
while(S.snip(part))
|
||||
parts.push_back(part);
|
||||
}
|
||||
assert(!parts.empty());
|
||||
|
||||
for(size_t j=0; j<parts.size()-1; j++)
|
||||
builder = builder->addNestedStructure(parts[j]);
|
||||
|
||||
builder->add(parts.back(), info.builder->dtype(chan));
|
||||
|
||||
for(size_t j=0; j<parts.size()-1; j++)
|
||||
builder = builder->endNested();
|
||||
}
|
||||
assert(!parts.empty());
|
||||
|
||||
for(size_t j=0; j<parts.size()-1; j++)
|
||||
builder = builder->addNestedStructure(parts[j]);
|
||||
|
||||
builder->add(parts.back(), info.builder->dtype(chan));
|
||||
|
||||
for(size_t j=0; j<parts.size()-1; j++)
|
||||
builder = builder->endNested();
|
||||
|
||||
info.attachment = mem.pvfldname;
|
||||
info.chan.swap(chan);
|
||||
@ -382,6 +337,7 @@ PDBProvider::PDBProvider(const epics::pvAccess::Configuration::shared_pointer &)
|
||||
info.triggers.push_back(*idx);
|
||||
}
|
||||
|
||||
assert(info.chan);
|
||||
records[i] = dbChannelRecord(info.chan);
|
||||
}
|
||||
pv->members.swap(members);
|
||||
|
@ -22,7 +22,7 @@
|
||||
struct epicsShareClass GroupConfig
|
||||
{
|
||||
struct epicsShareClass Field {
|
||||
std::string type, channel, trigger, predef;
|
||||
std::string type, channel, trigger;
|
||||
int putorder;
|
||||
|
||||
Field() :putorder(std::numeric_limits<int>::min()) {}
|
||||
@ -31,7 +31,6 @@ struct epicsShareClass GroupConfig
|
||||
std::swap(type, o.type);
|
||||
std::swap(channel, o.channel);
|
||||
std::swap(trigger, o.trigger);
|
||||
std::swap(predef, o.predef);
|
||||
std::swap(putorder, o.putorder);
|
||||
}
|
||||
};
|
||||
|
102
pdbApp/pvif.cpp
102
pdbApp/pvif.cpp
@ -573,7 +573,10 @@ struct PVIFPlain : public PVIF
|
||||
:PVIF(channel)
|
||||
,field(std::tr1::static_pointer_cast<PVD>(fld))
|
||||
,channel(channel)
|
||||
{}
|
||||
{
|
||||
if(!field)
|
||||
throw std::logic_error("PVIFPlain attached type mis-match");
|
||||
}
|
||||
|
||||
virtual ~PVIFPlain() {}
|
||||
|
||||
@ -601,7 +604,7 @@ struct PVIFPlain : public PVIF
|
||||
|
||||
struct PlainBuilder : public PVIFBuilder
|
||||
{
|
||||
PlainBuilder() {}
|
||||
PlainBuilder() :PVIFBuilder(true) {}
|
||||
virtual ~PlainBuilder() {}
|
||||
|
||||
// fetch the structure description
|
||||
@ -632,9 +635,98 @@ struct PlainBuilder : public PVIFBuilder
|
||||
return new PVIFPlain<pvd::PVScalarArray>(channel, root);
|
||||
}
|
||||
};
|
||||
|
||||
struct ExistingBuilder : public PVIFBuilder
|
||||
{
|
||||
ExistingBuilder() :PVIFBuilder(false) {}
|
||||
virtual ~ExistingBuilder() {}
|
||||
|
||||
// fetch the structure description
|
||||
virtual epics::pvData::FieldConstPtr dtype(dbChannel *channel) OVERRIDE FINAL {
|
||||
throw std::logic_error("Don't call me");
|
||||
}
|
||||
|
||||
// Attach to a structure instance.
|
||||
// must be of the type returned by dtype().
|
||||
// need not be the root structure
|
||||
virtual PVIF* attach(dbChannel *channel, const epics::pvData::PVFieldPtr& root) OVERRIDE FINAL
|
||||
{
|
||||
const long maxelem = dbChannelFinalElements(channel);
|
||||
|
||||
if(maxelem==1)
|
||||
return new PVIFPlain<pvd::PVScalar>(channel, root);
|
||||
else
|
||||
return new PVIFPlain<pvd::PVScalarArray>(channel, root);
|
||||
}
|
||||
};
|
||||
|
||||
pvd::StructureConstPtr NTNDArray(pvd::getFieldCreate()->createFieldBuilder()
|
||||
->setId("epics:nt/NTNDArray:1.0")
|
||||
->add("value", pvd::getFieldCreate()->createVariantUnion())
|
||||
->addNestedStructureArray("dimension")
|
||||
->add("size", pvd::pvInt)
|
||||
->endNested()
|
||||
->createStructure());
|
||||
|
||||
|
||||
struct NTNDArrayBuilder : public PVIFBuilder
|
||||
{
|
||||
NTNDArrayBuilder() :PVIFBuilder(true) {}
|
||||
virtual ~NTNDArrayBuilder() {}
|
||||
|
||||
// fetch the structure description
|
||||
virtual epics::pvData::FieldConstPtr dtype(dbChannel *channel) OVERRIDE FINAL {
|
||||
(void)channel; //ignored
|
||||
return NTNDArray;
|
||||
}
|
||||
|
||||
// Attach to a structure instance.
|
||||
// must be of the type returned by dtype().
|
||||
// need not be the root structure
|
||||
virtual PVIF* attach(dbChannel *channel, const epics::pvData::PVFieldPtr& root) OVERRIDE FINAL
|
||||
{
|
||||
pvd::PVDataCreatePtr create(pvd::getPVDataCreate());
|
||||
const short dbr = dbChannelFinalFieldType(channel);
|
||||
const pvd::ScalarType pvt = DBR2PVD(dbr);
|
||||
|
||||
pvd::PVStructure *base = dynamic_cast<pvd::PVStructure*>(root.get());
|
||||
if(!base)
|
||||
throw std::logic_error("Mis-matched attachment point");
|
||||
|
||||
// auto-magically ensure that dimension array has at least 2 elements
|
||||
// TODO: bit of a hack, should be able to do this as needed from builder for size field(s)
|
||||
{
|
||||
pvd::PVStructureArrayPtr dims(base->getSubFieldT<pvd::PVStructureArray>("dimension"));
|
||||
pvd::PVStructureArray::const_svector cur(dims->view());
|
||||
if(cur.size()<2 || !cur[0] || !cur[1]) {
|
||||
pvd::PVStructureArray::svector D(dims->reuse());
|
||||
pvd::StructureConstPtr dtype(dims->getStructureArray()->getStructure());
|
||||
if(D.size()<2) D.resize(2);
|
||||
if(!D[0])
|
||||
D[0] = create->createPVStructure(dtype);
|
||||
if(!D[1])
|
||||
D[1] = create->createPVStructure(dtype);
|
||||
dims->replace(pvd::freeze(D));
|
||||
}
|
||||
}
|
||||
|
||||
pvd::PVUnionPtr value(base->getSubFieldT<pvd::PVUnion>("value"));
|
||||
|
||||
pvd::PVFieldPtr arr(value->get());
|
||||
if(!arr) {
|
||||
arr = create->createPVScalarArray(pvt);
|
||||
value->set(arr);
|
||||
}
|
||||
|
||||
return new PVIFPlain<pvd::PVScalarArray>(channel, arr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}//namespace
|
||||
|
||||
PVIFBuilder::PVIFBuilder()
|
||||
PVIFBuilder::PVIFBuilder(bool buildsType)
|
||||
:buildsType(buildsType)
|
||||
{}
|
||||
|
||||
PVIFBuilder::~PVIFBuilder() {}
|
||||
@ -646,6 +738,10 @@ PVIFBuilder* PVIFBuilder::create(const std::string& type)
|
||||
return new ScalarBuilder;
|
||||
else if(type=="plain")
|
||||
return new PlainBuilder;
|
||||
else if(type=="existing")
|
||||
return new ExistingBuilder;
|
||||
else if(type=="NTNDArray" || type=="NTNDArray:1.0")
|
||||
return new NTNDArrayBuilder;
|
||||
else
|
||||
throw std::runtime_error(std::string("Unknown +type=")+type);
|
||||
}
|
||||
|
@ -277,6 +277,8 @@ private:
|
||||
|
||||
struct epicsShareClass PVIFBuilder {
|
||||
|
||||
const bool buildsType;
|
||||
|
||||
virtual ~PVIFBuilder();
|
||||
|
||||
// fetch the structure description
|
||||
@ -289,7 +291,7 @@ struct epicsShareClass PVIFBuilder {
|
||||
|
||||
static PVIFBuilder* create(const std::string& name);
|
||||
protected:
|
||||
PVIFBuilder();
|
||||
PVIFBuilder(bool buildsType);
|
||||
private:
|
||||
PVIFBuilder(const PVIFBuilder&);
|
||||
PVIFBuilder& operator=(const PVIFBuilder&);
|
||||
@ -297,7 +299,7 @@ private:
|
||||
|
||||
struct epicsShareClass ScalarBuilder : public PVIFBuilder
|
||||
{
|
||||
ScalarBuilder() {}
|
||||
ScalarBuilder() :PVIFBuilder(true) {}
|
||||
|
||||
virtual ~ScalarBuilder() {}
|
||||
|
||||
|
Reference in New Issue
Block a user