From d650865a6fc832c63d79e7e32b27d32da39046cd Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Wed, 3 Apr 2019 10:32:45 -0400 Subject: [PATCH] address issue #53; reorganize Client*Data --- src/Makefile | 1 + src/pv/pvaClient.h | 279 +++++++-------------------------- src/pvaClientData.cpp | 289 +++++++++++++++++++++++++++++++++++ src/pvaClientGetData.cpp | 198 +----------------------- src/pvaClientMonitor.cpp | 2 +- src/pvaClientMonitorData.cpp | 190 +---------------------- src/pvaClientPutData.cpp | 190 ++++------------------- src/pvaClientPutGet.cpp | 14 +- 8 files changed, 380 insertions(+), 783 deletions(-) create mode 100644 src/pvaClientData.cpp diff --git a/src/Makefile b/src/Makefile index ed7bd4c..7dfc878 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,6 +12,7 @@ INC += pv/pvaClient.h INC += pv/pvaClientMultiChannel.h LIBSRCS += pvaClient.cpp +LIBSRCS += pvaClientData.cpp LIBSRCS += pvaClientPutData.cpp LIBSRCS += pvaClientGetData.cpp LIBSRCS += pvaClientMonitorData.cpp diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 1ada4c7..3e302c9 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -44,6 +44,8 @@ namespace epics { namespace pvaClient { class PvaClient; typedef std::tr1::shared_ptr PvaClientPtr; +class PvaClientData; +typedef std::tr1::shared_ptr PvaClientDataPtr; class PvaClientGetData; typedef std::tr1::shared_ptr PvaClientGetDataPtr; class PvaClientPutData; @@ -490,18 +492,18 @@ public: }; /** - * @brief A class that holds data returned by PvaClientGet or PvaClientPutGet + * @brief A base class for PvaClientGetData, PvaClientPutData, and PvaClientMonitorData. * - * Overview of PvaClientGetData + * Overview of PvaClientData */ -class epicsShareClass PvaClientGetData +class epicsShareClass PvaClientData { public: - POINTER_DEFINITIONS(PvaClientGetData); + POINTER_DEFINITIONS(PvaClientData); /** * @brief Destructor */ - ~PvaClientGetData() {} + ~PvaClientData() {} /** @brief Set a prefix for throw messages. * * This is called by other pvaClient classes. @@ -608,6 +610,44 @@ public: * @return The timeStamp. */ epics::pvData::TimeStamp getTimeStamp(); + /** @brief Factory method for creating an instance of PvaClientData. + * + * NOTE: Not normally called by clients + * @param structure Introspection interface + * @throw runtime_error if failure. + */ + static PvaClientDataPtr create(epics::pvData::StructureConstPtr const & structure); +protected: + PvaClientData(epics::pvData::StructureConstPtr const & structure); + void checkValue(); + std::string messagePrefix; +private: + + epics::pvData::StructureConstPtr structure; + epics::pvData::PVStructurePtr pvStructure; + epics::pvData::BitSetPtr bitSet; + + + epics::pvData::PVFieldPtr pvValue; + epics::pvData::PVAlarm pvAlarm; + epics::pvData::PVTimeStamp pvTimeStamp; + friend class PvaClientGet; + friend class PvaClientPutGet; +}; + +/** + * @brief A class that holds data returned by PvaClientGet or PvaClientPutGet + * + * Overview of PvaClientGetData + */ +class epicsShareClass PvaClientGetData : public PvaClientData +{ +public: + POINTER_DEFINITIONS(PvaClientGetData); + /** + * @brief Destructor + */ + ~PvaClientGetData() {} /** @brief Factory method for creating an instance of PvaClientGetData. * * NOTE: Not normally called by clients @@ -617,15 +657,6 @@ public: static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure); private: PvaClientGetData(epics::pvData::StructureConstPtr const & structure); - void checkValue(); - epics::pvData::StructureConstPtr structure; - epics::pvData::PVStructurePtr pvStructure; - epics::pvData::BitSetPtr bitSet; - - std::string messagePrefix; - epics::pvData::PVFieldPtr pvValue; - epics::pvData::PVAlarm pvAlarm; - epics::pvData::PVTimeStamp pvTimeStamp; friend class PvaClientGet; friend class PvaClientPutGet; }; @@ -636,7 +667,7 @@ class PvaClientPostHandlerPvt; // private to PvaClientPutData * * Overview of PvaClientPutData */ -class epicsShareClass PvaClientPutData +class epicsShareClass PvaClientPutData : public PvaClientData { public: POINTER_DEFINITIONS(PvaClientPutData); @@ -644,93 +675,6 @@ public: * @brief Destructor */ ~PvaClientPutData() {} - /** @brief Set a prefix for throw messages. - * - * @param value The prefix. - */ - void setMessagePrefix(std::string const & value); - /** @brief Get the structure. - * - * @return The Structure - * @throw runtime_error if failure. - */ - epics::pvData::StructureConstPtr getStructure(); - /** @brief Get the pvStructure. - * - * @return the pvStructure. - * @throw runtime_error if failure. - */ - epics::pvData::PVStructurePtr getPVStructure(); - /** @brief Get the changed BitSet for the pvStructure - * - * This shows which fields have changed values. - * @return The bitSet - * @throw runtime_error if failure. - */ - epics::pvData::BitSetPtr getChangedBitSet(); - /** @brief Show the fields that have changed values. - * - * @param out The stream that shows the changed fields. - * @return The stream that was passed as out. - */ - std::ostream & showChanged(std::ostream & out); - /** - * @brief Is there a top level field named value. - * - * @return The answer. - */ - bool hasValue(); - /** @brief Is the value field a scalar? - * - * @return The answer. - */ - bool isValueScalar(); - /** @brief Is the value field a scalar array? - * @return The answer. - */ - bool isValueScalarArray(); - /** Get the interface to the value field. - * - * @return The interface. an excetion is thrown if a value field does not exist. - */ - epics::pvData::PVFieldPtr getValue(); - /** @brief Get the interface to a scalar value field. - * - * @return The interface for a scalar value field. - * @throw runtime_error if failure. - */ - epics::pvData::PVScalarPtr getScalarValue(); - /** @brief Get the interface to an array value field. - * @return The interface. - * An exception is thown if no array value field. - */ - std::tr1::shared_ptr getArrayValue(); - /** @brief Get the interface to a scalar array value field. - * @return Return the interface. - * @throw runtime_error if failure. - */ - std::tr1::shared_ptr getScalarArrayValue(); - /** @brief Get the value as a double. - * - * If value is not a numeric scalar an exception is thrown. - * @return The value. - */ - double getDouble(); - /** @brief Get the value as a string. - * @return The value. - * @throw runtime_error if failure. - */ - std::string getString(); - /** @brief Get the value as a double array. - * If the value is not a numeric array an exception is thrown. - * @return The value. - */ - epics::pvData::shared_vector getDoubleArray(); - /** @brief Get the value as a string array. - * @return The value. - * @throw runtime_error if failure. - */ - epics::pvData::shared_vector getStringArray(); /** @brief Put the value as a double. * @param value The new value. * An exception is also thrown if the actualy type can cause an overflow. @@ -764,17 +708,9 @@ public: static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const & structure); private: PvaClientPutData(epics::pvData::StructureConstPtr const &structure); - void checkValue(); void postPut(size_t fieldNumber); - std::vector postHandler; - epics::pvData::StructureConstPtr structure; - epics::pvData::PVStructurePtr pvStructure; - epics::pvData::BitSetPtr bitSet; friend class PvaClientPostHandlerPvt; - - std::string messagePrefix; - epics::pvData::PVFieldPtr pvValue; friend class PvaClientPut; friend class PvaClientPutGet; }; @@ -784,7 +720,7 @@ private: * * Overview of PvaClientMonitorData */ -class epicsShareClass PvaClientMonitorData +class epicsShareClass PvaClientMonitorData : public PvaClientData { public: POINTER_DEFINITIONS(PvaClientMonitorData); @@ -792,27 +728,6 @@ public: * @brief Destructor */ ~PvaClientMonitorData() {} - /** @brief Set a prefix for throw messages. - * @param value The prefix. - */ - void setMessagePrefix(std::string const & value); - /** @brief Get the structure. - * @return The Structure - * @throw runtime_error if failure. - */ - epics::pvData::StructureConstPtr getStructure(); - /** @brief Get the pvStructure. - * @return the pvStructure. - * @throw runtime_error if failure. - */ - epics::pvData::PVStructurePtr getPVStructure(); - /** @brief Get the changed BitSet for the pvStructure, - * - * This shows which fields have changed value. - * @return The bitSet - * @throw runtime_error if failure. - */ - epics::pvData::BitSetPtr getChangedBitSet(); /** @brief Get the overrun BitSet for the pvStructure * This shows which fields have had more than one change. * @return The bitSet @@ -823,111 +738,21 @@ public: * @param out The stream that shows the changed fields. * @return The stream that was passed as out. */ - std::ostream & showChanged(std::ostream & out); - /** @brief Show the fields that have overrun. - * @param out The stream that shows the overrun fields. - * @return The stream that was passed as out - */ std::ostream & showOverrun(std::ostream & out); - /** @brief Is there a top level field named value. - * @return The answer. - */ - bool hasValue(); - /** @brief Is the value field a scalar? - * @return The answer. - */ - bool isValueScalar(); - /** @brief Is the value field a scalar array? - * @return The answer. - */ - bool isValueScalarArray(); - /** @brief Get the interface to the value field. - * @return The interface. an excetion is thrown if a value field does not exist. - */ - epics::pvData::PVFieldPtr getValue(); - /** @brief Get the interface to a scalar value field. - * @return The interface for a scalar value field. - * @throw runtime_error if failure. - * An exception is thown if no scalar value field. - */ - epics::pvData::PVScalarPtr getScalarValue(); - /** @brief Get the interface to an array value field. - * @return The interface. - * @throw runtime_error if failure. - * An exception is thown if no array value field. - */ - std::tr1::shared_ptr getArrayValue(); - /** @brief Get the interface to a scalar array value field. - * @return Return the interface. - * @throw runtime_error if failure. - * An exception is thown if no scalar array value field. - */ - std::tr1::shared_ptr getScalarArrayValue(); - /** @brief Get the value as a double. - * - * If value is not a numeric scalar an exception is thrown. - * @return The value. - */ - double getDouble(); - /** @brief Get the value as a string. - * - * If value is not a scalar an exception is thrown - * @return The value. - * @throw runtime_error if failure. - */ - std::string getString(); - /** @brief Get the value as a double array. - * - * If the value is not a numeric array an exception is thrown. - * @return The value. - * @throw runtime_error if failure. - */ - epics::pvData::shared_vector getDoubleArray(); - /** @brief Get the value as a string array. - * - * If the value is not a string array an exception is thrown. - * @return The value. - * @throw runtime_error if failure. - */ - epics::pvData::shared_vector getStringArray(); - /** @brief Get the alarm. - * - * If the pvStructure as an alarm field it's values are returned. - * If no then alarm shows that not alarm defined. - * @return The alarm. - * @throw runtime_error if failure. - */ - epics::pvData::Alarm getAlarm(); - /** @brief Get the timeStamp. - * - * If the pvStructure has a timeStamp field, it's values are returned. - * If no then all fields are 0. - * @return The timeStamp. - */ - epics::pvData::TimeStamp getTimeStamp(); + /** Put data into PVStructure from monitorElement + * NOTE: Not normally called by clients + * @param monitorElement the monitorElement that has new data. + */ + void setElementData(epics::pvData::MonitorElementPtr const & monitorElement); /** Factory method for creating an instance of PvaClientGetData. * NOTE: Not normally called by clients * @param structure Introspection interface */ static PvaClientMonitorDataPtr create(epics::pvData::StructureConstPtr const & structure); - /** Put data into PVStructure from monitorElement - * NOTE: Not normally called by clients - * @param monitorElement the monitorElement that has new data. - */ - void setData(epics::pvData::MonitorElementPtr const & monitorElement); private: PvaClientMonitorData(epics::pvData::StructureConstPtr const & structure); - void checkValue(); - - epics::pvData::StructureConstPtr structure; - epics::pvData::PVStructurePtr pvStructure; - epics::pvData::BitSetPtr changedBitSet; epics::pvData::BitSetPtr overrunBitSet; - std::string messagePrefix; - epics::pvData::PVFieldPtr pvValue; - epics::pvData::PVAlarm pvAlarm; - epics::pvData::PVTimeStamp pvTimeStamp; friend class PvaClientMonitor; }; diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp new file mode 100644 index 0000000..c7e165d --- /dev/null +++ b/src/pvaClientData.cpp @@ -0,0 +1,289 @@ +/* pvaClientData.cpp */ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * EPICS pvData is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ +/** + * @author mrk + * @date 2019.04 + */ + +#include +#include + +#include +#include + +#define epicsExportSharedSymbols + +#include + +using std::tr1::static_pointer_cast; +using namespace epics::pvData; +using namespace epics::pvAccess; +using namespace std; + +namespace epics { namespace pvaClient { + + +typedef std::tr1::shared_ptr PVArrayPtr; +static ConvertPtr convert = getConvert(); +static string noStructure("no pvStructure "); +static string noValue("no value field"); +static string noScalar("value is not a scalar"); +static string notCompatibleScalar("value is not a compatible scalar"); +static string noArray("value is not an array"); +static string noScalarArray("value is not a scalarArray"); +static string notDoubleArray("value is not a doubleArray"); +static string notStringArray("value is not a stringArray"); +static string noAlarm("no alarm"); +static string noTimeStamp("no timeStamp"); + +PvaClientDataPtr PvaClientData::create(StructureConstPtr const & structure) +{ + if(PvaClient::getDebug()) { + cout << "PvaClientData::create" + << endl; + } + PvaClientDataPtr epv(new PvaClientData(structure)); + return epv; +} + +PvaClientData::PvaClientData(StructureConstPtr const & structure) +: structure(structure) +{ +} + +void PvaClientData::checkValue() +{ + if(PvaClient::getDebug()) { + cout << "PvaClientData::checkValue" + << endl; + } + if(pvValue) return; + throw std::runtime_error(messagePrefix + noValue); +} + +void PvaClientData::setMessagePrefix(std::string const & value) +{ + messagePrefix = value + " "; +} + +StructureConstPtr PvaClientData::getStructure() +{ + return structure; +} + +PVStructurePtr PvaClientData::getPVStructure() +{ + if(pvStructure) return pvStructure; + throw std::runtime_error(messagePrefix + noStructure); +} + +BitSetPtr PvaClientData::getChangedBitSet() +{ + if(bitSet)return bitSet; + throw std::runtime_error(messagePrefix + noStructure); +} + +std::ostream & PvaClientData::showChanged(std::ostream & out) +{ + if(!bitSet) throw std::runtime_error(messagePrefix + noStructure); + size_t nextSet = bitSet->nextSetBit(0); + PVFieldPtr pvField; + while(nextSet!=string::npos) { + if(nextSet==0) { + pvField = pvStructure; + } else { + pvField = pvStructure->getSubField(nextSet); + } + string name = pvField->getFullName(); + out << name << " = " << pvField << endl; + nextSet = bitSet->nextSetBit(nextSet+1); + } + return out; +} + +void PvaClientData::setData( + PVStructurePtr const & pvStructureFrom, + BitSetPtr const & bitSetFrom) +{ + if(PvaClient::getDebug()) { + cout << "PvaClientData::setData" + << endl; + } + pvStructure = pvStructureFrom; + bitSet = bitSetFrom; + pvValue = pvStructure->getSubField("value"); + if(pvValue) return; + // look for first field named value or is scalar or scalarArray + PVStructurePtr pvStructure = pvStructureFrom; + while(true) { + PVFieldPtr pvField(pvStructure->getPVFields()[0]); + if((pvField->getFieldName().compare("value")) == 0) { + pvValue = pvField; + return; + } + PVScalarPtr pvScalar = static_pointer_cast(pvField); + if(pvScalar) { + pvValue = pvField; + return; + } + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); + if(pvScalarArray) { + pvValue = pvField; + return; + } + PVStructurePtr pvStructure = static_pointer_cast(pvField); + if(!pvStructure) break; + } + messagePrefix = "did not find a field named value or a field that is a scalar or scalar array"; +} + +bool PvaClientData::hasValue() +{ + if(!pvValue) return false; + return true; +} + +bool PvaClientData::isValueScalar() +{ + if(!pvValue) return false; + if(pvValue->getField()->getType()==scalar) return true; + if((pvValue->getFieldName().compare("value")) != 0) return false; + PVStructurePtr pvStructure = static_pointer_cast(pvValue); + while(true) { + if(!pvStructure) break; + PVFieldPtr pvField(pvStructure->getPVFields()[0]); + PVScalarPtr pvScalar = static_pointer_cast(pvField); + if(pvScalar) { + pvValue = pvField; + return true; + } + PVStructurePtr pvStructure = static_pointer_cast(pvField); + } + messagePrefix = "did not find a scalar field"; + return false; +} + +bool PvaClientData::isValueScalarArray() +{ + if(!pvValue) return false; + if(pvValue->getField()->getType()==scalarArray) return true; + if((pvValue->getFieldName().compare("value")) != 0) return false; + PVStructurePtr pvStructure = static_pointer_cast(pvValue); + while(true) { + if(!pvStructure) break; + PVFieldPtr pvField(pvStructure->getPVFields()[0]); + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); + if(pvScalarArray) { + pvValue = pvField; + return true; + } + PVStructurePtr pvStructure = static_pointer_cast(pvField); + } + messagePrefix = "did not find a scalarArray field"; + return false; +} + +PVFieldPtr PvaClientData::getValue() +{ + checkValue(); + return pvValue; +} + +PVScalarPtr PvaClientData::getScalarValue() +{ + checkValue(); + if(!isValueScalar()) throw std::runtime_error(messagePrefix + noScalar); + PVScalarPtr pv = static_pointer_cast(pvValue); + if(!pv) throw std::runtime_error(messagePrefix + noScalar); + return pv; +} + +PVArrayPtr PvaClientData::getArrayValue() +{ + checkValue(); + PVArrayPtr pv = pvStructure->getSubField("value"); + if(!pv) throw std::runtime_error(messagePrefix + noArray); + return pv; +} + +PVScalarArrayPtr PvaClientData::getScalarArrayValue() +{ + checkValue(); + if(!isValueScalarArray()) throw std::runtime_error(messagePrefix + noScalarArray); + PVScalarArrayPtr pv = static_pointer_cast(pvValue); + if(!pv) throw std::runtime_error(messagePrefix + noScalarArray); + return pv; +} + +double PvaClientData::getDouble() +{ + PVScalarPtr pvScalar = getScalarValue(); + ScalarType scalarType = pvScalar->getScalar()->getScalarType(); + if(scalarType==pvDouble) { + PVDoublePtr pvDouble = static_pointer_cast(pvScalar); + return pvDouble->get(); + } + if(!ScalarTypeFunc::isNumeric(scalarType)) { + throw std::runtime_error(messagePrefix + notCompatibleScalar); + } + return convert->toDouble(pvScalar); +} + +string PvaClientData::getString() +{ + PVScalarPtr pvScalar = getScalarValue(); + return convert->toString(pvScalar); +} + +shared_vector PvaClientData::getDoubleArray() +{ + PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + PVDoubleArrayPtr pv = static_pointer_cast(pvScalarArray); + if(!pv) throw std::runtime_error(messagePrefix + notDoubleArray); + return pv->view(); +} + +shared_vector PvaClientData::getStringArray() +{ + PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + PVStringArrayPtr pv = static_pointer_cast(pvScalarArray); + if(!pv) throw std::runtime_error(messagePrefix + notStringArray); + return pv->view(); +} + + +Alarm PvaClientData::getAlarm() +{ + if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure); + PVStructurePtr pvs = pvStructure->getSubField("alarm"); + if(!pvs) throw std::runtime_error(messagePrefix + noAlarm); + pvAlarm.attach(pvs); + if(pvAlarm.isAttached()) { + Alarm alarm; + pvAlarm.get(alarm); + pvAlarm.detach(); + return alarm; + } + throw std::runtime_error(messagePrefix + noAlarm); +} + +TimeStamp PvaClientData::getTimeStamp() +{ + if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure); + PVStructurePtr pvs = pvStructure->getSubField("timeStamp"); + if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp); + pvTimeStamp.attach(pvs); + if(pvTimeStamp.isAttached()) { + TimeStamp timeStamp; + pvTimeStamp.get(timeStamp); + pvTimeStamp.detach(); + return timeStamp; + } + throw std::runtime_error(messagePrefix + noTimeStamp); +} + +}} diff --git a/src/pvaClientGetData.cpp b/src/pvaClientGetData.cpp index 6da72db..b6925bd 100644 --- a/src/pvaClientGetData.cpp +++ b/src/pvaClientGetData.cpp @@ -27,19 +27,6 @@ using namespace std; namespace epics { namespace pvaClient { -typedef std::tr1::shared_ptr PVArrayPtr; -static ConvertPtr convert = getConvert(); -static string noStructure("no pvStructure "); -static string noValue("no value field"); -static string noScalar("value is not a scalar"); -static string notCompatibleScalar("value is not a compatible scalar"); -static string noArray("value is not an array"); -static string noScalarArray("value is not a scalarArray"); -static string notDoubleArray("value is not a doubleArray"); -static string notStringArray("value is not a stringArray"); -static string noAlarm("no alarm"); -static string noTimeStamp("no timeStamp"); - PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure) { if(PvaClient::getDebug()) { @@ -51,190 +38,9 @@ PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure } PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure) -: structure(structure), - pvStructure(getPVDataCreate()->createPVStructure(structure)), - bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields()))) +: PvaClientData(structure) { - messagePrefix = ""; - pvValue = pvStructure->getSubField("value"); -} - -void PvaClientGetData::checkValue() -{ - if(PvaClient::getDebug()) { - cout << "PvaClientGetData::checkValue" - << endl; - } - if(pvValue) return; - throw std::runtime_error(messagePrefix + noValue); -} - -void PvaClientGetData::setMessagePrefix(std::string const & value) -{ - messagePrefix = value + " "; -} - -StructureConstPtr PvaClientGetData::getStructure() -{return structure;} - -PVStructurePtr PvaClientGetData::getPVStructure() -{ - if(pvStructure) return pvStructure; - throw std::runtime_error(messagePrefix + noStructure); -} - -BitSetPtr PvaClientGetData::getChangedBitSet() -{ - if(bitSet)return bitSet; - throw std::runtime_error(messagePrefix + noStructure); -} - -std::ostream & PvaClientGetData::showChanged(std::ostream & out) -{ - if(!bitSet) throw std::runtime_error(messagePrefix + noStructure); - size_t nextSet = bitSet->nextSetBit(0); - PVFieldPtr pvField; - while(nextSet!=string::npos) { - if(nextSet==0) { - pvField = pvStructure; - } else { - pvField = pvStructure->getSubField(nextSet); - } - string name = pvField->getFullName(); - out << name << " = " << pvField << endl; - nextSet = bitSet->nextSetBit(nextSet+1); - } - return out; -} - -void PvaClientGetData::setData( - PVStructurePtr const & pvStructureFrom, - BitSetPtr const & bitSetFrom) -{ - if(PvaClient::getDebug()) { - cout << "PvaClientGetData::setData" - << endl; - } - pvStructure = pvStructureFrom; - bitSet = bitSetFrom; - pvValue = pvStructure->getSubField("value"); -} - -bool PvaClientGetData::hasValue() -{ - if(!pvValue) return false; - return true; -} - -bool PvaClientGetData::isValueScalar() -{ - if(!pvValue) return false; - if(pvValue->getField()->getType()==scalar) return true; - return false; -} - -bool PvaClientGetData::isValueScalarArray() -{ - if(!pvValue) return false; - if(pvValue->getField()->getType()==scalarArray) return true; - return false; -} - -PVFieldPtr PvaClientGetData::getValue() -{ - checkValue(); - return pvValue; -} - -PVScalarPtr PvaClientGetData::getScalarValue() -{ - checkValue(); - PVScalarPtr pv = pvStructure->getSubField("value"); - if(!pv) throw std::runtime_error(messagePrefix + noScalar); - return pv; -} - -PVArrayPtr PvaClientGetData::getArrayValue() -{ - checkValue(); - PVArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) throw std::runtime_error(messagePrefix + noArray); - return pv; -} - -PVScalarArrayPtr PvaClientGetData::getScalarArrayValue() -{ - checkValue(); - PVScalarArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) throw std::runtime_error(messagePrefix + noScalarArray); - return pv; -} - -double PvaClientGetData::getDouble() -{ - PVScalarPtr pvScalar = getScalarValue(); - ScalarType scalarType = pvScalar->getScalar()->getScalarType(); - if(scalarType==pvDouble) { - PVDoublePtr pvDouble = static_pointer_cast(pvScalar); - return pvDouble->get(); - } - if(!ScalarTypeFunc::isNumeric(scalarType)) { - throw std::runtime_error(messagePrefix + notCompatibleScalar); - } - return convert->toDouble(pvScalar); -} - -string PvaClientGetData::getString() -{ - PVScalarPtr pvScalar = getScalarValue(); - return convert->toString(pvScalar); -} - -shared_vector PvaClientGetData::getDoubleArray() -{ - checkValue(); - PVDoubleArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) throw std::runtime_error(messagePrefix + notDoubleArray); - return pv->view(); -} - -shared_vector PvaClientGetData::getStringArray() -{ - checkValue(); - PVStringArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) throw std::runtime_error(messagePrefix + notStringArray); - return pv->view(); -} - - -Alarm PvaClientGetData::getAlarm() -{ - if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure); - PVStructurePtr pvs = pvStructure->getSubField("alarm"); - if(!pvs) throw std::runtime_error(messagePrefix + noAlarm); - pvAlarm.attach(pvs); - if(pvAlarm.isAttached()) { - Alarm alarm; - pvAlarm.get(alarm); - pvAlarm.detach(); - return alarm; - } - throw std::runtime_error(messagePrefix + noAlarm); -} - -TimeStamp PvaClientGetData::getTimeStamp() -{ - if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure); - PVStructurePtr pvs = pvStructure->getSubField("timeStamp"); - if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp); - pvTimeStamp.attach(pvs); - if(pvTimeStamp.isAttached()) { - TimeStamp timeStamp; - pvTimeStamp.get(timeStamp); - pvTimeStamp.detach(); - return timeStamp; - } - throw std::runtime_error(messagePrefix + noTimeStamp); +// PvaClientData::create(structure); } }} diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index 246f630..a1eaba6 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -439,7 +439,7 @@ bool PvaClientMonitor::poll() monitorElement = monitor->poll(); if(!monitorElement) return false; userPoll = true; - pvaClientData->setData(monitorElement); + pvaClientData->setElementData(monitorElement); return true; } diff --git a/src/pvaClientMonitorData.cpp b/src/pvaClientMonitorData.cpp index 03b8bce..319cbd7 100644 --- a/src/pvaClientMonitorData.cpp +++ b/src/pvaClientMonitorData.cpp @@ -53,43 +53,16 @@ PvaClientMonitorDataPtr PvaClientMonitorData::create(StructureConstPtr const & s } PvaClientMonitorData::PvaClientMonitorData(StructureConstPtr const & structure) -: structure(structure) +: PvaClientData(structure) { - messagePrefix = ""; } -void PvaClientMonitorData::setData(MonitorElementPtr const & monitorElement) +void PvaClientMonitorData::setElementData(MonitorElementPtr const & monitorElement) { - pvStructure = monitorElement->pvStructurePtr; - changedBitSet = monitorElement->changedBitSet; + PVStructurePtr pvStructure = monitorElement->pvStructurePtr; + BitSetPtr changedBitSet = monitorElement->changedBitSet; + setData(pvStructure,changedBitSet); overrunBitSet = monitorElement->overrunBitSet; - pvValue = pvStructure->getSubField("value"); -} - -void PvaClientMonitorData::checkValue() -{ - if(pvValue) return; - throw std::runtime_error(messagePrefix + noValue); -} - -void PvaClientMonitorData::setMessagePrefix(std::string const & value) -{ - messagePrefix = value + " "; -} - -StructureConstPtr PvaClientMonitorData::getStructure() -{return structure;} - -PVStructurePtr PvaClientMonitorData::getPVStructure() -{ - if(pvStructure) return pvStructure; - throw std::runtime_error(messagePrefix + noStructure); -} - -BitSetPtr PvaClientMonitorData::getChangedBitSet() -{ - if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure); - return changedBitSet; } BitSetPtr PvaClientMonitorData::getOverrunBitSet() @@ -98,24 +71,6 @@ BitSetPtr PvaClientMonitorData::getOverrunBitSet() return overrunBitSet; } -std::ostream & PvaClientMonitorData::showChanged(std::ostream & out) -{ - if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure); - size_t nextSet = changedBitSet->nextSetBit(0); - PVFieldPtr pvField; - while(nextSet!=string::npos) { - if(nextSet==0) { - pvField = pvStructure; - } else { - pvField = pvStructure->getSubField(nextSet); - } - string name = pvField->getFullName(); - out << name << " = " << pvField << endl; - nextSet = changedBitSet->nextSetBit(nextSet+1); - } - return out; -} - std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out) { if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure); @@ -123,9 +78,9 @@ std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out) PVFieldPtr pvField; while(nextSet!=string::npos) { if(nextSet==0) { - pvField = pvStructure; + pvField = getPVStructure(); } else { - pvField = pvStructure->getSubField(nextSet); + pvField = getPVStructure()->getSubField(nextSet); } string name = pvField->getFullName(); out << name << " = " << pvField << endl; @@ -134,135 +89,4 @@ std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out) return out; } -bool PvaClientMonitorData::hasValue() -{ - if(!pvValue) return false; - return true; -} - -bool PvaClientMonitorData::isValueScalar() -{ - if(!pvValue) return false; - if(pvValue->getField()->getType()==scalar) return true; - return false; -} - -bool PvaClientMonitorData::isValueScalarArray() -{ - if(!pvValue) return false; - if(pvValue->getField()->getType()==scalarArray) return true; - return false; -} - -PVFieldPtr PvaClientMonitorData::getValue() -{ - checkValue(); - return pvValue; -} - -PVScalarPtr PvaClientMonitorData::getScalarValue() -{ - checkValue(); - PVScalarPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + noScalar); - } - return pv; -} - -PVArrayPtr PvaClientMonitorData::getArrayValue() -{ - checkValue(); - PVArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + noArray); - } - return pv; -} - -PVScalarArrayPtr PvaClientMonitorData::getScalarArrayValue() -{ - checkValue(); - PVScalarArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + noScalarArray); - } - return pv; -} - -double PvaClientMonitorData::getDouble() -{ - PVScalarPtr pvScalar = getScalarValue(); - ScalarType scalarType = pvScalar->getScalar()->getScalarType(); - if(scalarType==pvDouble) { - PVDoublePtr pvDouble = static_pointer_cast(pvScalar); - return pvDouble->get(); - } - if(!ScalarTypeFunc::isNumeric(scalarType)) { - throw std::runtime_error(messagePrefix + notCompatibleScalar); - } - return convert->toDouble(pvScalar); -} - -string PvaClientMonitorData::getString() -{ - PVScalarPtr pvScalar = getScalarValue(); - return convert->toString(pvScalar); -} - -shared_vector PvaClientMonitorData::getDoubleArray() -{ - checkValue(); - PVDoubleArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + notDoubleArray); - } - return pv->view(); -} - -shared_vector PvaClientMonitorData::getStringArray() -{ - checkValue(); - PVStringArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + notStringArray); - } - return pv->view(); - -} - -Alarm PvaClientMonitorData::getAlarm() -{ - if(!pvStructure) { - throw std::runtime_error(messagePrefix + noAlarm); - } - PVStructurePtr pvs = pvStructure->getSubField("alarm"); - if(!pvs) throw std::runtime_error(messagePrefix + noAlarm); - pvAlarm.attach(pvs); - if(pvAlarm.isAttached()) { - Alarm alarm; - pvAlarm.get(alarm); - pvAlarm.detach(); - return alarm; - } - throw std::runtime_error(messagePrefix + noAlarm); -} - -TimeStamp PvaClientMonitorData::getTimeStamp() -{ - if(!pvStructure) { - throw std::runtime_error(messagePrefix + noTimeStamp); - } - PVStructurePtr pvs = pvStructure->getSubField("timeStamp"); - if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp); - pvTimeStamp.attach(pvs); - if(pvTimeStamp.isAttached()) { - TimeStamp timeStamp; - pvTimeStamp.get(timeStamp); - pvTimeStamp.detach(); - return timeStamp; - } - throw std::runtime_error(messagePrefix + noTimeStamp); -} - }} diff --git a/src/pvaClientPutData.cpp b/src/pvaClientPutData.cpp index 94ad0a8..4f264e5 100644 --- a/src/pvaClientPutData.cpp +++ b/src/pvaClientPutData.cpp @@ -25,6 +25,10 @@ using namespace epics::pvAccess; using namespace std; namespace epics { namespace pvaClient { +static ConvertPtr convert = getConvert(); +static string notCompatibleScalar("value is not a compatible scalar"); +static string notDoubleArray("value is not a doubleArray"); +static string notStringArray("value is not a stringArray"); class PvaClientPostHandlerPvt: public PostHandler { @@ -36,28 +40,23 @@ public: void postPut() { putData->postPut(fieldNumber);} }; -typedef std::tr1::shared_ptr PVArrayPtr; -static ConvertPtr convert = getConvert(); -static string noValue("no value field"); -static string notScalar("value is not a scalar"); -static string notCompatibleScalar("value is not a compatible scalar"); -static string notArray("value is not an array"); -static string notScalarArray("value is not a scalarArray"); -static string notDoubleArray("value is not a doubleArray"); -static string notStringArray("value is not a stringArray"); PvaClientPutDataPtr PvaClientPutData::create(StructureConstPtr const & structure) { + if(PvaClient::getDebug()) { + cout << "PvaClientPutData::create" + << endl; + } PvaClientPutDataPtr epv(new PvaClientPutData(structure)); return epv; } PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure) -: structure(structure), - pvStructure(getPVDataCreate()->createPVStructure(structure)), - bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields()))) +: PvaClientData(structure) { - messagePrefix = ""; + PVStructurePtr pvStructure(getPVDataCreate()->createPVStructure(structure)); + BitSetPtr bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields()))); + setData(pvStructure,bitSet); size_t nfields = pvStructure->getNumberFields(); postHandler.resize(nfields); PVFieldPtr pvField; @@ -71,141 +70,8 @@ PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure) } pvField->setPostHandler(postHandler[i]); } - pvValue = pvStructure->getSubField("value"); } -void PvaClientPutData::checkValue() -{ - if(pvValue) return; - throw std::runtime_error(messagePrefix + noValue); -} - -void PvaClientPutData::postPut(size_t fieldNumber) -{ - bitSet->set(fieldNumber); -} - -void PvaClientPutData::setMessagePrefix(std::string const & value) -{ - messagePrefix = value + " "; -} - -StructureConstPtr PvaClientPutData::getStructure() -{return structure;} - -PVStructurePtr PvaClientPutData::getPVStructure() -{return pvStructure;} - -BitSetPtr PvaClientPutData::getChangedBitSet() -{return bitSet;} - -std::ostream & PvaClientPutData::showChanged(std::ostream & out) -{ - size_t nextSet = bitSet->nextSetBit(0); - PVFieldPtr pvField; - while(nextSet!=string::npos) { - if(nextSet==0) { - pvField = pvStructure; - } else { - pvField = pvStructure->getSubField(nextSet); - } - string name = pvField->getFullName(); - out << name << " = " << pvField << endl; - nextSet = bitSet->nextSetBit(nextSet+1); - } - return out; -} - -bool PvaClientPutData::hasValue() -{ - if(!pvValue) return false; - return true; -} - -bool PvaClientPutData::isValueScalar() -{ - if(!pvValue) return false; - if(pvValue->getField()->getType()==scalar) return true; - return false; -} - -bool PvaClientPutData::isValueScalarArray() -{ - if(!pvValue) return false; - if(pvValue->getField()->getType()==scalarArray) return true; - return false; -} - -PVFieldPtr PvaClientPutData::getValue() -{ - checkValue(); - return pvValue; -} - -PVScalarPtr PvaClientPutData::getScalarValue() -{ - checkValue(); - PVScalarPtr pv = pvStructure->getSubField("value"); - if(!pv) throw std::runtime_error(messagePrefix + notScalar); - return pv; -} - -PVArrayPtr PvaClientPutData::getArrayValue() -{ - checkValue(); - PVArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) throw std::runtime_error(messagePrefix + notArray); - return pv; -} - -PVScalarArrayPtr PvaClientPutData::getScalarArrayValue() -{ - checkValue(); - PVScalarArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) throw std::runtime_error(messagePrefix + notScalarArray); - return pv; -} - -double PvaClientPutData::getDouble() -{ - PVScalarPtr pvScalar = getScalarValue(); - ScalarType scalarType = pvScalar->getScalar()->getScalarType(); - if(scalarType==pvDouble) { - PVDoublePtr pvDouble = static_pointer_cast(pvScalar); - return pvDouble->get(); - } - if(!ScalarTypeFunc::isNumeric(scalarType)) { - throw std::runtime_error(messagePrefix + notCompatibleScalar); - } - return convert->toDouble(pvScalar); -} - -string PvaClientPutData::getString() -{ - PVScalarPtr pvScalar = getScalarValue(); - return convert->toString(pvScalar); -} - -shared_vector PvaClientPutData::getDoubleArray() -{ - checkValue(); - PVDoubleArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + notDoubleArray); - } - return pv->view(); -} - -shared_vector PvaClientPutData::getStringArray() -{ - checkValue(); - PVStringArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + notStringArray); - } - return pv->view(); - -} void PvaClientPutData::putDouble(double value) { @@ -228,36 +94,32 @@ void PvaClientPutData::putString(std::string const & value) convert->fromString(pvScalar,value); } - - void PvaClientPutData::putDoubleArray(shared_vector const & value) { - checkValue(); - PVDoubleArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + notDoubleArray); - } + PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + PVDoubleArrayPtr pv = static_pointer_cast(pvScalarArray); + if(!pv) throw std::runtime_error(messagePrefix + notDoubleArray); pv->replace(value); } void PvaClientPutData::putStringArray(shared_vector const & value) { - checkValue(); - PVStringArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + notStringArray); - } + PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + PVStringArrayPtr pv = static_pointer_cast(pvScalarArray); + if(!pv) throw std::runtime_error(messagePrefix + notStringArray); pv->replace(value); } void PvaClientPutData::putStringArray(std::vector const & value) { - checkValue(); - PVScalarArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) { - throw std::runtime_error(messagePrefix + notScalarArray); - } - convert->fromStringArray(pv,0,value.size(),value,0); + PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + convert->fromStringArray(pvScalarArray,0,value.size(),value,0); } +void PvaClientPutData::postPut(size_t fieldNumber) +{ + getChangedBitSet()->set(fieldNumber); +} + + }} diff --git a/src/pvaClientPutGet.cpp b/src/pvaClientPutGet.cpp index bde22a3..57b7402 100644 --- a/src/pvaClientPutGet.cpp +++ b/src/pvaClientPutGet.cpp @@ -218,11 +218,7 @@ void PvaClientPutGet::putGetDone( channelPutGetStatus = status; putGetState = putGetComplete; if(status.isOK()) { - PVStructurePtr pvs = pvaClientGetData->getPVStructure(); - pvs->copyUnchecked(*getPVStructure,*getChangedBitSet); - BitSetPtr bs = pvaClientGetData->getChangedBitSet(); - bs->clear(); - *bs |= *getChangedBitSet; + pvaClientGetData->setData(getPVStructure,getChangedBitSet); } PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); if(req) { @@ -274,11 +270,7 @@ void PvaClientPutGet::getGetDone( channelPutGetStatus = status; putGetState = putGetComplete; if(status.isOK()) { - PVStructurePtr pvs = pvaClientGetData->getPVStructure(); - pvs->copyUnchecked(*getPVStructure,*getChangedBitSet); - BitSetPtr bs = pvaClientGetData->getChangedBitSet(); - bs->clear(); - *bs |= *getChangedBitSet; + pvaClientGetData->setData(getPVStructure,getChangedBitSet); } PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); if(req) { @@ -555,6 +547,4 @@ PvaClientChannelPtr PvaClientPutGet::getPvaClientChannel() return pvaClientChannel; } - - }}