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

EPICS pvDataCPP

-

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

+

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

Latest version:
@@ -56,6 +56,7 @@
Marty Kraimer, BNL
Michael Davidsaver, BNL
Matej Sekoranja, CosyLab
+
David Hickin, Diamond Light Source

Status of this Document

-

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:

-
pvDataAPP/pv
+
src/pv
This subdirectory contains all the public interfaces that describe pvData. The section from Namespace and Memory Management through Conversion discuss these interfaces.
-
pvDataApp/property
+
src/property
This section has support for managing "standard" fields.
-
pvDataApp/misc
+
src/misc
This section has support for facilities required by implementation code.
-
copy and monitor
+
src/copy and src/monitor
These sections provide pvData support for implementing pvAccess providers.
@@ -140,7 +141,7 @@ data interfaces. The first time reader may not understand them but hopefully wil idea of how pvData works. After reading the rest of this document the examples will be much easier to understand.

-

The documentation directory for this project has a file examples.zip. +

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();
 
fieldCreate
This creates instances of introspection objects. - It also provides fieldBuilder, which provides an easier way to create introspection objects. + It also provides fieldBuilder, which provides an easier way to create introspection objects.
pvDataCreate
This creates instances of data objects. @@ -213,7 +216,7 @@ It uses only createField. topfields.push_back(timeStamp); StructureConstPtr doubleScalar = fieldCreate->createStructure(topnames,topfields); - cout << doubleScalar->dump(cout) << endl; + cout << *doubleScalar << endl;

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 9
     PVStructurePtr 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:

pvType.h
C++ definitions for primitive types.
@@ -919,8 +922,8 @@ inline std::string const * get(StringArray const &value); inline std::string * get(StringArrayPtr &value); inline std::string const * get(StringArrayPtr const &value); } -inline StringArray & getVector(StringArrayPtr &value); -inline StringArray const & getVector(StringArrayPtr const &value); +inline StringArray & getVector(StringArrayPtr &value); +inline StringArray const & getVector(StringArrayPtr const &value); typedef std::vector<std::string>::iterator StringArray_iterator; typedef std::vector<std::string>::const_iterator StringArray_const_iterator;
@@ -942,26 +945,24 @@ typedef std::vector<std::string>::const_iterator StringArray_const_iterato over the network as a UTF8 encoded string. Since std::string implements copy on write semantics, it can be used for support for immutable strings. It can also be serialized/deserialized as a UTF8 encoded string. - Because it is not a C++ primitive the first letter is capitalized. This - is the same convention the Java implementation uses. - Note that string is treated like a primitive type. + Note that std::string is treated like a primitive type.
StringArray definitions
typedefs are provided for an array of std::strings, which is a std::vector<std::string>. This is used by introspection.
-

TBD +

TBD

boolean
Question for Michael. Why isn't the definition of boolean just
 typedef uint8_t boolean;
     
+
printer.h
Not documented. Is this needed? Nothing currently uses it.
-

pvIntrospect.h

@@ -1197,12 +1198,29 @@ public: ... }; +class BoundedString : public Scalar{ +public: + POINTER_DEFINITIONS(BoundedString); + virtual ~BoundedString(); + typedef BoundedString& reference; + typedef const BoundedString& const_reference; + + std::size_t getMaximumLength() const; + virtual std::string getID() const; + virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; +... +}; + class epicsShareClass Array : public Field{ public: POINTER_DEFINITIONS(Array); virtual ~Array(); typedef Array& reference; typedef const Array& const_reference; + enum ArraySizeType { variable, fixed, bounded }; + + virtual ArraySizeType getArraySizeType() const = 0; + virtual std::size_t getMaximumCapacity() const = 0; ... }; @@ -1215,6 +1233,8 @@ public: ScalarArray(ScalarType scalarType); ScalarType getElementType() const {return elementType;} + virtual ArraySizeType getArraySizeType() const; + virtual std::size_t getMaximumCapacity() const; virtual std::string getID() const; virtual std::ostream& dump(std::ostream& o) const; virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; @@ -1222,6 +1242,36 @@ public: ... }; +class epicsShareClass BoundedScalarArray : public ScalarArray{ +public: + POINTER_DEFINITIONS(BoundedScalarArray); + typedef BoundedScalarArray& reference; + typedef const BoundedScalarArray& const_reference; + + BoundedScalarArray(ScalarType scalarType, std::size_t size); + virtual ArraySizeType getArraySizeType() const; + virtual std::size_t getMaximumCapacity() const; + virtual std::string getID() const; + virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; +... +} + +class epicsShareClass FixedScalarArray : public ScalarArray{ +public: + POINTER_DEFINITIONS(FixedScalarArray); + typedef FixedScalarArray& reference; + typedef const FixedScalarArray& const_reference; + + FixedScalarArray(ScalarType scalarType, std::size_t size); + virtual ArraySizeType getArraySizeType() const {return Array::fixed;} + virtual std::size_t getMaximumCapacity() const {return size;} + virtual std::string getID() const; + virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; +... +}; + + + class StructureArray : public Field{ public: POINTER_DEFINITIONS(StructureArray); @@ -1229,6 +1279,8 @@ public: typedef const StructureArray& const_reference; StructureConstPtr getStructure() const {return pstructure;} + virtual ArraySizeType getArraySizeType() const; + virtual std::size_t getMaximumCapacity() const; virtual std::string getID() const; virtual std::ostream& dump(std::ostream& o) const; virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; @@ -1242,6 +1294,8 @@ public: typedef UnionArray& reference; typedef const UnionArray& const_reference; UnionConstPtr getUnion() const {return punion;} + virtual ArraySizeType getArraySizeType() const; + virtual std::size_t getMaximumCapacity() const; virtual std::string getID() const; virtual std::ostream& dump(std::ostream& o) const; virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; @@ -1376,7 +1430,7 @@ public: NULL is returned if not found.
getFieldIndex
-
Get the index for name. -1 is returned if not found. +
Get the index for name. -1 is returned if not found.
getFields
Get the array of types.
getFieldNames
@@ -1384,7 +1438,7 @@ public:
getFieldName
Get the name for the specified index.
isVariant
-
returns true if this is variant array and false otherwise. +
returns true if this is variant array and false otherwise.

fieldBuilder and createField

@@ -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.
       
Add a scalar field.
+
addBoundedString
+
+ Add a scalar field that is a string that has a maximum size. +
addArray
- Add a scalarArray field. + Add an array field. There are two methods: one to create a scalaArray + and one to create scalarArray, unionArray, or structureArray. +
+
addFixedArray
+
+ Add a fixed size scalarArray field. +
+
addBoundedArray
+
+ Add a bounded scalarArray field.
createStructure
@@ -1504,14 +1585,24 @@ description of the methods.
Create an instance of a FieldBuilder.
createScalar
Create a scalar introspection instance.
+
createBoundedString
+
create a scalar introspection instance for a bounded string.
createScalarArray
Create a scalar array introspection instance.
+
createFixedScalarArray
+
Create a scalar array introspection instance.
+
createBoundedScalarArray
+
Create a scalar array introspection instance.
createStructure
Create a structure introspection instance. Three methods are provided. The first creates an empty structure, i. e. a structure with no fields. The other two are similar. The only difference is that one provides an ID and the other does not. The one without will result in ID structure.
+
createStructureArray
+
Ceate a structure array introspection instance. + All elements will have the same introspection interface. +
createUnion
Create a union. There are two methods. Each has arguments for an array of types and an array of names. @@ -1687,7 +1778,13 @@ class PVScalarArray; class PVStructure; class PVStructureArray; class PVUnion; -class PVUnionArray; + +template<typename T> class PVScalarValue; +template<typename T> class PVValueArray; + +typedef PVValueArray<PVUnionPtr> PVUnionArray; +typedef std::tr1::shared_ptr<PVUnionArray> PVUnionArrayPtr; + typedef std::tr1::shared_ptr<PostHandler> PostHandlerPtr; @@ -1909,7 +2006,7 @@ public: which must be one of the ScalarType enums. For example:
-uint32 val = pv->getAs();
+uint32 val = pv->getAs<pvInt>();
 
@@ -2063,6 +2160,7 @@ public: virtual void serialize( ByteBuffer *pbuffer,SerializableControl *pflusher) const ; PVUnion(UnionConstPtr const & punion); + virtual std::ostream& dumpValue(std::ostream& o) const; };
@@ -2137,7 +2235,6 @@ public:
dumpValue
ostream method
-

PVScalarArray

@@ -2241,12 +2338,14 @@ public: If the field does not exist then a Ptr to a NULL value is returned without any error message being generated.
- Note that the template version replaces getBooleanField, etc.
+ Note The template version replaces getBooleanField, etc.
getSubField(int fieldOffset)
Get the field located a fieldOffset, where fieldOffset is relative to the top level structure. This returns null if the specified field is not located within this PVStructure. +
+ Note The template version replaces getBooleanField, etc.
dumpValue
Method for streams I/O.
@@ -2270,12 +2369,13 @@ public: static const ScalarType typeCode; virtual ~PVValueArray() {} + virtual ArrayConstPtr getArray() const std::ostream& dumpValue(std::ostream& o) const; std::ostream& dumpValue(std::ostream& o, size_t index) const; // inherited from PVVectorStorage const_svector view(); - void swap(const_svector& other); - void replace(const const_svector& next); + void swap(const_svector& other); + void replace(const const_svector& next); svector reuse(); ... }; @@ -2283,6 +2383,8 @@ public:

where

+
getArray
+
Get the introspection interface.
dumpValue
Method for streams I/O.
view
@@ -2297,13 +2399,12 @@ public:
reuse
Remove and return the current array data or an unique copy if shared.
-

TBD +

TBD

Check for completeness
Michael should check that PVScalarArray and PVValueArray have the correct set of methods and that the descriptions are correct.
-

PVStructureArray

@@ -2343,11 +2444,6 @@ public: DeserializableControl *pflusher); virtual std::ostream& dumpValue(std::ostream& o) const; virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const; - // inherited from PVVectorStorage - const_svector view(); - void swap(const_svector& other); - void replace(const const_svector& next); - svector reuse(); ... }

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. -
createPVUnion
+
createPVUnion
Create an instance of a PVUnion. Two methods are provided. The first uses a previously created union introspection interface. The second clones an existing PVUnion.
-
createPVVariantUnion
+
createPVVariantUnion
Creates an instance of a variant PVUnion. This is a union which has a single field which can be any pvData supported type,
@@ -2740,7 +2836,7 @@ void copy( size_t count);

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:

from
@@ -2763,20 +2859,21 @@ other copy functions. The arguments are:

An exception is thrown if:

-
type mismatch
+
type mismatch
The element types for the source and destination differ.
immutable
-
The destination array is immutable. +
The destination array is immutable.
capacity immutable
The destination array needs to have it's capacity extended but the capacity is immutable.
-

pvDataApp/property

+

src/property

Definition of Property

-

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

pvDataApp/factory

+

src/factory

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

-

pvDataAPP/misc

+

src/misc

Overview

@@ -3560,7 +3657,7 @@ implements getConvert.

More support for serializing objects.
sharedPtr.h
Defines POINTER_DEFINITIONS.
-
sharedVector.h +
sharedVector.h
Like std::vector except that std::shared_ptr is used for the data array.
status.h
@@ -3608,7 +3705,6 @@ public: BitSet& operator&=(const BitSet& set); BitSet& operator|=(const BitSet& set); BitSet& operator^=(const BitSet& set); - BitSet& operator-=(const BitSet& set); BitSet& operator=(const BitSet &set); void or_and(const BitSet& set1, const BitSet& set2); bool operator==(const BitSet &set) const; @@ -3667,10 +3763,6 @@ std::ostream& operator<<(std::ostream& o, const BitSet& b);
operator^=(const BitSet& set)
Performs a logical exclusive or of this target bit set with the argument bit set.
-
operator-=(const BitSet& set)
-

Clears all of the bits in this bitSet whose corresponding bit is set - in the specified bitSet.

-
operator=(const BitSet &set)
Assignment operator.
or_and(const BitSet& set1, const BitSet& set2)
@@ -3687,7 +3779,6 @@ std::ostream& operator<<(std::ostream& o, const BitSet& b); *flusher);
Deserialize the bitSet.
-

byteBuffer.h

@@ -3922,15 +4013,13 @@ once. This can be implemented as follows:

if(alreadyInitialized) return; // initialization } -

-

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:

createRequest
@@ -4802,9 +4891,7 @@ Monitor provides: of pvAccess but only pvData.
-

- -

support for copy

+

src/copy

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 -

support for monitor

-

This consists of two components: +

src/monitor

+

This consists of two components:

monitor
Used by code that implements pvAccess monitors.
monitorPlugin
Code that provides special semantics for monitors.
-

monitor

 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: +

pvStructurePtr
A top level structure with data values at the time the monitors occurs.
@@ -5018,13 +5105,13 @@ It has the fields:
overrunBitSet
Shows which fields have changed more than once since the previous monitor.
-

monitorElement queue

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

MonitorRequester

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 copy
. The implementation should not modify the fields in the structure being monitored. Called with pvTop locked. @@ -5193,7 +5279,7 @@ It has methods:

pairs. name is the subField name and value is the subField value.
Note that a plugin will below to a single client. -
+

MonitorPluginManager

MonitorPluginManager has the methods:

@@ -5221,6 +5307,7 @@ Should the method causeMonitor have arguments pvField and pvTop be defined so that they can not be modified. This would be possible if the following was defined: +

 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: