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();
+}
+