fixed bug in createRequest.cpp

This commit is contained in:
Marty Kraimer
2014-07-30 06:50:22 -04:00
parent b6e1b9c203
commit a4954c3825
7 changed files with 172 additions and 11 deletions

View File

@@ -5,8 +5,13 @@
<p>There is a lot of public code that does not have doxygen tags.</p>
<h2>postMonitor: PVUnion, PVUnionArray, and PVStructureArray</h2>
<p>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.</p>
that are treated like a top level field.</p>
<p>Currently if a subField of any of these is changed postMonitor is not called for the field itself.</p>
<p>David asked if this could be changed so that it is called.
Marty thinks this may not be a good idea.</p>
<h2>timeStamp, display, control, and valueAlarm</h2>
<p>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.</p>
<h2>monitorPlugin</h2>
<p>A debate is on-going about what semantics should be.</p>

View File

@@ -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
-------------

View File

@@ -37,7 +37,7 @@
<h1>EPICS pvDataCPP</h1>
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 08-July-2014</h2>
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 23-July-2014</h2>
<dl>
<dt>Latest version:</dt>
@@ -78,7 +78,9 @@ V4 control system programming environment:<br />
<h2 class="nocount">Status of this Document</h2>
<p>This is the 08-July-2014 version of the C++ implementation of pvData.
<p>For now this is a working copy so it is not the same as "This version" shown above.</p>
<p>This is the 23-July-2014 version of the C++ implementation of pvData.
</p>
<p>RELEASE_NOTES.md provides changes since the last release.
@@ -86,6 +88,7 @@ TODO.md describes things to do before the next release.
</p>
<div id="toc">
<h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
</div>
@@ -1685,7 +1688,10 @@ class PVScalar;
class PVScalarArray;
class PVStructure;
class PVStructureArray;
class PVUnion;
class PVUnionArray;
typedef std::tr1::shared_ptr&lt;PostHandler&gt; PostHandlerPtr;
typedef std::tr1::shared_ptr&lt;PVField&gt; PVFieldPtr;
typedef std::vector&lt;PVFieldPtr&gt; PVFieldPtrArray;
@@ -1857,7 +1863,15 @@ std::ostream&amp; operator&lt;&lt;(std::ostream&amp; o, const PVField&amp; f);
PVStructure.</dd>
<dt>postPut</dt>
<dd>If a postHandler is registered it is called otherwise no action is
taken.</dd>
taken.<br />
<b>NOTE: </b>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.
</dd>
<dt>setPostHandler</dt>
<dd>Set the postHandler for the record. Only a single handler can be
registered.

View File

@@ -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; j<nitems; j++) {
string item = items[j];
size_t equals = item.find('=');
string name = item.substr(0,equals);
string name = "_options." + item.substr(0,equals);
string value = item.substr(equals+1);
PVStringPtr pvValue = pvParent->getSubField<PVString>(name);
pvValue->put(value);

View File

@@ -979,7 +979,6 @@ public:
private:
friend class PVDataCreate;
UnionConstPtr unionPtr;
int32 selector;

View File

@@ -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

125
testApp/pv/testPVUnion.cpp Normal file
View File

@@ -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 <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <epicsUnitTest.h>
#include <testMain.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/convert.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/timeStamp.h>
#include <pv/pvTimeStamp.h>
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<PVUnion>("value");
PVStructurePtr pvTime= pvValue->select<PVStructure>(2);
TimeStamp timeStamp;
timeStamp.getCurrent();
PVTimeStamp pvTimeStamp;
pvTimeStamp.attach(pvTime);
pvTimeStamp.set(timeStamp);
testOk1(
pvTime->getSubField<PVLong>("secondsPastEpoch")->get()
==
pvValue->get<PVStructure>()->getSubField<PVLong>("secondsPastEpoch")->get()
);
PVDoublePtr pvDouble = pvValue->select<PVDouble>("doubleValue");
pvDouble->put(1e5);
testOk1(pvDouble->get()==pvValue->get<PVDouble>()->get());
PVIntPtr pvInt = pvValue->select<PVInt>("intValue");
pvInt->put(15);
testOk1(pvInt->get()==pvValue->get<PVInt>()->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<PVUnionArray>("value");
size_t num = 3;
shared_vector<PVUnionPtr> unions(3);
for(size_t i=0; i<num; ++i)
{
unions[i] = pvDataCreate->createPVUnion(pvValue->getUnionArray()->getUnion());
}
unions[0]->select("doubleValue");
unions[1]->select("intValue");
unions[2]->select("timeStamp");
PVDoublePtr pvDouble = unions[0]->get<PVDouble>();
pvDouble->put(1.235);
PVIntPtr pvInt = unions[1]->get<PVInt>();
pvInt->put(5);
PVStructurePtr pvTime = unions[2]->get<PVStructure>();
TimeStamp timeStamp;
timeStamp.getCurrent();
PVTimeStamp pvTimeStamp;
pvTimeStamp.attach(pvTime);
pvTimeStamp.set(timeStamp);
pvValue->replace(freeze(unions));
shared_vector<const PVUnionPtr> sharedUnions = pvValue->view();
testOk1(pvDouble->get()==sharedUnions[0]->get<PVDouble>()->get());
testOk1(pvInt->get()==sharedUnions[1]->get<PVInt>()->get());
testOk1(
pvTime->getSubField<PVLong>("secondsPastEpoch")->get()
==
sharedUnions[2]->get<PVStructure>()->getSubField<PVLong>("secondsPastEpoch")->get()
);
std::cout << "testPVUnionArray PASSED" << std::endl;
}
MAIN(testPVData)
{
testPlan(6);
testPVUnion();
testPVUnionArray();
return testDone();
}