From 7c58eae97eb4080a3931bf72b80b8d3ca1017b8a Mon Sep 17 00:00:00 2001 From: Dave Hickin Date: Fri, 21 Aug 2015 03:55:04 +0100 Subject: [PATCH] Add NTContinuum --- src/Makefile | 2 + src/nt/nt.h | 1 + src/nt/ntcontinuum.cpp | 202 +++++++++++++++++++++++++++++++ src/nt/ntcontinuum.h | 262 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 467 insertions(+) create mode 100644 src/nt/ntcontinuum.cpp create mode 100644 src/nt/ntcontinuum.h diff --git a/src/Makefile b/src/Makefile index f9cca3e..85fdbf8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,6 +20,7 @@ INC += ntenum.h INC += ntunion.h INC += ntaggregate.h INC += ntattribute.h +INC += ntcontinuum.h LIBSRCS += ntutils.cpp LIBSRCS += ntfield.cpp @@ -35,6 +36,7 @@ LIBSRCS += ntenum.cpp LIBSRCS += ntunion.cpp LIBSRCS += ntaggregate.cpp LIBSRCS += ntattribute.cpp +LIBSRCS += ntcontinuum.cpp LIBRARY = nt diff --git a/src/nt/nt.h b/src/nt/nt.h index 909c612..143292d 100644 --- a/src/nt/nt.h +++ b/src/nt/nt.h @@ -23,6 +23,7 @@ #include #include #include +#include #endif /* NT_H */ diff --git a/src/nt/ntcontinuum.cpp b/src/nt/ntcontinuum.cpp new file mode 100644 index 0000000..d6d28a9 --- /dev/null +++ b/src/nt/ntcontinuum.cpp @@ -0,0 +1,202 @@ +/* ntcontinuum.cpp */ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * EPICS pvDataCPP is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ + +#define epicsExportSharedSymbols +#include +#include + +using namespace std; +using namespace epics::pvData; + +namespace epics { namespace nt { + +static NTFieldPtr ntField = NTField::get(); + +namespace detail { + +StructureConstPtr NTContinuumBuilder::createStructure() +{ + FieldBuilderPtr builder = + getFieldCreate()->createFieldBuilder()-> + setId(NTContinuum::URI)-> + addArray("base", pvDouble)-> + addArray("value", pvDouble)-> + addArray("units", pvString); + + if (descriptor) + builder->add("descriptor", pvString); + + if (alarm) + builder->add("alarm", ntField->createAlarm()); + + if (timeStamp) + builder->add("timeStamp", ntField->createTimeStamp()); + + size_t extraCount = extraFieldNames.size(); + for (size_t i = 0; i< extraCount; i++) + builder->add(extraFieldNames[i], extraFields[i]); + + + StructureConstPtr s = builder->createStructure(); + + reset(); + return s; +} + +NTContinuumBuilder::shared_pointer NTContinuumBuilder::addDescriptor() +{ + descriptor = true; + return shared_from_this(); +} + +NTContinuumBuilder::shared_pointer NTContinuumBuilder::addAlarm() +{ + alarm = true; + return shared_from_this(); +} + +NTContinuumBuilder::shared_pointer NTContinuumBuilder::addTimeStamp() +{ + timeStamp = true; + return shared_from_this(); +} + + +PVStructurePtr NTContinuumBuilder::createPVStructure() +{ + return getPVDataCreate()->createPVStructure(createStructure()); +} + +NTContinuumPtr NTContinuumBuilder::create() +{ + return NTContinuumPtr(new NTContinuum(createPVStructure())); +} + +NTContinuumBuilder::NTContinuumBuilder() +{ + reset(); +} + +void NTContinuumBuilder::reset() +{ + descriptor = false; + alarm = false; + timeStamp = false; + extraFieldNames.clear(); + extraFields.clear(); +} + +NTContinuumBuilder::shared_pointer NTContinuumBuilder::add(string const & name, FieldConstPtr const & field) +{ + extraFields.push_back(field); extraFieldNames.push_back(name); + return shared_from_this(); +} + +} + +const std::string NTContinuum::URI("epics:nt/NTContinuum:1.0"); + +NTContinuum::shared_pointer NTContinuum::wrap(PVStructurePtr const & structure) +{ + if(!isCompatible(structure)) return shared_pointer(); + return wrapUnsafe(structure); +} + +NTContinuum::shared_pointer NTContinuum::wrapUnsafe(PVStructurePtr const & structure) +{ + return shared_pointer(new NTContinuum(structure)); +} + +bool NTContinuum::is_a(StructureConstPtr const & structure) +{ + return NTUtils::is_a(structure->getID(), URI); +} + +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; +} + + +NTContinuumBuilderPtr NTContinuum::createBuilder() +{ + return NTContinuumBuilderPtr(new detail::NTContinuumBuilder()); +} + +bool NTContinuum::attachTimeStamp(PVTimeStamp &pvTimeStamp) const +{ + PVStructurePtr ts = getTimeStamp(); + if (ts) + return pvTimeStamp.attach(ts); + else + return false; +} + +bool NTContinuum::attachAlarm(PVAlarm &pvAlarm) const +{ + PVStructurePtr al = getAlarm(); + if (al) + return pvAlarm.attach(al); + else + return false; +} + +PVStructurePtr NTContinuum::getPVStructure() const +{ + return pvNTContinuum; +} + +PVStringPtr NTContinuum::getDescriptor() const +{ + return pvNTContinuum->getSubField("descriptor"); +} + +PVStructurePtr NTContinuum::getTimeStamp() const +{ + return pvNTContinuum->getSubField("timeStamp"); +} + +PVStructurePtr NTContinuum::getAlarm() const +{ + return pvNTContinuum->getSubField("alarm"); +} + +PVDoubleArrayPtr NTContinuum::getBase() const +{ + return pvNTContinuum->getSubField("base"); +} + +PVDoubleArrayPtr NTContinuum::getValue() const +{ + return pvValue; +} + +PVStringArrayPtr NTContinuum::getUnits() const +{ + return pvNTContinuum->getSubField("units"); +} + +NTContinuum::NTContinuum(PVStructurePtr const & pvStructure) : + pvNTContinuum(pvStructure), + pvValue(pvNTContinuum->getSubField("value")) +{} + + +}} diff --git a/src/nt/ntcontinuum.h b/src/nt/ntcontinuum.h new file mode 100644 index 0000000..500e0ac --- /dev/null +++ b/src/nt/ntcontinuum.h @@ -0,0 +1,262 @@ +/* ntcontinuum.h */ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * EPICS pvDataCPP is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ +#ifndef NTCONTINUUM_H +#define NTCONTINUUM_H + +#ifdef epicsExportSharedSymbols +# define ntcontinuumEpicsExportSharedSymbols +# undef epicsExportSharedSymbols +#endif + +#ifdef ntcontinuumEpicsExportSharedSymbols +# define epicsExportSharedSymbols +# undef ntcontinuumEpicsExportSharedSymbols +#endif + +#include + +#include + + +namespace epics { namespace nt { + +class NTContinuum; +typedef std::tr1::shared_ptr NTContinuumPtr; + +namespace detail { + + /** + * @brief Interface for in-line creating of NTContinuum. + * + * One instance can be used to create multiple instances. + * An instance of this object must not be used concurrently (an object has a state). + * @author dgh + */ + class epicsShareClass NTContinuumBuilder : + public std::tr1::enable_shared_from_this + { + public: + POINTER_DEFINITIONS(NTContinuumBuilder); + + /** + * Add descriptor field to the NTContinuum. + * @return this instance of NTContinuumBuilder. + */ + shared_pointer addDescriptor(); + + /** + * Add alarm structure to the NTContinuum. + * @return this instance of NTContinuumBuilder. + */ + shared_pointer addAlarm(); + + /** + * Add timeStamp structure to the NTContinuum. + * @return this instance of NTContinuumBuilder. + */ + shared_pointer addTimeStamp(); + + /** + * Create a Structure that represents NTContinuum. + * This resets this instance state and allows new instance to be created. + * @return a new instance of Structure. + */ + epics::pvData::StructureConstPtr createStructure(); + + /** + * Create a PVStructure that represents NTContinuum. + * This resets this instance state and allows new instance to be created. + * @return a new instance of PVStructure. + */ + epics::pvData::PVStructurePtr createPVStructure(); + + /** + * Create a NTContinuum instance. + * This resets this instance state and allows new instance to be created. + * @return a new instance of NTContinuum. + */ + NTContinuumPtr create(); + /** + * Add extra Field to the type. + * @param name name of the field. + * @param field a field to add. + * @return this instance of NTContinuumBuilder. + */ + shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field); + + private: + NTContinuumBuilder(); + + void reset(); + + bool dim; + bool descriptor; + bool alarm; + bool timeStamp; + + // NOTE: this preserves order, however it does not handle duplicates + epics::pvData::StringArray extraFieldNames; + epics::pvData::FieldConstPtrArray extraFields; + + friend class ::epics::nt::NTContinuum; + }; + +} + +typedef std::tr1::shared_ptr NTContinuumBuilderPtr; + + + +/** + * @brief Convenience Class for NTContinuum + * + * @author dgh + */ +class epicsShareClass NTContinuum +{ +public: + POINTER_DEFINITIONS(NTContinuum); + + static const std::string URI; + + /** + * Wrap (aka dynamic cast, or wrap) the structure to NTContinuum. + * First isCompatible is called. + * This method will nullptr if the structure is is not compatible. + * This method will nullptr if the structure is nullptr. + * @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTContinuum. + * @return NTContinuum instance on success, nullptr otherwise. + */ + static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure); + + /** + * Wrap (aka dynamic cast, or wrap) the structure to NTContinuum without checking for isCompatible + * @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTContinuum. + * @return NTContinuum instance. + */ + static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure); + + /** + * Is the structure an NTContinuum. + * @param structure The structure to test. + * @return (false,true) if (is not, is) an NTContinuum. + */ + static bool is_a(epics::pvData::StructureConstPtr const & structure); + + /** + * Is the structure an NTContinuum. + * @param pvStructure The PVStructure to test. + * @return (false,true) if (is not, is) an NTContinuum. + */ + static bool is_a(epics::pvData::PVStructurePtr const & pvStructure); + + /** + * Is the Structure compatible with NTContinuum. + * This method introspects the fields to see if they are compatible. + * @param structure The Structure to test. + * @return (false,true) if (is not, is) an NTContinuum. + */ + static bool isCompatible( + epics::pvData::StructureConstPtr const &structure); + + /** + * Is the PVStructure compatible with NTContinuum. + * This method introspects the fields to see if they are compatible. + * @param pvStructure The PVStructure to test. + * @return (false,true) if (is not, is) an NTContinuum. + */ + static bool isCompatible( + epics::pvData::PVStructurePtr const &pvStructure); + + /** + * Checks if the specified structure is a valid NTContinuum. + * + * Checks whether the wrapped structure is valid with respect to this + * version of NTContinuum + * @return (false,true) if (is not, is) a valid NTContinuum. + */ + bool isValid(); + + /** + * Create a NTContinuum builder instance. + * @return builder instance. + */ + static NTContinuumBuilderPtr createBuilder(); + + /** + * Destructor. + */ + ~NTContinuum() {} + + /** + * Attach a pvTimeStamp. + * @param pvTimeStamp The pvTimeStamp that will be attached. + * Does nothing if no timeStamp. + * @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false. + */ + bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const; + + /** + * Attach an pvAlarm. + * @param pvAlarm The pvAlarm that will be attached. + * Does nothing if no alarm. + * @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false. + */ + bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const; + + /** + * Get the pvStructure. + * @return PVStructurePtr. + */ + epics::pvData::PVStructurePtr getPVStructure() const; + + /** + * Get the descriptor field. + * @return The pvString or null if no function field. + */ + epics::pvData::PVStringPtr getDescriptor() const; + + /** + * Get the timeStamp. + * @return PVStructurePtr which may be null. + */ + epics::pvData::PVStructurePtr getTimeStamp() const; + + /** + * Get the alarm. + * @return PVStructurePtr which may be null. + */ + epics::pvData::PVStructurePtr getAlarm() const; + + /** + * Get the base field. + * @return The PVDoubleArray for the base. + */ + epics::pvData::PVDoubleArrayPtr getBase() const; + + /** + * Get the value field. + * @return The PVDoubleArray for the values. + */ + epics::pvData::PVDoubleArrayPtr getValue() const; + + /** + * Get the units field. + * @return The PVStringArray for the units. + */ + epics::pvData::PVStringArrayPtr getUnits() const; + +private: + NTContinuum(epics::pvData::PVStructurePtr const & pvStructure); + epics::pvData::PVStructurePtr pvNTContinuum; + epics::pvData::PVDoubleArrayPtr pvValue; + + friend class detail::NTContinuumBuilder; +}; + +}} +#endif /* NTCONTINUUM_H */