From d650865a6fc832c63d79e7e32b27d32da39046cd Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Wed, 3 Apr 2019 10:32:45 -0400 Subject: [PATCH 01/12] 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; } - - }} From 3f6d93b22f881226ebe112ed60d31143dcf78502 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 4 Apr 2019 16:02:47 -0400 Subject: [PATCH 02/12] lots of minor changes --- src/pvaClient.cpp | 1 - src/pvaClientChannel.cpp | 1 - src/pvaClientData.cpp | 76 +++++++++++++++++------------ src/pvaClientGet.cpp | 68 +++++++++++--------------- src/pvaClientGetData.cpp | 10 +--- src/pvaClientMonitor.cpp | 2 - src/pvaClientMonitorData.cpp | 1 - src/pvaClientMultiChannel.cpp | 3 -- src/pvaClientMultiGetDouble.cpp | 1 - src/pvaClientMultiMonitorDouble.cpp | 1 - src/pvaClientMultiPutDouble.cpp | 1 - src/pvaClientNTMultiData.cpp | 1 - src/pvaClientNTMultiGet.cpp | 1 - src/pvaClientNTMultiMonitor.cpp | 1 - src/pvaClientNTMultiPut.cpp | 1 - src/pvaClientProcess.cpp | 1 - src/pvaClientPut.cpp | 1 - src/pvaClientPutData.cpp | 20 +++++--- src/pvaClientPutGet.cpp | 44 ++++++++++------- src/pvaClientRPC.cpp | 2 - 20 files changed, 116 insertions(+), 121 deletions(-) diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index b95e7ab..5545342 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -18,7 +18,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::pvAccess::ca; diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 16338a2..e6c9f09 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -18,7 +18,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp index c7e165d..e47c26d 100644 --- a/src/pvaClientData.cpp +++ b/src/pvaClientData.cpp @@ -42,10 +42,7 @@ static string noTimeStamp("no timeStamp"); PvaClientDataPtr PvaClientData::create(StructureConstPtr const & structure) { - if(PvaClient::getDebug()) { - cout << "PvaClientData::create" - << endl; - } + if(PvaClient::getDebug()) cout << "PvaClientData::create\n"; PvaClientDataPtr epv(new PvaClientData(structure)); return epv; } @@ -57,10 +54,7 @@ PvaClientData::PvaClientData(StructureConstPtr const & structure) void PvaClientData::checkValue() { - if(PvaClient::getDebug()) { - cout << "PvaClientData::checkValue" - << endl; - } + if(PvaClient::getDebug()) cout << "PvaClientData::checkValue\n"; if(pvValue) return; throw std::runtime_error(messagePrefix + noValue); } @@ -109,10 +103,7 @@ void PvaClientData::setData( PVStructurePtr const & pvStructureFrom, BitSetPtr const & bitSetFrom) { - if(PvaClient::getDebug()) { - cout << "PvaClientData::setData" - << endl; - } + if(PvaClient::getDebug()) cout << "PvaClientData::setData\n"; pvStructure = pvStructureFrom; bitSet = bitSetFrom; pvValue = pvStructure->getSubField("value"); @@ -125,62 +116,73 @@ void PvaClientData::setData( pvValue = pvField; return; } - PVScalarPtr pvScalar = static_pointer_cast(pvField); - if(pvScalar) { + if(pvField->getField()->getType()==scalar) { pvValue = pvField; return; } - PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); - if(pvScalarArray) { + if(pvField->getField()->getType()==scalarArray) { pvValue = pvField; return; } + if(pvField->getField()->getType()!=epics::pvData::structure) break; 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(PvaClient::getDebug()) cout << "PvaClientData::hasValue\n"; if(!pvValue) return false; return true; } bool PvaClientData::isValueScalar() { + if(PvaClient::getDebug()) cout << "PvaClientData::isValueScalar\n"; if(!pvValue) return false; if(pvValue->getField()->getType()==scalar) return true; - if((pvValue->getFieldName().compare("value")) != 0) return false; + if(pvValue->getField()->getType()!=epics::pvData::structure) 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; + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()<1) { + throw std::logic_error("PvaClientData::isValueScalar() found empty structure"); } + PVFieldPtr pvField(fieldPtrArray[0]); + if(!pvField) throw std::logic_error("PvaClientData::isValueScalar() found null field"); + if(pvField->getField()->getType()==scalar) { + pvValue = pvField; + return true; + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; PVStructurePtr pvStructure = static_pointer_cast(pvField); } - messagePrefix = "did not find a scalar field"; + messagePrefix = "did not find a scalar field "; return false; } bool PvaClientData::isValueScalarArray() { + if(PvaClient::getDebug()) cout << "PvaClientData::isValueScalarArray\n"; if(!pvValue) return false; if(pvValue->getField()->getType()==scalarArray) return true; - if((pvValue->getFieldName().compare("value")) != 0) return false; + if(pvValue->getField()->getType()!=epics::pvData::structure) 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) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()<1) { + throw std::logic_error("PvaClientData::isValueScalar() found empty structure"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + if(!pvField) throw std::logic_error("PvaClientData::isValueScalar() found null field"); + if(pvField->getField()->getType()==scalarArray) { pvValue = pvField; return true; } + if(pvField->getField()->getType()!=epics::pvData::structure) break; PVStructurePtr pvStructure = static_pointer_cast(pvField); } messagePrefix = "did not find a scalarArray field"; @@ -189,12 +191,14 @@ bool PvaClientData::isValueScalarArray() PVFieldPtr PvaClientData::getValue() { + if(PvaClient::getDebug()) cout << "PvaClientData::getValue\n"; checkValue(); return pvValue; } PVScalarPtr PvaClientData::getScalarValue() { + if(PvaClient::getDebug()) cout << "PvaClientData::getScalarValue\n"; checkValue(); if(!isValueScalar()) throw std::runtime_error(messagePrefix + noScalar); PVScalarPtr pv = static_pointer_cast(pvValue); @@ -204,6 +208,7 @@ PVScalarPtr PvaClientData::getScalarValue() PVArrayPtr PvaClientData::getArrayValue() { + if(PvaClient::getDebug()) cout << "PvaClientData::getArrayValue\n"; checkValue(); PVArrayPtr pv = pvStructure->getSubField("value"); if(!pv) throw std::runtime_error(messagePrefix + noArray); @@ -212,6 +217,7 @@ PVArrayPtr PvaClientData::getArrayValue() PVScalarArrayPtr PvaClientData::getScalarArrayValue() { + if(PvaClient::getDebug()) cout << "PvaClientData::getScalarArrayValue\n"; checkValue(); if(!isValueScalarArray()) throw std::runtime_error(messagePrefix + noScalarArray); PVScalarArrayPtr pv = static_pointer_cast(pvValue); @@ -221,6 +227,7 @@ PVScalarArrayPtr PvaClientData::getScalarArrayValue() double PvaClientData::getDouble() { + if(PvaClient::getDebug()) cout << "PvaClientData::getDouble\n"; PVScalarPtr pvScalar = getScalarValue(); ScalarType scalarType = pvScalar->getScalar()->getScalarType(); if(scalarType==pvDouble) { @@ -235,29 +242,37 @@ double PvaClientData::getDouble() string PvaClientData::getString() { + if(PvaClient::getDebug()) cout << "PvaClientData::getString\n"; PVScalarPtr pvScalar = getScalarValue(); return convert->toString(pvScalar); } shared_vector PvaClientData::getDoubleArray() { + if(PvaClient::getDebug()) cout << "PvaClientData::getDoubleArray\n"; PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + if(pvScalarArray->getScalarArray()->getElementType()!=pvDouble) { + throw std::runtime_error(messagePrefix + notDoubleArray); + } PVDoubleArrayPtr pv = static_pointer_cast(pvScalarArray); - if(!pv) throw std::runtime_error(messagePrefix + notDoubleArray); return pv->view(); } shared_vector PvaClientData::getStringArray() { + if(PvaClient::getDebug()) cout << "PvaClientData::getStringArray\n"; PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + if(pvScalarArray->getScalarArray()->getElementType()!=pvString) { + throw std::runtime_error(messagePrefix + notStringArray); + } PVStringArrayPtr pv = static_pointer_cast(pvScalarArray); - if(!pv) throw std::runtime_error(messagePrefix + notStringArray); return pv->view(); } Alarm PvaClientData::getAlarm() { + if(PvaClient::getDebug()) cout << "PvaClientData::getAlarm\n"; if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure); PVStructurePtr pvs = pvStructure->getSubField("alarm"); if(!pvs) throw std::runtime_error(messagePrefix + noAlarm); @@ -273,6 +288,7 @@ Alarm PvaClientData::getAlarm() TimeStamp PvaClientData::getTimeStamp() { + if(PvaClient::getDebug()) cout << "PvaClientData::getTimeStamp\n"; if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure); PVStructurePtr pvs = pvStructure->getSubField("timeStamp"); if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp); diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index c93fc0f..0b7398d 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -15,7 +15,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; @@ -99,18 +98,16 @@ PvaClientGet::PvaClientGet( getState(getIdle) { if(PvaClient::getDebug()) { - cout << "PvaClientGet::PvaClientGet::PvaClientGet" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout << "PvaClientGet::PvaClientGet channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } } PvaClientGet::~PvaClientGet() { if(PvaClient::getDebug()) { - cout<< "PvaClientGet::~PvaClientGet" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout<< "PvaClientGet::~PvaClientGet channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } } @@ -118,9 +115,8 @@ PvaClientGet::~PvaClientGet() void PvaClientGet::checkConnectState() { if(PvaClient::getDebug()) { - cout << "PvaClientGet::checkConnectState" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout << "PvaClientGet::checkConnectState channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } if(!pvaClientChannel->getChannel()->isConnected()) { string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() @@ -159,10 +155,10 @@ void PvaClientGet::channelGetConnect( StructureConstPtr const & structure) { if(PvaClient::getDebug()) { - cout << "PvaClientGet::channelGetConnect" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() + cout << "PvaClientGet::channelGetConnect channelName " + << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") - << endl; + << "\n"; } { Lock xx(mutex); @@ -196,10 +192,10 @@ void PvaClientGet::getDone( BitSetPtr const & bitSet) { if(PvaClient::getDebug()) { - cout << "PvaClientGet::getDone" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() + cout << "PvaClientGet::getDone channelName " + << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") - << endl; + << "\n"; } { Lock xx(mutex); @@ -219,9 +215,8 @@ void PvaClientGet::getDone( void PvaClientGet::connect() { if(PvaClient::getDebug()) { - cout << "PvaClientGet::connect" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout << "PvaClientGet::connect channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } issueConnect(); Status status = waitConnect(); @@ -234,9 +229,8 @@ void PvaClientGet::connect() void PvaClientGet::issueConnect() { if(PvaClient::getDebug()) { - cout << "PvaClientGet::issueConnect" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout << "PvaClientGet::issueConnect channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } if(connectState!=connectIdle) { string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() @@ -251,9 +245,8 @@ void PvaClientGet::issueConnect() Status PvaClientGet::waitConnect() { if(PvaClient::getDebug()) { - cout << "PvaClientGet::waitConnect" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout << "PvaClientGet::waitConnect channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } { Lock xx(mutex); @@ -275,9 +268,8 @@ Status PvaClientGet::waitConnect() void PvaClientGet::get() { if(PvaClient::getDebug()) { - cout << "PvaClientGet::get" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout << "PvaClientGet::get channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } issueGet(); Status status = waitGet(); @@ -290,9 +282,8 @@ void PvaClientGet::get() void PvaClientGet::issueGet() { if(PvaClient::getDebug()) { - cout << "PvaClientGet::issueGet" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout << "PvaClientGet::issueGet channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } if(connectState==connectIdle) connect(); if(getState==getActive) { @@ -307,9 +298,8 @@ void PvaClientGet::issueGet() Status PvaClientGet::waitGet() { if(PvaClient::getDebug()) { - cout << "PvaClientGet::waitGet" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout << "PvaClientGet::waitGet channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } { Lock xx(mutex); @@ -330,9 +320,8 @@ Status PvaClientGet::waitGet() PvaClientGetDataPtr PvaClientGet::getData() { if(PvaClient::getDebug()) { - cout<< "PvaClientGet::getData" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout<< "PvaClientGet::getData channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } checkConnectState(); if(getState==getIdle) get(); @@ -342,9 +331,8 @@ PvaClientGetDataPtr PvaClientGet::getData() void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester) { if(PvaClient::getDebug()) { - cout << "PvaClientGet::setRequester" - << " channelName " << pvaClientChannel->getChannel()->getChannelName() - << endl; + cout << "PvaClientGet::setRequester channelName " + << pvaClientChannel->getChannel()->getChannelName() << "\n"; } this->pvaClientGetRequester = pvaClientGetRequester; } diff --git a/src/pvaClientGetData.cpp b/src/pvaClientGetData.cpp index b6925bd..e253cb9 100644 --- a/src/pvaClientGetData.cpp +++ b/src/pvaClientGetData.cpp @@ -19,7 +19,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; @@ -29,18 +28,13 @@ namespace epics { namespace pvaClient { PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure) { - if(PvaClient::getDebug()) { - cout << "PvaClientGetData::create" - << endl; - } + if(PvaClient::getDebug()) cout << "PvaClientGetData::create\n"; PvaClientGetDataPtr epv(new PvaClientGetData(structure)); return epv; } PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure) : PvaClientData(structure) -{ -// PvaClientData::create(structure); -} +{} }} diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index a1eaba6..2fe0753 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -17,8 +17,6 @@ #include -using std::tr1::static_pointer_cast; -using std::tr1::dynamic_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; diff --git a/src/pvaClientMonitorData.cpp b/src/pvaClientMonitorData.cpp index 319cbd7..25806fe 100644 --- a/src/pvaClientMonitorData.cpp +++ b/src/pvaClientMonitorData.cpp @@ -19,7 +19,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; diff --git a/src/pvaClientMultiChannel.cpp b/src/pvaClientMultiChannel.cpp index 33e6481..932dc8a 100644 --- a/src/pvaClientMultiChannel.cpp +++ b/src/pvaClientMultiChannel.cpp @@ -17,9 +17,6 @@ #include - - -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; diff --git a/src/pvaClientMultiGetDouble.cpp b/src/pvaClientMultiGetDouble.cpp index 9b803d7..3683363 100644 --- a/src/pvaClientMultiGetDouble.cpp +++ b/src/pvaClientMultiGetDouble.cpp @@ -16,7 +16,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::nt; diff --git a/src/pvaClientMultiMonitorDouble.cpp b/src/pvaClientMultiMonitorDouble.cpp index 95dda92..dafdef7 100644 --- a/src/pvaClientMultiMonitorDouble.cpp +++ b/src/pvaClientMultiMonitorDouble.cpp @@ -16,7 +16,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::nt; diff --git a/src/pvaClientMultiPutDouble.cpp b/src/pvaClientMultiPutDouble.cpp index 0169641..d61b640 100644 --- a/src/pvaClientMultiPutDouble.cpp +++ b/src/pvaClientMultiPutDouble.cpp @@ -16,7 +16,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::nt; diff --git a/src/pvaClientNTMultiData.cpp b/src/pvaClientNTMultiData.cpp index c4ca69e..7e5de88 100644 --- a/src/pvaClientNTMultiData.cpp +++ b/src/pvaClientNTMultiData.cpp @@ -15,7 +15,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::nt; diff --git a/src/pvaClientNTMultiGet.cpp b/src/pvaClientNTMultiGet.cpp index 0f77ce1..6641e95 100644 --- a/src/pvaClientNTMultiGet.cpp +++ b/src/pvaClientNTMultiGet.cpp @@ -15,7 +15,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::nt; diff --git a/src/pvaClientNTMultiMonitor.cpp b/src/pvaClientNTMultiMonitor.cpp index 126476a..a095936 100644 --- a/src/pvaClientNTMultiMonitor.cpp +++ b/src/pvaClientNTMultiMonitor.cpp @@ -18,7 +18,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::nt; diff --git a/src/pvaClientNTMultiPut.cpp b/src/pvaClientNTMultiPut.cpp index cd18a6e..a965026 100644 --- a/src/pvaClientNTMultiPut.cpp +++ b/src/pvaClientNTMultiPut.cpp @@ -17,7 +17,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::nt; diff --git a/src/pvaClientProcess.cpp b/src/pvaClientProcess.cpp index e8b7d06..87412cf 100644 --- a/src/pvaClientProcess.cpp +++ b/src/pvaClientProcess.cpp @@ -15,7 +15,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index c42ba19..f046263 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -15,7 +15,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; diff --git a/src/pvaClientPutData.cpp b/src/pvaClientPutData.cpp index 4f264e5..5598529 100644 --- a/src/pvaClientPutData.cpp +++ b/src/pvaClientPutData.cpp @@ -43,10 +43,7 @@ public: PvaClientPutDataPtr PvaClientPutData::create(StructureConstPtr const & structure) { - if(PvaClient::getDebug()) { - cout << "PvaClientPutData::create" - << endl; - } + if(PvaClient::getDebug()) cout << "PvaClientPutData::create\n"; PvaClientPutDataPtr epv(new PvaClientPutData(structure)); return epv; } @@ -54,6 +51,7 @@ PvaClientPutDataPtr PvaClientPutData::create(StructureConstPtr const & structure PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure) : PvaClientData(structure) { + if(PvaClient::getDebug()) cout << "PvaClientPutData::PvaClientPutData\n"; PVStructurePtr pvStructure(getPVDataCreate()->createPVStructure(structure)); BitSetPtr bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields()))); setData(pvStructure,bitSet); @@ -75,6 +73,7 @@ PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure) void PvaClientPutData::putDouble(double value) { + if(PvaClient::getDebug()) cout << "PvaClientPutData::putDouble\n"; PVScalarPtr pvScalar = getScalarValue(); ScalarType scalarType = pvScalar->getScalar()->getScalarType(); if(scalarType==pvDouble) { @@ -90,34 +89,43 @@ void PvaClientPutData::putDouble(double value) void PvaClientPutData::putString(std::string const & value) { + if(PvaClient::getDebug()) cout << "PvaClientPutData::putString\n"; PVScalarPtr pvScalar = getScalarValue(); convert->fromString(pvScalar,value); } void PvaClientPutData::putDoubleArray(shared_vector const & value) { + if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\n"; PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + if(pvScalarArray->getScalarArray()->getElementType()!=pvDouble) { + throw std::runtime_error(messagePrefix + notDoubleArray); + } PVDoubleArrayPtr pv = static_pointer_cast(pvScalarArray); - if(!pv) throw std::runtime_error(messagePrefix + notDoubleArray); pv->replace(value); } void PvaClientPutData::putStringArray(shared_vector const & value) { + if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n"; PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + if(pvScalarArray->getScalarArray()->getElementType()!=pvString) { + throw std::runtime_error(messagePrefix + notStringArray); + } PVStringArrayPtr pv = static_pointer_cast(pvScalarArray); - if(!pv) throw std::runtime_error(messagePrefix + notStringArray); pv->replace(value); } void PvaClientPutData::putStringArray(std::vector const & value) { + if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n"; PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); convert->fromStringArray(pvScalarArray,0,value.size(),value,0); } void PvaClientPutData::postPut(size_t fieldNumber) { + if(PvaClient::getDebug()) cout << "PvaClientPutData::postPut\n"; getChangedBitSet()->set(fieldNumber); } diff --git a/src/pvaClientPutGet.cpp b/src/pvaClientPutGet.cpp index 57b7402..a370c07 100644 --- a/src/pvaClientPutGet.cpp +++ b/src/pvaClientPutGet.cpp @@ -14,7 +14,6 @@ #include -using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; @@ -174,7 +173,7 @@ void PvaClientPutGet::channelPutGetConnect( << " channelName " << pvaClientChannel->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; - } + } { Lock xx(mutex); this->channelPutGet = channelPutGet; @@ -215,10 +214,13 @@ void PvaClientPutGet::putGetDone( << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } - channelPutGetStatus = status; - putGetState = putGetComplete; - if(status.isOK()) { - pvaClientGetData->setData(getPVStructure,getChangedBitSet); + { + Lock xx(mutex); + channelPutGetStatus = status; + putGetState = putGetComplete; + if(status.isOK()) { + pvaClientGetData->setData(getPVStructure,getChangedBitSet); + } } PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); if(req) { @@ -239,14 +241,17 @@ void PvaClientPutGet::getPutDone( << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } - channelPutGetStatus = status; - putGetState = putGetComplete; - if(status.isOK()) { - PVStructurePtr pvs = pvaClientPutData->getPVStructure(); - pvs->copyUnchecked(*putPVStructure,*putBitSet); - BitSetPtr bs = pvaClientPutData->getChangedBitSet(); - bs->clear(); - *bs |= *putBitSet; + { + Lock xx(mutex); + channelPutGetStatus = status; + putGetState = putGetComplete; + if(status.isOK()) { + PVStructurePtr pvs = pvaClientPutData->getPVStructure(); + pvs->copyUnchecked(*putPVStructure,*putBitSet); + BitSetPtr bs = pvaClientPutData->getChangedBitSet(); + bs->clear(); + *bs |= *putBitSet; + } } PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); if(req) { @@ -267,10 +272,13 @@ void PvaClientPutGet::getGetDone( << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } - channelPutGetStatus = status; - putGetState = putGetComplete; - if(status.isOK()) { - pvaClientGetData->setData(getPVStructure,getChangedBitSet); + { + Lock xx(mutex); + channelPutGetStatus = status; + putGetState = putGetComplete; + if(status.isOK()) { + pvaClientGetData->setData(getPVStructure,getChangedBitSet); + } } PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); if(req) { diff --git a/src/pvaClientRPC.cpp b/src/pvaClientRPC.cpp index bcc21bc..94a5411 100644 --- a/src/pvaClientRPC.cpp +++ b/src/pvaClientRPC.cpp @@ -17,8 +17,6 @@ #include -using std::tr1::static_pointer_cast; -using std::tr1::dynamic_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; From 9ffeffd23f147a16b66f5e5c1efd8eb94b1ab1da Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 4 Apr 2019 16:27:53 -0400 Subject: [PATCH 03/12] mistake --- src/pvaClientData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp index e47c26d..969cfa7 100644 --- a/src/pvaClientData.cpp +++ b/src/pvaClientData.cpp @@ -125,7 +125,7 @@ void PvaClientData::setData( return; } if(pvField->getField()->getType()!=epics::pvData::structure) break; - PVStructurePtr pvStructure = static_pointer_cast(pvField); + pvStructure = static_pointer_cast(pvField); } messagePrefix = "did not find a field named value or a field that is a scalar or scalar array"; } From 763c41caa397277d81307d5e3cf471b880bb5e94 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Fri, 5 Apr 2019 14:37:05 -0400 Subject: [PATCH 04/12] setElementData=>setData --- src/pv/pvaClient.h | 2 +- src/pvaClientMonitor.cpp | 2 +- src/pvaClientMonitorData.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 3e302c9..ff439e0 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -743,7 +743,7 @@ public: * NOTE: Not normally called by clients * @param monitorElement the monitorElement that has new data. */ - void setElementData(epics::pvData::MonitorElementPtr const & monitorElement); + void setData(epics::pvData::MonitorElementPtr const & monitorElement); /** Factory method for creating an instance of PvaClientGetData. * NOTE: Not normally called by clients * @param structure Introspection interface diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index 2fe0753..e253366 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -437,7 +437,7 @@ bool PvaClientMonitor::poll() monitorElement = monitor->poll(); if(!monitorElement) return false; userPoll = true; - pvaClientData->setElementData(monitorElement); + pvaClientData->setData(monitorElement); return true; } diff --git a/src/pvaClientMonitorData.cpp b/src/pvaClientMonitorData.cpp index 25806fe..7c5d1da 100644 --- a/src/pvaClientMonitorData.cpp +++ b/src/pvaClientMonitorData.cpp @@ -56,11 +56,11 @@ PvaClientMonitorData::PvaClientMonitorData(StructureConstPtr const & structure) { } -void PvaClientMonitorData::setElementData(MonitorElementPtr const & monitorElement) +void PvaClientMonitorData::setData(MonitorElementPtr const & monitorElement) { PVStructurePtr pvStructure = monitorElement->pvStructurePtr; BitSetPtr changedBitSet = monitorElement->changedBitSet; - setData(pvStructure,changedBitSet); + PvaClientData::setData(pvStructure,changedBitSet); overrunBitSet = monitorElement->overrunBitSet; } From 99a7e3b0b527ec2f436c03d55eddd57ef3b04fee Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Sat, 6 Apr 2019 11:30:10 -0400 Subject: [PATCH 05/12] more changes --- src/pvaClientData.cpp | 228 ++++++++++++++++++++++++--------------- src/pvaClientPutData.cpp | 172 ++++++++++++++++++++++++++--- 2 files changed, 302 insertions(+), 98 deletions(-) diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp index 969cfa7..0f3d50c 100644 --- a/src/pvaClientData.cpp +++ b/src/pvaClientData.cpp @@ -32,11 +32,8 @@ 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"); @@ -107,27 +104,6 @@ void PvaClientData::setData( 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; - } - if(pvField->getField()->getType()==scalar) { - pvValue = pvField; - return; - } - if(pvField->getField()->getType()==scalarArray) { - pvValue = pvField; - return; - } - if(pvField->getField()->getType()!=epics::pvData::structure) break; - pvStructure = static_pointer_cast(pvField); - } - messagePrefix = "did not find a field named value or a field that is a scalar or scalar array"; } bool PvaClientData::hasValue() @@ -142,24 +118,6 @@ bool PvaClientData::isValueScalar() if(PvaClient::getDebug()) cout << "PvaClientData::isValueScalar\n"; if(!pvValue) return false; if(pvValue->getField()->getType()==scalar) return true; - if(pvValue->getField()->getType()!=epics::pvData::structure) return false; - PVStructurePtr pvStructure = static_pointer_cast(pvValue); - while(true) { - if(!pvStructure) break; - const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); - if(fieldPtrArray.size()<1) { - throw std::logic_error("PvaClientData::isValueScalar() found empty structure"); - } - PVFieldPtr pvField(fieldPtrArray[0]); - if(!pvField) throw std::logic_error("PvaClientData::isValueScalar() found null field"); - if(pvField->getField()->getType()==scalar) { - pvValue = pvField; - return true; - } - if(pvField->getField()->getType()!=epics::pvData::structure) break; - PVStructurePtr pvStructure = static_pointer_cast(pvField); - } - messagePrefix = "did not find a scalar field "; return false; } @@ -168,24 +126,6 @@ bool PvaClientData::isValueScalarArray() if(PvaClient::getDebug()) cout << "PvaClientData::isValueScalarArray\n"; if(!pvValue) return false; if(pvValue->getField()->getType()==scalarArray) return true; - if(pvValue->getField()->getType()!=epics::pvData::structure) return false; - PVStructurePtr pvStructure = static_pointer_cast(pvValue); - while(true) { - if(!pvStructure) break; - const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); - if(fieldPtrArray.size()<1) { - throw std::logic_error("PvaClientData::isValueScalar() found empty structure"); - } - PVFieldPtr pvField(fieldPtrArray[0]); - if(!pvField) throw std::logic_error("PvaClientData::isValueScalar() found null field"); - if(pvField->getField()->getType()==scalarArray) { - pvValue = pvField; - return true; - } - if(pvField->getField()->getType()!=epics::pvData::structure) break; - PVStructurePtr pvStructure = static_pointer_cast(pvField); - } - messagePrefix = "did not find a scalarArray field"; return false; } @@ -200,42 +140,73 @@ PVScalarPtr PvaClientData::getScalarValue() { if(PvaClient::getDebug()) cout << "PvaClientData::getScalarValue\n"; 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; + if(pvValue->getField()->getType()!=scalar) { + throw std::runtime_error(messagePrefix + noScalar); + } + return pvStructure->getSubField("value"); } PVArrayPtr PvaClientData::getArrayValue() { if(PvaClient::getDebug()) cout << "PvaClientData::getArrayValue\n"; checkValue(); - PVArrayPtr pv = pvStructure->getSubField("value"); - if(!pv) throw std::runtime_error(messagePrefix + noArray); - return pv; + Type type = pvValue->getField()->getType(); + if(type!=scalarArray && type!=structureArray && type!=unionArray) { + throw std::runtime_error(messagePrefix + noArray); + } + return pvStructure->getSubField("value"); } PVScalarArrayPtr PvaClientData::getScalarArrayValue() { if(PvaClient::getDebug()) cout << "PvaClientData::getScalarArrayValue\n"; 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; + Type type = pvValue->getField()->getType(); + if(type!=scalarArray) { + throw std::runtime_error(messagePrefix + noScalarArray); + } + return pvStructure->getSubField("value"); } double PvaClientData::getDouble() { if(PvaClient::getDebug()) cout << "PvaClientData::getDouble\n"; - PVScalarPtr pvScalar = getScalarValue(); + PVScalarPtr pvScalar; + PVStructurePtr pvStructure = getPVStructure(); + PVFieldPtr pvValue = pvStructure->getSubField("value"); + if(pvValue) { + Type type = pvValue->getField()->getType(); + if(type==scalar) pvScalar = static_pointer_cast(pvValue); + } + if(!pvScalar) { + while(true) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()!=1) { + throw std::logic_error( + "PvaClientData::getDouble() pvRequest for multiple fields"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + Type type = pvField->getField()->getType(); + if(type==scalar) { + pvScalar = static_pointer_cast(pvField); + break; + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; + pvStructure = static_pointer_cast(pvField); + } + } + if(!pvScalar) { + throw std::logic_error( + "PvaClientData::getDouble() did not find a scalar field"); + } 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); + throw std::logic_error( + "PvaClientData::getDouble() did not find a numeric scalar field"); } return convert->toDouble(pvScalar); } @@ -243,30 +214,119 @@ double PvaClientData::getDouble() string PvaClientData::getString() { if(PvaClient::getDebug()) cout << "PvaClientData::getString\n"; - PVScalarPtr pvScalar = getScalarValue(); + PVScalarPtr pvScalar; + PVStructurePtr pvStructure = getPVStructure(); + PVFieldPtr pvValue = pvStructure->getSubField("value"); + if(pvValue) { + Type type = pvValue->getField()->getType(); + if(type==scalar) pvScalar = static_pointer_cast(pvValue); + } + if(!pvScalar) { + while(true) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()!=1) { + throw std::logic_error( + "PvaClientData::getString() pvRequest for multiple fields"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + Type type = pvField->getField()->getType(); + if(type==scalar) { + pvScalar = static_pointer_cast(pvField); + break; + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; + pvStructure = static_pointer_cast(pvField); + } + } + if(!pvScalar) { + throw std::logic_error( + "PvaClientData::getString() did not find a scalar field"); + } return convert->toString(pvScalar); } shared_vector PvaClientData::getDoubleArray() { if(PvaClient::getDebug()) cout << "PvaClientData::getDoubleArray\n"; - PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); - if(pvScalarArray->getScalarArray()->getElementType()!=pvDouble) { - throw std::runtime_error(messagePrefix + notDoubleArray); + PVDoubleArrayPtr pvDoubleArray; + PVStructurePtr pvStructure = getPVStructure(); + PVFieldPtr pvValue = pvStructure->getSubField("value"); + if(pvValue) { + Type type = pvValue->getField()->getType(); + if(type==scalarArray) { + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvValue); + if(pvScalarArray->getScalarArray()->getElementType()==pvDouble) { + pvDoubleArray = static_pointer_cast(pvValue); + } + } } - PVDoubleArrayPtr pv = static_pointer_cast(pvScalarArray); - return pv->view(); + if(!pvDoubleArray) { + while(true) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()!=1) { + throw std::logic_error( + "PvaClientData::getDoubleArray() pvRequest for multiple fields"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + Type type = pvField->getField()->getType(); + if(type==scalarArray) { + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); + if(pvScalarArray->getScalarArray()->getElementType()==pvDouble) { + pvDoubleArray = static_pointer_cast(pvField); + break; + } + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; + pvStructure = static_pointer_cast(pvField); + } + } + if(!pvDoubleArray) { + throw std::logic_error( + "PvaClientData::getDoubleArray() did not find a scalar field"); + } + return pvDoubleArray->view(); } shared_vector PvaClientData::getStringArray() { if(PvaClient::getDebug()) cout << "PvaClientData::getStringArray\n"; - PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); - if(pvScalarArray->getScalarArray()->getElementType()!=pvString) { - throw std::runtime_error(messagePrefix + notStringArray); + PVStringArrayPtr pvStringArray; + PVStructurePtr pvStructure = getPVStructure(); + PVFieldPtr pvValue = pvStructure->getSubField("value"); + if(pvValue) { + Type type = pvValue->getField()->getType(); + if(type==scalarArray) { + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvValue); + if(pvScalarArray->getScalarArray()->getElementType()==pvString) { + pvStringArray = static_pointer_cast(pvValue); + } + } } - PVStringArrayPtr pv = static_pointer_cast(pvScalarArray); - return pv->view(); + if(!pvStringArray) { + while(true) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()!=1) { + throw std::logic_error( + "PvaClientData::getStringArray() pvRequest for multiple fields"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + Type type = pvField->getField()->getType(); + if(type==scalarArray) { + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); + if(pvScalarArray->getScalarArray()->getElementType()==pvString) { + pvStringArray = static_pointer_cast(pvField); + break; + } + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; + pvStructure = static_pointer_cast(pvField); + } + } + if(!pvStringArray) { + throw std::logic_error( + "PvaClientData::getStringArray() did not find a scalar field"); + } + return pvStringArray->view(); } diff --git a/src/pvaClientPutData.cpp b/src/pvaClientPutData.cpp index 5598529..4a71cbb 100644 --- a/src/pvaClientPutData.cpp +++ b/src/pvaClientPutData.cpp @@ -74,7 +74,34 @@ PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure) void PvaClientPutData::putDouble(double value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putDouble\n"; - PVScalarPtr pvScalar = getScalarValue(); + PVScalarPtr pvScalar; + PVStructurePtr pvStructure = getPVStructure(); + PVFieldPtr pvValue = pvStructure->getSubField("value"); + if(pvValue) { + Type type = pvValue->getField()->getType(); + if(type==scalar) pvScalar = static_pointer_cast(pvValue); + } + if(!pvScalar) { + while(true) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()!=1) { + throw std::logic_error( + "PvaClientData::putDouble() pvRequest for multiple fields"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + Type type = pvField->getField()->getType(); + if(type==scalar) { + pvScalar = static_pointer_cast(pvField); + break; + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; + pvStructure = static_pointer_cast(pvField); + } + } + if(!pvScalar) { + throw std::logic_error( + "PvaClientData::putDouble() did not find a scalar field"); + } ScalarType scalarType = pvScalar->getScalar()->getScalarType(); if(scalarType==pvDouble) { PVDoublePtr pvDouble = static_pointer_cast(pvScalar); @@ -82,7 +109,8 @@ void PvaClientPutData::putDouble(double value) return; } if(!ScalarTypeFunc::isNumeric(scalarType)) { - throw std::runtime_error(messagePrefix + notCompatibleScalar); + throw std::logic_error( + "PvaClientData::putDouble() did not find a numeric scalar field"); } convert->fromDouble(pvScalar,value); } @@ -90,36 +118,152 @@ void PvaClientPutData::putDouble(double value) void PvaClientPutData::putString(std::string const & value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putString\n"; - PVScalarPtr pvScalar = getScalarValue(); + PVScalarPtr pvScalar; + PVStructurePtr pvStructure = getPVStructure(); + PVFieldPtr pvValue = pvStructure->getSubField("value"); + if(pvValue) { + Type type = pvValue->getField()->getType(); + if(type==scalar) pvScalar = static_pointer_cast(pvValue); + } + if(!pvScalar) { + while(true) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()!=1) { + throw std::logic_error( + "PvaClientData::putString() pvRequest for multiple fields"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + Type type = pvField->getField()->getType(); + if(type==scalar) { + pvScalar = static_pointer_cast(pvField); + break; + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; + pvStructure = static_pointer_cast(pvField); + } + } + if(!pvScalar) { + throw std::logic_error( + "PvaClientData::putString() did not find a scalar field"); + } convert->fromString(pvScalar,value); } void PvaClientPutData::putDoubleArray(shared_vector const & value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\n"; - PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); - if(pvScalarArray->getScalarArray()->getElementType()!=pvDouble) { - throw std::runtime_error(messagePrefix + notDoubleArray); + PVDoubleArrayPtr pvDoubleArray; + PVStructurePtr pvStructure = getPVStructure(); + PVFieldPtr pvValue = pvStructure->getSubField("value"); + if(pvValue) { + Type type = pvValue->getField()->getType(); + if(type==scalarArray) { + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvValue); + if(pvScalarArray->getScalarArray()->getElementType()==pvDouble) { + pvDoubleArray = static_pointer_cast(pvValue); + } + } } - PVDoubleArrayPtr pv = static_pointer_cast(pvScalarArray); - pv->replace(value); + if(!pvDoubleArray) { + while(true) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()!=1) { + throw std::logic_error( + "PvaClientData::putDoubleArray() pvRequest for multiple fields"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + Type type = pvField->getField()->getType(); + if(type==scalarArray) { + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); + if(pvScalarArray->getScalarArray()->getElementType()==pvDouble) { + pvDoubleArray = static_pointer_cast(pvField); + break; + } + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; + pvStructure = static_pointer_cast(pvField); + } + } + if(!pvDoubleArray) { + throw std::logic_error( + "PvaClientData::putDoubleArray() did not find a scalar field"); + } + pvDoubleArray->replace(value); } void PvaClientPutData::putStringArray(shared_vector const & value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n"; - PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); - if(pvScalarArray->getScalarArray()->getElementType()!=pvString) { - throw std::runtime_error(messagePrefix + notStringArray); + PVStringArrayPtr pvStringArray; + PVStructurePtr pvStructure = getPVStructure(); + PVFieldPtr pvValue = pvStructure->getSubField("value"); + if(pvValue) { + Type type = pvValue->getField()->getType(); + if(type==scalarArray) { + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvValue); + if(pvScalarArray->getScalarArray()->getElementType()==pvString) { + pvStringArray = static_pointer_cast(pvValue); + } + } } - PVStringArrayPtr pv = static_pointer_cast(pvScalarArray); - pv->replace(value); + if(!pvStringArray) { + while(true) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()!=1) { + throw std::logic_error( + "PvaClientData::getStringArray() pvRequest for multiple fields"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + Type type = pvField->getField()->getType(); + if(type==scalarArray) { + PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); + if(pvScalarArray->getScalarArray()->getElementType()==pvString) { + pvStringArray = static_pointer_cast(pvField); + break; + } + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; + pvStructure = static_pointer_cast(pvField); + } + } + if(!pvStringArray) { + throw std::logic_error( + "PvaClientData::getStringArray() did not find a scalar field"); + } + pvStringArray->replace(value); } void PvaClientPutData::putStringArray(std::vector const & value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n"; - PVScalarArrayPtr pvScalarArray = getScalarArrayValue(); + PVScalarArrayPtr pvScalarArray; + PVStructurePtr pvStructure = getPVStructure(); + PVFieldPtr pvValue = pvStructure->getSubField("value"); + if(pvValue) { + Type type = pvValue->getField()->getType(); + if(type==scalarArray) pvScalarArray = static_pointer_cast(pvValue); + } + if(!pvScalarArray) { + while(true) { + const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); + if(fieldPtrArray.size()!=1) { + throw std::logic_error( + "PvaClientData::getStringArray() pvRequest for multiple fields"); + } + PVFieldPtr pvField(fieldPtrArray[0]); + Type type = pvField->getField()->getType(); + if(type==scalarArray) { + pvScalarArray = static_pointer_cast(pvField); + break; + } + if(pvField->getField()->getType()!=epics::pvData::structure) break; + pvStructure = static_pointer_cast(pvField); + } + } + if(!pvScalarArray) { + throw std::logic_error( + "PvaClientData::getStringArray() did not find a scalar field"); + } convert->fromStringArray(pvScalarArray,0,value.size(),value,0); } From 522a0509458c720d73febf81d8ba32ec6fbdb896 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Sun, 7 Apr 2019 14:34:56 -0400 Subject: [PATCH 06/12] add double and string methods to pvaClientChannel --- src/pv/pvaClient.h | 70 +++++++++++++++++++++++++++++++++++++++- src/pvaClientChannel.cpp | 58 +++++++++++++++++++++++++++++++++ src/pvaClientData.cpp | 4 +-- src/pvaClientPutData.cpp | 6 ++-- 4 files changed, 132 insertions(+), 6 deletions(-) diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index ff439e0..0f8a7f2 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -313,11 +313,42 @@ public: PvaClientGetPtr createGet(std::string const & request = "field(value,alarm,timeStamp)"); /** @brief Creates an PvaClientGet. * - * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. + * @param pvRequest The syntax of request is defined by the copy facility of pvData. + * @return The interface. * @return The interface. * @throw runtime_error if failure. */ PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest); + /** @brief Get the value as a double. + * + * @param request The syntax of request is defined by the copy facility of pvData. + * @return The value. + * @throw runtime_error if failure. + */ + double getDouble(std::string const & request = "field(value)"); + /** Get the value as a string. + * + * @param request The syntax of request is defined by the copy facility of pvData. + * @return The value. + * @throw runtime_error if failure. + */ + std::string getString(std::string const & request = "field(value)"); + /** @brief Get the value as a double array. + * + * @param request The syntax of request is defined by the copy facility of pvData. + * @return The value. + * @throw runtime_error if failure. + */ + epics::pvData::shared_vector getDoubleArray( + std::string const & request = "field(value)"); + /** @brief Get the value as a string array. + * + * @param request The syntax of request is defined by the copy facility of pvData. + * @return The value. + * @throw runtime_error if failure. + */ + epics::pvData::shared_vector getStringArray( + std::string const & request = "field(value)"); /** @brief create a PvaClientPut. * * Get a cached PvaClientPut or create and connect to a new PvaClientPut. @@ -341,6 +372,43 @@ public: * @return The interface. */ PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest); + /** @brief Put the value as a double. + * + * @param value The new value. + * @param request The syntax of request is defined by the copy facility of pvData. + * @throw runtime_error if failure. + */ + void putDouble(double value,std::string const & request = "field(value)"); + /** @brief Put the value as a string. + * + * @param value The new value. + * @param request The syntax of request is defined by the copy facility of pvData. + * @throw runtime_error if failure. + */ + void putString(std::string const & value,std::string const & request = "field(value)"); + /** @brief Copy the array to the value field. + * + * @param value The new value. + * @param request The syntax of request is defined by the copy facility of pvData. + * @throw runtime_error if failure. + */ + void putDoubleArray( + epics::pvData::shared_vector const & value, + std::string const & request = "field(value)"); + /** @brief Copy array to the value field. + * + * @param value The new value. + * @param request The syntax of request is defined by the copy facility of pvData. + * @throw runtime_error if failure. + */ + void putStringArray( + epics::pvData::shared_vector const & value, + std::string const & request = "field(value)"); + /** @brief Copy array to the value field. + * @param value data source + * @throw runtime_error if failure. + */ + void putStringArray(std::vector const & value,std::string const & request = "field(value)"); /** @brief create a PvaClientPutGet. * * First call createRequest as implemented by pvDataJava and then calls the next method. diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index e6c9f09..2ee538e 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -380,6 +380,26 @@ PvaClientGetPtr PvaClientChannel::createGet(PVStructurePtr const & pvRequest) return PvaClientGet::create(yyy,shared_from_this(),pvRequest); } +double PvaClientChannel::getDouble(string const & request) +{ + return get(request)->getData()->getDouble(); +} + +string PvaClientChannel::getString(string const & request) +{ + return get(request)->getData()->getString(); +} + +shared_vector PvaClientChannel::getDoubleArray(string const & request) +{ + return get(request)->getData()->getDoubleArray(); +} + +shared_vector PvaClientChannel::getStringArray(string const & request) +{ + return get(request)->getData()->getStringArray(); +} + PvaClientPutPtr PvaClientChannel::put(string const & request) { @@ -415,6 +435,44 @@ PvaClientPutPtr PvaClientChannel::createPut(PVStructurePtr const & pvRequest) return PvaClientPut::create(yyy,shared_from_this(),pvRequest); } +void PvaClientChannel::putDouble(double value,string const & request) +{ + PvaClientPutPtr clientPut = put(request); + PvaClientPutDataPtr putData = clientPut->getData(); + putData->putDouble(value); clientPut->put(); +} + +void PvaClientChannel::putString(std::string const & value,string const & request) +{ + PvaClientPutPtr clientPut = put(request); + PvaClientPutDataPtr putData = clientPut->getData(); + putData->putString(value); clientPut->put(); +} + +void PvaClientChannel::putDoubleArray( + shared_vector const & value, + string const & request) +{ + PvaClientPutPtr clientPut = put(request); + PvaClientPutDataPtr putData = clientPut->getData(); + size_t n = value.size(); + shared_vector valueArray(n); + for(size_t i=0; iputDoubleArray(freeze(valueArray)); clientPut->put(); +} + +void PvaClientChannel::putStringArray( + shared_vector const & value, + string const & request) +{ + PvaClientPutPtr clientPut = put(request); + PvaClientPutDataPtr putData = clientPut->getData(); + size_t n = value.size(); + shared_vector valueArray(n); + for(size_t i=0; iputStringArray(freeze(valueArray)); clientPut->put(); +} + PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp index 0f3d50c..7f14e5a 100644 --- a/src/pvaClientData.cpp +++ b/src/pvaClientData.cpp @@ -282,7 +282,7 @@ shared_vector PvaClientData::getDoubleArray() } if(!pvDoubleArray) { throw std::logic_error( - "PvaClientData::getDoubleArray() did not find a scalar field"); + "PvaClientData::getDoubleArray() did not find a scalarArray field"); } return pvDoubleArray->view(); } @@ -324,7 +324,7 @@ shared_vector PvaClientData::getStringArray() } if(!pvStringArray) { throw std::logic_error( - "PvaClientData::getStringArray() did not find a scalar field"); + "PvaClientData::getStringArray() did not find a scalarArray field"); } return pvStringArray->view(); } diff --git a/src/pvaClientPutData.cpp b/src/pvaClientPutData.cpp index 4a71cbb..8698622 100644 --- a/src/pvaClientPutData.cpp +++ b/src/pvaClientPutData.cpp @@ -186,7 +186,7 @@ void PvaClientPutData::putDoubleArray(shared_vector const & value) } if(!pvDoubleArray) { throw std::logic_error( - "PvaClientData::putDoubleArray() did not find a scalar field"); + "PvaClientData::putDoubleArray() did not find a scalarArray field"); } pvDoubleArray->replace(value); } @@ -228,7 +228,7 @@ void PvaClientPutData::putStringArray(shared_vector const & v } if(!pvStringArray) { throw std::logic_error( - "PvaClientData::getStringArray() did not find a scalar field"); + "PvaClientData::getStringArray() did not find a scalarArray field"); } pvStringArray->replace(value); } @@ -262,7 +262,7 @@ void PvaClientPutData::putStringArray(std::vector const & value) } if(!pvScalarArray) { throw std::logic_error( - "PvaClientData::getStringArray() did not find a scalar field"); + "PvaClientData::getStringArray() did not find a scalarArray field"); } convert->fromStringArray(pvScalarArray,0,value.size(),value,0); } From 00103f820742ea67155a59e717909434d44afec0 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Mon, 8 Apr 2019 14:11:27 -0400 Subject: [PATCH 07/12] getStringArray and putStringArray support all numeric array types --- src/pvaClientData.cpp | 18 ++++++------- src/pvaClientPutData.cpp | 57 +++++++++++----------------------------- 2 files changed, 23 insertions(+), 52 deletions(-) diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp index 7f14e5a..8cb06e7 100644 --- a/src/pvaClientData.cpp +++ b/src/pvaClientData.cpp @@ -290,19 +290,16 @@ shared_vector PvaClientData::getDoubleArray() shared_vector PvaClientData::getStringArray() { if(PvaClient::getDebug()) cout << "PvaClientData::getStringArray\n"; - PVStringArrayPtr pvStringArray; + PVScalarArrayPtr pvScalarArray; PVStructurePtr pvStructure = getPVStructure(); PVFieldPtr pvValue = pvStructure->getSubField("value"); if(pvValue) { Type type = pvValue->getField()->getType(); if(type==scalarArray) { - PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvValue); - if(pvScalarArray->getScalarArray()->getElementType()==pvString) { - pvStringArray = static_pointer_cast(pvValue); - } + pvScalarArray = static_pointer_cast(pvValue); } } - if(!pvStringArray) { + if(!pvScalarArray) { while(true) { const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); if(fieldPtrArray.size()!=1) { @@ -314,7 +311,7 @@ shared_vector PvaClientData::getStringArray() if(type==scalarArray) { PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); if(pvScalarArray->getScalarArray()->getElementType()==pvString) { - pvStringArray = static_pointer_cast(pvField); + pvScalarArray = static_pointer_cast(pvField); break; } } @@ -322,14 +319,15 @@ shared_vector PvaClientData::getStringArray() pvStructure = static_pointer_cast(pvField); } } - if(!pvStringArray) { + if(!pvScalarArray) { throw std::logic_error( "PvaClientData::getStringArray() did not find a scalarArray field"); } - return pvStringArray->view(); + shared_vector retValue; + pvScalarArray->getAs(retValue); + return retValue; } - Alarm PvaClientData::getAlarm() { if(PvaClient::getDebug()) cout << "PvaClientData::getAlarm\n"; diff --git a/src/pvaClientPutData.cpp b/src/pvaClientPutData.cpp index 8698622..e1fe8ce 100644 --- a/src/pvaClientPutData.cpp +++ b/src/pvaClientPutData.cpp @@ -194,31 +194,28 @@ void PvaClientPutData::putDoubleArray(shared_vector const & value) void PvaClientPutData::putStringArray(shared_vector const & value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n"; - PVStringArrayPtr pvStringArray; + PVScalarArrayPtr pvScalarArray; PVStructurePtr pvStructure = getPVStructure(); PVFieldPtr pvValue = pvStructure->getSubField("value"); if(pvValue) { Type type = pvValue->getField()->getType(); if(type==scalarArray) { - PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvValue); - if(pvScalarArray->getScalarArray()->getElementType()==pvString) { - pvStringArray = static_pointer_cast(pvValue); - } + pvScalarArray = static_pointer_cast(pvValue); } } - if(!pvStringArray) { + if(!pvScalarArray) { while(true) { const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); if(fieldPtrArray.size()!=1) { throw std::logic_error( - "PvaClientData::getStringArray() pvRequest for multiple fields"); + "PvaClientData::putStringArray() pvRequest for multiple fields"); } PVFieldPtr pvField(fieldPtrArray[0]); Type type = pvField->getField()->getType(); if(type==scalarArray) { PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); if(pvScalarArray->getScalarArray()->getElementType()==pvString) { - pvStringArray = static_pointer_cast(pvField); + pvScalarArray = static_pointer_cast(pvField); break; } } @@ -226,45 +223,21 @@ void PvaClientPutData::putStringArray(shared_vector const & v pvStructure = static_pointer_cast(pvField); } } - if(!pvStringArray) { + if(!pvScalarArray) { throw std::logic_error( - "PvaClientData::getStringArray() did not find a scalarArray field"); + "PvaClientData::putStringArray() did not find a scalarArray field"); } - pvStringArray->replace(value); + pvScalarArray->putFrom(value); + return; } -void PvaClientPutData::putStringArray(std::vector const & value) +void PvaClientPutData::putStringArray(std::vector const & value) { - if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n"; - PVScalarArrayPtr pvScalarArray; - PVStructurePtr pvStructure = getPVStructure(); - PVFieldPtr pvValue = pvStructure->getSubField("value"); - if(pvValue) { - Type type = pvValue->getField()->getType(); - if(type==scalarArray) pvScalarArray = static_pointer_cast(pvValue); - } - if(!pvScalarArray) { - while(true) { - const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); - if(fieldPtrArray.size()!=1) { - throw std::logic_error( - "PvaClientData::getStringArray() pvRequest for multiple fields"); - } - PVFieldPtr pvField(fieldPtrArray[0]); - Type type = pvField->getField()->getType(); - if(type==scalarArray) { - pvScalarArray = static_pointer_cast(pvField); - break; - } - if(pvField->getField()->getType()!=epics::pvData::structure) break; - pvStructure = static_pointer_cast(pvField); - } - } - if(!pvScalarArray) { - throw std::logic_error( - "PvaClientData::getStringArray() did not find a scalarArray field"); - } - convert->fromStringArray(pvScalarArray,0,value.size(),value,0); + size_t length = value.size(); + shared_vector val(length); + for(size_t i=0; i < length; ++i) val[i] = value[i]; + putStringArray(freeze(val)); + return; } void PvaClientPutData::postPut(size_t fieldNumber) From 0bb17d5b09605678e9241221f2a3677215202853 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Mon, 8 Apr 2019 14:23:58 -0400 Subject: [PATCH 08/12] make them work if not top level value field --- src/pvaClientData.cpp | 7 ++----- src/pvaClientPutData.cpp | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp index 8cb06e7..8178397 100644 --- a/src/pvaClientData.cpp +++ b/src/pvaClientData.cpp @@ -309,11 +309,8 @@ shared_vector PvaClientData::getStringArray() PVFieldPtr pvField(fieldPtrArray[0]); Type type = pvField->getField()->getType(); if(type==scalarArray) { - PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); - if(pvScalarArray->getScalarArray()->getElementType()==pvString) { - pvScalarArray = static_pointer_cast(pvField); - break; - } + pvScalarArray = static_pointer_cast(pvField); + break; } if(pvField->getField()->getType()!=epics::pvData::structure) break; pvStructure = static_pointer_cast(pvField); diff --git a/src/pvaClientPutData.cpp b/src/pvaClientPutData.cpp index e1fe8ce..a0d3cc1 100644 --- a/src/pvaClientPutData.cpp +++ b/src/pvaClientPutData.cpp @@ -213,11 +213,8 @@ void PvaClientPutData::putStringArray(shared_vector const & v PVFieldPtr pvField(fieldPtrArray[0]); Type type = pvField->getField()->getType(); if(type==scalarArray) { - PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); - if(pvScalarArray->getScalarArray()->getElementType()==pvString) { - pvScalarArray = static_pointer_cast(pvField); - break; - } + pvScalarArray = static_pointer_cast(pvField); + break; } if(pvField->getField()->getType()!=epics::pvData::structure) break; pvStructure = static_pointer_cast(pvField); From fb6f4355f38a590e061b992c8ecfdfbe6589ce7f Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Tue, 9 Apr 2019 06:19:14 -0400 Subject: [PATCH 09/12] getDoubleArray and putDoubleArray now work for all numeric scalar arrays --- src/pvaClientData.cpp | 25 +++++++++++++------------ src/pvaClientPutData.cpp | 23 +++++++++++------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp index 8178397..129b4cb 100644 --- a/src/pvaClientData.cpp +++ b/src/pvaClientData.cpp @@ -248,19 +248,16 @@ string PvaClientData::getString() shared_vector PvaClientData::getDoubleArray() { if(PvaClient::getDebug()) cout << "PvaClientData::getDoubleArray\n"; - PVDoubleArrayPtr pvDoubleArray; + PVScalarArrayPtr pvScalarArray; PVStructurePtr pvStructure = getPVStructure(); PVFieldPtr pvValue = pvStructure->getSubField("value"); if(pvValue) { Type type = pvValue->getField()->getType(); if(type==scalarArray) { PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvValue); - if(pvScalarArray->getScalarArray()->getElementType()==pvDouble) { - pvDoubleArray = static_pointer_cast(pvValue); - } } } - if(!pvDoubleArray) { + if(!pvScalarArray) { while(true) { const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); if(fieldPtrArray.size()!=1) { @@ -270,21 +267,25 @@ shared_vector PvaClientData::getDoubleArray() PVFieldPtr pvField(fieldPtrArray[0]); Type type = pvField->getField()->getType(); if(type==scalarArray) { - PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); - if(pvScalarArray->getScalarArray()->getElementType()==pvDouble) { - pvDoubleArray = static_pointer_cast(pvField); - break; - } + pvScalarArray = static_pointer_cast(pvField); + break; } if(pvField->getField()->getType()!=epics::pvData::structure) break; pvStructure = static_pointer_cast(pvField); } } - if(!pvDoubleArray) { + if(!pvScalarArray) { throw std::logic_error( "PvaClientData::getDoubleArray() did not find a scalarArray field"); } - return pvDoubleArray->view(); + ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType(); + if(!ScalarTypeFunc::isNumeric(scalarType)) { + throw std::logic_error( + "PvaClientData::getDoubleArray() did not find a numeric scalarArray field"); + } + shared_vector retValue; + pvScalarArray->getAs(retValue); + return retValue; } shared_vector PvaClientData::getStringArray() diff --git a/src/pvaClientPutData.cpp b/src/pvaClientPutData.cpp index a0d3cc1..e1cf019 100644 --- a/src/pvaClientPutData.cpp +++ b/src/pvaClientPutData.cpp @@ -152,19 +152,16 @@ void PvaClientPutData::putString(std::string const & value) void PvaClientPutData::putDoubleArray(shared_vector const & value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\n"; - PVDoubleArrayPtr pvDoubleArray; + PVScalarArrayPtr pvScalarArray; PVStructurePtr pvStructure = getPVStructure(); PVFieldPtr pvValue = pvStructure->getSubField("value"); if(pvValue) { Type type = pvValue->getField()->getType(); if(type==scalarArray) { - PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvValue); - if(pvScalarArray->getScalarArray()->getElementType()==pvDouble) { - pvDoubleArray = static_pointer_cast(pvValue); - } + pvScalarArray = static_pointer_cast(pvValue); } } - if(!pvDoubleArray) { + if(!pvScalarArray) { while(true) { const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); if(fieldPtrArray.size()!=1) { @@ -175,20 +172,22 @@ void PvaClientPutData::putDoubleArray(shared_vector const & value) Type type = pvField->getField()->getType(); if(type==scalarArray) { PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); - if(pvScalarArray->getScalarArray()->getElementType()==pvDouble) { - pvDoubleArray = static_pointer_cast(pvField); - break; - } + break; } if(pvField->getField()->getType()!=epics::pvData::structure) break; pvStructure = static_pointer_cast(pvField); } } - if(!pvDoubleArray) { + if(!pvScalarArray) { throw std::logic_error( "PvaClientData::putDoubleArray() did not find a scalarArray field"); } - pvDoubleArray->replace(value); + ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType(); + if(!ScalarTypeFunc::isNumeric(scalarType)) { + throw std::logic_error( + "PvaClientData::putDoubleArray() did not find a numeric scalarArray field"); + } + pvScalarArray->putFrom(value); } void PvaClientPutData::putStringArray(shared_vector const & value) From 150ac45de3660d041c1989f23c4910e99c92a203 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Tue, 9 Apr 2019 11:15:00 -0400 Subject: [PATCH 10/12] bug in pvaClientData; fix doxygen warning; update doc --- documentation/pvaClientCPP.html | 4 ++-- src/pv/pvaClient.h | 3 ++- src/pvaClientData.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/documentation/pvaClientCPP.html b/documentation/pvaClientCPP.html index 0279af3..68fe4c2 100644 --- a/documentation/pvaClientCPP.html +++ b/documentation/pvaClientCPP.html @@ -26,7 +26,7 @@

EPICS pvaClientCPP

-

Release 4.4 - December 2018

+

Release 4.4 - April 2019

Abstract

@@ -79,7 +79,7 @@ It is intended for developers that want to use pvaClientCPP.

Developer Guide

A guide for developers is available at +href="https://mrkraimer.github.io/website/developerGuide/developerGuide.html"> developerGuide

diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 0f8a7f2..123aa23 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -405,7 +405,8 @@ public: epics::pvData::shared_vector const & value, std::string const & request = "field(value)"); /** @brief Copy array to the value field. - * @param value data source + * @param value The data used to update the channel value. + * @param request The request as a string to pass to createRequest. * @throw runtime_error if failure. */ void putStringArray(std::vector const & value,std::string const & request = "field(value)"); diff --git a/src/pvaClientData.cpp b/src/pvaClientData.cpp index 129b4cb..5db266d 100644 --- a/src/pvaClientData.cpp +++ b/src/pvaClientData.cpp @@ -254,7 +254,7 @@ shared_vector PvaClientData::getDoubleArray() if(pvValue) { Type type = pvValue->getField()->getType(); if(type==scalarArray) { - PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvValue); + pvScalarArray = static_pointer_cast(pvValue); } } if(!pvScalarArray) { From 440c8fa496460ff0cb07d933be0c8294cbe844ab Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 11 Apr 2019 14:11:03 -0400 Subject: [PATCH 11/12] update RELEASE_NOTES --- documentation/RELEASE_NOTES.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 4792c7d..9203f41 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -2,6 +2,27 @@ This document summarizes the changes to the module between releases. +## release (EPICS 7.0.2.2 April 2019) + +Changes have been made for getDouble, putDouble, getDoubleArray, putDoubleArray, getString, putString, getStringArray, and putStringArray. + +1) Previously each only had support for a top level field named value. +Each now allows access to a single sub field that has the correct type. +Thus pvRequest must select a single field. For example + pva->channel("PVRdumbPowerSupply")->putDouble(1.0,"power.value" ); + +2) PvaChannel now has a method for each of the above. +For example instead of + PvaClientChannelPtr channel = pva->channel("PVRdouble"); + PvaClientPutPtr clientPut = channel->put(); + PvaClientPutDataPtr putData = clientPut->getData(); + putData->putDouble(1.0); clientPut->put(); +now it can be + pva->channel("PVRdouble")->putDouble(1.0 ); + +3) getDoubleArray and putDoubleArray work with any numeric scalar array + +4) getStringArray and putStringArray work with any scalar array. ## Release 4.4 (EPICS 7.0.2, Dec 2018) From 365a0b846f3454f242d2cdb29f202f6d53426686 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 11 Apr 2019 14:13:53 -0400 Subject: [PATCH 12/12] update RELEASE_NOTES --- documentation/RELEASE_NOTES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 9203f41..26bb62b 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -9,15 +9,19 @@ Changes have been made for getDouble, putDouble, getDoubleArray, putDoubleArray, 1) Previously each only had support for a top level field named value. Each now allows access to a single sub field that has the correct type. Thus pvRequest must select a single field. For example + pva->channel("PVRdumbPowerSupply")->putDouble(1.0,"power.value" ); 2) PvaChannel now has a method for each of the above. For example instead of + PvaClientChannelPtr channel = pva->channel("PVRdouble"); PvaClientPutPtr clientPut = channel->put(); PvaClientPutDataPtr putData = clientPut->getData(); putData->putDouble(1.0); clientPut->put(); + now it can be + pva->channel("PVRdouble")->putDouble(1.0 ); 3) getDoubleArray and putDoubleArray work with any numeric scalar array