From 333cd44da042020bf8bff953ddc36c47eaa80448 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Sat, 20 Mar 2021 10:48:08 -0400 Subject: [PATCH] The following were made to all special pvdbcr modules 1) Much cleaner implementation. 2) pvdbSpecialRegister.dbd is new --- src/Makefile | 5 - src/pv/pvdbcrAddRecord.h | 63 ------ src/pv/pvdbcrProcessRecord.h | 89 --------- src/pv/pvdbcrRemoveRecord.h | 63 ------ src/pv/pvdbcrTraceRecord.h | 66 ------ src/special/Makefile | 5 +- src/special/pvdbSpecialRegister.dbd | 6 + src/special/pvdbcrAddRecord.cpp | 116 ----------- src/special/pvdbcrAddRecordRegister.cpp | 145 ++++++++++++-- src/special/pvdbcrProcessRecord.cpp | 166 ---------------- src/special/pvdbcrProcessRecordRegister.cpp | 210 +++++++++++++++++--- src/special/pvdbcrRemoveRecord.cpp | 92 --------- src/special/pvdbcrRemoveRecordRegister.cpp | 120 +++++++++-- src/special/pvdbcrScalarArrayRegister.cpp | 64 +++--- src/special/pvdbcrScalarRegister.cpp | 71 +++---- src/special/pvdbcrTraceRecord.cpp | 95 --------- src/special/pvdbcrTraceRecordRegister.cpp | 129 +++++++++--- 17 files changed, 577 insertions(+), 928 deletions(-) delete mode 100644 src/pv/pvdbcrAddRecord.h delete mode 100644 src/pv/pvdbcrProcessRecord.h delete mode 100644 src/pv/pvdbcrRemoveRecord.h delete mode 100644 src/pv/pvdbcrTraceRecord.h create mode 100644 src/special/pvdbSpecialRegister.dbd delete mode 100644 src/special/pvdbcrAddRecord.cpp delete mode 100644 src/special/pvdbcrProcessRecord.cpp delete mode 100644 src/special/pvdbcrRemoveRecord.cpp delete mode 100644 src/special/pvdbcrTraceRecord.cpp diff --git a/src/Makefile b/src/Makefile index a6def5b..d40399f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -28,11 +28,6 @@ INC += pv/removeRecord.h INC += pv/addRecord.h INC += pv/processRecord.h -INC += pv/pvdbcrTraceRecord.h -INC += pv/pvdbcrRemoveRecord.h -INC += pv/pvdbcrAddRecord.h -INC += pv/pvdbcrProcessRecord.h - INC += pv/pvSupport.h INC += pv/controlSupport.h INC += pv/scalarAlarmSupport.h diff --git a/src/pv/pvdbcrAddRecord.h b/src/pv/pvdbcrAddRecord.h deleted file mode 100644 index 8e7cbd7..0000000 --- a/src/pv/pvdbcrAddRecord.h +++ /dev/null @@ -1,63 +0,0 @@ -/* PvdbcrAddRecord.h */ -/** - * 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 2021.03.12 - */ -#ifndef PVDBCRADDRECORD_H -#define PVDBCRADDRECORD_H - -#include - -#include - -namespace epics { namespace pvDatabase { - - -class PvdbcrAddRecord; -typedef std::tr1::shared_ptr PvdbcrAddRecordPtr; - -/** - * @brief Add another record in the same database. - * - * A record to add another record - * It is meant to be used via a channelPutGet request. - * The argument has one field: recordName. - * The result has a field named status. - */ -class epicsShareClass PvdbcrAddRecord : - public PVRecord -{ -public: - POINTER_DEFINITIONS(PvdbcrAddRecord); - /** - * Factory methods to create PvdbcrAddRecord. - * @param recordName The name for the PvdbcrAddRecord. - * @return A shared pointer to PvdbcrAddRecord. - */ - static PvdbcrAddRecordPtr create( - std::string const & recordName); - /** - * standard init method required by PVRecord - * @return true unless record name already exists. - */ - virtual bool init(); - /** - * @brief Add the record specified by recordName. - */ - virtual void process(); -private: - PvdbcrAddRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure); - epics::pvData::PVStringPtr pvRecordName; - epics::pvData::PVStringPtr pvResult; -}; - -}} - -#endif /* PVDBCRADDRECORD_H */ diff --git a/src/pv/pvdbcrProcessRecord.h b/src/pv/pvdbcrProcessRecord.h deleted file mode 100644 index c87ee6a..0000000 --- a/src/pv/pvdbcrProcessRecord.h +++ /dev/null @@ -1,89 +0,0 @@ -/* PvdbcrProcessRecord.h */ -/** - * 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 2021.03.12 - */ -#ifndef PVDBCRPROCESSRECORD_H -#define PVDBCRPROCESSRECORD_H - -#include -#include -#include -#include - -#include - -namespace epics { namespace pvDatabase { - -typedef std::tr1::shared_ptr EpicsThreadPtr; - -class PvdbcrProcessRecord; -typedef std::tr1::shared_ptr PvdbcrProcessRecordPtr; - -/** - * @brief Process another record in the same database. - * - * A record to process another record - * It is meant to be used via a channelPutGet request. - * The argument has one field: recordName. - * The result has a field named status. - */ -class epicsShareClass PvdbcrProcessRecord : - public PVRecord, - public epicsThreadRunable -{ -public: - POINTER_DEFINITIONS(PvdbcrProcessRecord); - /** - * Factory methods to create ProcessRecord. - * @param recordName The name for the ProcessRecord. - * @param delay Delay time to wait between process requests. - * @return A shared pointer to ProcessRecord. - */ - static PvdbcrProcessRecordPtr create( - std::string const & recordName,double delay); - /** - * standard init method required by PVRecord - * @return true unless record name already exists. - */ - virtual bool init(); - /** - * @brief Process the record specified by recordName. - */ - virtual void process(); - /** - * @brief The run method for the thread. - */ - virtual void run(); - /** - * @brief Start the thread - */ - void startThread(); - /** - * @brief Stop the thread - */ - void stop(); -private: - PvdbcrProcessRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure,double delay); - double delay; - EpicsThreadPtr thread; - epics::pvData::Event runStop; - epics::pvData::Event runReturn; - PVDatabasePtr pvDatabase; - PVRecordMap pvRecordMap; - epics::pvData::PVStringPtr pvCommand; - epics::pvData::PVStringPtr pvRecordName; - epics::pvData::PVStringPtr pvResult; - epics::pvData::Mutex mutex; -}; - -}} - -#endif /* PVDBCRPROCESSRECORD_H */ diff --git a/src/pv/pvdbcrRemoveRecord.h b/src/pv/pvdbcrRemoveRecord.h deleted file mode 100644 index 166edeb..0000000 --- a/src/pv/pvdbcrRemoveRecord.h +++ /dev/null @@ -1,63 +0,0 @@ -/* PvdbcrRemoveRecord.h */ -/** - * 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 2021.03.12 - */ -#ifndef PVDBCRREMOVERECORD_H -#define PVDBCRREMOVERECORD_H - -#include - -#include - -namespace epics { namespace pvDatabase { - - -class PvdbcrRemoveRecord; -typedef std::tr1::shared_ptr PvdbcrRemoveRecordPtr; - -/** - * @brief Remove another record in the same database. - * - * A record to remove another record - * It is meant to be used via a channelPutGet request. - * The argument has one field: recordName. - * The result has a field named status. - */ -class epicsShareClass PvdbcrRemoveRecord : - public PVRecord -{ -public: - POINTER_DEFINITIONS(PvdbcrRemoveRecord); - /** - * Factory methods to create PvdbcrRemoveRecord. - * @param recordName The name for the PvdbcrRemoveRecord. - * @return A shared pointer to PvdbcrRemoveRecord.. - */ - static PvdbcrRemoveRecordPtr create( - std::string const & recordName); - /** - * standard init method required by PVRecord - * @return true unless record name already exists. - */ - virtual bool init(); - /** - * @brief Remove the record specified by recordName. - */ - virtual void process(); -private: - PvdbcrRemoveRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure); - epics::pvData::PVStringPtr pvRecordName; - epics::pvData::PVStringPtr pvResult; -}; - -}} - -#endif /* PVDBCRREMOVERECORD_H */ diff --git a/src/pv/pvdbcrTraceRecord.h b/src/pv/pvdbcrTraceRecord.h deleted file mode 100644 index 38eccdd..0000000 --- a/src/pv/pvdbcrTraceRecord.h +++ /dev/null @@ -1,66 +0,0 @@ -/* PvdbcrTraceRecord.h */ -/** - * 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 2021.03.12 - */ -#ifndef PVDBCRTRACERECORD_H -#define PVDBCRTRACERECORD_H - -#include - -#include - - -namespace epics { namespace pvDatabase { - - -class PvdbcrTraceRecord; -typedef std::tr1::shared_ptr PvdbcrTraceRecordPtr; - -/** - * @brief Trace activity of PVRecord. - * - * A record to set the trace value for another record - * It is meant to be used via a channelPutGet request. - * The argument has two fields: recordName and level. - * The result has a field named status. - */ -class epicsShareClass PvdbcrTraceRecord : - public PVRecord -{ -public: - POINTER_DEFINITIONS(PvdbcrTraceRecord); - /** - * @brief Factory method to create PvdbcrTraceRecord. - * - * @param recordName The name for the PvdbcrTraceRecord. - * @return A shared pointer to PvdbcrTraceRecord. - */ - static PvdbcrTraceRecordPtr create( - std::string const & recordName); - /** - * standard init method required by PVRecord - * @return true unless record name already exists. - */ - virtual bool init(); - /** - * @brief Set the trace level for record specified by recordName. - */ - virtual void process(); -private: - PvdbcrTraceRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure); - epics::pvData::PVStringPtr pvRecordName; - epics::pvData::PVIntPtr pvLevel; - epics::pvData::PVStringPtr pvResult; -}; - -}} - -#endif /* PVDBCRTRACERECORD_H */ diff --git a/src/special/Makefile b/src/special/Makefile index b8b419d..15061da 100644 --- a/src/special/Makefile +++ b/src/special/Makefile @@ -2,10 +2,6 @@ SRC_DIRS += $(PVDATABASE_SRC)/special -LIBSRCS += pvdbcrTraceRecord.cpp -LIBSRCS += pvdbcrRemoveRecord.cpp -LIBSRCS += pvdbcrAddRecord.cpp -LIBSRCS += pvdbcrProcessRecord.cpp DBD += pvdbcrTraceRecordRegister.dbd DBD += pvdbcrRemoveRecordRegister.dbd @@ -13,6 +9,7 @@ DBD += pvdbcrAddRecordRegister.dbd DBD += pvdbcrProcessRecordRegister.dbd DBD += pvdbcrScalarRegister.dbd DBD += pvdbcrScalarArrayRegister.dbd +DBD += pvdbSpecialRegister.dbd LIBSRCS += pvdbcrTraceRecordRegister.cpp LIBSRCS += pvdbcrRemoveRecordRegister.cpp diff --git a/src/special/pvdbSpecialRegister.dbd b/src/special/pvdbSpecialRegister.dbd new file mode 100644 index 0000000..eb36e2e --- /dev/null +++ b/src/special/pvdbSpecialRegister.dbd @@ -0,0 +1,6 @@ +include "pvdbcrAddRecordRegister.dbd" +include "pvdbcrRemoveRecordRegister.dbd" +include "pvdbcrProcessRecordRegister.dbd" +include "pvdbcrTraceRecordRegister.dbd" +include "pvdbcrScalarRegister.dbd" +include "pvdbcrScalarArrayRegister.dbd" diff --git a/src/special/pvdbcrAddRecord.cpp b/src/special/pvdbcrAddRecord.cpp deleted file mode 100644 index 35c9073..0000000 --- a/src/special/pvdbcrAddRecord.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* pvdbcrAddRecord.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 2021.03.12 - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/pvDatabase.h" -#include "pv/pvdbcrAddRecord.h" - -using std::tr1::static_pointer_cast; -using namespace epics::pvData; -using namespace epics::pvAccess; -using namespace std; - -namespace epics { namespace pvDatabase { -PvdbcrAddRecordPtr PvdbcrAddRecord::create( - std::string const & recordName) -{ - FieldCreatePtr fieldCreate = getFieldCreate(); - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> - addNestedStructure("argument")-> - add("recordName",pvString)-> - addNestedUnion("union") -> - endNested()-> - endNested()-> - addNestedStructure("result") -> - add("status",pvString) -> - endNested()-> - createStructure(); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); - PvdbcrAddRecordPtr pvRecord( - new PvdbcrAddRecord(recordName,pvStructure)); - if(!pvRecord->init()) pvRecord.reset(); - return pvRecord; -} - -PvdbcrAddRecord::PvdbcrAddRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure) -: PVRecord(recordName,pvStructure) -{ -} - -bool PvdbcrAddRecord::init() -{ - initPVRecord(); - PVStructurePtr pvStructure = getPVStructure(); - pvRecordName = pvStructure->getSubField("argument.recordName"); - if(!pvRecordName) return false; - pvResult = pvStructure->getSubField("result.status"); - if(!pvResult) return false; - return true; -} - -void PvdbcrAddRecord::process() -{ - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - string name = pvRecordName->get(); - PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); - if(pvRecord) { - pvResult->put(name + " already exists"); - return; - } - PVUnionPtr pvUnion = getPVStructure()->getSubField("argument.union"); - if(!pvUnion) { - pvResult->put(name + " argument.union is NULL"); - return; - } - PVFieldPtr pvField(pvUnion->get()); - if(!pvField) { - pvResult->put(name + " union has no value"); - return; - } - if(pvField->getField()->getType()!=epics::pvData::structure) { - pvResult->put(name + " union most be a structure"); - return; - } - StructureConstPtr st = static_pointer_cast(pvField->getField()); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(st); - PVRecordPtr pvRec = PVRecord::create(name,pvStructure); - bool result = PVDatabase::getMaster()->addRecord(pvRec); - if(result) { - pvResult->put("success"); - } else { - pvResult->put("failure"); - } -} - - -}} diff --git a/src/special/pvdbcrAddRecordRegister.cpp b/src/special/pvdbcrAddRecordRegister.cpp index ee79897..ae18beb 100644 --- a/src/special/pvdbcrAddRecordRegister.cpp +++ b/src/special/pvdbcrAddRecordRegister.cpp @@ -7,47 +7,148 @@ * @author mrk * @date 2021.03.12 */ - - -/* Author: Marty Kraimer */ -#include #include -#include -#include -#include -#include +#include +#include +#include #include -#include +#include +#include +#include +#include -// The following must be the last include for code pvDatabase uses +// The following must be the last include for code exampleLink uses #include #define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/pvDatabase.h" -#include "pv/pvdbcrAddRecord.h" using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::pvDatabase; +using namespace epics::pvaClient; using namespace std; -static const iocshArg testArg0 = { "recordName", iocshArgString }; -static const iocshArg testArg1 = { "asLevel", iocshArgInt }; -static const iocshArg *testArgs[] = {&testArg0,&testArg1}; +class PvdbcrAddRecord; +typedef std::tr1::shared_ptr PvdbcrAddRecordPtr; -static const iocshFuncDef pvdbcrAddRecordFuncDef = {"pvdbcrAddRecord", 2,testArgs}; + +class epicsShareClass PvdbcrAddRecord : + public PVRecord +{ +private: + PvdbcrAddRecord( + std::string const & recordName, + epics::pvData::PVStructurePtr const & pvStructure); + PVStringPtr pvRecordName; + epics::pvData::PVStringPtr pvResult; +public: + POINTER_DEFINITIONS(PvdbcrAddRecord); + + static PvdbcrAddRecordPtr create( + std::string const & recordName); + virtual bool init(); + virtual void process(); +}; + +PvdbcrAddRecordPtr PvdbcrAddRecord::create( + std::string const & recordName) +{ + FieldCreatePtr fieldCreate = getFieldCreate(); + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> + addNestedStructure("argument")-> + add("recordName",pvString)-> + addNestedUnion("union") -> + endNested()-> + endNested()-> + addNestedStructure("result") -> + add("status",pvString) -> + endNested()-> + createStructure(); + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); + PvdbcrAddRecordPtr pvRecord( + new PvdbcrAddRecord(recordName,pvStructure)); + if(!pvRecord->init()) pvRecord.reset(); + return pvRecord; +} + +PvdbcrAddRecord::PvdbcrAddRecord( + std::string const & recordName, + PVStructurePtr const & pvStructure) +: PVRecord(recordName,pvStructure) +{ +} + +bool PvdbcrAddRecord::init() +{ + initPVRecord(); + PVStructurePtr pvStructure = getPVStructure(); + pvRecordName = pvStructure->getSubField("argument.recordName"); + if(!pvRecordName) return false; + pvResult = pvStructure->getSubField("result.status"); + if(!pvResult) return false; + return true; +} + +void PvdbcrAddRecord::process() +{ + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + string name = pvRecordName->get(); + PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); + if(pvRecord) { + pvResult->put(name + " already exists"); + return; + } + PVUnionPtr pvUnion = getPVStructure()->getSubField("argument.union"); + if(!pvUnion) { + pvResult->put(name + " argument.union is NULL"); + return; + } + PVFieldPtr pvField(pvUnion->get()); + if(!pvField) { + pvResult->put(name + " union has no value"); + return; + } + if(pvField->getField()->getType()!=epics::pvData::structure) { + pvResult->put(name + " union most be a structure"); + return; + } + StructureConstPtr st = static_pointer_cast(pvField->getField()); + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(st); + PVRecordPtr pvRec = PVRecord::create(name,pvStructure); + bool result = PVDatabase::getMaster()->addRecord(pvRec); + if(result) { + pvResult->put("success"); + } else { + pvResult->put("failure"); + } +} + +static const iocshArg arg0 = { "recordName", iocshArgString }; +static const iocshArg arg1 = { "asLevel", iocshArgInt }; +static const iocshArg arg2 = { "asGroup", iocshArgString }; +static const iocshArg *args[] = {&arg0,&arg1,&arg2}; + +static const iocshFuncDef pvdbcrAddRecordFuncDef = {"pvdbcrAddRecord", 3,args}; static void pvdbcrAddRecordCallFunc(const iocshArgBuf *args) { - char *recordName = args[0].sval; - if(!recordName) { - throw std::runtime_error("pvdbcrAddRecord invalid number of arguments"); + char *sval = args[0].sval; + if(!sval) { + throw std::runtime_error("pvdbcrAddRecord recordName not specified"); } + string recordName = string(sval); int asLevel = args[1].ival; + string asGroup("DEFAULT"); + sval = args[2].sval; + if(sval) { + asGroup = string(sval); + } PvdbcrAddRecordPtr record = PvdbcrAddRecord::create(recordName); record->setAsLevel(asLevel); - bool result = PVDatabase::getMaster()->addRecord(record); - if(!result) cout << "recordname" << " not added" << endl; + record->setAsGroup(asGroup); + PVDatabasePtr master = PVDatabase::getMaster(); + bool result = master->addRecord(record); + if(!result) cout << "recordname " << recordName << " not added" << endl; } static void pvdbcrAddRecordRegister(void) diff --git a/src/special/pvdbcrProcessRecord.cpp b/src/special/pvdbcrProcessRecord.cpp deleted file mode 100644 index 7e6f78b..0000000 --- a/src/special/pvdbcrProcessRecord.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* pvdbcrProcessRecord.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 2021.03.12 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/pvDatabase.h" -#include "pv/pvdbcrProcessRecord.h" - -using std::tr1::static_pointer_cast; -using namespace epics::pvData; -using namespace epics::pvAccess; -using namespace std; - -namespace epics { namespace pvDatabase { - -PvdbcrProcessRecordPtr PvdbcrProcessRecord::create( - std::string const & recordName,double delay) -{ - FieldCreatePtr fieldCreate = getFieldCreate(); - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> - addNestedStructure("argument")-> - add("command",pvString)-> - add("recordName",pvString)-> - endNested()-> - addNestedStructure("result") -> - add("status",pvString) -> - endNested()-> - createStructure(); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); - PvdbcrProcessRecordPtr pvRecord( - new PvdbcrProcessRecord(recordName,pvStructure,delay)); - if(!pvRecord->init()) pvRecord.reset(); - return pvRecord; -} - -void PvdbcrProcessRecord::startThread() -{ - thread = EpicsThreadPtr(new epicsThread( - *this, - "processRecord", - epicsThreadGetStackSize(epicsThreadStackSmall), - epicsThreadPriorityLow)); - thread->start(); -} - -void PvdbcrProcessRecord::stop() -{ - runStop.signal(); - runReturn.wait(); -} - - -PvdbcrProcessRecord::PvdbcrProcessRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure,double delay) -: PVRecord(recordName,pvStructure), - delay(delay), - pvDatabase(PVDatabase::getMaster()) -{ -} - -bool PvdbcrProcessRecord::init() -{ - initPVRecord(); - PVStructurePtr pvStructure = getPVStructure(); - pvCommand = pvStructure->getSubField("argument.command"); - pvRecordName = pvStructure->getSubField("argument.recordName"); - if(!pvRecordName) return false; - pvResult = pvStructure->getSubField("result.status"); - if(!pvResult) return false; - startThread(); - return true; -} - -void PvdbcrProcessRecord::process() -{ - string recordName = pvRecordName->get(); - string command = pvCommand->get(); - if(command.compare("add")==0) { - epicsGuard guard(mutex); - std::map::iterator iter = pvRecordMap.find(recordName); - if(iter!=pvRecordMap.end()) { - pvResult->put(recordName + " already present"); - return; - } - PVRecordPtr pvRecord = pvDatabase->findRecord(recordName); - if(!pvRecord) { - pvResult->put(recordName + " not in pvDatabase"); - return; - } - pvRecordMap.insert(PVRecordMap::value_type(recordName,pvRecord)); - pvResult->put("success"); - return; - } else if(command.compare("remove")==0) { - epicsGuard guard(mutex); - std::map::iterator iter = pvRecordMap.find(recordName); - if(iter==pvRecordMap.end()) { - pvResult->put(recordName + " not found"); - return; - } - pvRecordMap.erase(iter); - pvResult->put("success"); - return; - } else { - pvResult->put(command + " not a valid command: only add and remove are valid"); - return; - } -} - -void PvdbcrProcessRecord::run() -{ - while(true) { - if(runStop.tryWait()) { - runReturn.signal(); - return; - } - if(delay>0.0) epicsThreadSleep(delay); - epicsGuard guard(mutex); - PVRecordMap::iterator iter; - for(iter = pvRecordMap.begin(); iter!=pvRecordMap.end(); ++iter) { - PVRecordPtr pvRecord = (*iter).second; - pvRecord->lock(); - pvRecord->beginGroupPut(); - try { - pvRecord->process(); - } catch (std::exception& ex) { - std::cout << "record " << pvRecord->getRecordName() << "exception " << ex.what() << "\n"; - } catch (...) { - std::cout<< "record " << pvRecord->getRecordName() << " process exception\n"; - } - pvRecord->endGroupPut(); - pvRecord->unlock(); - } - } -} - - -}} diff --git a/src/special/pvdbcrProcessRecordRegister.cpp b/src/special/pvdbcrProcessRecordRegister.cpp index bc0228b..f029fd8 100644 --- a/src/special/pvdbcrProcessRecordRegister.cpp +++ b/src/special/pvdbcrProcessRecordRegister.cpp @@ -7,52 +7,212 @@ * @author mrk * @date 2021.03.12 */ - - -/* Author: Marty Kraimer */ - #include -#include #include -#include -#include -#include +#include +#include +#include +#include #include -#include +#include +#include +#include +#include -// The following must be the last include for code pvDatabase uses +// The following must be the last include for code exampleLink uses #include #define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/pvDatabase.h" -#include "pv/pvdbcrProcessRecord.h" - using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::pvDatabase; +using namespace epics::pvaClient; using namespace std; -static const iocshArg testArg0 = { "recordName", iocshArgString }; -static const iocshArg testArg1 = { "delay", iocshArgDouble }; -static const iocshArg testArg2 = { "asLevel", iocshArgInt }; -static const iocshArg *testArgs[] = {&testArg0,&testArg1,&testArg2}; +typedef std::tr1::shared_ptr EpicsThreadPtr; +class PvdbcrProcessRecord; +typedef std::tr1::shared_ptr PvdbcrProcessRecordPtr; -static const iocshFuncDef pvdbcrProcessRecordFuncDef = {"pvdbcrProcessRecord", 3,testArgs}; +class epicsShareClass PvdbcrProcessRecord : + public PVRecord, + public epicsThreadRunable +{ +public: + POINTER_DEFINITIONS(PvdbcrProcessRecord); + static PvdbcrProcessRecordPtr create( + std::string const & recordName,double delay); + virtual bool init(); + virtual void process(); + virtual void run(); + void startThread(); + void stop(); +private: + PvdbcrProcessRecord( + std::string const & recordName, + epics::pvData::PVStructurePtr const & pvStructure,double delay); + double delay; + EpicsThreadPtr thread; + epics::pvData::Event runStop; + epics::pvData::Event runReturn; + PVDatabasePtr pvDatabase; + PVRecordMap pvRecordMap; + epics::pvData::PVStringPtr pvCommand; + epics::pvData::PVStringPtr pvRecordName; + epics::pvData::PVStringPtr pvResult; + epics::pvData::Mutex mutex; +}; + +PvdbcrProcessRecordPtr PvdbcrProcessRecord::create( + std::string const & recordName,double delay) +{ + FieldCreatePtr fieldCreate = getFieldCreate(); + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> + addNestedStructure("argument")-> + add("command",pvString)-> + add("recordName",pvString)-> + endNested()-> + addNestedStructure("result") -> + add("status",pvString) -> + endNested()-> + createStructure(); + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); + PvdbcrProcessRecordPtr pvRecord( + new PvdbcrProcessRecord(recordName,pvStructure,delay)); + if(!pvRecord->init()) pvRecord.reset(); + return pvRecord; +} + +void PvdbcrProcessRecord::startThread() +{ + thread = EpicsThreadPtr(new epicsThread( + *this, + "processRecord", + epicsThreadGetStackSize(epicsThreadStackSmall), + epicsThreadPriorityLow)); + thread->start(); +} + +void PvdbcrProcessRecord::stop() +{ + runStop.signal(); + runReturn.wait(); +} + + +PvdbcrProcessRecord::PvdbcrProcessRecord( + std::string const & recordName, + epics::pvData::PVStructurePtr const & pvStructure,double delay) +: PVRecord(recordName,pvStructure), + delay(delay), + pvDatabase(PVDatabase::getMaster()) +{ +} + +bool PvdbcrProcessRecord::init() +{ + initPVRecord(); + PVStructurePtr pvStructure = getPVStructure(); + pvCommand = pvStructure->getSubField("argument.command"); + pvRecordName = pvStructure->getSubField("argument.recordName"); + if(!pvRecordName) return false; + pvResult = pvStructure->getSubField("result.status"); + if(!pvResult) return false; + startThread(); + return true; +} + +void PvdbcrProcessRecord::process() +{ + string recordName = pvRecordName->get(); + string command = pvCommand->get(); + if(command.compare("add")==0) { + epicsGuard guard(mutex); + std::map::iterator iter = pvRecordMap.find(recordName); + if(iter!=pvRecordMap.end()) { + pvResult->put(recordName + " already present"); + return; + } + PVRecordPtr pvRecord = pvDatabase->findRecord(recordName); + if(!pvRecord) { + pvResult->put(recordName + " not in pvDatabase"); + return; + } + pvRecordMap.insert(PVRecordMap::value_type(recordName,pvRecord)); + pvResult->put("success"); + return; + } else if(command.compare("remove")==0) { + epicsGuard guard(mutex); + std::map::iterator iter = pvRecordMap.find(recordName); + if(iter==pvRecordMap.end()) { + pvResult->put(recordName + " not found"); + return; + } + pvRecordMap.erase(iter); + pvResult->put("success"); + return; + } else { + pvResult->put(command + " not a valid command: only add and remove are valid"); + return; + } +} + +void PvdbcrProcessRecord::run() +{ + while(true) { + if(runStop.tryWait()) { + runReturn.signal(); + return; + } + if(delay>0.0) epicsThreadSleep(delay); + epicsGuard guard(mutex); + PVRecordMap::iterator iter; + for(iter = pvRecordMap.begin(); iter!=pvRecordMap.end(); ++iter) { + PVRecordPtr pvRecord = (*iter).second; + pvRecord->lock(); + pvRecord->beginGroupPut(); + try { + pvRecord->process(); + } catch (std::exception& ex) { + std::cout << "record " << pvRecord->getRecordName() << "exception " << ex.what() << "\n"; + } catch (...) { + std::cout<< "record " << pvRecord->getRecordName() << " process exception\n"; + } + pvRecord->endGroupPut(); + pvRecord->unlock(); + } + } +} + +static const iocshArg arg0 = { "recordName", iocshArgString }; +static const iocshArg arg1 = { "delay", iocshArgDouble }; +static const iocshArg arg2 = { "asLevel", iocshArgInt }; +static const iocshArg arg3 = { "asGroup", iocshArgString }; +static const iocshArg *args[] = {&arg0,&arg1,&arg2,&arg3}; + +static const iocshFuncDef pvdbcrProcessRecordFuncDef = {"pvdbcrProcessRecord", 4,args}; static void pvdbcrProcessRecordCallFunc(const iocshArgBuf *args) { - char *recordName = args[0].sval; - if(!recordName) { - throw std::runtime_error("pvdbcrProcessRecordCreate invalid number of arguments"); + char *sval = args[0].sval; + if(!sval) { + throw std::runtime_error("pvdbcrProcessRecord recordName not specified"); } + string recordName = string(sval); double delay = args[1].dval; - int asLevel = args[2].ival; if(delay<0.0) delay = 1.0; + int asLevel = args[2].ival; + string asGroup("DEFAULT"); + sval = args[3].sval; + if(sval) { + asGroup = string(sval); + } PvdbcrProcessRecordPtr record = PvdbcrProcessRecord::create(recordName,delay); record->setAsLevel(asLevel); - bool result = PVDatabase::getMaster()->addRecord(record); - if(!result) cout << "recordname" << " not added" << endl; + record->setAsGroup(asGroup); + PVDatabasePtr master = PVDatabase::getMaster(); + bool result = master->addRecord(record); + if(!result) cout << "recordname " << recordName << " not added" << endl; } static void pvdbcrProcessRecordRegister(void) diff --git a/src/special/pvdbcrRemoveRecord.cpp b/src/special/pvdbcrRemoveRecord.cpp deleted file mode 100644 index 726a537..0000000 --- a/src/special/pvdbcrRemoveRecord.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* pvdbcrRemoveRecord.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 2021.03.12 - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/pvDatabase.h" -#include "pv/pvdbcrRemoveRecord.h" - -using std::tr1::static_pointer_cast; -using namespace epics::pvData; -using namespace epics::pvAccess; -using namespace std; - -namespace epics { namespace pvDatabase { - -PvdbcrRemoveRecordPtr PvdbcrRemoveRecord::create( - std::string const & recordName) -{ - FieldCreatePtr fieldCreate = getFieldCreate(); - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> - addNestedStructure("argument")-> - add("recordName",pvString)-> - endNested()-> - addNestedStructure("result") -> - add("status",pvString) -> - endNested()-> - createStructure(); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); - PvdbcrRemoveRecordPtr pvRecord( - new PvdbcrRemoveRecord(recordName,pvStructure)); - if(!pvRecord->init()) pvRecord.reset(); - return pvRecord; -} - -PvdbcrRemoveRecord::PvdbcrRemoveRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure) -: PVRecord(recordName,pvStructure) -{ -} - -bool PvdbcrRemoveRecord::init() -{ - initPVRecord(); - PVStructurePtr pvStructure = getPVStructure(); - pvRecordName = pvStructure->getSubField("argument.recordName"); - if(!pvRecordName) return false; - pvResult = pvStructure->getSubField("result.status"); - if(!pvResult) return false; - return true; -} - -void PvdbcrRemoveRecord::process() -{ - string name = pvRecordName->get(); - PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); - if(!pvRecord) { - pvResult->put(name + " not found"); - return; - } - pvRecord->remove(); - pvResult->put("success"); -} - - -}} diff --git a/src/special/pvdbcrRemoveRecordRegister.cpp b/src/special/pvdbcrRemoveRecordRegister.cpp index fbbde3e..477cb51 100644 --- a/src/special/pvdbcrRemoveRecordRegister.cpp +++ b/src/special/pvdbcrRemoveRecordRegister.cpp @@ -7,47 +7,123 @@ * @author mrk * @date 2021.03.12 */ - - -/* Author: Marty Kraimer */ -#include #include -#include -#include -#include -#include +#include +#include +#include #include -#include +#include +#include +#include +#include -// The following must be the last include for code pvDatabase uses +// The following must be the last include for code exampleLink uses #include #define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/pvDatabase.h" -#include "pv/pvdbcrRemoveRecord.h" using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::pvDatabase; +using namespace epics::pvaClient; using namespace std; -static const iocshArg testArg0 = { "recordName", iocshArgString }; -static const iocshArg testArg1 = { "asLevel", iocshArgInt }; -static const iocshArg *testArgs[] = {&testArg0,&testArg1}; +class PvdbcrRemoveRecord; +typedef std::tr1::shared_ptr PvdbcrRemoveRecordPtr; -static const iocshFuncDef pvdbcrRemoveRecordFuncDef = {"pvdbcrRemoveRecord", 2,testArgs}; + +class epicsShareClass PvdbcrRemoveRecord : + public PVRecord +{ +public: + POINTER_DEFINITIONS(PvdbcrRemoveRecord); + static PvdbcrRemoveRecordPtr create( + std::string const & recordName); + virtual bool init(); + virtual void process(); +private: + PvdbcrRemoveRecord( + std::string const & recordName, + epics::pvData::PVStructurePtr const & pvStructure); + epics::pvData::PVStringPtr pvRecordName; + epics::pvData::PVStringPtr pvResult; +}; + +PvdbcrRemoveRecordPtr PvdbcrRemoveRecord::create( + std::string const & recordName) +{ + FieldCreatePtr fieldCreate = getFieldCreate(); + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> + addNestedStructure("argument")-> + add("recordName",pvString)-> + endNested()-> + addNestedStructure("result") -> + add("status",pvString) -> + endNested()-> + createStructure(); + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); + PvdbcrRemoveRecordPtr pvRecord( + new PvdbcrRemoveRecord(recordName,pvStructure)); + if(!pvRecord->init()) pvRecord.reset(); + return pvRecord; +} + +PvdbcrRemoveRecord::PvdbcrRemoveRecord( + std::string const & recordName, + epics::pvData::PVStructurePtr const & pvStructure) +: PVRecord(recordName,pvStructure) +{ +} + +bool PvdbcrRemoveRecord::init() +{ + initPVRecord(); + PVStructurePtr pvStructure = getPVStructure(); + pvRecordName = pvStructure->getSubField("argument.recordName"); + if(!pvRecordName) return false; + pvResult = pvStructure->getSubField("result.status"); + if(!pvResult) return false; + return true; +} + +void PvdbcrRemoveRecord::process() +{ + string name = pvRecordName->get(); + PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); + if(!pvRecord) { + pvResult->put(name + " not found"); + return; + } + pvRecord->remove(); + pvResult->put("success"); +} + +static const iocshArg arg0 = { "recordName", iocshArgString }; +static const iocshArg arg1 = { "asLevel", iocshArgInt }; +static const iocshArg arg2 = { "asGroup", iocshArgString }; +static const iocshArg *args[] = {&arg0,&arg1,&arg2}; + +static const iocshFuncDef pvdbcrRemoveRecordFuncDef = {"pvdbcrRemoveRecord", 3,args}; static void pvdbcrRemoveRecordCallFunc(const iocshArgBuf *args) { - char *recordName = args[0].sval; - if(!recordName) { - throw std::runtime_error("pvdbcrRemoveRecordCreate invalid number of arguments"); + char *sval = args[0].sval; + if(!sval) { + throw std::runtime_error("pvdbcrRemoveRecord recordName not specified"); } + string recordName = string(sval); int asLevel = args[1].ival; + string asGroup("DEFAULT"); + sval = args[2].sval; + if(sval) { + asGroup = string(sval); + } PvdbcrRemoveRecordPtr record = PvdbcrRemoveRecord::create(recordName); record->setAsLevel(asLevel); - bool result = PVDatabase::getMaster()->addRecord(record); - if(!result) cout << "recordname" << " not added" << endl; + record->setAsGroup(asGroup); + PVDatabasePtr master = PVDatabase::getMaster(); + bool result = master->addRecord(record); + if(!result) cout << "recordname " << recordName << " not added" << endl; } static void pvdbcrRemoveRecordRegister(void) diff --git a/src/special/pvdbcrScalarArrayRegister.cpp b/src/special/pvdbcrScalarArrayRegister.cpp index 7b564a8..5e0a3da 100644 --- a/src/special/pvdbcrScalarArrayRegister.cpp +++ b/src/special/pvdbcrScalarArrayRegister.cpp @@ -10,35 +10,24 @@ /* Author: Marty Kraimer */ - -#include #include -#include -#include -#include -#include -#include -#include -#include - -// The following must be the last include for code pvDatabase uses +#include +#include +// The following must be the last include for code exampleLink uses #include #define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/pvDatabase.h" using namespace epics::pvData; -using namespace epics::nt; -using namespace epics::pvAccess; using namespace epics::pvDatabase; using namespace std; -static const iocshArg testArg0 = { "recordName", iocshArgString }; -static const iocshArg testArg1 = { "scalarType", iocshArgString }; -static const iocshArg testArg2 = { "asLevel", iocshArgInt }; -static const iocshArg *testArgs[] = {&testArg0,&testArg1,&testArg2}; +static const iocshArg arg0 = { "recordName", iocshArgString }; +static const iocshArg arg1 = { "scalarType", iocshArgString }; +static const iocshArg arg2 = { "asLevel", iocshArgInt }; +static const iocshArg arg3 = { "asGroup", iocshArgString }; +static const iocshArg *args[] = {&arg0,&arg1,&arg2,&arg3}; -static const iocshFuncDef pvdbcrScalarArrayFuncDef = {"pvdbcrScalarArray", 3,testArgs}; +static const iocshFuncDef pvdbcrScalarArrayFuncDef = {"pvdbcrScalarArray", 4,args}; static void pvdbcrScalarArrayCallFunc(const iocshArgBuf *args) { @@ -53,22 +42,27 @@ static void pvdbcrScalarArrayCallFunc(const iocshArgBuf *args) } string scalarType = string(sval); int asLevel = args[2].ival; - try { - ScalarType st = epics::pvData::ScalarTypeFunc::getScalarType(scalarType); - NTScalarArrayBuilderPtr ntScalarArrayBuilder = NTScalarArray::createBuilder(); - PVStructurePtr pvStructure = ntScalarArrayBuilder-> - value(st)-> - addAlarm()-> - addTimeStamp()-> - createPVStructure(); - PVRecordPtr record = PVRecord::create(recordName,pvStructure); - record->setAsLevel(asLevel); - PVDatabasePtr master = PVDatabase::getMaster(); - bool result = master->addRecord(record); - if(!result) cout << "recordname " << recordName << " not added" << endl; - } catch(std::exception& ex) { - cerr << "failure " << ex.what() << "/n"; + string asGroup("DEFAULT"); + sval = args[3].sval; + if(sval) { + asGroup = string(sval); } + ScalarType st = epics::pvData::ScalarTypeFunc::getScalarType(scalarType); + FieldCreatePtr fieldCreate = getFieldCreate(); + StandardFieldPtr standardField = getStandardField(); + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + StructureConstPtr top = fieldCreate->createFieldBuilder()-> + addArray("value",st) -> + add("timeStamp",standardField->timeStamp()) -> + add("alarm",standardField->alarm()) -> + createStructure(); + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(top); + PVRecordPtr record = PVRecord::create(recordName,pvStructure); + record->setAsLevel(asLevel); + record->setAsGroup(asGroup); + PVDatabasePtr master = PVDatabase::getMaster(); + bool result = master->addRecord(record); + if(!result) cout << "recordname " << recordName << " not added" << endl; } static void pvdbcrScalarArrayRegister(void) diff --git a/src/special/pvdbcrScalarRegister.cpp b/src/special/pvdbcrScalarRegister.cpp index e44a777..c6688cc 100644 --- a/src/special/pvdbcrScalarRegister.cpp +++ b/src/special/pvdbcrScalarRegister.cpp @@ -7,68 +7,59 @@ * @author mrk * @date 2021.03.12 */ - - -/* Author: Marty Kraimer */ - -#include #include -#include -#include -#include -#include -#include -#include -#include - -// The following must be the last include for code pvDatabase uses +#include +#include +// The following must be the last include for code exampleLink uses #include #define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/pvDatabase.h" using namespace epics::pvData; -using namespace epics::nt; -using namespace epics::pvAccess; using namespace epics::pvDatabase; using namespace std; -static const iocshArg testArg0 = { "recordName", iocshArgString }; -static const iocshArg testArg1 = { "scalarType", iocshArgString }; -static const iocshArg testArg2 = { "asLevel", iocshArgInt }; -static const iocshArg *testArgs[] = {&testArg0,&testArg1,&testArg2}; +static const iocshArg arg0 = { "recordName", iocshArgString }; +static const iocshArg arg1 = { "scalarType", iocshArgString }; +static const iocshArg arg2 = { "asLevel", iocshArgInt }; +static const iocshArg arg3 = { "asGroup", iocshArgString }; +static const iocshArg *args[] = {&arg0,&arg1,&arg2,&arg3}; -static const iocshFuncDef pvdbcrScalarFuncDef = {"pvdbcrScalar", 3,testArgs}; +static const iocshFuncDef pvdbcrScalarFuncDef = {"pvdbcrScalar", 4,args}; static void pvdbcrScalarCallFunc(const iocshArgBuf *args) { char *sval = args[0].sval; if(!sval) { - throw std::runtime_error("pvdbcrScalarCreate recordName not specified"); + throw std::runtime_error("pvdbcrScalarArrayCreate recordName not specified"); } string recordName = string(sval); sval = args[1].sval; if(!sval) { - throw std::runtime_error("pvdbcrScalarCreate scalarType not specified"); + throw std::runtime_error("pvdbcrScalarArrayCreate scalarType not specified"); } string scalarType = string(sval); int asLevel = args[2].ival; - try { - ScalarType st = epics::pvData::ScalarTypeFunc::getScalarType(scalarType); - NTScalarBuilderPtr ntScalarBuilder = NTScalar::createBuilder(); - PVStructurePtr pvStructure = ntScalarBuilder-> - value(st)-> - addAlarm()-> - addTimeStamp()-> - createPVStructure(); - PVRecordPtr record = PVRecord::create(recordName,pvStructure); - record->setAsLevel(asLevel); - PVDatabasePtr master = PVDatabase::getMaster(); - bool result = master->addRecord(record); - if(!result) cout << "recordname " << recordName << " not added" << endl; - } catch(std::exception& ex) { - cerr << "failure " << ex.what() << "/n"; + string asGroup("DEFAULT"); + sval = args[3].sval; + if(sval) { + asGroup = string(sval); } + ScalarType st = epics::pvData::ScalarTypeFunc::getScalarType(scalarType); + FieldCreatePtr fieldCreate = getFieldCreate(); + StandardFieldPtr standardField = getStandardField(); + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + StructureConstPtr top = fieldCreate->createFieldBuilder()-> + add("value",st) -> + add("timeStamp",standardField->timeStamp()) -> + add("alarm",standardField->alarm()) -> + createStructure(); + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(top); + PVRecordPtr record = PVRecord::create(recordName,pvStructure); + record->setAsLevel(asLevel); + record->setAsGroup(asGroup); + PVDatabasePtr master = PVDatabase::getMaster(); + bool result = master->addRecord(record); + if(!result) cout << "recordname " << recordName << " not added" << endl; } static void pvdbcrScalarRegister(void) diff --git a/src/special/pvdbcrTraceRecord.cpp b/src/special/pvdbcrTraceRecord.cpp deleted file mode 100644 index e0a481a..0000000 --- a/src/special/pvdbcrTraceRecord.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* pvdbcrTraceRecord.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 2021.03.12 - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/channelProviderLocal.h" -#include "pv/pvdbcrTraceRecord.h" - -using std::tr1::static_pointer_cast; -using namespace epics::pvData; -using namespace epics::pvAccess; -using namespace std; - -namespace epics { namespace pvDatabase { - -PvdbcrTraceRecordPtr PvdbcrTraceRecord::create( - std::string const & recordName) -{ - FieldCreatePtr fieldCreate = getFieldCreate(); - PVDataCreatePtr pvDataCreate = getPVDataCreate(); - StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> - addNestedStructure("argument")-> - add("recordName",pvString)-> - add("level",pvInt)-> - endNested()-> - addNestedStructure("result") -> - add("status",pvString) -> - endNested()-> - createStructure(); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); - PvdbcrTraceRecordPtr pvRecord( - new PvdbcrTraceRecord(recordName,pvStructure)); - if(!pvRecord->init()) pvRecord.reset(); - return pvRecord; -} - -PvdbcrTraceRecord::PvdbcrTraceRecord( - std::string const & recordName, - epics::pvData::PVStructurePtr const & pvStructure) -: PVRecord(recordName,pvStructure) -{ -} - - -bool PvdbcrTraceRecord::init() -{ - initPVRecord(); - PVStructurePtr pvStructure = getPVStructure(); - pvRecordName = pvStructure->getSubField("argument.recordName"); - if(!pvRecordName) return false; - pvLevel = pvStructure->getSubField("argument.level"); - if(!pvLevel) return false; - pvResult = pvStructure->getSubField("result.status"); - if(!pvResult) return false; - return true; -} - -void PvdbcrTraceRecord::process() -{ - string name = pvRecordName->get(); - PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); - if(!pvRecord) { - pvResult->put(name + " not found"); - return; - } - pvRecord->setTraceLevel(pvLevel->get()); - pvResult->put("success"); -} - - -}} diff --git a/src/special/pvdbcrTraceRecordRegister.cpp b/src/special/pvdbcrTraceRecordRegister.cpp index a9b5f0c..ac394e6 100644 --- a/src/special/pvdbcrTraceRecordRegister.cpp +++ b/src/special/pvdbcrTraceRecordRegister.cpp @@ -7,48 +7,127 @@ * @author mrk * @date 2021.03.12 */ - - -/* Author: Marty Kraimer */ - -#include -#include -#include -#include -#include -#include + #include +#include +#include +#include #include -#include +#include +#include +#include +#include -// The following must be the last include for code pvDatabase uses +// The following must be the last include for code exampleLink uses #include #define epicsExportSharedSymbols -#include "pv/pvStructureCopy.h" -#include "pv/pvDatabase.h" -#include "pv/pvdbcrTraceRecord.h" using namespace epics::pvData; using namespace epics::pvAccess; using namespace epics::pvDatabase; +using namespace epics::pvaClient; using namespace std; -static const iocshArg testArg0 = { "recordName", iocshArgString }; -static const iocshArg testArg1 = { "asLevel", iocshArgInt }; -static const iocshArg *testArgs[] = {&testArg0,&testArg1}; +class PvdbcrTraceRecord; +typedef std::tr1::shared_ptr PvdbcrTraceRecordPtr; -static const iocshFuncDef pvdbcrTraceRecordFuncDef = {"pvdbcrTraceRecord", 2,testArgs}; +class epicsShareClass PvdbcrTraceRecord : + public PVRecord +{ +public: + POINTER_DEFINITIONS(PvdbcrTraceRecord); + static PvdbcrTraceRecordPtr create( + std::string const & recordName); + virtual bool init(); + virtual void process(); +private: + PvdbcrTraceRecord( + std::string const & recordName, + epics::pvData::PVStructurePtr const & pvStructure); + epics::pvData::PVStringPtr pvRecordName; + epics::pvData::PVIntPtr pvLevel; + epics::pvData::PVStringPtr pvResult; +}; + +PvdbcrTraceRecordPtr PvdbcrTraceRecord::create( + std::string const & recordName) +{ + FieldCreatePtr fieldCreate = getFieldCreate(); + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> + addNestedStructure("argument")-> + add("recordName",pvString)-> + add("level",pvInt)-> + endNested()-> + addNestedStructure("result") -> + add("status",pvString) -> + endNested()-> + createStructure(); + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); + PvdbcrTraceRecordPtr pvRecord( + new PvdbcrTraceRecord(recordName,pvStructure)); + if(!pvRecord->init()) pvRecord.reset(); + return pvRecord; +} + +PvdbcrTraceRecord::PvdbcrTraceRecord( + std::string const & recordName, + epics::pvData::PVStructurePtr const & pvStructure) +: PVRecord(recordName,pvStructure) +{ +} + + +bool PvdbcrTraceRecord::init() +{ + initPVRecord(); + PVStructurePtr pvStructure = getPVStructure(); + pvRecordName = pvStructure->getSubField("argument.recordName"); + if(!pvRecordName) return false; + pvLevel = pvStructure->getSubField("argument.level"); + if(!pvLevel) return false; + pvResult = pvStructure->getSubField("result.status"); + if(!pvResult) return false; + return true; +} + +void PvdbcrTraceRecord::process() +{ + string name = pvRecordName->get(); + PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); + if(!pvRecord) { + pvResult->put(name + " not found"); + return; + } + pvRecord->setTraceLevel(pvLevel->get()); + pvResult->put("success"); +} + +static const iocshArg arg0 = { "recordName", iocshArgString }; +static const iocshArg arg1 = { "asLevel", iocshArgInt }; +static const iocshArg arg2 = { "asGroup", iocshArgString }; +static const iocshArg *args[] = {&arg0,&arg1,&arg2}; + +static const iocshFuncDef pvdbcrTraceRecordFuncDef = {"pvdbcrTraceRecord", 3,args}; static void pvdbcrTraceRecordCallFunc(const iocshArgBuf *args) { - char *recordName = args[0].sval; - if(!recordName) { - throw std::runtime_error("traceRecordCreate invalid number of arguments"); + char *sval = args[0].sval; + if(!sval) { + throw std::runtime_error("pvdbcrTraceRecord recordName not specified"); + } + string recordName = string(sval); + int asLevel = args[1].ival; + string asGroup("DEFAULT"); + sval = args[2].sval; + if(sval) { + asGroup = string(sval); } - int asLevel = args[1].ival; PvdbcrTraceRecordPtr record = PvdbcrTraceRecord::create(recordName); record->setAsLevel(asLevel); - bool result = PVDatabase::getMaster()->addRecord(record); - if(!result) cout << "recordname" << " not added" << endl; + record->setAsGroup(asGroup); + PVDatabasePtr master = PVDatabase::getMaster(); + bool result = master->addRecord(record); + if(!result) cout << "recordname " << recordName << " not added" << endl; } static void pvdbcrTraceRecordRegister(void)