From a4954c38250b3475c9076300d4e071c8ed4b0d75 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Wed, 30 Jul 2014 06:50:22 -0400 Subject: [PATCH] fixed bug in createRequest.cpp --- documentation/TODO.html | 11 ++- documentation/TODO.md | 13 +++- documentation/pvDataCPP.html | 20 +++++- src/copy/createRequest.cpp | 8 ++- src/pv/pvData.h | 1 - testApp/pv/Makefile | 5 ++ testApp/pv/testPVUnion.cpp | 125 +++++++++++++++++++++++++++++++++++ 7 files changed, 172 insertions(+), 11 deletions(-) create mode 100644 testApp/pv/testPVUnion.cpp diff --git a/documentation/TODO.html b/documentation/TODO.html index 313b7bd..f2fd04f 100644 --- a/documentation/TODO.html +++ b/documentation/TODO.html @@ -5,8 +5,13 @@

There is a lot of public code that does not have doxygen tags.

postMonitor: PVUnion, PVUnionArray, and PVStructureArray

PVUnion, PVUnionArray, and PVStructureArray all have elements -that are treated like a top level field. -The implementation should be changed so that it implements PostHandler. -Thus when an element is modified it will call postPut for itself.

+that are treated like a top level field.

+

Currently if a subField of any of these is changed postMonitor is not called for the field itself.

+

David asked if this could be changed so that it is called. +Marty thinks this may not be a good idea.

+

timeStamp, display, control, and valueAlarm

+

normativeTypes.html defines time_t, display_t, control_t, and alarmlimit_t. +The definitions are not compatible with how property defined timeStamp, display, control, and valueAlarm. +The definition of alarm_t does match the definition of property alarm.

monitorPlugin

A debate is on-going about what semantics should be.

\ No newline at end of file diff --git a/documentation/TODO.md b/documentation/TODO.md index ffc147f..63e097c 100644 --- a/documentation/TODO.md +++ b/documentation/TODO.md @@ -17,9 +17,18 @@ postMonitor: PVUnion, PVUnionArray, and PVStructureArray PVUnion, PVUnionArray, and PVStructureArray all have elements that are treated like a top level field. -The implementation should be changed so that it implements PostHandler. -Thus when an element is modified it will call postPut for itself. +Currently if a subField of any of these is changed postMonitor is not called for the field itself. + +David asked if this could be changed so that it is called. +Marty thinks this may not be a good idea. + +timeStamp, display, control, and valueAlarm +---------- + +normativeTypes.html defines time_t, display_t, control_t, and alarmlimit_t. +The definitions are not compatible with how property defined timeStamp, display, control, and valueAlarm. +The definition of alarm_t does match the definition of property alarm. monitorPlugin ------------- diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html index 1823fa4..bbe60d0 100644 --- a/documentation/pvDataCPP.html +++ b/documentation/pvDataCPP.html @@ -37,7 +37,7 @@

EPICS pvDataCPP

-

EPICS v4 Working Group, Working Draft, 08-July-2014

+

EPICS v4 Working Group, Working Draft, 23-July-2014

Latest version:
@@ -78,7 +78,9 @@ V4 control system programming environment:

Status of this Document

-

This is the 08-July-2014 version of the C++ implementation of pvData. +

For now this is a working copy so it is not the same as "This version" shown above.

+ +

This is the 23-July-2014 version of the C++ implementation of pvData.

RELEASE_NOTES.md provides changes since the last release. @@ -86,6 +88,7 @@ TODO.md describes things to do before the next release.

+

Table of Contents

@@ -1685,7 +1688,10 @@ class PVScalar; class PVScalarArray; class PVStructure; class PVStructureArray; +class PVUnion; +class PVUnionArray; +typedef std::tr1::shared_ptr<PostHandler> PostHandlerPtr; typedef std::tr1::shared_ptr<PVField> PVFieldPtr; typedef std::vector<PVFieldPtr> PVFieldPtrArray; @@ -1857,7 +1863,15 @@ std::ostream& operator<<(std::ostream& o, const PVField& f); PVStructure.
postPut
If a postHandler is registered it is called otherwise no action is - taken.
+ taken.
+ NOTE: The implementation of the various data interfaces automatically + call postPut when a field is changed. However this is not true + for a subField of a PVUnion, PVUnionArray, or PVStructureArray. + If a subField of any of these is changed then the code that is making + the modification must call postPut for the PVUnion, PVUnionArray, or PVStructureArray + field. Note also that it is not a good idea to modify a subfield of a PVUnionArray + or a PVStructureArray since it violates the idea of Copy On Write for arrays. +
setPostHandler
Set the postHandler for the record. Only a single handler can be registered. diff --git a/src/copy/createRequest.cpp b/src/copy/createRequest.cpp index b4c7dea..567d7f6 100644 --- a/src/copy/createRequest.cpp +++ b/src/copy/createRequest.cpp @@ -129,7 +129,11 @@ private: fieldNames[j] = item.substr(0,equals); fields[j] = fieldCreate->createScalar(pvString); } - return fieldCreate->createStructure(fieldNames,fields); + StringArray names(1); + FieldConstPtrArray field(1); + names[0] = "_options"; + field[0] = fieldCreate->createStructure(fieldNames,fields); + return fieldCreate->createStructure(names,field); } void initRequestOptions( @@ -142,7 +146,7 @@ private: for(size_t j=0; jgetSubField(name); pvValue->put(value); diff --git a/src/pv/pvData.h b/src/pv/pvData.h index e8042aa..5909ea7 100644 --- a/src/pv/pvData.h +++ b/src/pv/pvData.h @@ -979,7 +979,6 @@ public: private: friend class PVDataCreate; - UnionConstPtr unionPtr; int32 selector; diff --git a/testApp/pv/Makefile b/testApp/pv/Makefile index c9faf7a..2f7a4a3 100644 --- a/testApp/pv/Makefile +++ b/testApp/pv/Makefile @@ -32,6 +32,11 @@ testPVData_SRCS += testPVData.cpp testPVData_LIBS += pvData Com TESTS += testPVData +PROD_HOST += testPVUnion +testPVUnion_SRCS += testPVUnion.cpp +testPVUnion_LIBS += pvData Com +TESTS += testPVUnion + PROD_HOST += testConvert testConvert_SRCS += testConvert.cpp testConvert_LIBS += pvData Com diff --git a/testApp/pv/testPVUnion.cpp b/testApp/pv/testPVUnion.cpp new file mode 100644 index 0000000..1ff0fc5 --- /dev/null +++ b/testApp/pv/testPVUnion.cpp @@ -0,0 +1,125 @@ +/* testPVUnion.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: Marty Kraimer Date: 2014.07 */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace epics::pvData; +using std::tr1::static_pointer_cast; +using std::string; +using std::cout; +using std::endl; + +static bool debug = false; + +static FieldCreatePtr fieldCreate = getFieldCreate(); +static PVDataCreatePtr pvDataCreate = getPVDataCreate(); +static StandardFieldPtr standardField = getStandardField(); +static StandardPVFieldPtr standardPVField = getStandardPVField(); +static ConvertPtr convert = getConvert(); + +static void testPVUnion() +{ + if(debug) + std::cout << std::endl << "testPVUnion" << std::endl; + PVStructurePtr pvStructure = pvDataCreate->createPVStructure( + standardField->regUnion( + fieldCreate->createFieldBuilder()-> + add("doubleValue", pvDouble)-> + add("intValue", pvInt)-> + add("timeStamp",standardField->timeStamp())-> + createUnion(), + "alarm,timeStamp")); + PVUnionPtr pvValue = pvStructure->getSubField("value"); + PVStructurePtr pvTime= pvValue->select(2); + TimeStamp timeStamp; + timeStamp.getCurrent(); + PVTimeStamp pvTimeStamp; + pvTimeStamp.attach(pvTime); + pvTimeStamp.set(timeStamp); + testOk1( + pvTime->getSubField("secondsPastEpoch")->get() + == + pvValue->get()->getSubField("secondsPastEpoch")->get() + ); + PVDoublePtr pvDouble = pvValue->select("doubleValue"); + pvDouble->put(1e5); + testOk1(pvDouble->get()==pvValue->get()->get()); + PVIntPtr pvInt = pvValue->select("intValue"); + pvInt->put(15); + testOk1(pvInt->get()==pvValue->get()->get()); + std::cout << "testPVUnion PASSED" << std::endl; +} + +static void testPVUnionArray() +{ + if(debug) + std::cout << std::endl << "testPVUnion" << std::endl; + PVStructurePtr pvStructure = pvDataCreate->createPVStructure( + standardField->unionArray( + fieldCreate->createFieldBuilder()-> + add("doubleValue", pvDouble)-> + add("intValue", pvInt)-> + add("timeStamp",standardField->timeStamp())-> + createUnion(), + "alarm,timeStamp")); + PVUnionArrayPtr pvValue = pvStructure->getSubField("value"); + size_t num = 3; + shared_vector unions(3); + for(size_t i=0; icreatePVUnion(pvValue->getUnionArray()->getUnion()); + } + unions[0]->select("doubleValue"); + unions[1]->select("intValue"); + unions[2]->select("timeStamp"); + PVDoublePtr pvDouble = unions[0]->get(); + pvDouble->put(1.235); + PVIntPtr pvInt = unions[1]->get(); + pvInt->put(5); + PVStructurePtr pvTime = unions[2]->get(); + TimeStamp timeStamp; + timeStamp.getCurrent(); + PVTimeStamp pvTimeStamp; + pvTimeStamp.attach(pvTime); + pvTimeStamp.set(timeStamp); + pvValue->replace(freeze(unions)); + shared_vector sharedUnions = pvValue->view(); + testOk1(pvDouble->get()==sharedUnions[0]->get()->get()); + testOk1(pvInt->get()==sharedUnions[1]->get()->get()); + testOk1( + pvTime->getSubField("secondsPastEpoch")->get() + == + sharedUnions[2]->get()->getSubField("secondsPastEpoch")->get() + ); + std::cout << "testPVUnionArray PASSED" << std::endl; +} + + +MAIN(testPVData) +{ + testPlan(6); + testPVUnion(); + testPVUnionArray(); + return testDone(); +} +