diff --git a/documentation/examples.zip b/documentation/examples.zip index 1f27dd5..dcefb77 100644 Binary files a/documentation/examples.zip and b/documentation/examples.zip differ diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html index d870733..638385e 100644 --- a/documentation/pvDataCPP.html +++ b/documentation/pvDataCPP.html @@ -37,7 +37,7 @@
This product is made available subject to acceptance of the
This is the 23-July-2014 version of the C++ implementation of pvData. +
This is the 08-Oct-2014 version of the C++ implementation of pvData.
RELEASE_NOTES.md provides changes since the last release. @@ -120,17 +121,17 @@ href="./html/index.html">doxygenDoc
This document discusses the following:
The documentation directory for this project has a file examples.zip. It has the code for the examples. After it is unzipped:
@@ -149,10 +150,12 @@ cp ExampleRELEASE.local RELEASE.local #edit RELEASE.local cd .. make ++Now you are ready to run the examples: +
bin/linux-x86_64/introspectMain bin/linux-x86_64/dataMain-
The examples assume that the following statements have been issued:
using std::cout; @@ -166,7 +169,7 @@ StandardPVFieldPtr standardPVField = getStandardPVField();
Using FieldBuilder the same can be done via:
@@ -227,13 +230,13 @@ It uses only createField.
add("userTag", pvInt)->
endNested()->
createStructure();
- cout << doubleScalarHard->dump(cout) << endl;
+ cout << *doubleScalarHard << endl;
The easiest way to produce the structure is:
StructureConstPtr stringArrayEasy =
getStandardField()->scalarArray(pvString,"alarm,timeStamp");
- cout << stringArrayEasy->dump(cout) << "\n\n";
+ cout << *stringArrayEasy << "\n\n";
These three ways produce:
@@ -270,7 +273,7 @@ via standardField:StructureConstPtr stringArrayEasy = standardField->scalarArray(pvString,"alarm,timeStamp"); - cout <<stringArrayEasy->dump(cout) << endl; + cout << *stringArrayEasy << endl;It produces :@@ -311,7 +314,7 @@ A hard way to create an structure with an enumerated value field and a time stam add("userTag", pvInt)-> endNested()-> createStructure(); - cout <<ntEnumHard->dump(cout) << endl; + cout << *ntEnumHard << endl;It produces:@@ -328,7 +331,7 @@ ev4:nt/NTEnum:1.0 fields: alarm and timeStamp:StructureConstPtr ntEnumEasy = getStandardField()->enumerated("alarm,timeStamp"); - cout <<ntEnumEsay->dump(cout) << endl; + cout << *ntEnumEasy << endl;It produces:@@ -356,10 +359,10 @@ ev4:nt/NTEnum add("intValue", pvInt)-> add("timeStamp",standardField->timeStamp())-> createUnion(); - cout <<ntunion->dump(cout) << endl; + cout << *ntunion << endl; StructureConstPtr unionValue = standardField->regUnion(punion,"alarm,timeStamp"); - cout <<unionValue->dump(cout) << endl; + cout << *unionValue << endl;It produces:@@ -395,7 +398,7 @@ ev4:nt/NTUnion:1.0-UnionArrayConstPtr unionArray = fieldCreate->createUnionArray( fieldCreate->createVariantUnion()); - cout << unionArray->dump(cout) << "\n\n"; + cout << *unionArray << "\n\n";Produces
@@ -423,7 +426,7 @@ any add("alarm",standardField->alarm()) -> endNested()-> createStructure(); - std::cout << powerSupply->dumpValue(cout) <<std::endl; + std::cout << *powerSupply <<std::endl;It produces:@@ -464,7 +467,7 @@ structure PVDoublePtr pvdouble = doubleValue->getSubField<PVDouble>("value"); pvdouble->put(1e5); - cout << doubleValue->dumpValue(cout) << endl; + cout << *doubleValue << endl; double value = doubleValue->getSubField<PVDouble>("value")->get(); cout << "from get " << value << "\n\n";@@ -494,7 +497,7 @@ from get 100000 for(size_t i=0; i< len; ++i) xxx[i] = i; shared_vector<const double> data(freeze(xxx)); pvDoubleArray->replace(data); - cout << doubleArrayValue->dumpValue(cout) << endl; + cout << *doubleArrayValue << endl; shared_vector<const double> getData = pvDoubleArray->view(); cout << "via getData"; @@ -520,7 +523,7 @@ via getData 0 1 2 3 4 5 6 7 8 9PVStructurePtr pvntenum = pvDataCreate->createPVStructure( standardField->enumerated("alarm,timeStamp")); - cout << pvntenum->dumpValue(cout) << "\n\n"; + cout << *pvntenum << "\n\n";This produces:@@ -558,7 +561,7 @@ ev4:nt/NTEnum:1.0 endNested()-> createStructure(); PVStructurePtr pvpowerSupply = pvDataCreate->createPVStructure(powerSupply); - cout << pvpowerSupply->dumpValue(cout) << endl; + cout << *pvpowerSupply << endl;This produces:@@ -604,9 +607,9 @@ structure PVStructurePtr pvTimeStamp = pvStructure->getSubField<PVUnion>("value")->select<PVStructure>(2); pvTimeStamp->getSubField<PVLong>("secondsPastEpoch")->put(1000); - cout << pvStructure->dumpValue(cout) << "\n"; + cout << *pvStructure) << "\n"; pvStructure->getSubField<PVUnion>("value")->select<PVDouble>(0)->put(1e5); - cout << pvStructure->dumpValue(cout) << "\n\n"; + cout << *pvStructure << "\n\n";This produces:@@ -647,13 +650,13 @@ ev4:nt/NTUnion:1.0 pvDataCreate->createPVStructure(standardField->timeStamp()); pvStructure->getSubField<PVUnion>("value")->set(pvTimeStamp); pvTimeStamp->getSubField<PVLong>("secondsPastEpoch")->put(1000); - cout << pvStructure->dumpValue(cout) << "\n"; + cout << *pvStructure << "\n"; pvStructure->getSubField<PVUnion>("value")->set( pvDataCreate->createPVScalar(pvDouble)); PVDoublePtr pvValue = static_pointer_cast<PVDouble>( pvStructure->getSubField<PVUnion>("value")->get()); pvValue->put(1e5); - cout << pvStructure->dumpValue(cout) << "\n\n"; + cout << *pvStructure << "\n\n";This produces:@@ -712,21 +715,21 @@ ev4:nt/NTUnion:1.0 createUnion(), "alarm,timeStamp")); cout << "introspection\n"; - cout <<pvStructure->getStructure()->dump(cout) << endl; + cout << *pvStructure->getStructure() << endl; cout << "data\n"; - cout << pvStructure->dumpValue(cout) << "\n"; + cout << *pvStructure << "\n"; PVUnionPtr pvUnion = pvStructure->getSubField<PVUnion>("value");; pvUnion->select("doubleValue"); PVDoublePtr pvDouble = pvUnion->get<PVDouble>(); pvDouble->put(1.55); cout << "select valueDouble\n"; - cout << pvStructure->dumpValue(cout) << "\n"; + cout << *pvStructure << "\n"; cout << "value = " << pvDouble->get() << "\n"; pvUnion->select("structValue"); pvDouble = pvUnion->get<PVStructure>()->getSubField<PVDouble>("doubleValue"); pvDouble->put(1.65); cout << "select structValue\n"; - cout << pvStructure->dumpValue(cout) << "\n"; + cout << *pvStructure << "\n"; cout << "value = " << pvDouble->get() << "\n";This produces: @@ -838,10 +841,10 @@ typedef PVScalarValue<boolean> PVBoolean; typedef std::tr1::shared_ptr<PVBoolean> PVBooleanPtr;pvDataApp/pv
+src/pv
-Directory pvDataApp/pv has header files that completely describe pvData. -The implementation is provided in directory pvDataApp/factory. +
Directory src/pv has header files that completely describe pvData. +The implementation is provided in directory src/factory. Test programs appears in testApp/pv.
NOTES:
@@ -868,7 +871,7 @@ introspection and data interfaces for pvData. data objects. Class Convert provides a rich set of methods for converting and copying data between fields. -Directory pvDataApp/pv has the following header files:
+Directory src/pv has the following header files:
TBD +
TBD
typedef uint8_t boolean;
+
@@ -1394,8 +1448,16 @@ class epicsShareClass FieldBuilder :
public:
FieldBuilderPtr setId(std::string const & id);
FieldBuilderPtr add(std::string const & name, ScalarType scalarType);
+ FieldBuilderPtr addBoundedString(std::string const & name, std::size_t maxLength);
FieldBuilderPtr add(std::string const & name, FieldConstPtr const & field);
FieldBuilderPtr addArray(std::string const & name, ScalarType scalarType);
+ FieldBuilderPtr addFixedArray(
+ std::string const & name,
+ ScalarType scalarType,
+ std::size_t size);
+ FieldBuilderPtr addBoundedArray(std::string const &
+ name,ScalarType scalarType,
+ std::size_t bound);
FieldBuilderPtr addArray(std::string const & name, FieldConstPtr const & element);
StructureConstPtr createStructure();
UnionConstPtr createUnion();
@@ -1411,8 +1473,14 @@ public:
static FieldCreatePtr getFieldCreate();
FieldBuilderPtr createFieldBuilder() const;
ScalarConstPtr createScalar(ScalarType scalarType) const;
+ BoundedStringConstPtr createBoundedString(std::size_t maxLength) const;
ScalarArrayConstPtr createScalarArray(ScalarType elementType) const;
- StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const;
+ ScalarArrayConstPtr createFixedScalarArray(
+ ScalarType elementType, std::size_t size) const
+ ScalarArrayConstPtr createBoundedScalarArray(
+ ScalarType elementType, std::size_t bound) const;
+ StructureArrayConstPtr createStructureArray(
+ StructureConstPtr const & structure) const;
StructureConstPtr createStructure () const;
StructureConstPtr createStructure (
StringArray const & fieldNames,
@@ -1458,9 +1526,22 @@ description of the methods.
-uint32 val = pv->getAs(); +uint32 val = pv->getAs<pvInt>();
where
TBD +
TBD
where
@@ -2449,7 +2545,7 @@ public: std::tr1::shared_ptr<PVAT> createPVScalarArray(); PVStructureArrayPtr createPVStructureArray(StructureArrayConstPtr const & structureArray); - PVStructureArrayPtr createPVStructureArray(StructureConstPtr const ∓ structure); + PVStructureArrayPtr createPVStructureArray(StructureConstPtr const & structure); PVUnionArrayPtr createPVUnionArray(UnionArrayConstPtr const & unionArray); PVUnionArrayPtr createPVUnionArray(UnionConstPtr const & punion); @@ -2487,12 +2583,12 @@ PVDoublePtr pvDouble = getPVDataCreate()->createPVScalar<PVDouble>(); If structToClone is null then the new structure is initialized to have 0 subfields. The third method uses a previously created structure introspection interface. -The last copy is the only one most client need to call. -It either throws an error of the element types do not match or calls the +It either throws an error if the element types do not match or calls the other copy functions. The arguments are:
An exception is thrown if:
Only fields named "value" have properties. A record can have multiple value +
+Often a field named "value" has properties. A record can have multiple value fields, which can appear in the top level structure of a record or in a substructure. All other fields in the structure containing a value field are considered properties of the value field. The fieldname is also the property @@ -3463,7 +3560,7 @@ public: bool choicesMutable(); StringArrayPtr const & getChoices(); int32 getNumberChoices(); - bool setChoices(StringArray &choices,int32 numberChoices); + bool setChoices(StringArray &choices); };
where
@@ -3502,7 +3599,7 @@ public: -Directory factory has code that implements everything described by the files in directory pv
@@ -3522,7 +3619,7 @@ implements getConvert.Other files implement PVData base classes
-Clears all of the bits in this bitSet whose corresponding bit is set - in the specified bitSet.
--
Lock has a private variable: +
Lock has a private variable:
bool locked;and improves efficiency by checking the local variable before calling the mutex methods. This is not thread safe if any methods are called by a thread other than the thread that created the Lock. -
It is thread safe if used as follows:
{
@@ -4720,7 +4809,7 @@ be used to schedule multiple callbacks. It has the methods:
typeCast.h
TBD Michael will explain.
-pvDataApp/pvMisc
+src/pvMisc
bitSetUtil.h
@@ -4750,7 +4839,7 @@ currently has only one method:
entire structures if the structure offset bit is set.
-support for copy and monitor
+src/copy and src/monitor
copy and monitor are not used in this project.
They are intended for use by pvAccess and by pvAccess servers.
They are provided with this project because the code depends only on
@@ -4767,7 +4856,7 @@ had knowledge of PVRecord. The C++ version was implemented in pvDatabaseCPP
and the Java version on pvIOCJava.
At present only the C++ version of the new API for pvCopy is implemented.
-Copy provides:
+
Copy provides:
copy provides the ability to create a structure that has a copy of an arbitrary subset of the fields in an existing top level structure. In addition it allows global options and field specific options. @@ -4975,15 +5062,14 @@ where -
This consists of two components: +
This consists of two components:
class MonitorElement {
@@ -5010,6 +5096,7 @@ class MonitorRequester : public virtual Requester {
monitorElement
MonitorElement holds the data for one element of a monitor queue.
It has the fields:
+
A queue of monitor elements must be implemented by any channel provider that implements Channel::createMonitor. For an example implementation look at pvDatabaseCPP. It has the following: +
typedef Queue<MonitorElement> MonitorElementQueue;
typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr;
@@ -5076,7 +5163,6 @@ Note that each client has it's own queue that is not shared with other client.
Release the monitor element.
The caller owns the monitor element between the calls to poll and release.
-This must be implemented by a pvAccess client. @@ -5144,7 +5230,7 @@ It has methods:
Should the value of pvField cause a monitor to be raised. pvField and pvTop are fields in the top level structure being monitored. monitorElement has the top level structure - for the copy. + for the copyMonitorPluginManager has the methods:
typedef std::tr1::shared_ptr<const PVField> PVFieldConstPtr; typedef std::tr1::shared_ptr<const PVStructure> PVStructureConstPtr; @@ -5237,7 +5324,6 @@ In addition all methods defined in pvDataCPP must be checked. In particular many of the methods in Convert must have their arguments modified. Big job. -monitorPlugin example
Example Plugin Overview
This section describes an example plugin that:
@@ -5270,6 +5356,7 @@ structure powerSupply
A pvAccess client wants to create a monitor on the powerSupply as follows: The client wants a top level structure that looks like: +
structure powerSupply
structure alarm
@@ -5284,9 +5371,9 @@ structure powerSupply
In addition the client wants monitors to occur only when one of the monitored
fields changes value but not just because a put occurred.
Also if only the timeStamp changes value then that should not cause a monitor.
-
The example monitor plugin implements the semantics the
client wants. It can be attached to any field via the following options:
+
[plugin=onChange,raiseMonitor=value]
@@ -5295,7 +5382,6 @@ value. In addition value equals false means do not raise a monitor
for changes to this field.
But if a change to another field does cause a monitor the change to this field
will be passed to the client.
-
Assume that the client has already connected to the channel.
The client can then issue the commands: