diff --git a/src/nt/ntaggregate.cpp b/src/nt/ntaggregate.cpp index 148834e..071c7be 100644 --- a/src/nt/ntaggregate.cpp +++ b/src/nt/ntaggregate.cpp @@ -190,21 +190,92 @@ bool NTAggregate::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTAggregate::isCompatible(StructureConstPtr const &structure) +{ + if (structure.get() == 0) return false; + + ScalarConstPtr valueField = structure->getField("value"); + if (valueField.get() == 0 || valueField->getScalarType() != pvDouble) + return false; + + ScalarConstPtr nField = structure->getField("N"); + if (nField.get() == 0 || nField->getScalarType() != pvLong) + return false; + + FieldConstPtr field = structure->getField("dispersion"); + if (field.get()) + { + ScalarConstPtr dispersionField = structure->getField("dispersion"); + if (!dispersionField.get() || dispersionField->getScalarType() != pvDouble) + return false; + } + + field = structure->getField("first"); + if (field.get()) + { + ScalarConstPtr firstField = structure->getField("first"); + if (!firstField.get() || firstField->getScalarType() != pvDouble) + return false; + } + + field = structure->getField("firstTimeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + field = structure->getField("last"); + if (field.get()) + { + ScalarConstPtr lastField = structure->getField("last"); + if (!lastField.get() || lastField->getScalarType() != pvDouble) + return false; + } + + field = structure->getField("lastTimeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + field = structure->getField("max"); + if (field.get()) + { + ScalarConstPtr maxField = structure->getField("max"); + if (!maxField.get() || maxField->getScalarType() != pvDouble) + return false; + } + + field = structure->getField("min"); + if (field.get()) + { + ScalarConstPtr minField = structure->getField("min"); + if (!minField.get() || minField->getScalarType() != pvDouble) + return false; + } + + field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + return true; +} + bool NTAggregate::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - PVDoublePtr 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; - - return true; + return isCompatible(pvStructure->getStructure()); } NTAggregateBuilderPtr NTAggregate::createBuilder() diff --git a/src/nt/ntattribute.cpp b/src/nt/ntattribute.cpp index 64fb54f..ae0c418 100644 --- a/src/nt/ntattribute.cpp +++ b/src/nt/ntattribute.cpp @@ -126,26 +126,53 @@ bool NTAttribute::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTAttribute::isCompatible(StructureConstPtr const & structure) +{ + if (structure.get() == 0) return false; + + ScalarConstPtr nameField = structure->getField("name"); + if (nameField.get() == 0 || nameField->getScalarType() != pvString) + return false; + + UnionConstPtr valueField = structure->getField("value"); + if (valueField.get() == 0 || !valueField->isVariant()) + return false; + + FieldConstPtr field = structure->getField("tags"); + if (field.get()) + { + ScalarArrayConstPtr tagsField = structure->getField("tags"); + if (tagsField.get() == 0 || tagsField->getElementType() != pvString) + return false; + } + + field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + return true; +} + + bool NTAttribute::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - PVUnionPtr pvValue = pvStructure->getSubField("value"); - if(!pvValue) return false; - - // TODO tags - - 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; + return isCompatible(pvStructure->getStructure()); } NTAttributeBuilderPtr NTAttribute::createBuilder() diff --git a/src/nt/ntcontinuum.cpp b/src/nt/ntcontinuum.cpp index d6d28a9..34817d5 100644 --- a/src/nt/ntcontinuum.cpp +++ b/src/nt/ntcontinuum.cpp @@ -116,22 +116,49 @@ bool NTContinuum::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTContinuum::isCompatible(StructureConstPtr const & structure) +{ + if (structure.get() == 0) return false; + + ScalarArrayConstPtr baseField = structure->getField("base"); + if (baseField.get() == 0 || baseField->getElementType() != pvDouble) + return false; + + ScalarArrayConstPtr valueField = structure->getField("value"); + if (valueField.get() == 0 || valueField->getElementType() != pvDouble) + return false; + + ScalarArrayConstPtr unitsField = structure->getField("units"); + if (unitsField.get() == 0 || unitsField->getElementType() != pvString) + return false; + + FieldConstPtr field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + return true; +} + + bool NTContinuum::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - PVDoubleArrayPtr pvBase = pvStructure->getSubField("base"); - if(!pvBase) return false; - PVDoubleArrayPtr pvValue = pvStructure->getSubField("value"); - if(!pvValue) return false; - PVStringArrayPtr pvUnits = 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; - return true; + + return isCompatible(pvStructure->getStructure()); } diff --git a/src/nt/ntenum.cpp b/src/nt/ntenum.cpp index 213f444..b99a028 100644 --- a/src/nt/ntenum.cpp +++ b/src/nt/ntenum.cpp @@ -117,21 +117,41 @@ bool NTEnum::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTEnum::isCompatible(StructureConstPtr const &structure) +{ + if (structure.get() == 0) return false; + + NTFieldPtr ntField = NTField::get(); + + FieldConstPtr valueField = structure->getField("value"); + if (!valueField.get() || !ntField->isEnumerated(valueField)) + return false; + + FieldConstPtr field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + return true; +} + + bool NTEnum::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - PVStructurePtr pvValue = pvStructure->getSubField("value"); - if(!pvValue) return false; - if (!ntField->isEnumerated(pvValue->getField())) 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; + return isCompatible(pvStructure->getStructure()); } NTEnumBuilderPtr NTEnum::createBuilder() diff --git a/src/nt/nthistogram.cpp b/src/nt/nthistogram.cpp index 549c2a9..303e63c 100644 --- a/src/nt/nthistogram.cpp +++ b/src/nt/nthistogram.cpp @@ -129,18 +129,46 @@ bool NTHistogram::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTHistogram::isCompatible(StructureConstPtr const &structure) +{ + if(!structure.get()) return false; + + ScalarArrayConstPtr rangesField = structure->getField("ranges"); + if(!rangesField.get() || rangesField->getElementType() != pvDouble) return false; + + ScalarArrayConstPtr valueField = structure->getField("value"); + if(!valueField.get()) return false; + + ScalarType scalarType = valueField->getElementType(); + if (scalarType != pvShort && + scalarType != pvInt && + scalarType != pvLong) + return false; + + FieldConstPtr field = structure->getField("descriptor"); + if(field) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + field = structure->getField("alarm"); + if (!field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (!field.get() && !ntField->isTimeStamp(field)) + return false; + + return true; +} + bool NTHistogram::isCompatible(PVStructurePtr const & pvStructure) { - if(!pvStructure) return false; - 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; - return true; + if(!pvStructure.get()) return false; + + return isCompatible(pvStructure->getStructure()); } diff --git a/src/nt/ntmatrix.cpp b/src/nt/ntmatrix.cpp index e7fdab0..3470d5b 100644 --- a/src/nt/ntmatrix.cpp +++ b/src/nt/ntmatrix.cpp @@ -133,22 +133,52 @@ bool NTMatrix::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTMatrix::isCompatible(StructureConstPtr const & structure) +{ + if (structure.get() == 0) return false; + + ScalarArrayConstPtr valueField = structure->getField("value"); + if (valueField.get() == 0 || valueField->getElementType() != pvDouble) + return false; + + FieldConstPtr field = structure->getField("dim"); + if (field.get()) + { + ScalarArrayConstPtr dimField = structure->getField("dim"); + if (dimField.get() == 0 || dimField->getElementType() != pvInt) + return false; + } + + field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + field = structure->getField("display"); + if (field.get() && !ntField->isDisplay(field)) + return false; + + return true; +} + bool NTMatrix::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - 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; + + return isCompatible(pvStructure->getStructure()); } diff --git a/src/nt/ntmultiChannel.cpp b/src/nt/ntmultiChannel.cpp index 0530d34..fa21d93 100644 --- a/src/nt/ntmultiChannel.cpp +++ b/src/nt/ntmultiChannel.cpp @@ -228,30 +228,94 @@ bool NTMultiChannel::is_a(StructureConstPtr const &structure) return NTUtils::is_a(structure->getID(), URI); } + +bool NTMultiChannel::isCompatible(StructureConstPtr const & structure) +{ + if (!structure.get()) return false; + + UnionArrayConstPtr valueField = structure->getField("value"); + if (!valueField.get()) return false; + + ScalarArrayConstPtr channelNameField = structure->getField( + "channelName"); + if (!channelNameField.get()) return false; + if (channelNameField->getElementType() != pvString) return false; + + FieldConstPtr field = structure->getField("severity"); + if (field.get()) + { + ScalarArrayConstPtr severityField = structure->getField("severity"); + if (!severityField.get() || severityField->getElementType() != pvInt) + return false; + } + + field = structure->getField("status"); + if (field.get()) + { + ScalarArrayConstPtr statusField = structure->getField("status"); + if (!statusField.get() || statusField->getElementType() != pvInt) + return false; + } + + field = structure->getField("message"); + if (field.get()) + { + ScalarArrayConstPtr messageField = structure->getField("message"); + if (!messageField.get() || messageField->getElementType() != pvString) + return false; + } + + field = structure->getField("secondsPastEpoch"); + if (field.get()) + { + ScalarArrayConstPtr secondsPastEpochField = structure->getField("secondsPastEpoch"); + if (!secondsPastEpochField.get() || secondsPastEpochField->getElementType() != pvLong) + return false; + } + + field = structure->getField("nanoseconds"); + if (field.get()) + { + ScalarArrayConstPtr nanosecondsField = structure->getField("nanoseconds"); + if (!nanosecondsField.get() || nanosecondsField->getElementType() != pvInt) + return false; + } + + field = structure->getField("userTag"); + if (field.get()) + { + ScalarArrayConstPtr userTagField = structure->getField("userTag"); + if (!userTagField.get() || userTagField->getElementType() != pvInt) + return false; + } + + field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + return true; +} + + bool NTMultiChannel::isCompatible(PVStructurePtr const &pvStructure) { - if(!pvStructure) return false; - 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; + if(!pvStructure.get()) return false; + + return isCompatible(pvStructure->getStructure()); } NTMultiChannelBuilderPtr NTMultiChannel::createBuilder() diff --git a/src/nt/ntnameValue.cpp b/src/nt/ntnameValue.cpp index c396758..7a6590d 100644 --- a/src/nt/ntnameValue.cpp +++ b/src/nt/ntnameValue.cpp @@ -128,20 +128,44 @@ bool NTNameValue::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTNameValue::isCompatible(StructureConstPtr const & structure) +{ + if (structure.get() == 0) return false; + + ScalarArrayConstPtr nameField = structure->getField("name"); + if (nameField.get() == 0 || nameField->getElementType() != pvString) + return false; + + ScalarArrayConstPtr valueField = structure->getField("value"); + if (valueField.get() == 0) + return false; + + FieldConstPtr field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field && !ntField->isTimeStamp(field)) + return false; + + return true; +} + bool NTNameValue::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - PVStringArrayPtr pvName = pvStructure->getSubField("name"); - if(!pvName) return false; - PVFieldPtr 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; - return true; + + return isCompatible(pvStructure->getStructure()); } NTNameValueBuilderPtr NTNameValue::createBuilder() diff --git a/src/nt/ntndarrayAttribute.cpp b/src/nt/ntndarrayAttribute.cpp index 6a98015..60dcd2e 100644 --- a/src/nt/ntndarrayAttribute.cpp +++ b/src/nt/ntndarrayAttribute.cpp @@ -7,6 +7,7 @@ #define epicsExportSharedSymbols #include +#include #include using namespace std; @@ -130,31 +131,31 @@ bool NTNDArrayAttribute::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTNDArrayAttribute::isCompatible(StructureConstPtr const & structure) +{ + if (!NTAttribute::isCompatible(structure)) return false; + + // descriptor required field for attibute in an ndarray + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (descriptorField.get() == 0 || descriptorField->getScalarType() != pvString) + return false; + + ScalarConstPtr sourcedTypeField = structure->getField("sourceType"); + if (sourcedTypeField.get() == 0 || sourcedTypeField->getScalarType() != pvInt) + return false; + + ScalarConstPtr sourcedField = structure->getField("source"); + if (sourcedField.get() == 0 || sourcedField->getScalarType() != pvString) + return false; + + return true; +} + bool NTNDArrayAttribute::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - PVUnionPtr pvValue = pvStructure->getSubField("value"); - if(!pvValue) return false; - - // TODO tags - - PVStringPtr pvDescriptor = pvStructure->getSubField("descriptor"); - if(!pvDescriptor) return false; - - PVStringPtr pvSource = pvStructure->getSubField("source"); - if(!pvSource) return false; - - PVIntPtr pvSourceType = pvStructure->getSubField("sourceType"); - if(!pvSourceType) return false; - - 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; - - return true; + return isCompatible(pvStructure->getStructure()); } NTNDArrayAttributeBuilderPtr NTNDArrayAttribute::createBuilder() diff --git a/src/nt/ntscalar.cpp b/src/nt/ntscalar.cpp index 969a4f2..e9d64ca 100644 --- a/src/nt/ntscalar.cpp +++ b/src/nt/ntscalar.cpp @@ -148,22 +148,49 @@ bool NTScalar::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTScalar::isCompatible(StructureConstPtr const &structure) +{ + if (structure.get() == 0) return false; + + ScalarConstPtr valueField = structure->getField("value"); + if (valueField.get() == 0) + return false; + + FieldConstPtr field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + field = structure->getField("display"); + if (field.get() && !ntField->isDisplay(field)) + return false; + + field = structure->getField("control"); + if (field.get() && !ntField->isControl(field)) + return false; + + return true; +} + + bool NTScalar::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - 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; + + return isCompatible(pvStructure->getStructure()); } NTScalarBuilderPtr NTScalar::createBuilder() diff --git a/src/nt/ntscalarArray.cpp b/src/nt/ntscalarArray.cpp index 07bc2d2..8dfea9c 100644 --- a/src/nt/ntscalarArray.cpp +++ b/src/nt/ntscalarArray.cpp @@ -145,22 +145,48 @@ bool NTScalarArray::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTScalarArray::isCompatible(StructureConstPtr const & structure) +{ + if (structure.get() == 0) return false; + + ScalarArrayConstPtr valueField = structure->getField("value"); + if (valueField.get() == 0) + return false; + + FieldConstPtr field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + field = structure->getField("display"); + if (field.get() && !ntField->isDisplay(field)) + return false; + + field = structure->getField("control"); + if (field.get() && !ntField->isControl(field)) + return false; + + return true; +} + bool NTScalarArray::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - 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; + + return isCompatible(pvStructure->getStructure()); } diff --git a/src/nt/ntscalarMultiChannel.cpp b/src/nt/ntscalarMultiChannel.cpp index 88af28b..4ea42cb 100644 --- a/src/nt/ntscalarMultiChannel.cpp +++ b/src/nt/ntscalarMultiChannel.cpp @@ -225,30 +225,94 @@ bool NTScalarMultiChannel::is_a(StructureConstPtr const &structure) return NTUtils::is_a(structure->getID(), URI); } + +bool NTScalarMultiChannel::isCompatible(StructureConstPtr const & structure) +{ + if (!structure.get()) return false; + + ScalarArrayConstPtr valueField = structure->getField("value"); + if (!valueField.get()) return false; + + ScalarArrayConstPtr channelNameField = structure->getField( + "channelName"); + if (!channelNameField.get()) return false; + if (channelNameField->getElementType() != pvString) return false; + + FieldConstPtr field = structure->getField("severity"); + if (field.get()) + { + ScalarArrayConstPtr severityField = structure->getField("severity"); + if (!severityField.get() || severityField->getElementType() != pvInt) + return false; + } + + field = structure->getField("status"); + if (field.get()) + { + ScalarArrayConstPtr statusField = structure->getField("status"); + if (!statusField.get() || statusField->getElementType() != pvInt) + return false; + } + + field = structure->getField("message"); + if (field.get()) + { + ScalarArrayConstPtr messageField = structure->getField("message"); + if (!messageField.get() || messageField->getElementType() != pvString) + return false; + } + + field = structure->getField("secondsPastEpoch"); + if (field.get()) + { + ScalarArrayConstPtr secondsPastEpochField = structure->getField("secondsPastEpoch"); + if (!secondsPastEpochField.get() || secondsPastEpochField->getElementType() != pvLong) + return false; + } + + field = structure->getField("nanoseconds"); + if (field.get()) + { + ScalarArrayConstPtr nanosecondsField = structure->getField("nanoseconds"); + if (!nanosecondsField.get() || nanosecondsField->getElementType() != pvInt) + return false; + } + + field = structure->getField("userTag"); + if (field.get()) + { + ScalarArrayConstPtr userTagField = structure->getField("userTag"); + if (!userTagField.get() || userTagField->getElementType() != pvInt) + return false; + } + + field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + return true; +} + + bool NTScalarMultiChannel::isCompatible(PVStructurePtr const &pvStructure) { - if(!pvStructure) return false; - 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("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; + if(!pvStructure.get()) return false; + + return isCompatible(pvStructure->getStructure()); } NTScalarMultiChannelBuilderPtr NTScalarMultiChannel::createBuilder() diff --git a/src/nt/nttable.cpp b/src/nt/nttable.cpp index abede47..5f9ab0b 100644 --- a/src/nt/nttable.cpp +++ b/src/nt/nttable.cpp @@ -143,16 +143,51 @@ bool NTTable::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTTable::isCompatible(StructureConstPtr const & structure) +{ + if (!structure.get()) return false; + + StructureConstPtr valueField = structure->getField("value"); + if (!valueField.get()) + return false; + + FieldConstPtrArray const & fields = valueField->getFields(); + for (FieldConstPtrArray::const_iterator it = fields.begin(); + it != fields.end(); ++it) + { + if ((*it)->getType() != scalarArray) return false; + } + + ScalarArrayConstPtr labelsField = structure->getField("labels"); + if (!labelsField.get() || labelsField->getElementType() != pvString) + return false; + + FieldConstPtr field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + return true; +} + bool NTTable::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - 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"); - if(!pvLabel) return false; - return true; + + return isCompatible(pvStructure->getStructure()); } NTTableBuilderPtr NTTable::createBuilder() diff --git a/src/nt/ntunion.cpp b/src/nt/ntunion.cpp index f911f71..b4ddd86 100644 --- a/src/nt/ntunion.cpp +++ b/src/nt/ntunion.cpp @@ -118,23 +118,40 @@ bool NTUnion::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTUnion::isCompatible(StructureConstPtr const &structure) +{ + if (structure.get() == 0) return false; + + UnionConstPtr valueField = structure->getField("value"); + if (valueField.get() == 0) + return false; + + FieldConstPtr field = structure->getField("descriptor"); + if (field.get()) + { + ScalarConstPtr descriptorField = structure->getField("descriptor"); + if (!descriptorField.get() || descriptorField->getScalarType() != pvString) + return false; + } + + NTFieldPtr ntField = NTField::get(); + + field = structure->getField("alarm"); + if (field.get() && !ntField->isAlarm(field)) + return false; + + field = structure->getField("timeStamp"); + if (field.get() && !ntField->isTimeStamp(field)) + return false; + + return true; +} + bool NTUnion::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - 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; - - return true; + return isCompatible(pvStructure->getStructure()); } NTUnionBuilderPtr NTUnion::createBuilder() diff --git a/src/nt/nturi.cpp b/src/nt/nturi.cpp index e99f409..378d72d 100644 --- a/src/nt/nturi.cpp +++ b/src/nt/nturi.cpp @@ -143,27 +143,55 @@ bool NTURI::is_a(StructureConstPtr const & structure) return NTUtils::is_a(structure->getID(), URI); } +bool NTURI::isCompatible(StructureConstPtr const & structure) +{ + if (!structure.get()) return false; + + ScalarConstPtr schemeField = structure->getField("scheme"); + if (schemeField.get() == 0 || schemeField->getScalarType() != pvString) + return false; + + ScalarConstPtr pathField = structure->getField("path"); + if (pathField.get() == 0 || pathField->getScalarType() != pvString) + return false; + + FieldConstPtr field = structure->getField("authority"); + if (field.get()) + { + ScalarConstPtr authorityField = structure->getField("authority"); + if (!authorityField.get() || authorityField->getScalarType() != pvString) + return false; + } + + field = structure->getField("query"); + if (field.get()) + { + StructureConstPtr queryField = structure->getField("query"); + if (!queryField.get()) + return false; + + FieldConstPtrArray const & fields = queryField->getFields(); + for (FieldConstPtrArray::const_iterator it = fields.begin(); + it != fields.end(); ++it) + { + if ((*it)->getType() != scalar) return false; + ScalarType scalarType = std::tr1::dynamic_pointer_cast( + (*it))->getScalarType(); + if (scalarType != pvString && + scalarType != pvInt && + scalarType != pvDouble) return false; + } + } + + return true; +} + + bool NTURI::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure) return false; - PVStringPtr pvScheme = pvStructure->getSubField("scheme"); - if(!pvScheme) return false; - - PVStringPtr pvPath = pvStructure->getSubField("path"); - if(!pvPath) return false; - - PVFieldPtr pvAuthority = pvStructure->getSubField("authority"); - PVStringPtr pvAuthority2 = pvStructure->getSubField("authority"); - if(!pvAuthority && pvAuthority2) return false; - - PVFieldPtr pvQuery = pvStructure->getSubField("query"); - PVStructurePtr pvQuery2 = pvStructure->getSubField("query"); - if(!pvAuthority && pvAuthority2) return false; - - //TODO check query field types - - return true; + return isCompatible(pvStructure->getStructure()); } NTURIBuilderPtr NTURI::createBuilder()