From 2f7c82757ff7ea8500fe00e1cea9e23cadd8aeca Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Tue, 7 Apr 2020 12:53:01 -0400 Subject: [PATCH 1/3] pvArrayPlugin now supports union scalarArray --- src/copy/pvArrayPlugin.cpp | 47 +++++++++++++++++++++++++++------ src/pv/pvArrayPlugin.h | 6 ++++- src/pvAccess/monitorFactory.cpp | 12 ++++----- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/copy/pvArrayPlugin.cpp b/src/copy/pvArrayPlugin.cpp index 13c32b5..6f506bb 100644 --- a/src/copy/pvArrayPlugin.cpp +++ b/src/copy/pvArrayPlugin.cpp @@ -76,9 +76,19 @@ static vector split(string const & colonSeparatedList) { PVArrayFilterPtr PVArrayFilter::create( const std::string & requestValue, - const PVFieldPtr & master) + const PVFieldPtr & masterField) { - Type type = master->getField()->getType(); + bool masterIsUnion = false; + PVUnionPtr pvUnion; + Type type = masterField->getField()->getType(); + if(type==epics::pvData::union_) { + pvUnion = std::tr1::static_pointer_cast(masterField); + PVFieldPtr pvField = pvUnion->get(); + if(pvField) { + masterIsUnion = true; + type = pvField->getField()->getType(); + } + } if(type!=scalarArray) { PVArrayFilterPtr filter = PVArrayFilterPtr(); return filter; @@ -112,25 +122,45 @@ PVArrayFilterPtr PVArrayFilter::create( PVArrayFilterPtr filter = PVArrayFilterPtr(); return filter; } + PVScalarArrayPtr masterArray; + if(masterIsUnion) { + masterArray = static_pointer_cast(pvUnion->get()); + } else { + masterArray = static_pointer_cast(masterField); + } PVArrayFilterPtr filter = PVArrayFilterPtr( - new PVArrayFilter( - start,increment,end,static_pointer_cast(master))); + new PVArrayFilter(start,increment,end,masterField,masterArray)); return filter; } -PVArrayFilter::PVArrayFilter(long start,long increment,long end,const PVScalarArrayPtr & masterArray) +PVArrayFilter::PVArrayFilter( + long start,long increment,long end, + const PVFieldPtr & masterField, + const epics::pvData::PVScalarArrayPtr masterArray) : start(start), increment(increment), end(end), + masterField(masterField), masterArray(masterArray) { } -bool PVArrayFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bool toCopy) +bool PVArrayFilter::filter(const PVFieldPtr & pvField,const BitSetPtr & bitSet,bool toCopy) { - PVScalarArrayPtr copyArray = static_pointer_cast(pvCopy); + PVFieldPtr pvCopy = pvField; + PVScalarArrayPtr copyArray; + Type type = masterField->getField()->getType(); + if(type==epics::pvData::union_) { + PVUnionPtr pvMasterUnion = std::tr1::static_pointer_cast(masterField); + PVUnionPtr pvCopyUnion = std::tr1::static_pointer_cast(pvCopy); + if(toCopy) pvCopyUnion->copy(*pvMasterUnion); + PVFieldPtr pvField = pvCopyUnion->get(); + copyArray = static_pointer_cast(pvField); + } else { + copyArray = static_pointer_cast(pvCopy); + } long len = 0; long start = this->start; long end = this->end; @@ -164,7 +194,7 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bo } } copyArray->setLength(len); - bitSet->set(pvCopy->getFieldOffset()); + bitSet->set(masterField->getFieldOffset()); return true; } if (end - start >= 0) len = 1 + (end - start) / increment; @@ -181,6 +211,7 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bo indto += increment; } } + masterField->postPut(); return true; } diff --git a/src/pv/pvArrayPlugin.h b/src/pv/pvArrayPlugin.h index d74ba1e..d9902b2 100644 --- a/src/pv/pvArrayPlugin.h +++ b/src/pv/pvArrayPlugin.h @@ -63,9 +63,13 @@ private: long start; long increment; long end; + epics::pvData::PVFieldPtr masterField; epics::pvData::PVScalarArrayPtr masterArray; - PVArrayFilter(long start,long increment,long end,const epics::pvData::PVScalarArrayPtr & masterArray); + PVArrayFilter( + long start,long increment,long end, + const epics::pvData::PVFieldPtr & masterField, + const epics::pvData::PVScalarArrayPtr masterArray); public: POINTER_DEFINITIONS(PVArrayFilter); virtual ~PVArrayFilter(); diff --git a/src/pvAccess/monitorFactory.cpp b/src/pvAccess/monitorFactory.cpp index ed3d368..72a425e 100644 --- a/src/pvAccess/monitorFactory.cpp +++ b/src/pvAccess/monitorFactory.cpp @@ -291,7 +291,7 @@ void MonitorLocal::dataPut(PVRecordFieldPtr const & pvRecordField) { if(pvRecord->getTraceLevel()>1) { - cout << "PVCopyMonitor::dataPut(pvRecordField)" << endl; + cout << "MonitorLocal::dataPut(pvRecordField)" << endl; } if(state!=active) return; { @@ -316,7 +316,7 @@ void MonitorLocal::dataPut( { if(pvRecord->getTraceLevel()>1) { - cout << "PVCopyMonitor::dataPut(requested,pvRecordField)" << endl; + cout << "MonitorLocal::dataPut(requested,pvRecordField)" << endl; } if(state!=active) return; { @@ -343,7 +343,7 @@ void MonitorLocal::beginGroupPut(PVRecordPtr const & pvRecord) { if(pvRecord->getTraceLevel()>1) { - cout << "PVCopyMonitor::beginGroupPut()" << endl; + cout << "MonitorLocal::beginGroupPut()" << endl; } if(state!=active) return; { @@ -357,7 +357,7 @@ void MonitorLocal::endGroupPut(PVRecordPtr const & pvRecord) { if(pvRecord->getTraceLevel()>1) { - cout << "PVCopyMonitor::endGroupPut dataChanged " << dataChanged << endl; + cout << "MonitorLocal::endGroupPut dataChanged " << dataChanged << endl; } if(state!=active) return; { @@ -374,7 +374,7 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord) { if(pvRecord->getTraceLevel()>1) { - cout << "PVCopyMonitor::unlisten\n"; + cout << "MonitorLocal::unlisten\n"; } { Lock xx(mutex); @@ -384,7 +384,7 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord) if(requester) { if(pvRecord->getTraceLevel()>1) { - cout << "PVCopyMonitor::unlisten calling requester->unlisten\n"; + cout << "MonitorLocal::unlisten calling requester->unlisten\n"; } requester->unlisten(getPtrSelf()); } From ad479309b0e4919b198be85c451ed9c6475e5fdd Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Wed, 8 Apr 2020 11:06:59 -0400 Subject: [PATCH 2/3] fix bitset bug --- src/copy/pvArrayPlugin.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/copy/pvArrayPlugin.cpp b/src/copy/pvArrayPlugin.cpp index 6f506bb..acab57d 100644 --- a/src/copy/pvArrayPlugin.cpp +++ b/src/copy/pvArrayPlugin.cpp @@ -174,7 +174,7 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvField,const BitSetPtr & bitSet,b if (end < 0) end = 0; } - if(toCopy) { + if(toCopy) { if (end >= no_elements) end = no_elements - 1; if (end - start >= 0) len = 1 + (end - start) / increment; if(len<=0 || start>=no_elements) { @@ -194,7 +194,6 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvField,const BitSetPtr & bitSet,b } } copyArray->setLength(len); - bitSet->set(masterField->getFieldOffset()); return true; } if (end - start >= 0) len = 1 + (end - start) / increment; From 1e62844a22aee206641f23f63355c9807a98f006 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Sun, 12 Apr 2020 14:01:22 -0400 Subject: [PATCH 3/3] testPlugin found bug: added unionArrayTest --- src/copy/pvArrayPlugin.cpp | 5 ++- test/src/testPlugin.cpp | 70 +++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/copy/pvArrayPlugin.cpp b/src/copy/pvArrayPlugin.cpp index acab57d..01b646a 100644 --- a/src/copy/pvArrayPlugin.cpp +++ b/src/copy/pvArrayPlugin.cpp @@ -151,8 +151,10 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvField,const BitSetPtr & bitSet,b { PVFieldPtr pvCopy = pvField; PVScalarArrayPtr copyArray; + bool isUnion = false; Type type = masterField->getField()->getType(); if(type==epics::pvData::union_) { + isUnion = true; PVUnionPtr pvMasterUnion = std::tr1::static_pointer_cast(masterField); PVUnionPtr pvCopyUnion = std::tr1::static_pointer_cast(pvCopy); if(toCopy) pvCopyUnion->copy(*pvMasterUnion); @@ -194,6 +196,7 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvField,const BitSetPtr & bitSet,b } } copyArray->setLength(len); + bitSet->set(pvField->getFieldOffset()); return true; } if (end - start >= 0) len = 1 + (end - start) / increment; @@ -210,7 +213,7 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvField,const BitSetPtr & bitSet,b indto += increment; } } - masterField->postPut(); + if(isUnion) masterField->postPut(); return true; } diff --git a/test/src/testPlugin.cpp b/test/src/testPlugin.cpp index f0cbd59..5a46685 100644 --- a/test/src/testPlugin.cpp +++ b/test/src/testPlugin.cpp @@ -145,6 +145,73 @@ static void arrayTest() testOk1(nset==1); } +static void unionArrayTest() +{ + if(debug) {cout << endl << endl << "****unionArrayTest****" << endl;} + bool result = false; + uint32 nset = 0; + size_t n = 10; + shared_vector values(n); + for(size_t i=0; i(PVDataCreate::getPVDataCreate()->createPVScalarArray(pvDouble)); + const shared_vector yyy(freeze(values)); + pvDoubleArray->putFrom(yyy); + + StandardFieldPtr standardField = getStandardField(); + FieldCreatePtr fieldCreate = getFieldCreate(); + StructureConstPtr top = fieldCreate->createFieldBuilder()-> + add("value",fieldCreate->createVariantUnion()) -> + add("timeStamp", standardField->timeStamp()) -> + addNestedStructure("subfield") -> + add("value",fieldCreate->createVariantUnion()) -> + endNested()-> + createStructure(); + PVStructurePtr pvRecordStructure(PVDataCreate::getPVDataCreate()->createPVStructure(top)); + PVRecordPtr pvRecord(PVRecord::create("unionArrayRecord",pvRecordStructure)); + PVUnionPtr pvUnion = pvRecord->getPVStructure()->getSubField("value"); + pvUnion->set(pvDoubleArray); + pvUnion = pvRecord->getPVStructure()->getSubField("subfield.value"); + pvUnion->set(pvDoubleArray); + if(debug) { cout << "initial\n" << pvRecordStructure << "\n";} + + PVStructurePtr pvRequest(CreateRequest::create()->createRequest("value[array=1:3]")); + PVCopyPtr pvCopy(PVCopy::create(pvRecordStructure,pvRequest,"")); + PVStructurePtr pvStructureCopy(pvCopy->createPVStructure()); + BitSetPtr bitSet(new BitSet(pvStructureCopy->getNumberFields())); + PVDoubleArrayPtr pvValue(pvRecordStructure->getSubField("value")); + result = pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet); + nset = bitSet->cardinality(); + if(debug) { + cout << "after get value" + << " result " << (result ? "true" : "false") + << " nset " << nset + << " bitSet " << *bitSet + << " pvStructureCopy\n" << pvStructureCopy + << "\n"; + } + testOk1(result==true); + testOk1(nset==1); + + pvRequest = CreateRequest::create()->createRequest("subfield.value[array=1:3]"); + pvCopy = PVCopy::create(pvRecordStructure,pvRequest,""); + pvStructureCopy = pvCopy->createPVStructure(); + bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields())); + pvValue = pvRecordStructure->getSubField("subfield.value"); + result = pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet); + nset = bitSet->cardinality(); + if(debug) { + cout << "after get subfield.value" + << " result " << (result ? "true" : "false") + << " nset " << nset + << " bitSet " << *bitSet + << " pvStructureCopy\n" << pvStructureCopy + << "\n"; + } + testOk1(result==true); + testOk1(nset==1); +} + static void timeStampTest() { if(debug) {cout << endl << endl << "****timeStampTest****" << endl;} @@ -267,10 +334,11 @@ static void ignoreTest() MAIN(testPlugin) { - testPlan(22); + testPlan(26); PVDatabasePtr pvDatabase(PVDatabase::getMaster()); deadbandTest(); arrayTest(); + unionArrayTest(); timeStampTest(); ignoreTest(); return 0;