From 7465da3217acc33f42cd4e8f441babe0da7cf40e Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Fri, 12 Sep 2014 15:41:36 -0400 Subject: [PATCH] implemented is_compatible --- src/nt/ntmultiChannel.cpp | 21 +++++++++++++++++++-- src/nt/ntnameValue.cpp | 8 +++++++- src/nt/ntndarray.cpp | 25 +++++++++++++++++++++++++ src/nt/ntscalar.cpp | 12 ++++++++++++ src/nt/ntscalarArray.cpp | 15 ++++++++++++--- src/nt/nttable.cpp | 27 +++++++++++++++++++-------- test/nt/ntndarrayTest.cpp | 24 ++++++++++++++++++++++-- 7 files changed, 116 insertions(+), 16 deletions(-) diff --git a/src/nt/ntmultiChannel.cpp b/src/nt/ntmultiChannel.cpp index 55b3d48..8b4c6fe 100644 --- a/src/nt/ntmultiChannel.cpp +++ b/src/nt/ntmultiChannel.cpp @@ -16,11 +16,10 @@ namespace epics { namespace nt { static FieldCreatePtr fieldCreate = getFieldCreate(); static PVDataCreatePtr pvDataCreate = getPVDataCreate(); +static NTFieldPtr ntField = NTField::get(); namespace detail { -static NTFieldPtr ntField = NTField::get(); - NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addValue(UnionConstPtr valuePtr) { value = true; @@ -222,6 +221,24 @@ bool NTMultiChannel::is_compatible(PVStructurePtr const &pvStructure) { PVUnionArrayPtr pvValue = pvStructure->getSubField("value"); if(!pvValue) return false; + PVFieldPtr pvField = pvStructure->getSubField("descriptor"); + if(pvField && !pvStructure->getSubField("descriptor")) return false; + pvField = pvStructure->getSubField("alarm"); + if(pvField && !ntField->isAlarm(pvField->getField())) return false; + pvField = pvStructure->getSubField("timeStamp"); + if(pvField && !ntField->isTimeStamp(pvField->getField())) return false; + pvField = pvStructure->getSubField("severity"); + if(pvField && !pvStructure->getSubField("severity")) return false; + pvField = pvStructure->getSubField("status"); + if(pvField && !pvStructure->getSubField("status")) return false; + pvField = pvStructure->getSubField("message"); + if(pvField && !pvStructure->getSubField("message")) return false; + pvField = pvStructure->getSubField("secondsPastEpoch"); + if(pvField && !pvStructure->getSubField("secondsPastEpoch")) return false; + pvField = pvStructure->getSubField("nanoseconds"); + if(pvField && !pvStructure->getSubField("nanoseconds")) return false; + pvField = pvStructure->getSubField("userTag"); + if(pvField && !pvStructure->getSubField("userTag")) return false; return true; } diff --git a/src/nt/ntnameValue.cpp b/src/nt/ntnameValue.cpp index ac5ae45..5708381 100644 --- a/src/nt/ntnameValue.cpp +++ b/src/nt/ntnameValue.cpp @@ -11,10 +11,10 @@ using namespace std; using namespace epics::pvData; namespace epics { namespace nt { +static NTFieldPtr ntField = NTField::get(); namespace detail { -static NTFieldPtr ntField = NTField::get(); NTNameValueBuilder::shared_pointer NTNameValueBuilder::value( epics::pvData::ScalarType scalarType @@ -134,6 +134,12 @@ bool NTNameValue::is_compatible(PVStructurePtr const & pvStructure) if(!pvNames) return false; PVFieldPtr pvValues = pvStructure->getSubField("values"); if(!pvValues) return false; + PVFieldPtr pvField = pvStructure->getSubField("descriptor"); + if(pvField && !pvStructure->getSubField("descriptor")) return false; + pvField = pvStructure->getSubField("alarm"); + if(pvField && !ntField->isAlarm(pvField->getField())) return false; + pvField = pvStructure->getSubField("timeStamp"); + if(pvField && !ntField->isTimeStamp(pvField->getField())) return false; return true; } diff --git a/src/nt/ntndarray.cpp b/src/nt/ntndarray.cpp index 0436f8f..8683b04 100644 --- a/src/nt/ntndarray.cpp +++ b/src/nt/ntndarray.cpp @@ -14,6 +14,8 @@ using namespace epics::pvData; namespace epics { namespace nt { +static NTFieldPtr ntField = NTField::get(); + namespace detail { const std::string ntAttrStr("uri:ev4:nt/2014/pwd:NTAttribute"); @@ -212,6 +214,29 @@ bool NTNDArray::is_a(StructureConstPtr const & structure) bool NTNDArray::is_compatible(PVStructurePtr const & pvStructure) { + PVUnionPtr pvValue = pvStructure->getSubField("value"); + if(!pvValue) return false; + PVFieldPtr pvField = pvStructure->getSubField("descriptor"); + if(pvField && !pvStructure->getSubField("descriptor")) return false; + pvField = pvStructure->getSubField("alarm"); + if(pvField && !ntField->isAlarm(pvField->getField())) return false; + pvField = pvStructure->getSubField("timeStamp"); + if(pvField && !ntField->isTimeStamp(pvField->getField())) return false; + pvField = pvStructure->getSubField("display"); + if(pvField && !ntField->isDisplay(pvField->getField())) return false; + if(!pvStructure->getSubField("compressedSize")) return false; + if(!pvStructure->getSubField("uncompressedSize")) return false; + PVStructurePtr pvCodec = pvStructure->getSubField("codec"); + if(!pvCodec) return false; + if(!pvCodec->getSubField("name")) return false; + if(!pvCodec->getSubField("parameters")) return false; + PVStructureArrayPtr pvDimension = pvStructure->getSubField("dimension"); + if(pvDimension->getStructureArray()->getStructure()->getID().compare("dimension_t")!=0) return false; + if(!pvStructure->getSubField("uniqueId")) return false; + pvField = pvStructure->getSubField("dataTimeStamp"); + if(pvField && !ntField->isTimeStamp(pvField->getField())) return false; + PVStructureArrayPtr pvAttribute = pvStructure->getSubField("attribute"); + if(!pvAttribute->getStructureArray()->getStructure()->getID().compare("ntAttrStr")!=0) return false; return true; } diff --git a/src/nt/ntscalar.cpp b/src/nt/ntscalar.cpp index d988361..b6e3f62 100644 --- a/src/nt/ntscalar.cpp +++ b/src/nt/ntscalar.cpp @@ -12,6 +12,8 @@ using namespace epics::pvData; namespace epics { namespace nt { +static NTFieldPtr ntField = NTField::get(); + namespace detail { static NTFieldPtr ntField = NTField::get(); @@ -150,6 +152,16 @@ bool NTScalar::is_compatible(PVStructurePtr const & pvStructure) { PVScalarPtr pvValue = pvStructure->getSubField("value"); if(!pvValue) return false; + PVFieldPtr pvField = pvStructure->getSubField("descriptor"); + if(pvField && !pvStructure->getSubField("descriptor")) return false; + pvField = pvStructure->getSubField("alarm"); + if(pvField && !ntField->isAlarm(pvField->getField())) return false; + pvField = pvStructure->getSubField("timeStamp"); + if(pvField && !ntField->isTimeStamp(pvField->getField())) return false; + pvField = pvStructure->getSubField("display"); + if(pvField && !ntField->isDisplay(pvField->getField())) return false; + pvField = pvStructure->getSubField("control"); + if(pvField && !ntField->isControl(pvField->getField())) return false; return true; } diff --git a/src/nt/ntscalarArray.cpp b/src/nt/ntscalarArray.cpp index 18c2e9f..1c61a8d 100644 --- a/src/nt/ntscalarArray.cpp +++ b/src/nt/ntscalarArray.cpp @@ -12,10 +12,10 @@ using namespace epics::pvData; namespace epics { namespace nt { -namespace detail { - static NTFieldPtr ntField = NTField::get(); +namespace detail { + NTScalarArrayBuilder::shared_pointer NTScalarArrayBuilder::arrayValue( epics::pvData::ScalarType elementType ) @@ -123,7 +123,6 @@ NTScalarArrayBuilder::shared_pointer NTScalarArrayBuilder::add(string const & na return shared_from_this(); } - } const std::string NTScalarArray::URI("uri:ev4:nt/2014/pwd:NTScalarArray"); @@ -150,6 +149,16 @@ bool NTScalarArray::is_compatible(PVStructurePtr const & pvStructure) { PVScalarArrayPtr pvValue = pvStructure->getSubField("value"); if(!pvValue) return false; + PVFieldPtr pvField = pvStructure->getSubField("descriptor"); + if(pvField && !pvStructure->getSubField("descriptor")) return false; + pvField = pvStructure->getSubField("alarm"); + if(pvField && !ntField->isAlarm(pvField->getField())) return false; + pvField = pvStructure->getSubField("timeStamp"); + if(pvField && !ntField->isTimeStamp(pvField->getField())) return false; + pvField = pvStructure->getSubField("display"); + if(pvField && !ntField->isDisplay(pvField->getField())) return false; + pvField = pvStructure->getSubField("control"); + if(pvField && !ntField->isControl(pvField->getField())) return false; return true; } diff --git a/src/nt/nttable.cpp b/src/nt/nttable.cpp index 1c8f36d..c20009b 100644 --- a/src/nt/nttable.cpp +++ b/src/nt/nttable.cpp @@ -14,10 +14,10 @@ using namespace epics::pvData; namespace epics { namespace nt { -namespace detail { - static NTFieldPtr ntField = NTField::get(); +namespace detail { + NTTableBuilder::shared_pointer NTTableBuilder::add( std::string const & name, epics::pvData::ScalarType scalarType ) @@ -87,13 +87,13 @@ NTTableBuilder::shared_pointer NTTableBuilder::addTimeStamp() PVStructurePtr NTTableBuilder::createPVStructure() { - PVStringArray::svector l; - l.resize(labels.size()); - std::copy(labels.begin(), labels.end(), l.begin()); - PVStructurePtr s = getPVDataCreate()->createPVStructure(createStructure()); - s->getSubField("labels")->replace(freeze(l)); - + StringArray const & fieldNames = + s->getSubField("value")->getStructure()->getFieldNames(); + size_t len = fieldNames.size(); + shared_vector names(len); + for(size_t i=0; igetSubField("labels")->replace(freeze(names)); return s; } @@ -147,6 +147,17 @@ bool NTTable::is_a(StructureConstPtr const & structure) bool NTTable::is_compatible(PVStructurePtr const & pvStructure) { + PVFieldPtr pvField = pvStructure->getSubField("alarm"); + if(pvField && !ntField->isAlarm(pvField->getField())) return false; + pvField = pvStructure->getSubField("timeStamp"); + if(pvField && !ntField->isTimeStamp(pvField->getField())) return false; + PVStringArrayPtr pvLabel = pvStructure->getSubField("labels"); + const shared_vector column(pvLabel->view()); + size_t len = column.size(); + for(size_t i=0; igetSubField(value)) return false; + } return true; } diff --git a/test/nt/ntndarrayTest.cpp b/test/nt/ntndarrayTest.cpp index a52bcb4..41096b4 100644 --- a/test/nt/ntndarrayTest.cpp +++ b/test/nt/ntndarrayTest.cpp @@ -51,6 +51,25 @@ void test_builder() } +void test_all() +{ + testDiag("test_builder"); + + NTNDArrayBuilderPtr builder = NTNDArray::createBuilder(); + testOk(builder.get() != 0, "Got builder"); + + PVStructurePtr pvStructure = builder-> + addDescriptor()-> + addTimeStamp()-> + addAlarm()-> + addDisplay()-> + add("extra1",fieldCreate->createScalar(pvString)) -> + add("extra2",fieldCreate->createScalarArray(pvString)) -> + createPVStructure(); + std::cout << *pvStructure << std::endl; + testOk1(NTNDArray::is_compatible(pvStructure)==true); +} + void test_narrow() { @@ -75,8 +94,8 @@ void test_narrow() testOk1(pvStructure.get() != 0); if (!pvStructure) return; - testOk1(NTNDArray::is_compatible(pvStructure)==true); + NTNDArrayPtr ptr = NTNDArray::narrow(pvStructure); testOk(ptr.get() != 0, "narrow OK"); @@ -85,8 +104,9 @@ void test_narrow() } MAIN(testNTNDArray) { - testPlan(23); + testPlan(25); test_builder(); + test_all(); test_narrow(); return testDone(); }