From 2818b0384ce73e1f9bb52993b25ed85a86ff201a Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Tue, 30 Sep 2014 15:06:43 -0400 Subject: [PATCH 01/15] flow: Created branch 'release/4.0'. From 19a181b38f99d1f3dd795b95805da35fccafa57a Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Tue, 30 Sep 2014 15:26:23 -0400 Subject: [PATCH 02/15] change ev4:nt: to 3v4:nt/ --- documentation/pvDataCPP.html | 34 +++++++++++++++++----------------- src/factory/StandardField.cpp | 14 +++++++------- src/pv/standardField.h | 2 +- src/pv/standardPVField.h | 2 +- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html index 1d80ff6..c872b15 100644 --- a/documentation/pvDataCPP.html +++ b/documentation/pvDataCPP.html @@ -254,7 +254,7 @@ structure int userTag easy way -uri:ev4:nt/2014/pwd:NTScalarArray +ev4:nt/NTScalarArray:1.0 string[] value alarm_t alarm int severity @@ -274,7 +274,7 @@ via standardField:

It produces :
-uri:ev4:nt/2014/pwd:NTScalarArray
+ev4:nt/NTScalarArray:1.0
     string[] value
     alarm_t alarm
         int severity
@@ -302,7 +302,7 @@ A hard way to create an structure with an enumerated value field and a time stam
 
     StructureConstPtr ntEnumHard =
     fieldCreate->createFieldBuilder()->
-        setId("uri:ev4:nt/2014/pwd/NTEnum")->
+        setId("ev4:nt/NTEnum:1.0")->
         add("value", enum_t)->
         addNestedStructure("timeStamp")->
             setId("time_t")->
@@ -315,7 +315,7 @@ A hard way to create an structure with an enumerated value field and a time stam
 
It produces:
-uri:ev4:nt/2014/pwd/NTEnum
+ev4:nt/NTEnum:1.0
     enum_t value
         int index
         string[] choices
@@ -332,7 +332,7 @@ fields: alarm and timeStamp:

It produces:
-uri:ev4:nt/2014/pwd:NTEnum
+ev4:nt/NTEnum
     enum_t value
         int index
         string[] choices
@@ -372,7 +372,7 @@ union
         int userTag
 
 structure with value field being a union
-uri:ev4:nt/2014/pwd:NTUnion
+ev4:nt/NTUnion:1.0
     union value
         double doubleValue
         int intValue
@@ -470,7 +470,7 @@ structure
 
This produces:
-uri:ev4:nt/2014/pwd:NTScalar 
+ev4:nt/NTScalar:1.0
     double value 100000
     alarm_t alarm
         int severity 0
@@ -503,7 +503,7 @@ from get 100000
 
This produces:
-uri:ev4:nt/2014/pwd:NTScalarArray 
+ev4:nt/NTScalarArray:1.0
     double[] value [0,1,2,3,4,5,6,7,8,9]
     alarm_t alarm
         int severity 0
@@ -524,7 +524,7 @@ via getData 0 1 2 3 4 5 6 7 8 9
 
This produces:
-uri:ev4:nt/2014/pwd:NTEnum 
+ev4:nt/NTEnum:1.0
     enum_t value
         int index 0
         string[] choices []
@@ -610,7 +610,7 @@ structure
 
This produces:
-uri:ev4:nt/2014/pwd:NTUnion
+ev4:nt/NTUnio:1.0
     union value
         time_t
             long secondsPastEpoch 1000
@@ -625,7 +625,7 @@ uri:ev4:nt/2014/pwd:NTUnion
         int nanoseconds 0
         int userTag 0
 0x60a2c8
-uri:ev4:nt/2014/pwd:NTUnion
+ev4:nt/NTUnio:1.0
     union value
         double  100000
     alarm_t alarm
@@ -657,7 +657,7 @@ uri:ev4:nt/2014/pwd:NTUnion
 
This produces:
-uri:ev4:nt/2014/pwd:NTUnion
+ev4:nt/NTUnio:1.0
     any value
         time_t
             long secondsPastEpoch 1000
@@ -672,7 +672,7 @@ uri:ev4:nt/2014/pwd:NTUnion
         int nanoseconds 0
         int userTag 0
 0x60a2c8
-uri:ev4:nt/2014/pwd:NTUnion
+ev4:nt/NTUnio:1.0
     any value
         double  100000
     alarm_t alarm
@@ -732,7 +732,7 @@ uri:ev4:nt/2014/pwd:NTUnion
 This produces:
 
 introspection
-uri:ev4:nt/2014/pwd:NTUnion
+ev4:nt/NTUnio:1.0
     union value
         double doubleValue
         double[] doubleArrayValue
@@ -768,7 +768,7 @@ uri:ev4:nt/2014/pwd:NTUnion
         int userTag
 0x60a2c8
 data
-uri:ev4:nt/2014/pwd:NTUnion
+ev4:nt/NTUnion:1.0
     union value
         (none)
     alarm_t alarm
@@ -781,7 +781,7 @@ uri:ev4:nt/2014/pwd:NTUnion
         int userTag 0
 0x60a2c8
 select valueDouble
-uri:ev4:nt/2014/pwd:NTUnion
+ev4:nt/NTUnion:1.0
     union value
         double  1.55
     alarm_t alarm
@@ -795,7 +795,7 @@ uri:ev4:nt/2014/pwd:NTUnion
 0x60a2c8
 value = 1.55
 select structValue
-uri:ev4:nt/2014/pwd:NTUnion
+ev4:nt/NTUnion:1.0
     union value
         structure
             double doubleValue 1.65
diff --git a/src/factory/StandardField.cpp b/src/factory/StandardField.cpp
index 7a3711e..efc3086 100644
--- a/src/factory/StandardField.cpp
+++ b/src/factory/StandardField.cpp
@@ -503,28 +503,28 @@ StructureConstPtr StandardField::scalar(
     ScalarType type,string  const &properties)
 {
     ScalarConstPtr field = fieldCreate->createScalar(type); // scalar_t
-    return createProperties("ev4:nt:NTScalar:1.0",field,properties);
+    return createProperties("ev4:nt/NTScalar:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::regUnion(
     UnionConstPtr const &field,
         string const & properties)
 {
-   return createProperties("ev4:nt:NTUnion:1.0",field,properties);
+   return createProperties("ev4:nt/NTUnion:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::variantUnion(
     string const & properties)
 {
     UnionConstPtr field =  fieldCreate->createVariantUnion();
-    return createProperties("ev4:nt:NTUnion:1.0",field,properties);
+    return createProperties("ev4:nt/NTUnion:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::scalarArray(
     ScalarType elementType, string  const &properties)
 {
     ScalarArrayConstPtr field = fieldCreate->createScalarArray(elementType); // scalar_t[]
-    return createProperties("ev4:nt:NTScalarArray:1.0",field,properties);
+    return createProperties("ev4:nt/NTScalarArray:1.0",field,properties);
 }
 
 
@@ -533,7 +533,7 @@ StructureConstPtr StandardField::structureArray(
 {
     StructureArrayConstPtr field = fieldCreate->createStructureArray(
         structure);
-    return createProperties("ev4:nt:NTStructureArray:1.0",field,properties);
+    return createProperties("ev4:nt/NTStructureArray:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::unionArray(
@@ -541,7 +541,7 @@ StructureConstPtr StandardField::unionArray(
 {
     UnionArrayConstPtr field = fieldCreate->createUnionArray(
         punion);
-    return createProperties("ev4:nt:NTUnionArray:1.0",field,properties);
+    return createProperties("ev4:nt/NTUnionArray:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::enumerated()
@@ -560,7 +560,7 @@ StructureConstPtr StandardField::enumerated()
 StructureConstPtr StandardField::enumerated(string  const &properties)
 {
     StructureConstPtr field = enumerated(); // enum_t
-    return createProperties("ev4:nt:NTEnum:1.0",field,properties);
+    return createProperties("ev4:nt/NTEnum:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::alarm()
diff --git a/src/pv/standardField.h b/src/pv/standardField.h
index a746234..f0dbf90 100644
--- a/src/pv/standardField.h
+++ b/src/pv/standardField.h
@@ -122,7 +122,7 @@ public:
      */
     StructureConstPtr enumerated();
     /** Create a structure that has an enumerated structure value field
-     * The id for the structure is "ev4:nt:NTEnum:1.0".
+     * The id for the structure is "ev4:nt/NTEnum:1.0".
      * @param properties A comma separated list of properties.
      * This is some combination of "alarm,timeStamp,display,control,valueAlarm".
      * @return The const shared pointer to the structure.
diff --git a/src/pv/standardPVField.h b/src/pv/standardPVField.h
index e267c17..5b35afe 100644
--- a/src/pv/standardPVField.h
+++ b/src/pv/standardPVField.h
@@ -84,7 +84,7 @@ public:
     PVStructurePtr enumerated(StringArray const &choices);
     /**
      * Create a structure that has an enumerated structure value field.
-     * The id for the structure is "ev4:nt:NTEnum:1.0".
+     * The id for the structure is "ev4:nt/NTEnum:1.0".
      * @param choices This is a StringArray of choices.
      * @param properties A comma separated list of properties.
      * @return The const shared pointer to the structure.

From 6127763302b93d9afe6062654d6d4ed4a2b39256 Mon Sep 17 00:00:00 2001
From: Marty Kraimer 
Date: Tue, 30 Sep 2014 16:59:37 -0400
Subject: [PATCH 03/15] Added tag 4.0.0 for changeset 1348c22b1258

---
 .hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags b/.hgtags
index 1c3718d..145b55d 100644
--- a/.hgtags
+++ b/.hgtags
@@ -11,3 +11,4 @@ d70c5ad29163306f50979a95b5aebbe9a93cfe76 2.0-BETA
 58092712d092ee521d1e1c8fa596a67f7d113ee9 3.0.2
 40b681ffc5cd609320e3f8ffc8eb6aa3bfdfbf19 before_merge_changesAfter3_0_2
 260f35b9c6cad113f242c83c89be9cdac802f610 3.1.0
+1348c22b125861ecb9da95b23f20314b167ee155 4.0.0

From 3e645f3c791327d168221dab0cf9f38f92533662 Mon Sep 17 00:00:00 2001
From: dhickin 
Date: Fri, 3 Oct 2014 15:24:20 +0100
Subject: [PATCH 04/15] Corrected spelling in pvDataCPP.html.

---
 documentation/pvDataCPP.html | 186 +++++++++++++++++------------------
 1 file changed, 93 insertions(+), 93 deletions(-)

diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html
index c872b15..fba8398 100644
--- a/documentation/pvDataCPP.html
+++ b/documentation/pvDataCPP.html
@@ -68,7 +68,7 @@ license.

EPICS Version 4 provides efficient storage, access, and communication, of memory resident structured data. -pvData is the storage compoment. +pvData is the storage component. pvDataCPP is the C++ implementation of pvData. It is one part of the set of related products in the EPICS V4 control system programming environment:
@@ -97,7 +97,7 @@ TODO.md describes things to do before the next release.

pvData is one of a set of related projects. It describes and implements data that the other projects support. Thus it is not useful by itself but understanding pvData is required in order to understand the other projects. The -reader should also become familar with project pvAccess, which is +reader should also become familiar with project pvAccess, which is located via the same sourceforge site as this project.

The Java and C++ implementation of pvData implement the same data model but @@ -107,7 +107,7 @@ differ in implementation because of the differences between Java and C++.

first two chapters:

Introduction
-
A brief descripton of pvData.
+
A brief description of pvData.
PVData Meta Language
A language used to describe data.
@@ -172,11 +172,11 @@ StandardPVFieldPtr standardPVField = getStandardPVField();
This creates instances of data objects.
standardField
-
This provides support for introspection obects for standard fields, +
This provides support for introspection objects for standard fields, Standard fields are alarm, timeStamp, display, enumerated structure, and value alarm.
standardPVField
-
This provides support for data obects for standard fields, +
This provides support for data objects for standard fields,
@@ -245,7 +245,7 @@ structure int nanoseconds int userTag -hardway +hard way structure double value time_t timeStamp @@ -639,7 +639,7 @@ ev4:nt/NTUnio:1.0 0x60a2c8
-

varient union example

+

variant union example

     PVStructurePtr pvStructure = pvDataCreate->createPVStructure(
         standardField->variantUnion("alarm,timeStamp"));
@@ -821,10 +821,10 @@ value = 1.65
      // ...
 }}
-

Memory Managemment

+

Memory Management

Many pvDataCPP introspection and data objects are designed to be shared. They are -made availiable via std::tr1::shared_ptr. +made available via std::tr1::shared_ptr. The following naming convention is used in typedefs:

@@ -847,14 +847,14 @@ Test programs appears in testApp/pv.

NOTES:

interface
-
The documention uses the word interface. +
The documentation uses the word interface. This is an analogy with how Java defines interface. C++ does not have interfaces but directory pv defines classes with public members that are similar to the Java interfaces. Most of the implementation is in factory.
-
Naming Convertions
-
The naming convertions for variables, methods, and classes follow the - Java convertions, i. e. class name begin with an upper case letter, +
Naming Conventions
+
The naming conventions for variables, methods, and classes follow the + Java conventions, i. e. class name begin with an upper case letter, variables and methods begin with a lower case letter.
@@ -885,14 +885,14 @@ copying data between fields.

Provides access to introspection interfaces for standard structures like timeStamp, alarm, etc.
standardPVField.h
-
Cteates data interfaces for standard data structures like timeStamp, +
Creates data interfaces for standard data structures like timeStamp, alarm, etc.

pvType.h

This provides C/C++ definitions for the pvData primitive types: boolean, -byte, short, int, long, ubyte,ushort, uint,u long,float, double, and string. +byte, short, int, long, ubyte, ushort, uint, ulong, float, double, and string. Because pvData is network data, the C++ implementation must implement the proper semantics for the primitive types.

@@ -938,7 +938,7 @@ typedef std::vector<std::string>::const_iterator StringArray_const_iterato in a future implementation they should be changes via "#ifdef" preprocessor statements.
std::string
-
pvData requires that a string be an immutable string that is transfered +
pvData requires that a string be an immutable string that is transferred 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. @@ -971,10 +971,10 @@ than showing the entire file, it will be described in parts.

The primary purpose for pvData is to support network access to structured data. pvAccess transports top level pvStructures. In addition a pvAccess server holds a set of pvnames, where each name is a unique name in the local network. -This is also refered to as the channel name. +This is also referred to as the channel name.

-

Given a pvname , it is possible to introspect the types of the associated data +

Given a pvname, it is possible to introspect the types of the associated data access to data. The reflection and data interfaces are separate because the data may not be available. For example when a pvAccess client connects to a pvname, the client library can obtain the reflection information without obtaining any @@ -1035,8 +1035,8 @@ std::ostream& operator<<(std::ostream& o, const ScalarType& sc structure introspection interface.

union_t
This is like a structure that has a single subfield. - The type for the subfield can either be any type, which is called a varient union, - of can be one od a specified set of types. + The type for the subfield can either be any type, which is called a variant union, + of can be one of a specified set of types. In the data interfaces the type can be changed dynamically. '
unionArray
@@ -1120,15 +1120,15 @@ following:

Has fields that can be any of the supported types.
StructureArray
The field holds an array of structures. Each element has the same - Structure interspection interface. A pvAccess client can only get/put + Structure introspection interface. A pvAccess client can only get/put entire PVStructure elements NOT subfields of array elements.
Union
- This has two flavors: a varient union or a union of a fixed set + This has two flavors: a variant union or a union of a fixed set of types. A PVUnion will have a single subfield. - If the union introspection interface is a varient union then + If the union introspection interface is a variant union then the single field can be of any type and has the name any. - If the union is not a varient type then the type can be one of + If the union is not a variant type then the type can be one of a fixed set of types and a name associated with the type. The union introspection interface has a field array and a string array that has the fixed set of types and associated names. @@ -1136,7 +1136,7 @@ following:

UnionArray
This is an array of unions. A PVUnionArray is an array - of PVUnions. Each element has the same interspection interface + of PVUnions. Each element has the same introspection interface but the subfield of each element can have a different type.
FieldBuilder
@@ -1369,10 +1369,10 @@ public:
getNumberFields
Get the number of possible field types. Both getFields and getFieldNames will return an array with getNumberFields elements. - A value of 0 is returned for invarient arrays. + A value of 0 is returned for invariant arrays.
getField
-
Given a name ot an index the type is returned. +
Given a name or an index the type is returned. NULL is returned if not found.
getFieldIndex
@@ -1384,7 +1384,7 @@ public:
getFieldName
Get the name for the specified index.
isVariant
-
returns true if this is varient array and false otherwise. +
returns true if this is variant array and false otherwise.

fieldBuilder and createField

@@ -1519,13 +1519,13 @@ description of the methods.
       
createVariantUnion
- Create a varient union. The id will be any. + Create a variant union. The id will be any.
createUnionArray
Create a union array. punion is the introspection interface for each element.
createVariantUnionArray
-
Create a union array where each element is a varient union.
+
Create a union array where each element is a variant union.
createStructureArray
Create a structure array introspection instance.
appendField
@@ -1622,8 +1622,8 @@ public: will be created with the first element being a union with the specified scalar type and name value. The other fields in the structure will be the corresponding property structures. -
varient`Union
-
Create a varient union. A structure +
variant`Union
+
Create a variant union. A structure will be created with the first element being a union with the specified scalar type and name value. The other fields in the structure will be the corresponding property structures.
@@ -1679,7 +1679,7 @@ showing the entire file, it will be described in parts.

typedefs

These are typedefs for Array and Ptr for the various pvData class -definitions, i.e. typdefs for "std::vector" and "std::tr1::shared_ptr".

+definitions, i.e. typedefs for "std::vector" and "std::tr1::shared_ptr".

 class PVField;
 class PVScalar;
@@ -1830,7 +1830,7 @@ std::ostream& operator<<(std::ostream& o, const PVField& f);
       name will be an empty string.
   
getFullName
Fully expand the name of this field using the - names of its parent fields with a dot '.' seperating + names of its parent fields with a dot '.' separating each name.
getFieldOffset
@@ -2026,9 +2026,9 @@ pv->putFrom<pvInt>(val);

A PVUnion has a single subfield. The Union introspection interface determines the possible field types for the subfield. -If it is a varient union then any type is allowed and the +If it is a variant union then any type is allowed and the subfield name is normally any. -If it is not a varient union that the Union interface determines +If it is not a variant union that the Union interface determines the possible field types and names.

 class PVUnion : public PVField
@@ -2069,7 +2069,7 @@ public:
    
getUnion
Get the introspection interface.
get
-
Get the curent field. A template version does the conversion. +
Get the current field. A template version does the conversion. NULL is returned if no field is selected or if the caller ' asks for the wrong type.
@@ -2133,7 +2133,7 @@ public:
setCapacityMutable
Specify if the capacity can be changed.
setCapacity
-
Set the capaciity.
+
Set the capacity.
dumpValue
ostream method
@@ -2143,7 +2143,7 @@ public:

PVScalarArray

PVScalarArray is the base class for scalar array data. PVValueArray is a -templete for the various scalar array data classes. There is a class for each +template for the various scalar array data classes. There is a class for each possible scalar type, i. e. PVBooleanArray, ..., PVStringArray.

 class PVScalarArray : public PVArray {
@@ -2179,13 +2179,13 @@ public:
      
Assign the given value after conversion. A copy and element-wise conversion is performed unless the element type of the PVScalarArray matches the type of the provided data. - If the types do match then a new refernce to the provided data is kept. + If the types do match then a new reference to the provided data is kept.
assign
Assign the given PVScalarArray's value. A copy and element-wise conversion is performed unless the element type of the PVScalarArray matches the type of the provided data. - If the types do match then a new refernce to the provided data is kept. + If the types do match then a new reference to the provided data is kept.
@@ -2238,7 +2238,7 @@ public: A non-null result is returned if fieldName is a field of the PVStructure. The fieldName can be of the form name.name... - If the field does not exist the a Ptr to a NULL value is returned + 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.
@@ -2493,7 +2493,7 @@ PVDoublePtr pvDouble = getPVDataCreate()->createPVScalar<PVDouble>(); The second clones an existing PVUnion.
createPVVariantUnion
-
Creates an instance of a varient PVUnion. +
Creates an instance of a variant PVUnion. This is a union which has a single field which can be any pvData supported type,
createPVScalarArray
@@ -2768,7 +2768,7 @@ other copy functions. The arguments are:

immutable
The destination array is immutable.
capacity immutable
-
The destination array needs to have it's capacity extentended +
The destination array needs to have it's capacity extended but the capacity is immutable.
@@ -2783,7 +2783,7 @@ considered properties of the value field. The fieldname is also the property name. The value field can have any type, i.e. scalar, scalarArray, or structure. Typical property fields are timeStamp, alarm, display, control, and history. The timeStamp is a special case. If it appears anywhere in the -structure hieraracy above a value field it is a property of the value field.

+structure hierarchy above a value field it is a property of the value field.

For example the following top level structure has a single value field. The value field has properties alarm, timeStamp, and display.

@@ -2882,7 +2882,7 @@ general purpose clients.

characteristics for the value field.
history
Provides a history buffer for the value field. Note that currently - PVData does not define history suppoprt.
+ PVData does not define history support.
other
Other standard properties can be defined.
@@ -2950,7 +2950,7 @@ seconds is kept as a 64 bit integer, it allows for a time much greater than the present age of the universe. Since the nanoseconds portion is kept as a 32 bit integer it is subject to overflow if a value that corresponds to a value that is greater than a little more than 2 seconds of less that about -2 seconds. The -support code always adjust seconds so that the nanoSecconds part is normlized, +support code always adjust seconds so that the nanoseconds part is normalized, i. e. it has is 0<=nanoseconds<nanoSecPerSec..

Two header files are provided for manipulating time stamps:

@@ -3015,7 +3015,7 @@ public:

where

TimeStamp()
-
The defauly constuctor. Both seconds and nanoseconds are set to 0.
+
The default constructor. Both seconds and nanoseconds are set to 0.
TimeStamp(int64 secondsPastEpoch,int32 nanoseconds = 0)
A constructor that gives initial values to seconds and nanoseconds.
normalize
@@ -3282,7 +3282,7 @@ public:

where

Control
-
The default constructure.
+
The default constructor.
getLow
Get the low limit.
getHigh
@@ -3376,7 +3376,7 @@ public:

where

Control
-
The default constructure.
+
The default constructor.
getLow
Get the low limit.
getHigh
@@ -3477,7 +3477,7 @@ public:
detach
Just detaches from the pvData structure.
isAttached
-
Is there an attachment to an enemerated structure?
+
Is there an attachment to an enumerated structure?
setIndex
Set the index field in the pvData structure. An exception is thrown if not attached to a pvData structure.
@@ -3566,7 +3566,7 @@ implements getConvert.

status.h
A way to pass status information to a client.
templateMeta.h
-
TBD Michael can You provide an explaination?
+
TBD Michael can You provide an explanation?
thread.h
Provides thread support.
timeFunction.h
@@ -3575,7 +3575,7 @@ implements getConvert.

An implementation of Timer that does not require an object to be created for each timer request.
typeCast.h
-
TBD Michael can You provide an explaination?
+
TBD Michael can You provide an explanation?

Note that directory testApp/misc has test code for all the classes in misc. @@ -3815,7 +3815,7 @@ public:

wait
Wait until event is full or until timeout. The return value is (false,true) if the wait completed because event (was not, was) full. A - false value normally means that that a timeout occured. It is also + false value normally means that that a timeout occurred. It is also returned if an error occurs or because the event is being deleted.
tryWait
returns (false,true) if the event is (empty,full)
@@ -3927,7 +3927,7 @@ once. This can be implemented as follows:

 bool locked;
 
-and improves efficency by checking the local variable before calling the +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.

@@ -4038,8 +4038,8 @@ public:

noDefaultMethods.h

If a class privately extends this class then the compiler can not create any -of the following: default constructor, default copy constructror, or default -assignment contructor.

+of the following: default constructor, default copy constructor, or default +assignment constructor.

/* This is based on Item 6 of
  * Effective C++, Third Edition, Scott Meyers
  */
@@ -4049,7 +4049,7 @@ assignment contructor.

NoDefaultMethods(){}; ~NoDefaultMethods(){} private: - // do not implment + // do not implement NoDefaultMethods(const NoDefaultMethods&); NoDefaultMethods & operator=(const NoDefaultMethods &); };
@@ -4058,7 +4058,7 @@ assignment contructor.

This provides a bounded queue. When the queue is full the user code is expected to keep using the current element until a new -free element becomes avalable.

+free element becomes available.

 template <typename T>
 class Queue
@@ -4089,7 +4089,7 @@ public:
   
getNumberFree
Get the number of free elements in the queue.
capacity
-
Get the capacity, i.e. the maximun number of elements the queue can +
Get the capacity, i.e. the maximum number of elements the queue can hold.
getNumberFree
Get the number of free elements.
@@ -4237,7 +4237,7 @@ public:

serializeHelper.h

This is a helper class for serialization, which is required for sending and -receiving pvData over the nerwork.

+receiving pvData over the network.

class SerializeHelper : public NoDefaultMethods {
 public:
     static void writeSize(int s, ByteBuffer* buffer,
@@ -4278,7 +4278,7 @@ public:
 
 

sharedVector.h

-shared_vector is a holder for a contigious piece of memory. +shared_vector is a holder for a contiguous piece of memory. Data is shared, but offset and length are not. This allows one vector to have access to only a subset of a piece of memory.

@@ -4318,7 +4318,7 @@ shared_vector differs from std::vector as follows:

shared_vector has additional constructors from raw pointers and shared_ptr s. The copy constructor and assignment operator allow implicit castings from type 'shared_vector<T>' to 'shared_vector<const T>>'. - To faciliate safe modification the methods unique() and make_unique() are provided + To facilitate safe modification the methods unique() and make_unique() are provided The slice() method selects a sub-set of the shared_vector. The low level accessors dataPtr(), dataOffset(), dataCount(), and dataTotal(). @@ -4400,7 +4400,7 @@ public: where
shared_vector
-
Several flavors of constructor are provided. The most commingly used is: +
Several flavors of constructor are provided. The most commonly used is:
 shared_vector(size_t c);
        
@@ -4425,7 +4425,7 @@ shared_vector(size_t c); is the sole owner of the data array.
begin,...,rend
-
Standard interators.
+
Standard iterators.
front
Return a reference to the first element.
back
@@ -4456,7 +4456,7 @@ shared_vector(size_t c);
slice
Reduce the view of this shared_vector.
dataPtr
-
A readonly shared_ptr to the array.
+
A read-only shared_ptr to the array.
dataOffset
Offset in the data array of first visible element.
dataCount
@@ -4566,7 +4566,7 @@ public:

Runnable must be implement by code that wants to be run via a thread. It has one virtual method: run. Run is the code that is run as a thread. When run -compeletes it can not be restarted. If code wants to delete a thread then it +completes it can not be restarted. If code wants to delete a thread then it MUST arrange that the run returns before the thread can be deleted. An exception is thrown if run remains active when delete is called.

@@ -4588,7 +4588,7 @@ exception is thrown if run remains active when delete is called.

TimeFunction is a facility that measures the average number of seconds a function call requires. When timeCall is called, it calls function in a loop. It starts with a loop of one iteration. If the total elapsed time is less then -.1 seconds it increases the number of iterrations by a factor of 10. It keeps +.1 seconds it increases the number of iterations by a factor of 10. It keeps repeating until the elapsed time is greater than .1 seconds. It returns the average number of seconds per call.

class TimeFunctionRequester;
@@ -4676,9 +4676,9 @@ public:
 
callback
This is called when a timer expires. This is called with no locks held. - When called a delay timer is no longer on the queue but a periodioc timer + When called a delay timer is no longer on the queue but a periodic timer is on a queue. Thus the callback for a delay timer can issue a new - schedule request but a periodic timer must not. Note the explaination of + schedule request but a periodic timer must not. Note the explanation of TimerNode.cancel below.
timerStopped
Timer.stop was called when a timer request was queued. or if the timer @@ -4707,7 +4707,7 @@ be used to schedule multiple callbacks. It has the methods:

Timer has the methods:

Timer
-
The consttructor.
+
The constructor.
~Timer
The destructor. The queue is emptied and TimerCallback.timerStopped is called for each element of the queue.
@@ -4763,7 +4763,7 @@ provides a language independent overview of copy and monitor.

NOTE:pvRequest.html must be updated since it is based on an earlier version of pvCopy that -had knowlege of PVRecord. The C++ version was implemented in pvDatabaseCPP +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.

@@ -4776,13 +4776,13 @@ At present only the C++ version of the new API for pvCopy is implemented. Given an ascii string createRequest creates a PVStructure that provides a pvData representation of the information from the ascii string. It is this structure that can be passed to the channel create methods.
- The information in a pvRequest selects an arbitrarary subset of the + The information in a pvRequest selects an arbitrary subset of the fields in a top level structure that resides in the server. In addition options can be specified. Both global and field specific options can be specified.
pvCopy
-
This is a faculity used by channel providers. +
This is a facility used by channel providers. It provides client specific code that manages a copy of an arbitrary subset of the fields in a top level structure that resides in the provider. It also allows provider access to options specified @@ -4898,7 +4898,7 @@ where This is the method for creating a PVCopy instance.
pvMaster
-
the top level sructure managed by the server.
+
the top level structure managed by the server.
pvRequest
selects the set of subfields desired and options for each field.
@@ -4954,12 +4954,12 @@ where
updateCopyFromBitSet
For each set bit in bitSet set the field in copyPVStructure to the value - of the corrseponding field in pvMaster. + of the corresponding field in pvMaster.
updateMaster
For each set bit in bitSet set the field in pvMaster to the value - of the corrseponding field in copyPVStructure. + of the corresponding field in copyPVStructure.
getOptions
@@ -4979,7 +4979,7 @@ where

This consists of two components:

monitor
-
Used by code that implements pvAccess montors.
+
Used by code that implements pvAccess monitors.
monitorPlugin
Code that provides special semantics for monitors.
@@ -5016,7 +5016,7 @@ It has the fields:
changedBitSet
Shows which fields have changed since the previous monitor.
overrunBitSet
-
Shows which fields have changed more han once since the previous monitor.
+
Shows which fields have changed more than once since the previous monitor.

monitorElement queue

@@ -5059,7 +5059,7 @@ Note that each client has it's own queue that is not shared with other client.
start
Start monitoring. - This will result in a an inital monitor that has the current value + This will result in a an initial monitor that has the current value of all fields.
stop
@@ -5069,11 +5069,11 @@ Note that each client has it's own queue that is not shared with other client.
poll
Called to get a monitor element. - If no new elemants are available then a null pointer is returned. + If no new elements are available then a null pointer is returned.
release
- Release the monotor element. + Release the monitor element. The caller owns the monitor element between the calls to poll and release.
@@ -5201,7 +5201,7 @@ It has methods:

MonitorPluginManager is a singleton. The first call to get will create the single instance. - Further calls will rerurn the single instance. + Further calls will return the single instance.
addPlugin
@@ -5209,18 +5209,18 @@ It has methods:

findPlugin
- Find a plugin. A NULL shared pointer is reurned if it has not been added. + Find a plugin. A NULL shared pointer is returned if it has not been added.
showNames
- Show the names of all puugins that have been added. + Show the names of all plugins that have been added.

NOTE: Should the method causeMonitor have arguments pvField and pvTop -be defined so that they can not be modfied. -This would be posssible if the following was defined: +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;
@@ -5232,7 +5232,7 @@ virtual bool causeMonitor(
         PVStructureConstPtr const &pvTop,
         MonitorElementPtr const &monitorElement) = 0;
 
-But just adding these definitions is not sufficent. +But just adding these definitions is not sufficient. In addition all methods defined in pvDataCPP must be checked. In particular many of the methods in Convert must have their arguments modified. @@ -5258,15 +5258,15 @@ structure powerSupply structure power double value structure alarm - struvture display + structure display structure voltage double value structure alarm - struvture display + structure display structure current double value structure alarm - struvture display + structure display

A pvAccess client wants to create a monitor on the powerSupply as follows: The client wants a top level structure that looks like: @@ -5282,7 +5282,7 @@ structure powerSupply double value

In addition the client wants monitors to occur only when one of the monitored -fields changes value but not just because a put occured. +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 @@ -5291,7 +5291,7 @@ client wants. It can be attached to any field via the following options: [plugin=onChange,raiseMonitor=value]

This plugin will trigger a monitor for the field only if the field changes -value. In addition value equals false means do not raise a monotor +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. From 3692f4fb3c6c5230d962204f2f0ee9aa71ffde7c Mon Sep 17 00:00:00 2001 From: dhickin Date: Fri, 3 Oct 2014 15:58:55 +0100 Subject: [PATCH 05/15] Correctly produce <> for templates in code samples for PVUnionArray in pvDataCPP.html. --- documentation/pvDataCPP.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html index fba8398..6ac2253 100644 --- a/documentation/pvDataCPP.html +++ b/documentation/pvDataCPP.html @@ -2365,10 +2365,10 @@ public:

PVUnionArray

The interface for an array of unions is:

-template&ly;&gt;
-class epicsShareClass PVValueArray&ly;PVUnionPtr&gt; : public detail::PVVectorStorage&ly;PVUnionPtr,PVArray&gt;
+template<>
+class epicsShareClass PVValueArray<PVUnionPtr> : public detail::PVVectorStorage<PVUnionPtr,PVArray>
 {
-    typedef detail::PVVectorStorage&ly;PVUnionPtr,PVArray&gt; base_t;
+    typedef detail::PVVectorStorage<PVUnionPtr,PVArray> base_t;
 public:
     POINTER_DEFINITIONS(PVUnionArray);
     typedef PVUnionPtr  value_type;
@@ -2378,8 +2378,8 @@ public:
     typedef const PVUnionArray& const_reference;
 
     //TODO: full namespace can be removed along with local typedef 'shared_vector'
-    typedef ::epics::pvData::shared_vector&ly;PVUnionPtr&gt; svector;
-    typedef ::epics::pvData::shared_vector&ly;const PVUnionPtr&gt; const_svector;
+    typedef ::epics::pvData::shared_vector<PVUnionPtr> svector;
+    typedef ::epics::pvData::shared_vector<const PVUnionPtr> const_svector;
     
     virtual ~PVValueArray() {}
     virtual ArrayConstPtr getArray() const;

From e980823294a8c796b277236be457be810ff98fe2 Mon Sep 17 00:00:00 2001
From: dhickin 
Date: Sat, 4 Oct 2014 00:22:46 +0100
Subject: [PATCH 06/15] Corrected NTUnio->NTUnion.

---
 documentation/pvDataCPP.html | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html
index 6ac2253..46d6f3e 100644
--- a/documentation/pvDataCPP.html
+++ b/documentation/pvDataCPP.html
@@ -657,7 +657,7 @@ ev4:nt/NTUnio:1.0
 
This produces:
-ev4:nt/NTUnio:1.0
+ev4:nt/NTUnion:1.0
     any value
         time_t
             long secondsPastEpoch 1000
@@ -672,7 +672,7 @@ ev4:nt/NTUnio:1.0
         int nanoseconds 0
         int userTag 0
 0x60a2c8
-ev4:nt/NTUnio:1.0
+ev4:nt/NTUnion:1.0
     any value
         double  100000
     alarm_t alarm
@@ -732,7 +732,7 @@ ev4:nt/NTUnio:1.0
 This produces:
 
 introspection
-ev4:nt/NTUnio:1.0
+ev4:nt/NTUnion:1.0
     union value
         double doubleValue
         double[] doubleArrayValue

From efbdb722e7eb31fde60374beeaff0663ed4c47e7 Mon Sep 17 00:00:00 2001
From: dhickin 
Date: Sat, 4 Oct 2014 01:28:19 +0100
Subject: [PATCH 07/15] Made sub-field/subfield consistent by changing to
 subfield.

---
 documentation/pvDataCPP.html | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html
index 46d6f3e..f081a8d 100644
--- a/documentation/pvDataCPP.html
+++ b/documentation/pvDataCPP.html
@@ -287,7 +287,7 @@ ev4:nt/NTScalarArray:1.0
 0x607188
 

enumerated structure

-

An enumerated structure is a structure with two sub-fields: +

An enumerated structure is a structure with two subfields: index, which is an int, and choices, which is an array of string. The following examples create a structure which has a field names value, which is an enumerated structure and additional fields. @@ -2481,10 +2481,10 @@ PVDoublePtr pvDouble = getPVDataCreate()->createPVScalar<PVDouble>();

createPVStructure
Create an instance of a PVStructure. Three methods are provided. - The first uses an array of field names and an array of PVFields to initialize the sub-fields. + The first uses an array of field names and an array of PVFields to initialize the subfields. The second initializes the subfields by cloning the fields contained in - structToClone. The newly created sub-fields will have the same values as the original. - If structToClone is null then the new structure is initialized to have 0 sub-fields. + structToClone. The newly created subfields will have the same values as the original. + 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
From 515282abfe57932429ff80673aecf1d41feea8ee Mon Sep 17 00:00:00 2001 From: dhickin Date: Sat, 4 Oct 2014 01:33:59 +0100 Subject: [PATCH 08/15] Spelling and typos. --- documentation/copyandmonitor.html | 40 ++++++++++++++--------------- documentation/pvArray.html | 26 +++++++++---------- documentation/pvDataDiscussion.html | 10 ++++---- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/documentation/copyandmonitor.html b/documentation/copyandmonitor.html index bf3afd2..3b25eb1 100644 --- a/documentation/copyandmonitor.html +++ b/documentation/copyandmonitor.html @@ -52,7 +52,7 @@ provides a language independent overview of copy and monitor.

NOTE:pvRequest.html must be updated since it is based on an earlier version of pvCopy that -had knowlege of PVRecord. The C++ version was implemented in pvDatabaseCPP +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.

@@ -65,13 +65,13 @@ At present only the C++ version of the new API for pvCopy is implemented. Given an ascii string createRequest creates a PVStructure that provides a pvData representation of the information from the ascii string. It is this structure that can be passed to the channel create methods.
- The information in a pvRequest selects an arbitrarary subset of the + The information in a pvRequest selects an arbitrary subset of the fields in a top level structure that resides in the server. In addition options can be specified. Both global and field specific options can be specified.
pvCopy
-
This is a faculity used by channel providers. +
This is a facility used by channel providers. It provides client specific code that manages a copy of an arbitrary subset of the fields in a top level structure that resides in the provider. It also allows provider access to options specified @@ -185,7 +185,7 @@ where This is the method for creating a PVCopy instance.
pvMaster
-
the top level sructure managed by the server.
+
the top level structure managed by the server.
pvRequest
selects the set of subfields desired and options for each field.
@@ -241,12 +241,12 @@ where
updateCopyFromBitSet
For each set bit in bitSet set the field in copyPVStructure to the value - of the corrseponding field in pvMaster. + of the corresponding field in pvMaster.
updateMaster
For each set bit in bitSet set the field in pvMaster to the value - of the corrseponding field in copyPVStructure. + of the corresponding field in copyPVStructure.
getOptions
@@ -266,7 +266,7 @@ where

This consists of two components:

monitor
-
Used by code that implements pvAccess montors.
+
Used by code that implements pvAccess monitors.
monitorPlugin
Code that provides special semantics for monitors.
@@ -346,7 +346,7 @@ Note that each client has it's own queue that is not shared with other client.
start
Start monitoring. - This will result in a an inital monitor that has the current value + This will result in a an initial monitor that has the current value of all fields.
stop
@@ -356,11 +356,11 @@ Note that each client has it's own queue that is not shared with other client.
poll
Called to get a monitor element. - If no new elemants are available then a null pointer is returned. + If no new elements are available then a null pointer is returned.
release
- Release the monotor element. + Release the monitor element. The caller owns the monitor element between the calls to poll and release.
@@ -488,7 +488,7 @@ It has methods:

MonitorPluginManager is a singleton. The first call to get will create the single instance. - Further calls will rerurn the single instance. + Further calls will return the single instance.
addPlugin
@@ -496,18 +496,18 @@ It has methods:

findPlugin
- Find a plugin. A NULL shared pointer is reurned if it has not been added. + Find a plugin. A NULL shared pointer is returned if it has not been added.
showNames
- Show the names of all puugins that have been added. + Show the names of all plugins that have been added.

NOTE: Should the method causeMonitor have arguments pvField and pvTop -be defined so that they can not be modfied. -This would be posssible if the following was defined: +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;
@@ -519,7 +519,7 @@ virtual bool causeMonitor(
         PVStructureConstPtr const &pvTop,
         MonitorElementPtr const &monitorElement) = 0;
 
-But just adding these definitions is not sufficent. +But just adding these definitions is not sufficient. In addition all methods defined in pvDataCPP must be checked. In particular many of the methods in Convert must have their arguments modified. @@ -545,15 +545,15 @@ structure powerSupply structure power double value structure alarm - struvture display + structure display structure voltage double value structure alarm - struvture display + structure display structure current double value structure alarm - struvture display + structure display

A pvAccess client wants to create a monitor on the powerSupply as follows: The client wants a top level structure that looks like: @@ -578,7 +578,7 @@ client wants. It can be attached to any field via the following options: [plugin=onChange,raiseMonitor=value]

This plugin will trigger a monitor for the field only if the field changes -value. In addition value equals false means do not raise a monotor +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. diff --git a/documentation/pvArray.html b/documentation/pvArray.html index 9f7c031..9de1fb7 100644 --- a/documentation/pvArray.html +++ b/documentation/pvArray.html @@ -68,7 +68,7 @@ license.

Changes

Since the last version of this document the following changes have -been made to the proposed interface definitionsi for PVValueArray:

+been made to the proposed interface definitions for PVValueArray:

put(const svector &from)
This has been removed. shareData can be used instead.
@@ -93,7 +93,7 @@ purpose for pvData:
pvData (Process Variable Data) defines and implements an efficent way to store, access, and communicate memory resident data structures.
This statement appears as the first sentence of pvDataJava.html. -A few sentances later the document makes clear that communication +A few sentences later the document makes clear that communication includes network communication. Thus pvData provides an interface for network accessible structured data. If the interfaces for C++ and Java are similar then @@ -160,7 +160,7 @@ PVScalar and extensions, PVArray and extensions. PVStructureArray is not discussed.

PVField

-

This is the base for all the PVXXX iterfaces. +

This is the base for all the PVXXX interfaces. It provides basic methods for allowing network transfer and for traversing structured data. The pvDataJava and pvDataCPP definitions are similar. @@ -306,7 +306,7 @@ methods:

The proposed version is like the pvDataCPP version except for dumpValue -and the stream interators.

+and the stream iterators.

pvDataJava

 interface PVScalar extends PVField {
@@ -1161,7 +1161,7 @@ typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
    
put
This is the recommended method for modifying the array elements. It may change the capacity if len asks for more elements - than the cureent capacity allows. + than the current capacity allows. It does not change the current length.
shareData
@@ -1169,7 +1169,7 @@ typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr; Note that if capacity is ever changed then data will no longer be shared. This method can also be called to force the PVValueArray to have a new - raw array. This is usefull for implementing Copy On Write. + raw array. This is useful for implementing Copy On Write. @@ -1218,12 +1218,12 @@ and start with a brief summary modeled after Section 31.3(STL Containers) in:
The subsection names are the same names that Stroustrup uses. Each subsection starts with a brief summary that is similar to -the summary Stroustrup has at the beginnining of each subsection.

+the summary Stroustrup has at the beginning of each subsection.

The comparison is always with std::vector. In addition it shows what is defined by by std::vector but not by shared_vector.

Someone who already understand the C++ STL can understand shared_vector -by just looking at the brief summarys. +by just looking at the brief summaries. For others the brief summary is followed by tutorial information.

shared_vector example

@@ -1322,7 +1322,7 @@ These are not used by any of the client methods.

Brief Summary

 C c();         Default constructor; c is empty.
-C c(n);        c is initialized with n elementis with the value value_type{};
+C c(n);        c is initialized with n elements with the value value_type{};
                offset is 0; size is n;
 C c(n,e);      Initialize c with n copies of e.
                offset is 0; size is n;
@@ -1373,7 +1373,7 @@ shared_vector(size_t n, value_type e);
 

The first three constructors all create a new shared_vector by also creating a new raw array, The difference is the size of the array, i.e. how many elements it contains, -and how the elements are initalized. +and how the elements are initialized.

shared_vector()
@@ -1405,7 +1405,7 @@ emptyArray 1 zeroArray {16}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...] oneArray {8}[1, 1, 1, 1, 1, 1, 1, 1]
-

NOTE EXISTING: Why did emptyArray disply the above. +

NOTE EXISTING: Why did emptyArray display the above. Should it be "emptyArray {0} []"?

Construct by sharing raw array from a shared_vector

@@ -1593,7 +1593,7 @@ crend() Constant last element of reverse sequence

shared_vector supports both iterators and reverse iterators as defined by the STL. For both constant iterators are also defined. -A constant iterator does not allow an array elemnent to be modified.

+A constant iterator does not allow an array element to be modified.

The following is an example of a constant iterator.

 int32 sum = 0;
@@ -1705,7 +1705,7 @@ produces:
 
 void make_unique()         Make caller the only user of std::tr1::shared_ptr
 bool unique()              Is the caller the only user of std::tr1::shared_ptr
-void slice(offset,length)  Change window offset andsize
+void slice(offset,length)  Change window offset and size
 
 // following should only be used for debugging
 const std::tr1::shared_ptr<E>&
diff --git a/documentation/pvDataDiscussion.html b/documentation/pvDataDiscussion.html
index 5f9b13b..d059dd7 100644
--- a/documentation/pvDataDiscussion.html
+++ b/documentation/pvDataDiscussion.html
@@ -70,11 +70,11 @@ license.

more and more member functions. These member functions have nothing to do with the primary primary purpose for pvData: -
pvData (Process Variable Data) defines and implements an efficent +
pvData (Process Variable Data) defines and implements an efficient way to store, access, and communicate memory resident data structures.
This statement appears as the first sentence of pvDataJava.html. -A few sentances later the document makes it clear that communication -includes efficent network communication. +A few sentences later the document makes it clear that communication +includes efficient network communication. Thus pvData provides an interface for network accessible structured data. The problem of adding member functions that have nothing to do with the primary purpose started with the Java API. @@ -82,7 +82,7 @@ It already had extra methods that solved problems that should have had a differe This document removes the extra methods so that when new problems arise in the future the solution will not involve adding new member functions to the introspection and data API.

-

The introspection and data API for pvData should only encapuslate methods that support the primary purpose +

The introspection and data API for pvData should only encapsulate methods that support the primary purpose stated above. The interfaces for C++ and Java should be similar so that someone who understands the interface in one of the languages @@ -308,7 +308,7 @@ public interface PVDataCreate { The existing Java implementation of toString displayed all elements. For large arrays this is not desirable. The new methods provide a way for the client to limit the number of elements. -The default might be set to something like display up to 10 elements with 5 fron the beginning and 5 from the end.

+The default might be set to something like display up to 10 elements with 5 from the beginning and 5 from the end.

For C++ this can be a replacement for dumpValue.

PVBooleanArray, ..., PVStructureArray

The old get and put are replaced by two new and simpler methods: From 188b94ce19ec47de7907cf15b3545c745ec825c8 Mon Sep 17 00:00:00 2001 From: dhickin Date: Sat, 4 Oct 2014 02:45:53 +0100 Subject: [PATCH 09/15] Corrected spelling of synchrotron in licence. --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 1f555ec..3f43ff2 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ Copyright (c) 2008 Martin R. Kraimer Copyright (c) 2006 The University of Chicago, as Operator of Argonne National Laboratory. -Copyright (c) 2006 Deutsches Elektronen-Synchroton, +Copyright (c) 2006 Deutsches Elektronen-Synchrotron, Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY. Copyright (c) 2007 Control System Laboratory, (COSYLAB) Ljubljana Slovenia From b1d5f7d7e570160224ac8888a0eaf00be1752392 Mon Sep 17 00:00:00 2001 From: dhickin Date: Tue, 7 Oct 2014 15:32:26 +0100 Subject: [PATCH 10/15] Corrected NTUnio to NTUnion --- documentation/pvDataCPP.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html index f081a8d..d870733 100644 --- a/documentation/pvDataCPP.html +++ b/documentation/pvDataCPP.html @@ -610,7 +610,7 @@ structure

This produces:
-ev4:nt/NTUnio:1.0
+ev4:nt/NTUnion:1.0
     union value
         time_t
             long secondsPastEpoch 1000
@@ -625,7 +625,7 @@ ev4:nt/NTUnio:1.0
         int nanoseconds 0
         int userTag 0
 0x60a2c8
-ev4:nt/NTUnio:1.0
+ev4:nt/NTUnion:1.0
     union value
         double  100000
     alarm_t alarm

From 943ea633a42cb44307bfee644c759b66d082d8aa Mon Sep 17 00:00:00 2001
From: Marty Kraimer 
Date: Wed, 8 Oct 2014 14:48:30 -0400
Subject: [PATCH 11/15] more work on pvDataCPP.html; minor changes to examples

---
 documentation/examples.zip   | Bin 102821 -> 9203 bytes
 documentation/pvDataCPP.html | 278 +++++++++++++++++++++++------------
 2 files changed, 182 insertions(+), 96 deletions(-)

diff --git a/documentation/examples.zip b/documentation/examples.zip
index 1f27dd599e79fd60f7e505a290db81cddc9bb217..dcefb77277909066077492d33a4cdcc683869287 100644
GIT binary patch
delta 4171
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 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:

From 8bf24de0b3cdffaae8d530ea44893f87f568f966 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Wed, 8 Oct 2014 15:03:52 -0400 Subject: [PATCH 12/15] removed pvArray.html and pvDataDiscussion.html; good ideas now implemented --- documentation/pvArray.html | 1842 --------------------------- documentation/pvDataDiscussion.html | 792 ------------ 2 files changed, 2634 deletions(-) delete mode 100644 documentation/pvArray.html delete mode 100644 documentation/pvDataDiscussion.html diff --git a/documentation/pvArray.html b/documentation/pvArray.html deleted file mode 100644 index 9de1fb7..0000000 --- a/documentation/pvArray.html +++ /dev/null @@ -1,1842 +0,0 @@ - - - - - - EPICS pvArray - - - - - - - - -
-

EPICS Array

- - -

EPICS v4 Working Group, Working Draft, 28-Jun-2013

- -
-
Latest version:
-
pvArray.html -
-
This version:
-
none
-
Previous version:
-
None
-
Editors:
-
Marty Kraimer, BNL
- Michael Davidsaver, BNL
-
- - -
-
- - -
-

Table of Contents

-
-
- - -

Changes

-

Since the last version of this document the following changes have -been made to the proposed interface definitions for PVValueArray:

-
-
put(const svector &from)
-
This has been removed. shareData can be used instead.
-
get
-
The get methods has been replaced by two methods. - One allows write access to array elements and the other does not. -
-
-

The stream operator++ methods were changed so that they only appear -in PVField. All the complexity should be hidden in the implementation -and, perhaps like Java, in the convert facility.

-

A few minor changes were made because of mistakes in documenting -existing API descriptions.

-

Introduction

-

This is the documentation for pvData.h as defined by pvDataCPP-md. -When complete it will be merged into pvDataCPP.html. -This document proposes an implementation of the PVXXX interfaces that are -different than the existing pvDataCPP-md interfaces. -See the next section for a comparison of the four interface descriptions. -The main reason for proposing a different definition is the primary -purpose for pvData: -

pvData (Process Variable Data) defines and implements an efficent -way to store, access, and communicate memory resident data structures.
-This statement appears as the first sentence of pvDataJava.html. -A few sentences later the document makes clear that communication -includes network communication. -Thus pvData provides an interface for network accessible structured data. -If the interfaces for C++ and Java are similar then -someone who understands the interface in one of the languages -and knows both languages will quickly understand the interface of the other language. -With only a few exceptions the naming and other conventions do -not follow the C++ standard library conventions. -The pvData.h API is similar to the definition for Java. -The differences are mainly related to language differences. -Some differences are: -
-
shared pointers
-
Java has a garbage collector. In C++ the implementation manages - memory. An important tool is std::tr1::shared_ptr.
-
PVArray
-
The Java garbage collector allows raw data arrays, e. g. int[], - to be shared. For C++ a shared_vector holds the raw data. -
-
ostream replaces toString
-
In Java every object has method toString(). - For C++ stream operator<< replaces toString
-
shared_vector
-
This is similar to std::vector but uses a shared_ptr to wrap the raw - data and also supports a window into the raw data. It does follow the - naming and other conventions for C++ standard library containers. - Code that wants to use features of the C++ standard library - like iterators and algorithms can get the shared_vector. -
-
-

There is one big difference from the existing Java API: -The method PVValueArray::get. -As an example the Java definition for PVDoubleArray is currently: -

-    int get(int offset, int length, DoubleArrayData data);
-
-This document assumes this will be replaced by: -
-    double[] get();
-
-

The existing version allowed the data source to provide the array in chunks. -The new version assumes that the data source always provides contiguous storage -for the entire raw array. If this is accepted it simplifies a lot of code. -

-

Three topics not discussed in this document are: -

-
pvDataCreate
-
There should be a new method something like: -
-PVScalarArrayPtr createPVScalarArray(const PVScalarArray &, size_t offset, size_t length);
-      
- This will share the raw data array but allow a new window. -
-
convert
-
This will be changed to do conversions itself instead of calling - methods like getAs. It will again support methods toXXXArray and fromXXXArray. - Templates should be used to minimize the code required.
-
PVStructureArray
-
This should also be able to use shared_vector to hold elements.
-
-

-

PVXXX: pvDataJava, pvDataCPP, pvDataCPP-md, and proposed interface

-

The following compares the definitions of the following: PVField, -PVScalar and extensions, PVArray and extensions. -PVStructureArray is not discussed. -

-

PVField

-

This is the base for all the PVXXX interfaces. -It provides basic methods for allowing network transfer and for -traversing structured data. -The pvDataJava and pvDataCPP definitions are similar. -pvDataCPP-md added method getFullName. -The proposed interface is like the existing pvDataCPP except that -the dumpValue method is replaced by the stream operator<<. -

-

Java

-
interface PVField extends Requester, Serializable {
-    std::string getFieldName();
-    void setRequester(Requester requester);
-    int getFieldOffset();
-    int getNextFieldOffset();
-    int getNumberFields();
-    PVAuxInfo getPVAuxInfo();
-    boolean isImmutable();
-    void setImmutable();
-    Field getField();
-    PVStructure getParent();
-    void renameField(std::string newName);
-    void postPut(); // calls PVRecordField.postPut if this is a field of a record
-    void setPostHandler(PostHandler postHandler);
-    void toString(StringBuilder buf);
-    void toString(StringBuilder buf,int indentLevel);
-    std::string toString();
-}
-

pvDataCPP

-
class PVField
-: virtual public Serializable,
-  public std::tr1::enable_shared_from_this<PVField>
-{
-public:
-   POINTER_DEFINITIONS(PVField);
-   virtual ~PVField();
-   virtual void message(std::string message,MessageType messageType);
-   std::string getFieldName() const ;
-   virtual void setRequester(RequesterPtr const &prequester);
-   std::size_t getFieldOffset() const;
-   std::size_t getNextFieldOffset() const;
-   std::size_t getNumberFields() const;
-   PVAuxInfoPtr & getPVAuxInfo()
-   bool isImmutable() const;
-   virtual void setImmutable();
-   const FieldConstPtr & getField() const ;
-   PVStructure * getParent() const
-   void replacePVField(const PVFieldPtr&  newPVField);
-   void renameField(std::string const &newName);
-   void postPut() ;
-   void setPostHandler(PostHandlerPtr const &postHandler);
-   virtual bool equals(PVField &pv);
-   virtual void toString(StringBuilder buf) ;
-   virtual void toString(StringBuilder buf,int indentLevel);
-   virtual std::ostream& dumpValue(std::ostream& o) const =0;
- ...
-}
-
-std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f);
-
-

pvDataCPP-md

-
class PVField
-: virtual public Serializable,
-  public std::tr1::enable_shared_from_this<PVField>
-{
-public:
-   POINTER_DEFINITIONS(PVField);
-   virtual ~PVField();
-   virtual void message(std::string message,MessageType messageType);
-   std::string getFieldName() const ;
-   virtual void setRequester(RequesterPtr const &prequester);
-   std::size_t getFieldOffset() const;
-   std::size_t getNextFieldOffset() const;
-   std::size_t getNumberFields() const;
-   PVAuxInfoPtr & getPVAuxInfo()
-   bool isImmutable() const;
-   virtual void setImmutable();
-   const FieldConstPtr & getField() const ;
-   PVStructure * getParent() const
-   void replacePVField(const PVFieldPtr&  newPVField);
-   void renameField(std::string const &newName);
-   void postPut() ;
-   void setPostHandler(PostHandlerPtr const &postHandler);
-   virtual bool equals(PVField &pv);
-   virtual void toString(StringBuilder buf) ;
-   virtual void toString(StringBuilder buf,int indentLevel);
-   std::ostream& dumpValue(std::ostream& o) const;
-   // not in pvDataCPP
-   std::string getFullName() const;
- ...
-}
-
-std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f);
-
-

proposed

-
-class PVField
-: virtual public Serializable,
-  public std::tr1::enable_shared_from_this
-{
-public:
-    POINTER_DEFINITIONS(PVField);
-    virtual ~PVField();
-    virtual void message(std::string message,MessageType messageType);
-    const std::string& getFieldName() const;
-    virtual void setRequester(RequesterPtr const &prequester);
-    std::size_t getFieldOffset() const;
-    std::size_t getNextFieldOffset() const;
-    std::size_t getNumberFields() const;
-    PVAuxInfoPtr & getPVAuxInfo();
-    bool isImmutable() const;
-    void setImmutable();
-    const FieldConstPtr & getField() const;
-    PVStructure * getParent() const;
-    void replacePVField(const PVFieldPtr&  newPVField);
-    void renameField(std::string const & newName);
-    void postPut();
-    void setPostHandler(PostHandlerPtr const &postHandler);
-    virtual bool equals(PVField &pv);
-    void toString(StringBuilder buf) ;
-    void toString(StringBuilder buf,int indentLevel);
-    std::ostream& operator<<(std::ostream& o) const;
-...
-};
-
-
-

PVScalar

-

The Java and pvDataCPP versions differ in that Java has an interface definition -for each scalar type, i. e. PVBoolean, ..., PVString, -and the CPP versions provide a template PVValue for the implementation.

-

-pvDataCPP-md differs from pvDataCPP in that it implements three additional -methods: -

-
getAs
-
This is used to implement the Convert::toXXX methods. - This belongs in the Convert implementation not in PVScalar.
-
putFrom
-
This is used to implement the Convert::fromXXX scalar methods. - This belongs in the Convert implementation not in PVScalar.
-
assign
-
This does the same thing as the Convert::fromXXX methods except - that it does not go through Convert. - This belongs in the Convert implementation not in PVScalar.
-
-

-

The proposed version is like the pvDataCPP version except for dumpValue -and the stream iterators.

-

pvDataJava

-
-interface PVScalar extends PVField {
-    Scalar getScalar();
-}
-
-interface PVBoolean extends PVScalar {
-    boolean get();
-    void put(boolean value);
-}
-
-interface PVByte extends PVScalar {
-    byte get();
-    void put(byte value);
-}
-...
-interface PVDouble extends PVScalar {
-    double get();
-    void put(double value);
-}
-interface PVString extends PVScalar, SerializableArray {
-    std::string get();
-    void put(std::string value);
-}
-
-

pvDataCPP

-
class PVScalar : public PVField {
-public:
-    POINTER_DEFINITIONS(PVScalar);
-    virtual ~PVScalar();
-    typedef PVScalar &reference;
-    typedef const PVScalar& const_reference;
-    const ScalarConstPtr getScalar() const ;
- ...
-}
-
-template<typename T>
-class PVScalarValue : public PVScalar {
-public:
-    POINTER_DEFINITIONS(PVScalarValue);
-    typedef T value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    virtual ~PVScalarValue() {}
-    virtual T get() const = 0;
-    virtual void put(T value) = 0;
-    std::ostream& dumpValue(std::ostream& o) const
-    void operator>>=(T& value) const;
-    void operator<<=(T value);
- ...
-}
-
-typedef PVScalarValue PVBoolean;
-typedef PVScalarValue PVByte;
-...typedef PVScalarValue PVDouble;
-typedef std::tr1::shared_ptr PVBooleanPtr;
-typedef std::tr1::shared_ptr PVBytePtr;
-...
-typedef std::tr1::shared_ptr PVDoublePtr;
-
-
-// PVString is special case, since it implements SerializableArray
-class PVString : public PVScalarValue<std::string>, SerializableArray {
-public:
-    virtual ~PVString() {}
- ...
-};
- -

pvDataCPP-md

-
class PVScalar : public PVField {
-public:
-    POINTER_DEFINITIONS(PVScalar);
-    virtual ~PVScalar();
-    typedef PVScalar &reference;
-    typedef const PVScalar& const_reference;
-    const ScalarConstPtr getScalar() const ;
-
-    // not in pvDataCPP
-    template<ScalarType ID>
-    inline typename ScalarTypeTraits<ID>::type getAs() const;
-
-    virtual void getAs(void *, ScalarType) const = 0;
-    template<ScalarType ID>
-    inline void putFrom(typename ScalarTypeTraits<ID>::type val)
-
-    virtual void putFrom(const void *, ScalarType) = 0;
-    virtual void assign(const PVScalar&) = 0;
-
- ...
-}
-
-template<typename T>
-class PVScalarValue : public PVScalar {
-public:
-    POINTER_DEFINITIONS(PVScalarValue);
-    typedef T value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    virtual ~PVScalarValue() {}
-    virtual T get() const = 0;
-    virtual void put(T value) = 0;
-    std::ostream& dumpValue(std::ostream& o) const
-    void operator>>=(T& value) const;
-    void operator<<=(T value);
-
-    // not in pvDataCPP
-    static const ScalarType typeCode;
- ...
-}
-
-typedef PVScalarValue PVBoolean;
-typedef PVScalarValue PVByte;
-...typedef PVScalarValue PVDouble;
-typedef std::tr1::shared_ptr PVBooleanPtr;
-typedef std::tr1::shared_ptr PVBytePtr;
-...
-typedef std::tr1::shared_ptr PVDoublePtr;
-
-
-// PVString is special case, since it implements SerializableArray
-class PVString : public PVScalarValue<std::string>, SerializableArray {
-public:
-    virtual ~PVString() {}
- ...
-};
-

proposed

-
-class PVScalar : public PVField {
-public:
-    POINTER_DEFINITIONS(PVScalar);
-    virtual ~PVScalar();
-
-    typedef PVScalar &reference;
-    typedef const PVScalar& const_reference;
-
-    const ScalarConstPtr getScalar() const;
-...
-};
-
-template<typename T>
-class PVScalarValue : public PVScalar {
-public:
-    POINTER_DEFINITIONS(PVScalarValue);
-    typedef T value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-
-    virtual ~PVScalarValue() {}
-    virtual T get() const = 0;
-    virtual void put(T value) = 0;
-
-    void operator>>=(T& value) const;
-    void operator<<=(T value);
-...
-};
-typedef PVScalarValue<uint8> PVBoolean;
-typedef PVScalarValue<int8> PVByte;
-typedef PVScalarValue<double> PVDouble;
-...
-typedef std::tr1::shared_ptr<PVBoolean> PVBooleanPtr;
-typedef std::tr1::shared_ptr<PVByte> PVBytePtr;
-...
-typedef std::tr1::shared_ptr<PVDouble> PVDoublePtr;
-
-// PVString is special case, since it implements SerializableArray
-class PVString : public PVScalarValue<std::string>, SerializableArray {
-public:
-    virtual ~PVString() {}
- ...
-};
-
-

PVArray

-

The Java and pvDataCPP versions differ in that Java has an interface definition -for each scalarArray type, i. e. PVBooleanArray, ..., PVStringArray, -and the CPP versions provide a template PVValueArray for the implementation.

-

-pvDataCPP-md differs from pvDataCPP in that it implements additional -methods: -

-
getAs
-
This is used to implement the Convert::toXXXArray methods. - This belongs in the Convert implementation not in PVArray.
-
putFrom
-
This is used to implement the Convert::fromXXXArray scalar methods. - This belongs in the Convert implementation not in PVArray.
-
assign
-
This does the same thing as the Convert::fromXXXArray methods except - that it does not go through Convert. - This belongs in the Convert implementation not in PVArray.
-
copyOut
-
This is used to copy data to a raw array.
-
copyIn
-
This is used to copy data in from a raw array. -
-

-

The proposed version is differs from pvJava, pvDataCPP, and pvCPP-md. -It is like the Java version if the Java get method is simplified as discussed above. -For example PVDoubleArray::get becomes: -

-    double[] get();
-
-The corresponding C++ version becomes: -
-    const svector & get();
-    const const_svector & get() const;
-
-

-

The remaining difference is that dumpValue is replaced by the stream operator<<.

-

The main difference from the pvDataJava version is that PVValueArray "wraps" shared_vector. -Thus shared_vector takes the place of the raw arrays in Java. -This allows the C++ interface to be more similar to Java.

-

The main difference from the pvDataCPP-md version is that it does not implement -the extra methods and allows -the client access to the shared_vector. -The client is then able to perform C++ specific things to the data. -BUT it also means that if the client modifies the shared_vector -the client is also responsible for ensuring that the -immutable and capacity related features of PVField and PVArray are -respected and the postPut is properly handled. -

-

Note that two get methods exist. -One allows write access to the raw data and the other doesn't/

-

pvDataJava

-
interface PVArray extends PVField, SerializableArray {
-    int getLength();
-    void setLength(int length);
-    int getCapacity();
-    void setCapacity(int length);
-    boolean isCapacityMutable();
-    void setCapacityMutable(boolean isMutable);
-}
-
-interface PVScalarArray extends PVArray {
-    ScalarArray getScalarArray();
-}
-

For each scalar type an associated array data interface is defined. Each has -a get and put method. For example:

-
public class DoubleArrayData {
-    public double[] data;
-    public int offset;
-}
-
-interface PVDoubleArray extends PVArray {
-    int get(int offset, int len, DoubleArrayData data);
-    int put(int offset,int len, double[] from, int fromOffset);
-    void shareData(double[] from);
-}
-

pvDataCPP

-
class PVArray : public PVField, public SerializableArray {
-public:
-    POINTER_DEFINITIONS(PVArray);
-    virtual ~PVArray();
-    virtual void setImmutable();
-    std::size_t getLength() const;
-    virtual void setLength(std::size_t length);
-    std::size_t getCapacity() const;
-    bool isCapacityMutable() const;
-    void setCapacityMutable(bool isMutable);
-    virtual void setCapacity(std::size_t capacity) = 0;
-    virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const = 0;
-
- ...
-};
-
-
-template<typename T>
-class PVArrayData {
-private:
-    std::vector<T> init;
-public:
-    POINTER_DEFINITIONS(PVArrayData);
-    typedef T  value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    std::vector<T> & data;
-    std::size_t offset;
-    PVArrayData()
-    : data(init)
-    {}
-};
-
-class PVScalarArray : public PVArray {
-public:
-    POINTER_DEFINITIONS(PVScalarArray);
-    virtual ~PVScalarArray();
-    typedef PVScalarArray &reference;
-    typedef const PVScalarArray& const_reference;
-    const ScalarArrayConstPtr getScalarArray() const ;
- ...
-}
-
-template<typename T>
-class PVValueArray : public PVScalarArray {
-public:
-    POINTER_DEFINITIONS(PVValueArray);
-    typedef T  value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-
-    typedef PVArrayData<T> ArrayDataType;
-    typedef std::vector<T> vector;
-    typedef const std::vector<T> const_vector;
-    typedef std::tr1::shared_ptr<vector> shared_vector;
-    typedef PVValueArray & reference;
-    typedef const PVValueArray & const_reference;
-
-    virtual ~PVValueArray() {}
-    virtual std::size_t get(
-         std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
-    virtual std::size_t put(std::size_t offset,
-        std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
-    virtual std::size_t put(std::size_t offset,
-        std::size_t length, const_vector &from, std::size_t fromOffset);
-    virtual void shareData(
-         shared_vector const & value,
-         std::size_t capacity,
-         std::size_t length) = 0;
-    virtual pointer get() = 0;
-    virtual pointer get() const = 0;
-    virtual vector const & getVector() = 0;
-    virtual shared_vector const & getSharedVector() = 0;
-    std::ostream& dumpValue(std::ostream& o) const;
-    std::ostream& dumpValue(std::ostream& o, size_t index) const;
-
-...
-};
-
-/**
- * Definitions for the various scalarArray types.
- */
-typedef PVArrayData<uint8> BooleanArrayData;
-typedef PVValueArray<uint8> PVBooleanArray;
-typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
-...
-typedef PVArrayData<std::string> StringArrayData;
-typedef PVValueArray<std::string> PVStringArray;
-typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;i
-
- -

pvDataCPP-md

-
class PVArray : public PVField, public SerializableArray {
-public:
-    POINTER_DEFINITIONS(PVArray);
-    virtual ~PVArray();
-    virtual void setImmutable();
-    std::size_t getLength() const;
-    virtual void setLength(std::size_t length);
-    std::size_t getCapacity() const;
-    bool isCapacityMutable() const;
-    void setCapacityMutable(bool isMutable);
-    virtual void setCapacity(std::size_t capacity) = 0;
-    virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const = 0;
- ...
-};
-
-std::ostream& operator<<(format::array_at_internal const& manip, const PVArray& array);
-
-template<typename T>
-class PVArrayData {
-private:
-    std::vector<T> init;
-public:
-    POINTER_DEFINITIONS(PVArrayData);
-    typedef T  value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    std::vector<T> & data;
-    std::size_t offset;
-    PVArrayData()
-    : data(init)
-    {}
-};
-
-class PVScalarArray : public PVArray {
-public:
-    POINTER_DEFINITIONS(PVScalarArray);
-    virtual ~PVScalarArray();
-    typedef PVScalarArray &reference;
-    typedef const PVScalarArray& const_reference;
-    const ScalarArrayConstPtr getScalarArray() const ;
-
-    // in pvDataCPP but not in pvDataCPP=md
-    //virtual std::ostream& dumpValue(std::ostream& o, size_t index) const = 0;
-
-    // not in pvDataCPP
-    template<ScalarType ID>
-    virtual void
-    getAs(shared_vector<typename ScalarTypeTraits<ID>::type>& out) const;
-
-    virtual void
-    getAs(ScalarType, shared_vector<void>& out) const = 0;
-
-    template<ScalarType ID>
-    inline size_t copyOut(typename ScalarTypeTraits<ID>::type* inp, size_t len) const;
-
-    virtual size_t copyOut(ScalarType id, void* ptr, size_t olen) const = 0;
-
-    template<ScalarType ID>
-    inline void putFrom(const shared_vector<typename ScalarTypeTraits<ID>::type>& inp);
-
-    virtual void putFrom(ScalarType, const shared_vector<void>&) = 0;
-
-    template<ScalarType ID>
-    inline void copyIn(const typename ScalarTypeTraits<ID>::type* inp, size_t len);
-
-    virtual void copyIn(ScalarType, const void*, size_t) = 0;
-
-    virtual void assign(PVScalarArray& pv) = 0;
-    
- ...
-}
-
-template<typename T>
-class PVValueArray : public detail::PVVectorStorage {
-    typedef detail::PVVectorStorage base_t;
-public:
-    POINTER_DEFINITIONS(PVValueArray);
-    typedef T  value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    typedef PVArrayData<T> ArrayDataType;
-    typedef std::vector<T> vector;
-    typedef const std::vector<T> const_vector;
-    typedef std::tr1::shared_ptr<vector> shared_vector;
-    typedef PVValueArray & reference;
-    typedef const PVValueArray & const_reference;
-
-    virtual ~PVValueArray() {}
-    virtual std::size_t get(
-         std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
-    virtual std::size_t put(std::size_t offset,
-        std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
-    virtual std::size_t put(std::size_t offset,
-        std::size_t length, const_vector &from, std::size_t fromOffset);
-    virtual void shareData(
-         shared_vector const & value,
-         std::size_t capacity,
-         std::size_t length) = 0;
-    virtual pointer get() = 0;
-    virtual pointer get() const = 0;
-    virtual vector const & getVector() = 0;
-    virtual shared_vector const & getSharedVector() = 0;
-    std::ostream& dumpValue(std::ostream& o) const;
-    std::ostream& dumpValue(std::ostream& o, size_t index) const;
-
-    /// not in pvDataCPP
-    static const ScalarType typeCode;
-    typedef ::epics::pvData::shared_vector<T> svector;
-    typedef ::epics::pvData::shared_vector<const T> const_svector;
-
-     virtual void
-    getAs(ScalarType id, ::epics::pvData::shared_vector<void>& out) const;
-    virtual size_t copyOut(ScalarType id, void* ptr, size_t olen) const;
-    virtual void
-    putFrom(ScalarType id, const ::epics::pvData::shared_vector<void>& inp);
-    virtual void copyIn(ScalarType id, const void* ptr, size_t len);
-    virtual void assign(PVScalarArray& pv);
-
-
-protected:
-    PVValueArray(ScalarArrayConstPtr const & scalar)
-    : PVScalarArray(scalar) {}
-    friend class PVDataCreate;
-};
-template<typename T>
-std::size_t PVValueArray<T>::put(
-    std::size_t offset,
-    std::size_t length,
-    const_vector &from,
-    std::size_t fromOffset)
-{ return put(offset,length, &from[0], fromOffset); }
-
-/**
- * Definitions for the various scalarArray types.
- */
-typedef PVArrayData<uint8> BooleanArrayData;
-typedef PVValueArray<uint8> PVBooleanArray;
-typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
-...
-typedef PVArrayData<std::string> StringArrayData;
-typedef PVValueArray<std::string> PVStringArray;
-typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;i
-
-

proposed

-
class PVArray : public PVField, public SerializableArray {
-public:
-    POINTER_DEFINITIONS(PVArray);
-    virtual ~PVArray();
-    virtual std::size_t getLength() const = 0;
-    virtual void setLength(std::size_t length) = 0;
-    bool isCapacityMutable() const;
-    void setCapacityMutable(bool isMutable);
-    virtual std::size_t getCapacity() const = 0;
-    virtual void setCapacity(std::size_t capacity) = 0;
- ...
-};
-
-
-class PVScalarArray : public PVArray {
-public:
-    POINTER_DEFINITIONS(PVScalarArray);
-    typedef PVScalarArray &reference;
-    typedef const PVScalarArray& const_reference;
-
-    virtual ~PVScalarArray();
-    const ScalarArrayConstPtr getScalarArray() const;
- ...
-};
-
-template<typename T>
-class PVValueArray : public PVScalarArray
-{
-public:
-    POINTER_DEFINITIONS(PVValueArray);
-    typedef T  value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    typedef PVValueArray & reference;
-    typedef const PVValueArray & const_reference;
-
-    typedef shared_vector<T> svector;
-    typedef shared_vector<const T> const_svector;
-
-    virtual ~PVValueArray() {}
-    const svector & get() ;
-    const const_svector &get() const;
-    size_t put(size_t offset,size_t length, const_pointer from, size_t fromOffset);
-
-    void shareData(const svector &from);
-
-...
-};
-
-typedef PVValueArray<uint8> PVBooleanArray;
-typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
-...
-typedef PVValueArray<std::string> PVStringArray;
-typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
-
- - - -

pvDataApp/pv

-

pvData.h

-

This provides the interface for network accessible data. -Although templates are used to minimize the amount of code, -the interface is not meant to be extended. -Only the types defined by pvIntrospect are implemented.

- -

PVField

-
-class PVField
-: virtual public Serializable,
-  public std::tr1::enable_shared_from_this
-{
-public:
-    POINTER_DEFINITIONS(PVField);
-    virtual ~PVField();
-    virtual void message(std::string message,MessageType messageType);
-    const std::string& getFieldName() const;
-    virtual void setRequester(RequesterPtr const &prequester);
-    std::size_t getFieldOffset() const;
-    std::size_t getNextFieldOffset() const;
-    std::size_t getNumberFields() const;
-    PVAuxInfoPtr & getPVAuxInfo();
-    bool isImmutable() const;
-    void setImmutable();
-    const FieldConstPtr & getField() const;
-    PVStructure * getParent() const;
-    void replacePVField(const PVFieldPtr&  newPVField);
-    void renameField(std::string const & newName);
-    void postPut();
-    void setPostHandler(PostHandlerPtr const &postHandler);
-    virtual bool equals(PVField &pv);
-    void toString(StringBuilder buf) ;
-    void toString(StringBuilder buf,int indentLevel);
-    std::ostream& operator<<(std::ostream& o) const;
-...
-};
-
-std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f);
-std::ostream& operator<<(std::ostream& o, const PVFieldPtr & f, size_t index);
-
-

The public methods for PVField are:

-
-
~PVField
-
Destructor. Since shared pointers are used it should never be called by - user code.
-
message
-
Code attached to this field can call this method to report - problems.
-
getFieldName
-
Get the field name. If the field is a top level structure the field - name will be an empty string.
-
setRequester
-
Sets a requester to be called when message or getRequesterName are - called. This is only legal for the top level PVField.
-
getFieldOffset
-
Get offset of the PVField field within top level structure. Every field - within the PVStructure has a unique offset. The top level structure has - an offset of 0. The first field within the structure has offset equal to - 1. The other offsets are determined by recursively traversing each - structure of the tree.
-
getNextFieldOffset
-
Get the next offset. If the field is a scalar or array field then this - is just offset + 1. If the field is a structure it is the offset of the - next field after this structure. Thus (nextOffset - offset) is always - equal to the total number of fields within the field.
-
getNumberFields
-
Get the total number of fields in this field. This is nextFieldOffset - - fieldOffset.
-
getPVAuxInfo
-
Get the PVAuxInfo for this field. PVAuxInfo is described below.
-
isImmutable
-
Is the field immutable?
-
setImmutable
-
Make the field immutable. Once a field is immutable it can never be - changed since there is no method to again make it mutable. This is an - important design decision since it allows immutable array fields to share - the internal primitive data array.
-
getField
-
Get the reflection interface for the data.
-
getParent
-
Get the interface for the parent or null if this is the top level - PVStructure.
-
replacePVField
-
Replace the data implementation for the field.
-
renameField
-
Rename the field name.
-
postPut
-
If a postHandler is registered it is called otherwise no action is - taken.
-
setPostHandler
-
Set the postHandler for the record. Only a single handler can be - registered.
-
operator<<
-
Stream output -
-

PVScalar

-
-class PVScalar : public PVField {
-public:
-    POINTER_DEFINITIONS(PVScalar);
-    virtual ~PVScalar();
-
-    typedef PVScalar &reference;
-    typedef const PVScalar& const_reference;
-
-    const ScalarConstPtr getScalar() const;
-...
-};
-
-

where

-
-
getScalar
-
Get the introspection interface for the PVScalar.
-
- -

PVScalarValue

-
-template
-class PVScalarValue : public PVScalar {
-public:
-    POINTER_DEFINITIONS(PVScalarValue);
-    typedef T value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-
-    virtual ~PVScalarValue() {}
-    virtual T get() const = 0;
-    virtual void put(T value) = 0;
-    void operator>>=(T& value) const;
-    void operator<<=(T value);
-...
-};
-typedef PVScalarValue<uint8> PVBoolean;
-typedef PVScalarValue<int8> PVByte;
-typedef PVScalarValue<int16> PVShort;
-typedef PVScalarValue<int32> PVInt;
-typedef PVScalarValue<int64> PVLong;
-typedef PVScalarValue<uint8> PVUByte;
-typedef PVScalarValue<uint16> PVUShort;
-typedef PVScalarValue<uint32> PVUInt;
-typedef PVScalarValue<uint64> PVULong;
-typedef PVScalarValue<float> PVFloat;
-typedef PVScalarValue<double> PVDouble;
-typedef std::tr1::shared_ptr<PVBoolean> PVBooleanPtr;
-typedef std::tr1::shared_ptr<PVByte> PVBytePtr;
-typedef std::tr1::shared_ptr<PVShort> PVShortPtr;
-typedef std::tr1::shared_ptr<PVInt> PVIntPtr;
-typedef std::tr1::shared_ptr<PVLong> PVLongPtr;
-typedef std::tr1::shared_ptr<PVUByte> PVUBytePtr;
-typedef std::tr1::shared_ptr<PVUShort> PVUShortPtr;
-typedef std::tr1::shared_ptr<PVUInt> PVUIntPtr;
-typedef std::tr1::shared_ptr<PVULong> PVULongPtr;
-typedef std::tr1::shared_ptr<PVFloat> PVFloatPtr;
-typedef std::tr1::shared_ptr<PVDouble> PVDoublePtr;
-
-// PVString is special case, since it implements SerializableArray
-class PVString : public PVScalarValue<std::string>, SerializableArray {
-public:
-    virtual ~PVString() {}
- ...
-};
-
- -

where

-
-
get
-
Get the value stored in the object.
-
put
-
Change the value stored in the object.
-
operator<<
-
operator>>
-
Methods for stream I/O.
-
- - -

PVArray

- -

PVArray is the base interface for all the other PV Array interfaces. It -extends PVField and provides the additional methods:

-
class PVArray : public PVField, public SerializableArray {
-public:
-    POINTER_DEFINITIONS(PVArray);
-    virtual ~PVArray();
-    virtual std::size_t getLength() const = 0;
-    virtual void setLength(std::size_t length) = 0;
-    bool isCapacityMutable() const;
-    void setCapacityMutable(bool isMutable);
-    virtual std::size_t getCapacity() const = 0;
-    virtual void setCapacity(std::size_t capacity) = 0;
- ...
-};
-
-
getLength
-
Get the current length. This is less than or equal to the capacity.
-
setLength
-
Set the length. If the PVField is not mutable then an exception is - thrown. If this is greater than the capacity setCapacity is called.
-
isCapacityMutable
-
Is the capacity mutable
-
setCapacityMutable
-
Specify if the capacity can be changed.
-
getCapacity
-
Get the capacity, i.e. this is the size of the underlying data - array.
-
setCapacity
-
Set the capacity. The semantics are implementation dependent but - typical semantics are as follows: If the capacity is not mutable an - exception is thrown. A new data array is created and data is copied from - the old array to the new array.
-
- - -

PVScalarArray

- -

PVScalarArray is the base class for scalar array data. PVValueArray is a -templete for the various scalar array data classes. There is a class for each -possible scalar type, i. e. PVBooleanArray, ..., PVStringArray.

-
class PVScalarArray : public PVArray {
-public:
-    POINTER_DEFINITIONS(PVScalarArray);
-    typedef PVScalarArray &reference;
-    typedef const PVScalarArray& const_reference;
-
-    virtual ~PVScalarArray();
-    const ScalarArrayConstPtr getScalarArray() const;
- ...
-};
-
- -

where

-
-
getScalarArray
-
Get the introspection interface.
-
- -

PVValueArray

- -

This is a template class plus instances for PVBooleanArray, ..., -PVStringArray.

-
template<typename T>
-class PVValueArray : public PVScalarArray {
-public:
-    POINTER_DEFINITIONS(PVValueArray);
-    typedef T  value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    typedef PVValueArray & reference;
-    typedef const PVValueArray & const_reference;
-
-    typedef shared_vector<T> svector;
-    typedef shared_vector<const T> const_svector;
-
-    virtual ~PVValueArray() {}
-    const svector & get() ;
-    const const_svector &get() const;
-    size_t put(size_t offset,size_t length, const_pointer from, size_t fromOffset);
-
-    void shareData(const svector &from);
-...
-};
-
-typedef PVValueArray<uint8> PVBooleanArray;
-typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
-
-typedef PVValueArray<int8> PVByteArray;
-typedef std::tr1::shared_ptr<PVByteArray> PVByteArrayPtr;
-
-typedef PVValueArray<int16> PVShortArray;
-typedef std::tr1::shared_ptr<PVShortArray> PVShortArrayPtr;
-
-typedef PVValueArray<int32> PVIntArray;
-typedef std::tr1::shared_ptr<PVIntArray> PVIntArrayPtr;
-
-typedef PVValueArray<int64> PVLongArray;
-typedef std::tr1::shared_ptr<PVLongArray> PVLongArrayPtr;
-
-typedef PVValueArray<uint8> PVUByteArray;
-typedef std::tr1::shared_ptr<PVUByteArray> PVUByteArrayPtr;
-
-typedef PVValueArray<uint16> PVUShortArray;
-typedef std::tr1::shared_ptr<PVUShortArray> PVUShortArrayPtr;
-
-typedef PVValueArray<uint32> PVUIntArray;
-typedef std::tr1::shared_ptr<PVUIntArray> PVUIntArrayPtr;
-
-typedef PVValueArray<uint64> PVULongArray;
-typedef std::tr1::shared_ptr<PVULongArray> PVULongArrayPtr;
-
-typedef PVValueArray<float> PVFloatArray;
-typedef std::tr1::shared_ptr<PVFloatArray> PVFloatArrayPtr;
-
-typedef PVValueArray<double> PVDoubleArray;
-typedef std::tr1::shared_ptr<PVDoubleArray> PVDoubleArrayPtr;
-
-typedef PVValueArray<std::string> PVStringArray;
-typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
-
- -

where

-
-
get
-
Get the shared_vector that holds the data. - Code that calls this is able to modify the array elements - but should be very careful if it does. - For example it must call postPut after modifying the array elements. - It must also respect isImmutable(). -
-
size_t put(size_t offset,size_t length, const_pointer from, size_t fromOffset);
-
put
-
This is the recommended method for modifying the array elements. - It may change the capacity if len asks for more elements - than the current capacity allows. - It does not change the current length. -
-
shareData
-
Share data with an existing shared_vector. - Note that if capacity is ever changed then data will no - longer be shared. - This method can also be called to force the PVValueArray to have a new - raw array. This is useful for implementing Copy On Write. -
-
- -

shared_vector

-

Status

-

I think that all public components of sharedVector.h -are now documented, but not all have a description or example. -Thus the documentation needs more work. -

-

When NOTE EXISTING appears it means that there is a question about -the existing shared_vector implementation.

-

Introduction

-

A shared_vector is a container as defined by the C++ standard library. -It is like std::vector but provides two additional features -1) shared raw array and 2) a window into the raw array.

-

To support these two features a shared_vector keeps the following -private data: -

-
m_sdata
-
This is a std::tr1::shared_ptr for the actual data array. -
-
m_offset
-
This is the offset of the first element seen by the window.
-
m_count
-
This is the size, i. e. total number of elements, seen by the window.
-
m_total
-
This is the number of elements between offset and the end of the array referenced - by m_sdata.
-
-Note that only m_sdata is shared. Thus each shared_vector has it's own window.

-

The following subsections are organized as follows: -

-
shared_vector example
-
The example code is based on a shared_vector<int32> - This subsection show the C++ definitions that are assumed by - the example code. - The source that contains the example code will be part - of this project but not yet.
-
std::vector compatible subsections
-
The types and methods that have the same names as std::vector.
-
share_vector specific
-
The methods that are not part of std::vector.
-

-

The subsections that are compatible with std::vector are organized -and start with a brief summary modeled after Section 31.3(STL Containers) in:
-"The C++ Programming Language, C++11, Fourth Edition", Bjarne Stroustrup,2013
-The subsection names are the same names that Stroustrup uses. -Each subsection starts with a brief summary that is similar to -the summary Stroustrup has at the beginning of each subsection.

-

The comparison is always with std::vector. -In addition it shows what is defined by by std::vector but not by -shared_vector.

-

Someone who already understand the C++ STL can understand shared_vector -by just looking at the brief summaries. -For others the brief summary is followed by tutorial information. -

-

shared_vector example

-

The examples all assume that the following has been defined:

-
-typedef shared_vector<int32> Int32Array;
-...
-static void dumpArray(std::string const &message,Int32Array const& int32Array);
-
-

The following: -

-Int32Array int32Array(5);
-dumpArray("example",int32Array);
-
-creates a shared vector that holds an array of five elements where each element is a -32 bit signed integer. -The call to dumpArray displays the message and the array elements on standard out: -
-example 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
-

-

exampleSharedVector is a main program that has the code for the -examples shown below.

-

Member Types

-

Brief Summary -

-value_type              Type of element
-size_type               Unsigned type of subscripts, element counts, etc.
-difference_type         Signed type of difference between iterators
-iterator                Behaves like value_type*
-const_iterator          Behaves like const value_type*
-reverse_iterator        Behaves like value_type*
-const_reverse_iterator  Behaves like const value_type*
-reference               value_types&
-const_reference         const_value_type&
-pointer                 Behaves like value_type *
-const_pointer           Behaves like const value_type*
-//not part of std::vector
-element_type            same as value_type
-shared_pointer_type     std::tr1::shared_ptr<value_type>
-// defined by std::vector but not by shared_vector
-allocator_type
-
-

-

-The typedefs are compatible with the STL container member types. -These define types for various types of variables that belong to a container -or are used to access a container.

-

value_type, reference, and const_reference

-

These three typedefs define the same types as the equivalent types for -an element of the shared_vector. -

-Int32Array::value_type value;
-//is the same as
-int32 value;
-
-Int32Array::reference rvalue = value;
-//is the same as
-int32 & rvalue = value;
-
-Int32Array::const_reference rvalue = value;
-//is the same as
-const int32 & rvalue = value;
-
-

-

pointer and const_pointer

-

The following is an example of code that uses the -pointer typedef:

-
-Int32Array int32Array(5);
-Int32Array::pointer pint32Array = int32Array.data();
-size_t len = int32Array.size();
-for(size_t i=0; i<len; ++i) pint32Array[i] = i;
-
-

A const_pointer is like a pointer except that only read access to the array elements -is allowed.

-

NOTE: data The above code is better implemented as:

-
-Int32Array int32Array(5);
-size_t len = int32Array.size();
-for(size_t i=0; i<len; ++i) int32Array[i] = i;
-
- -

difference_type

-

This is used to get the number of elements between two elements. -For example:

-
-Int32Array::difference_type pdiff = int32Array[3] - int32Array[1];
-// pdiff will have the value 2
-
-

element_type and shared_pointer_type

-

These are member types defined by std::tr1::shared_ptr. -These are not used by any of the client methods.

- -

Constructors, Destructor, and Assignments

-

Brief Summary -

-C c();         Default constructor; c is empty.
-C c(n);        c is initialized with n elements with the value value_type{};
-               offset is 0; size is n;
-C c(n,e);      Initialize c with n copies of e.
-               offset is 0; size is n;
-
-C c(c);        Copy an existing shared_vector of the same type.
-               offset and taken same as v.
-               shared_ptr is copied; not the raw array
-C operator=(c) Assignment constructor.
-               shared_ptr is copied; not the raw array
-C c(c,o,n);    Copy an existing std::tr1::shared_ptr<value_type>
-               offset is o; size is c;
-C c(r,o,n);    Use an existing raw pointer.
-               default deleter use "delete[]" to delete.
-               offset is o; size is c;
-C c(r,d,o,n);  Use an existing raw pointer and deleter d;
-               offset is o; size is c;
-
-not implemented
-~C()           The C++ default destructor is used.
-C++11 specific
-&& constructor move constructor
-{} constructor uniform initializer constructor
-
-where -
-
C
-
The class name, e. g. shared_vector<int32>
-
c
-
shared_vector instance
-
n
-
size, i. e. the number of elements
-
o
-
offset
-
e
-
element instance
-
r
-
raw pointer, e. g. int32 *
-
d
-
a deleter, i. e. object that destroys the raw array.
-
-

-

Construct by creating new raw array

-
-shared_vector();
-shared_vector(size_t n);
-shared_vector(size_t n, value_type e);
-
-

The first three constructors all create a new shared_vector -by also creating a new raw array, -The difference is the size of the array, i.e. how many elements it contains, -and how the elements are initialized. -

-
-
shared_vector()
-
The array is empty, i.e. it has no elements.
-
shared_vector(size_t n)
-
The array has n elements. Each element is initialized -by the default constructor for the element type. -For numeric elements, like int32, this means 0.
-
shared_vector(size_t n, value_type e)
-
The array has n elements. -Each element has the initial value e. -
-
-

The following: -

-    cout << "***exampleConstructors***" << endl;
-    Int32Array emptyArray();
-    Int32Array zeroArray(16);
-    int32 value = 1;
-    Int32Array oneArray(8, value);
-    dumpArray("emptyArray",emptyArray);
-    dumpArray("zeroArray",zeroArray);
-    dumpArray("oneArray",oneArray);
-
-produces -
-***exampleConstructors***
-emptyArray 1
-zeroArray {16}[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...]
-oneArray {8}[1, 1, 1, 1, 1, 1, 1, 1]
-
-

NOTE EXISTING: Why did emptyArray display the above. -Should it be "emptyArray {0} []"? -

-

Construct by sharing raw array from a shared_vector

-
-shared_vector(const shared_vector& o);
-shared_vector_base& operator=(const shared_vector_base& o);
-
-

These create a vector by coping the contents of an existing shared_vector -of the same type into the newly created vector. -Note that the complete raw array is not copied but just the std::tr1:: shared_ptr -that holds the array.

-

The following: -

-    cout << "***exampleCopyConstructors***" << endl;
-    size_t max = 16;
-    Int32Array int32Array(max);
-    for(size_t i=0; i<max; ++i) int32Array[i] = i+1;
-    Int32Array xxx(int32Array);    //copy constructor
-    Int32Array yyy = int32Array;   //copy assignment
-    cout << "dataPtr int32Array " << int32Array.dataPtr();
-    cout << " xxx " << xxx.dataPtr();
-    cout << " yyy " << yyy.dataPtr() << endl;
-    dumpArray("int32Array",emptyArray);
-    dumpArray("xxx",emptyArray);
-    dumpArray("yyy",emptyArray);
-
-produces -
-***exampleConstructors***
-dataPtr int32Array 0x136ea90 xxx 0x136ea90 yyy 0x136ea90
-int32Array {16}[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...]
-xxx {16}[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...]
-yyy {16}[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...]
-
-

Construct by wrapping an existing raw array

-
-shared_vector(A v, size_t o, size_t c)
-shared_vector(A d, B b, size_t o, size_t c)
-
-

NOTE EXISTING: Are these constructors necessary? -If code wants to wrap an existing raw array then -a std::tr1::shared_ptr can first be created -and the constructor in the next section can be called.

-

These "wrap" an existing raw pointer. -They allows access to a sub-array starting at offset o> -and has size c -The second provides a destructor and the first has a default deleter.

-

The default deleter does the following: -When the shared_vector is deleted, i. e. when no code references it, -the statement "delete[] a;" is executed.

-

An example of wrapping a raw array without using these constructors is:

-
-class Int32ArrayDeleter
-{
-//Note that this an example that does nothing.
-//But it could have private data
-public:
-     Int32ArrayDeleter() {}
-     virtual ~Int32ArrayDeleter() {}
-     void operator()(int32* a){
-         // MUST HANDLE DELETION
-         // default is "delete[] a;"
-     }
-};
-...
-int32 *pother; // something managed by other code
-size_t capacity; // size of array managed by other code
-
-Int32Array int32Array(pother,int32array_deleter,0,capacity);
-
-

This is used to wrap arrays that are managed by other -code. This should only be used if You understand the other code -and know what your deleter has to do. -An example, exampleShareRawArray, gives a more complete example. -

- -

Create a shared_vector from an existing shared_ptr

-
-shared_vector(const std::tr1::shared_ptr<E1>& d, size_t o, size_t c)
-
-

This creates a vector from an existing smart pointer. -Thus the vector will share reference counting with the existing smart -pointer. This is useful for creating "windows" into the array -that the smart pointer references.

- - - -

Create a shared_vector from an existing shared_vector

-
- template<typename E1>
-    shared_vector(const shared_vector<E1>& o) :base_t(o) {}
-
-

NOTE EXISTING: I do not understand how this works or what it does.

-

This create a vector by coping the contents of an existing shared_vector -of the same or a different but related type -into the newly created vector. -This constructor creates a new raw array and copies the elements from -the existing array to the new array.

- -

Size and Capacity

-

Brief Summary -

-size()      Return the number of elements in the window
-empty()     Is the window empty? this means shared_ptr is empty
-max_size()  The maximum possible number of elements.
-capacity()  The number of possible elements without re-allocating raw array.
-reserve(n)  Reserve at least n elements in raw array; May cause reallocation.
-resize(n)   Change size to n; May cause reallocation
-clear()     shared_ptr is reset, Window will be empty.
-
-not implemented
-resize(n,v)
-shrink_to_fit()
-

-

Details -

-size_t size() const;
-bool empty() const;
-size_t max_size() const;
-size_t capacity() const;
-void reserve(size_t n);
-void resize(size_t n);
-void clear();
-
-

-
-
size
-
The current number of elements in the window.
-
empty
-
(true,false) if size is (0,>0)
-
max_size
-
Maximum possible number of elements. -NOTE EXISTING; Should be ((size_t)-1)/sizeof(T) -
-
capacity
-
The maximum size the window can be without reallocating raw array
-
reserve
-
Set the maximum number of element that the window can see. - If the caller is the only user of the window and the number - of elements specified does not cause the number of elements to change - then this method just returns. - In all other cases a new raw array is allocated.

-
resize
-
Change the window size: may cause a reallocation of the raw array.
-
clear
-
If the shared_vector is not already empty the shared_ptr will - be reset. The new size will be 0.
-
-

The following: -

-static void exampleSizeEtc()
-{
-    cout << "***exampleSizeEtc***" << endl;
-    size_t max = 16;
-    Int32Array int32Array(max);
-    size_t capacity = int32Array.capacity();
-    size_t size = int32Array.size();
-    bool empty = int32Array.empty();
-    size_t max_size = int32Array.max_size();
-    cout<< "capacity" << capacity;
-    cout<< " size " << size;
-    cout<< " empty " << (empty ? true : false) ;
-    cout<< " max_size " << max_size << endl;
-}
-
-
-produces: -
-***exampleSizeEtc***
-capacity16 size 16 empty 0 max_size 18446744073709551615
-
-

-

Iterators

-

Brief Summary -

-begin()      First element
-end()        One past last element
-cbegin()     Constant first element
-cend()       Constant last element
-rbegin()     First element of reverse sequence
-rend()       One past last element of reverse sequence
-crbegin()    Constant first element of reverse sequence
-crend()      Constant last element of reverse sequence
-

-

-shared_vector supports both iterators and reverse iterators as defined by the STL. -For both constant iterators are also defined. -A constant iterator does not allow an array element to be modified.

-

The following is an example of a constant iterator.

-
-int32 sum = 0;
-for(Int32Array::const_iterator iter=int32Array.begin(); iter<int32Array.end(); ++iter )
-{
-     sum += *iter;
-}
-
-

The following is an example of a non constant iterator.

-
-int32 value = 0;
-for(Int32Array::iterator iter=int32Array.begin(); iter<int32Array.end(); ++iter )
-{
-     *iter += ++value;
-}
-
-

Element Access

-

Brief Summary -

-operator[i]    random element access 
-data()         return the raw array
-
-implemented by std::vector but not implemented
-front()
-back()
-at()
-

-

Note that: -

-Int32Array::pointer pint32= int32Array.data();
-
-is guaranteed to be the same as -
-int32 * pint32 = int32Array.data();
-
-

-

NOTE EXISTING: data() should be defined to return a const_pointer. -It is currently defined to return a plain pointer.

-

Stack Operations

-

Brief Summary -

-push_back(x)     Add an element after the last element
-pop_back(x)      Remove the last element.
-

-

List operations

-

shared_vector does not support the standard list operations like: -

-implemented by std::vector but not by shared_vector
-
-insert(p,x)   Add x before p
-...
-
-

-

Other Operations

-

Brief Summary -

-operator==       Do all elements of both containers compare equal.
-operator!=       Does any element not compare equal.
-operator<<       ostream operator
-swap(c2)         Swap the contents of two shared_vectors of the same type.
-swap(c1,c2)      Swap the contents of two shared_vectors of the same type.
-
-not implemented
-operator<
-operator<=
-operator>
-operator>=
-

-

operators equals, not equals, and ostream

-
-template<typename A, typename B>
-bool operator==(const epics::pvData::shared_vector<A>& a,
-                const epics::pvData::shared_vector<B>& b);
-
-template<typename A, typename B>
-bool operator!=(const epics::pvData::shared_vector<A>& a,
-                const epics::pvData::shared_vector<B>& b);
-
-template<typename E>
-std::ostream& operator<<(
-    std::ostream& strm, const epics::pvData::shared_vector<E>& arr);
-
-
-

swap

-

Swap the contents of two shared_vectors. The following code: -

-    cout << "***exampleSwap***" << endl;
-    Int32Array first(8);
-    Int32Array second(16);
-    cout << " before swap  size ";
-    cout<< "first " << first.size() << " second " << second.size() << endl;
-    first.swap(second);
-    cout << " after swap   size ";
-    cout<< "first " << first.size() << " second " << second.size() << endl;
-    swap(first,second);
-    cout << " swap again   size ";
-    cout<< "first " << first.size() << " second " << second.size() << endl;
-
-produces: -
-***exampleSwap***
- before swap  size first 8 second 16
- after swap   size first 16 second 8
- swap again   size first 8 second 16
-

- -

shared_vector specific operations

-

Brief Summary -

-void make_unique()         Make caller the only user of std::tr1::shared_ptr
-bool unique()              Is the caller the only user of std::tr1::shared_ptr
-void slice(offset,length)  Change window offset and size
-
-// following should only be used for debugging
-const std::tr1::shared_ptr<E>&
-       dataPtr()           Return const  shared_ptr
-size_t dataOffset()        Return offset.
-size_t dataCount()         Return count which is also the size
-size_t dataTotal()         Return total number of elements between
-                           offset and end of the raw array
-
-// following converts from type FROM to type TO
-shared_vector static_shared_vector_cast(const shared_vector<FROM>& src);
-
-// following casts from const Type to Type
-shared_vector
-const_shared_vector_cast(const shared_vector<const TYPE>& src)
-

-

NOTE EXISTING: The C++ standard library considers a slice to be every nth element -of some part of an array, i. e., slice has arguments (offset,length,stride). -shared_vector only has offset and length. -Perhaps it should have another name like rewindow. -

make_unique and unique

-
-void make_unique();
-bool unique() const;
-
-
-
make_unique
-
Makes sure that caller is the only user of this standard_vector. - If the caller is not already the only user a new raw array is allocated.
-
unique
-
- Returns (true,false) if there is only one user of the shared_vector. -
-
-

slice

-
-void slice(size_t offset, size_t length=(size_t)-1);
-
-

This modifies the "window" into the raw array starting at offset and of -the specified length. The offset and length are forced to be -within the raw array. -Note that this method never reallocates the underlying raw array. -

-

The following code: -

-static void exampleSlice()
-{
-    cout << "***exampleSlice***" << endl;
-    size_t max = 16;
-    Int32Array int32Array(max);
-    int32 value = 0;
-    for(Int32Array::iterator iter = int32Array.begin(); iter!=int32Array.end(); ++iter)
-    {
-        *iter = ++value;
-    }
-    dumpArray("int32Array",int32Array);
-    size_t offset = 0;
-    size_t length = 8;
-    Int32Array window1(int32Array);
-    window1.slice(offset,length);
-    dumpArray("window1",window1);
-    offset = 8;
-    length = 8;
-    Int32Array window2(int32Array);
-    window2.slice(offset,length);
-    dumpArray("window2",window2);
-    offset = 2;
-    length = 4;
-    Int32Array window3(window2);
-    window3.slice(offset,length);
-    dumpArray("window3",window3);
-}
-
-produces the following output: -
-***exampleSlice***
-int32Array 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
-window1 1 2 3 4 5 6 7 8
-window2 9 10 11 12 13 14 15 16
-window3 11 12 13 14
-
-

dataPtr, dataOffset, dataCount, and dataTotal

-
-
dataPtr
-
Returns the shared_ptr that holds the raw array. -
-
dataOffset
-
Offset in the data array of first element
-
dataCount
-
Number of visible elements. - Same as size. -
-
dataTotal
-
Total number of elements between m_offset and the end of data. - Same as capacity. -
-
-

The following: -

-static void exampleDataEtc()
-{
-    cout << "***exampleDataEtc***" << endl;
-    size_t max = 16;
-    Int32Array int32Array(max);
-    long use_count = int32Array.dataPtr().use_count();
-    long offset = int32Array.dataOffset();
-    long count = int32Array.dataCount();
-    long total = int32Array.dataTotal();
-    cout << "use_count " << use_count;
-    cout << " offset " << offset;
-    cout << " count " << count;
-    cout << " total " <<  total << endl;
-}
-
-produces: -
-***exampleDataEtc***
-use_count 1 offset 0 count 16 total 16
-
-

- -

static_shared_vector_cast

-

Not yet documented

- -

const_shared_vector_cast

-

Not yet documented

- -

specialization for untyped pointers

-

Not yet documented

- - -
- - diff --git a/documentation/pvDataDiscussion.html b/documentation/pvDataDiscussion.html deleted file mode 100644 index d059dd7..0000000 --- a/documentation/pvDataDiscussion.html +++ /dev/null @@ -1,792 +0,0 @@ - - - - - - EPICS pvDataDiscussion - - - - - - - - -
-

EPICS pvDataDiscussion

- - -

EPICS v4 Working Group, Working Draft, 03-Jul-2013

- -
-
Latest version:
-
pvDataDiscussion.html -
-
This version:
-
none
-
Previous version:
-
None
-
Editors:
-
Marty Kraimer, BNL
-
- - -
-
- - -
-

Table of Contents

-
-
- - -

Introduction

-

As pvDataCPP progressed PVField and derived classes accumulated -more and more member functions. -These member functions have nothing to do with the primary primary -purpose for pvData: -

pvData (Process Variable Data) defines and implements an efficient -way to store, access, and communicate memory resident data structures.
-This statement appears as the first sentence of pvDataJava.html. -A few sentences later the document makes it clear that communication -includes efficient network communication. -Thus pvData provides an interface for network accessible structured data. -The problem of adding member functions that have nothing to do with the primary purpose -started with the Java API. -It already had extra methods that solved problems that should have had a different solution. -This document removes the extra methods so that when new problems arise in the future -the solution will not involve adding new member functions to the introspection and data API. -

-

The introspection and data API for pvData should only encapsulate methods that support the primary purpose -stated above. -The interfaces for C++ and Java should be similar so that -someone who understands the interface in one of the languages -and knows both languages will quickly understand the interface of the other language.

-

There is another problem with the existing API. There are methods that allow the "structure" -to change after an pvData object is created. An example is PVField::renameField(std::string newName). -Such methods should not exist.

-

There are methods regarding immutability: setImmutable, isImmutablei, setCapacityMutable, and isCapacityMutable. -Should they exists? For now lets assume no. -

-

One last issue is the interface for array data. This document proposes a simplified -version of what currently exists. It requires that the implementation always provides storage for -the complete raw array. The existing APIs allow the implementation to provide the data in -"chunks". Giving up this requirement simplifies the array interfaces. -The existing C++ implementation of PVValueArray has serious problems. -The shared_vector that is implemented in pvDataCP-md provides the solution to fixing -the problems. This document describes an API that is very similar to the new Java API -except that raw arrays are replaced by shared_vector.

-

This document will first describe changes to the existing Java interfaces -and then the corresponding C++ API.

-

Java API

-

The following shows which methods will be removed from the existing interfaces -and what will be added. -The methods to be removed are in red -and methods to add are in blue -Also the removed methods are at the end with a comment above. -The new methods also have a comment. -

-

Introspection Interfaces

- -
interface Field extends Serializable {
-    std::string getId();
-    Type getType();
-    // following will be removed
-    void toString(StringBuilder buf);
-    void toString(StringBuilder buf,int indentLevel);
-    std::string toString();
-}
-
-
-// new interface
-interface FieldTostd::string {
-    std::string toString(Field field);
-}
-
-interface Scalar extends Field {
-    ScalarType getScalarType();
-}
-
-interface ScalarArray extends Field {
-    ScalarType getElementType();
-}
-
-interface Structure extends Field {
-    Field getField(std::string fieldName);
-    int getFieldIndex(std::string fieldName);
-    Field[] getFields();
-    Field getField(int fieldIndex);
-    std::string[] getFieldNames();
-    std::string getFieldName(int fieldIndex)
-}
-
-interface StructureArray extends Field {
-    Structure getStructure();
-}
-
-interface FieldCreate {
-    Scalar createScalar(ScalarType scalarType);
-    ScalarArray createScalarArray(ScalarType elementType);
-    StructureArray createStructureArray(Structure elementStructure);
-    Structure createStructure(std::string[] fieldNames, Field[] field);
-    Structure createStructure(std::string id,std::string[] fieldNames, Field[] field);
-    Structure createStructure(Structure structToClone);
-    Field deserialize(ByteBuffer buffer, DeserializableControl control);
-    // following will be removed
-    Structure appendField(Structure structure,std::string fieldName, Field field);
-    Structure appendFields(Structure structure,std::string[] fieldNames, Field[] fields);
-}
-
-

Data Interfaces

-
-interface PVField extends Requester, Serializable {
-    std::string getFieldName();
-    void setRequester(Requester requester);
-    int getFieldOffset();
-    int getNextFieldOffset();
-    int getNumberFields();
-    Field getField();
-    PVStructure getParent();
-    void postPut();
-    void setPostHandler(PostHandler postHandler);
-    // following will be removed
-    PVAuxInfo getPVAuxInfo();
-    boolean isImmutable();
-    void setImmutable();
-    void renameField(std::string newName);
-    void toString(StringBuilder buf);
-    void toString(StringBuilder buf,int indentLevel);
-    std::string toString();
-}
-
-
-// The following is a new interface
-interface PVFieldTostd::string {
-    std::string toString(PVField pvField);
-    void setMaxInitialArrayElements(int num);
-    void setMaxFinalArrayElements(int num);
-    int getMaxInitialArrayElements();
-    int getMaxFinalArrayElements();
-}
-    
-interface PVScalar extends PVField{
-    Scalar getScalar();
-}
-
-interface PVDouble extends PVScalar{
-    double get();
-    void put(double value);
-}
-// also PVBoolean, PVByte, PVShort, PVInt, PVLong, PVFloat, and PVString
-
-interface PVArray extends PVField, SerializableArray {
-    int getLength();
-    void setLength(int length);
-    int getCapacity();
-    void setCapacity(int length);
-    // following will be removed
-    boolean isCapacityMutable();
-    void setCapacityMutable(boolean isMutable);
-}
-
-interface PVScalarArray extends PVArray {
-    ScalarArray getScalarArray();
-}
-
-
-//following will be removed
-public class DoubleArrayData {
-    public double[] data;
-    public int offset;
-}
-
-interface PVDoubleArray extends PVArray {
-    // following are new
-    double[] get();
-    void swap(double[] value);
-    //following will be removed
-    int get(int offset, int len, DoubleArrayData data);
-    int put(int offset,int len, double[] from, int fromOffset);
-    void shareData(double[] from);
-}
-
-// also PVBooleanArray, ..., PVStringArray
-
-
-interface PVStructure extends PVField , BitSetSerializable{
-    Structure getStructure();
-    PVField[] getPVFields();
-    PVField getSubField(std::string fieldName);
-    PVField getSubField(int fieldOffset);
-    // The following are convenience methods
-    PVBoolean getBooleanField(std::string fieldName);
-    PVByte getByteField(std::string fieldName);
-    PVShort getShortField(std::string fieldName);
-    PVInt getIntField(std::string fieldName);
-    PVLong getLongField(std::string fieldName);
-    PVFloat getFloatField(std::string fieldName);
-    PVDouble getDoubleField(std::string fieldName);
-    PVString getStringField(std::string fieldName);
-    PVScalarArray getScalarArrayField(std::string fieldName);
-    PVStructureArray getStructureArrayField(std::string fieldName);
-    PVStructure getStructureField(std::string fieldName);
-    PVArray getArrayField(std::string fieldName,ScalarType elementType);
-    // following will be removed
-    void appendPVField(std::string fieldName,PVField pvField);
-    void appendPVFields(std::string[] fieldNames,PVField[] pvFields);
-    void removePVField(std::string fieldName);
-    void replacePVField(PVField oldPVField,PVField newPVField);
-    std::string getExtendsStructureName();
-    boolean putExtendsStructureName(std::string extendsStructureName);
-    public boolean checkValid();
-}
- 
-
-//following will be removed
-public class StructureArrayData {
-    public PVStructure[] data;
-    public int offset;
-}
-
-
-interface PVStructureArray extends PVArray{
-    StructureArray getStructureArray();
-    // following are new
-    PVStructure[] get();
-    void swap(PVStructure[] value);
-    // following will be removed
-    int get(int offset, int length, StructureArrayData data);
-    int put(int offset,int length, PVStructure[] from, int fromOffset);
-    void shareData(PVStructure[] from);
-}
-
-
-public interface PVDataCreate {
-    PVField createPVField(Field field);
-    PVField createPVField(PVField fieldToClone);
-    PVScalar createPVScalar(Scalar scalar);
-    PVScalar createPVScalar(ScalarType fieldType);
-    PVScalar createPVScalar(PVScalar scalarToClone);
-    PVScalarArray createPVScalarArray(ScalarArray array);
-    PVScalarArray createPVScalarArray(ScalarType elementType);
-    PVScalarArray createPVScalarArray(PVScalarArray arrayToClone;
-    PVStructureArray createPVStructureArray(StructureArray structureArray);
-    PVStructure createPVStructure(Structure structure);
-    PVStructure createPVStructure(std::string[] fieldNames,Field[] fields);
-    PVStructure createPVStructure(PVStructure structToClone);
-    // following will be removed
-    PVField[] flattenPVStructure(PVStructure pvStructure);
-}
-
-

PVFieldTostd::string

-

In addition to toString this has methods to limit the number of array element to display. -The existing Java implementation of toString displayed all elements. -For large arrays this is not desirable. -The new methods provide a way for the client to limit the number of elements. -The default might be set to something like display up to 10 elements with 5 from the beginning and 5 from the end.

-

For C++ this can be a replacement for dumpValue.

-

PVBooleanArray, ..., PVStructureArray

-

The old get and put are replaced by two new and simpler methods: -

-
get
-
Returns the raw array. If the client code modifies the elements in the array then - the client must call postPut. The client also has to realize that if the raw array held by the PVXXXArray changes - then the client is no longer sharing data -
swap
-
This exchanges the old raw data with the new raw data.
-
-

-

-The method setCapacity will always create a new raw array and copy old data from the old to the new array. -This is not true now since the implementation does not create a new array if the old capacity is equal to the requested capacity. -

-

C++ API

-

The C++ class definitions are similar to the Java definitions with two main exceptions: -

-
toString
-
In c++ this is replaced by std::ostream.
-
raw array data
-
Java supports array data like double[] - The C++ replacement is shared_vector<double>, which is implemented - in pvDataCPP-md.
-

Introspection Interfaces

- -
-class Field :
-    virtual public Serializable,
-    public std::tr1::enable_shared_from_this<Field>
-{
-public:
-    POINTER_DEFINITIONS(Field);
-    virtual ~Field();
-    Type getType() const{return m_type;}
-    virtual std::string getID() const = 0;
-    
-    // following will be removed
-    virtual void toString(StringBuilder buf) const{toString(buf,0);}
-    virtual void toString(StringBuilder buf,int indentLevel) const;
-    
- ...
-};
-
-// new function
-std::ostream &toString(Field::const_reference field, std::ostream& o);
-
-
-class Scalar : public Field{
-public:
-    POINTER_DEFINITIONS(Scalar);
-    virtual ~Scalar();
-    typedef Scalar& reference;
-    typedef const Scalar& const_reference;
-
-    ScalarType getScalarType() const {return scalarType;}
-    virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
-    virtual void deserialize(ByteBuffer *buffer, DeserializableContol *control);
-    
-    // following will be removed
-    virtual void toString(StringBuilder buf) const{toString(buf,0);}
-    virtual void toString(StringBuilder buf,int indentLevel) const;
-    virtual std::string getID() const;
-    
- ...
-};
-class ScalarArray : public Field{
-public:
-    POINTER_DEFINITIONS(ScalarArray);
-    typedef ScalarArray& reference;
-    typedef const ScalarArray& const_reference;
-
-    ScalarArray(ScalarType scalarType);
-    ScalarType  getElementType() const {return elementType;}
-    virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
-    virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
-    
-    // following will be removed
-    virtual void toString(StringBuilder buf) const{toString(buf,0);}
-    virtual void toString(StringBuilder buf,int indentLevel) const;
-    virtual std::string getID() const;
-    
- ...
-};
-
-class Structure : public Field {
-public:
-    POINTER_DEFINITIONS(Structure);
-    typedef Structure& reference;
-    typedef const Structure& const_reference;
-
-   std::size_t getNumberFields() const {return numberFields;}
-   FieldConstPtr getField(std::string const & fieldName) const;
-   FieldConstPtr getField(std::size_t index) const;
-   std::size_t getFieldIndex(std::string const &fieldName) const;
-   FieldConstPtrArray const & getFields() const {return fields;}
-   StringArray const & getFieldNames() const;
-   std::string getFieldName(std::size_t fieldIndex);
-   virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
-   virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
-    
-    // following will be removed
-   void renameField(std::size_t fieldIndex,std::string const &newName);
-   virtual void toString(StringBuilder buf,int indentLevel) const;
-   virtual std::string getID() const;
-   
- ...
-};
-
-class StructureArray : public Field{
-public:
-    POINTER_DEFINITIONS(StructureArray);
-    typedef StructureArray& reference;
-    typedef const StructureArray& const_reference;
-
-    StructureConstPtr  getStructure() const {return pstructure;}
-    virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
-    virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
-    
-    // following will be removed
-    virtual void toString(StringBuilder buf,int indentLevel=0) const;
-    virtual std::string getID() const;
-    
- ...
-};
-
-class FieldCreate  {
-public:
-    static FieldCreatePtr getFieldCreate();
-    ScalarConstPtr  createScalar(ScalarType scalarType) const
-    ScalarArrayConstPtr createScalarArray(ScalarType elementType) const;
-    StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const;
-    StructureConstPtr createStructure (
-        StringArray const & fieldNames,
-        FieldConstPtrArray const & fields) const;
-    StructureConstPtr createStructure (
-        std::string const &id,
-        StringArray const & fieldNames,
-        FieldConstPtrArray const & fields) const;
-    FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const;
-    
-    // following will be removed
-    StructureConstPtr appendField(
-        StructureConstPtr const & structure,
-        std::string const &fieldName, FieldConstPtr const & field) const;
-    StructureConstPtr appendFields(
-        StructureConstPtr const & structure,
-        StringArray const & fieldNames,
-        FieldConstPtrArray const & fields) const;
-    
- ...
-};
-
-extern FieldCreatePtr getFieldCreate();
- 
-

Data Interfaces

-
-class PVField
-: virtual public Serializable,
-  public std::tr1::enable_shared_from_this<PVField>
-{
-public:
-   POINTER_DEFINITIONS(PVField);
-   virtual ~PVField();
-   inline const std::string &getFieldName() const ;
-   virtual void setRequester(RequesterPtr const &prequester);
-   std::size_t getFieldOffset() const;
-   std::size_t getNextFieldOffset() const;
-   std::size_t getNumberFields() const;
-   const FieldConstPtr & getField() const ;
-   PVStructure * getParent() const
-   void postPut() ;
-   void setPostHandler(PostHandlerPtr const &postHandler);
-    // following will be removed
-    
-   virtual void message(std::string message,MessageType messageType);
-   void replacePVField(const PVFieldPtr&  newPVField);
-   std::string getFullName() const;
-   virtual bool equals(PVField &pv);
-   PVAuxInfoPtr & getPVAuxInfo()
-   bool isImmutable() const;
-   virtual void setImmutable();
-   void replacePVField(const PVFieldPtr&  newPVField);
-   void renameField(std::string const &newName);
-   virtual void toString(StringBuilder buf) ;
-   virtual void toString(StringBuilder buf,int indentLevel);
-   std::ostream& dumpValue(std::ostream& o) const;
-   
- ...
-};
-
-
-// The following is a new class
-class PVFieldTostd::string {
-    std::string toString(const PVFieldPtr &pvField);
-    void setMaxInitialArrayElements(size_t num);
-    void setMaxFinalArrayElements(size_t num);
-    size_t getMaxInitialArrayElements();
-    size_t getMaxFinalArrayElements();
-...
-}
-
-class PVScalar : public PVField {
-public:
-    POINTER_DEFINITIONS(PVScalar);
-    virtual ~PVScalar();
-    typedef PVScalar &reference;
-    typedef const PVScalar& const_reference;
-
-    const ScalarConstPtr getScalar() const ;
- ...
-}
-
-
-template<typename T>
-class PVScalarValue : public PVScalar {
-public:
-    POINTER_DEFINITIONS(PVScalarValue);
-    typedef T value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-
-    virtual ~PVScalarValue() {}
-    virtual T get() const = 0;
-    virtual void put(T value) = 0;
-    
-    // following will be removed
-    std::ostream& dumpValue(std::ostream& o)
-    void operator>>=(T& value) const;
-    void operator<<=(T value);
-    
- ...
-}
-
-// PVString is special case, since it implements SerializableArray
-class PVString : public PVScalarValue<std::string>, SerializableArray {
-public:
-    virtual ~PVString() {}
- ...
-}
-class PVArray : public PVField, public SerializableArray {
-public:
-    POINTER_DEFINITIONS(PVArray);
-    virtual ~PVArray();
-    std::size_t getLength() const;
-    virtual void setLength(std::size_t length);
-    std::size_t getCapacity() const;
-    virtual void setCapacity(std::size_t capacity) = 0;
-    
-    // following will be removed
-    virtual void setImmutable();
-    bool isCapacityMutable() const;
-    void setCapacityMutable(bool isMutable);
-    virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const = 0;
-    
- ...
-};
-
-class PVScalarArray : public PVArray {
-public:
-    POINTER_DEFINITIONS(PVScalarArray);
-    virtual ~PVScalarArray();
-    typedef PVScalarArray &reference;
-    typedef const PVScalarArray& const_reference;
-
-    const ScalarArrayConstPtr getScalarArray() const ;
-    
-    // following will be removed
-    virtual std::ostream& dumpValue(std::ostream& o, size_t index) const = 0;
-    
- ...
-}
-
-
-// following will be removed
-template<typename T>
-class PVArrayData {
-private:
-    std::vector<T> init;
-public:
-    POINTER_DEFINITIONS(PVArrayData);
-    typedef T  value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    std::vector<T> & data;
-    std::size_t offset;
-    PVArrayData()
-    : data(init)
-    {}
-};
-
-
-template<typename T>
-class PVValueArray : public PVScalarArray {
-public:
-    POINTER_DEFINITIONS(PVValueArray);
-    typedef T  value_type;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    // following are new typeDefs
-    typedef shared_vector<T> svector;
-    typedef shared_vector<const T> const_svector; 
-
-    virtual ~PVValueArray() {}
-    // following are added
-    svector get();
-    void swap(svector& value);
-    
-    // following are removed
-    typedef PVValueArray & reference;
-    typedef const PVValueArray & const_reference;
-    typedef PVArrayData<T> ArrayDataType;
-    typedef std::vector<T> vector;
-    typedef const std::vector<T> const_vector;
-    typedef std::tr1::shared_ptr<vector> shared_vector;
-
-    virtual std::size_t get(
-         std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
-    virtual std::size_t put(std::size_t offset,
-        std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
-    virtual std::size_t put(std::size_t offset,
-        std::size_t length, const_vector &from, std::size_t fromOffset);
-    virtual void shareData(
-         shared_vector const & value,
-         std::size_t capacity,
-         std::size_t length) = 0;
-    virtual pointer get() = 0;
-    virtual pointer get() const = 0;
-    virtual vector const & getVector() = 0;
-    virtual shared_vector const & getSharedVector() = 0;
-    std::ostream& dumpValue(std::ostream& o) const;
-    std::ostream& dumpValue(std::ostream& o, size_t index) const;
-    
-...
-};
-
-typedef PVValueArray<uint8> PVBooleanArray;
-typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
-...
-typedef PVValueArray<std::string> PVStringArray;
-typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
-
-class PVStructure : public PVField,public BitSetSerializable {
-public:
-    POINTER_DEFINITIONS(PVStructure);
-    virtual ~PVStructure();
-    typedef PVStructure & reference;
-    typedef const PVStructure & const_reference;
-
-    StructureConstPtr getStructure() const;
-    const PVFieldPtrArray & getPVFields() const;
-    PVFieldPtr getSubField(std::string const &fieldName) const;
-    PVFieldPtr getSubField(std::size_t fieldOffset) const;
-    PVBooleanPtr getBooleanField(std::string const &fieldName) ;
-    PVBytePtr getByteField(std::string const &fieldName) ;
-    PVShortPtr getShortField(std::string const &fieldName) ;
-    PVIntPtr getIntField(std::string const &fieldName) ;
-    PVLongPtr getLongField(std::string const &fieldName) ;
-    PVUBytePtr getUByteField(std::string const &fieldName) ;
-    PVUShortPtr getUShortField(std::string const &fieldName) ;
-    PVUIntPtr getUIntField(std::string const &fieldName) ;
-    PVULongPtr getULongField(std::string const &fieldName) ;
-    PVFloatPtr getFloatField(std::string const &fieldName) ;
-    PVDoublePtr getDoubleField(std::string const &fieldName) ;
-    PVStringPtr getStringField(std::string const &fieldName) ;
-    PVStructurePtr getStructureField(std::string const &fieldName) ;
-    PVScalarArrayPtr getScalarArrayField(
-        std::string const &fieldName,ScalarType elementType) ;
-    PVStructureArrayPtr getStructureArrayField(std::string const &fieldName) ;
-    virtual void serialize(
-        ByteBuffer *pbuffer,SerializableControl *pflusher) const ;
-    virtual void deserialize(
-        ByteBuffer *pbuffer,DeserializableControl *pflusher);
-    virtual void serialize(ByteBuffer *pbuffer,
-        SerializableControl *pflusher,BitSet *pbitSet) const;
-    virtual void deserialize(ByteBuffer *pbuffer,
-        DeserializableControl*pflusher,BitSet *pbitSet);
-    PVStructure(StructureConstPtr const & structure);
-    PVStructure(StructureConstPtr const & structure,PVFieldPtrArray const & pvFields);
-    
-    // following are removed
-    void appendPVField(
-        std::string const &fieldName,
-        PVFieldPtr const & pvField);
-    void appendPVFields(
-        StringArray const & fieldNames,
-        PVFieldPtrArray const & pvFields);
-    void removePVField(std::string const &fieldName);
-    virtual void setImmutable();
-    std::string getExtendsStructureName() const;
-    bool putExtendsStructureName(
-        std::string const &extendsStructureName);
-    
-};
-
-
-// following will be removed
-typedef PVArrayData<PVStructurePtr> StructureArrayData;
-
-
-class PVStructureArray : public PVArray
-{
-public:
-    POINTER_DEFINITIONS(PVStructureArray);
-    typedef PVStructurePtr  value_type;
-    typedef PVStructurePtr* pointer;
-    typedef const PVStructurePtr* const_pointer;
-    
-    // following are new typeDefs
-    typedef shared_vector<PVStructurePtr> svector;
-    typedef shared_vector<const PVStructurePtr> const_svector;
-    
-
-    virtual ~PVStructureArray() {}
-    virtual void setCapacity(size_t capacity);
-    virtual void setLength(std::size_t length);
-    virtual StructureArrayConstPtr getStructureArray() const ;
-    virtual void serialize(ByteBuffer *pbuffer,
-        SerializableControl *pflusher) const;
-    virtual void deserialize(ByteBuffer *buffer,
-    virtual void serialize(ByteBuffer *pbuffer,
-        SerializableControl *pflusher, std::size_t offset, std::size_t count) const ;
-    // following are new
-    svector get();
-    void swap(svector & value);
-    
-    // following are removed
-    typedef PVArrayData<PVStructurePtr> ArrayDataType;
-    typedef std::vector<PVStructurePtr> vector;
-    typedef const std::vector<PVStructurePtr> const_vector;
-    typedef std::tr1::shared_ptr<vector> shared_vector;
-    typedef PVStructureArray &reference;
-    typedef const PVStructureArray& const_reference;
-    
-    virtual std::size_t append(std::size_t number);
-    virtual bool remove(std::size_t offset,std::size_t number);
-    virtual void compress();
-    virtual std::size_t get(std::size_t offset, std::size_t length,
-        StructureArrayData &data);
-    virtual std::size_t put(std::size_t offset,std::size_t length,
-        const_vector const & from, std::size_t fromOffset);
-    virtual void shareData(
-         shared_vector const & value,
-         std::size_t capacity,
-         std::size_t length);
-    virtual pointer get() { return &((*value.get())[0]); }
-    virtual pointer get() const { return &((*value.get())[0]); }
-    virtual vector const & getVector() {return *value;}
-    virtual shared_vector const & getSharedVector() {return value;}
-    
- ...
-};
-
-class PVDataCreate {
-public:
-    static PVDataCreatePtr getPVDataCreate();
-    PVFieldPtr createPVField(FieldConstPtr const & field);
-    PVFieldPtr createPVField(PVFieldPtr const & fieldToClone);
-    PVScalarPtr createPVScalar(ScalarConstPtr const & scalar);
-    PVScalarPtr createPVScalar(ScalarType scalarType);
-    PVScalarPtr createPVScalar(PVScalarPtr const & scalarToClone);
-    PVScalarArrayPtr createPVScalarArray(ScalarArrayConstPtr const & scalarArray);
-    PVScalarArrayPtr createPVScalarArray(ScalarType elementType);
-    PVScalarArrayPtr createPVScalarArray(PVScalarArrayPtr const  & scalarArrayToClone);
-    PVStructureArrayPtr createPVStructureArray(StructureArrayConstPtr const & structureArray);
-    PVStructurePtr createPVStructure(StructureConstPtr const & structure);
-    PVStructurePtr createPVStructure(
-        StringArray const & fieldNames,PVFieldPtrArray const & pvFields);
-   PVStructurePtr createPVStructure(PVStructurePtr const & structToClone);
- ...
-};
-
-extern PVDataCreatePtr getPVDataCreate();
-
- - -
- - From 64bb660f447acfbf75c7747a8b771fb14d9c3fa1 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Wed, 15 Oct 2014 14:47:48 -0400 Subject: [PATCH 13/15] Added tag 4.0.0 for changeset 9c62aaa83b9d --- .hgtags | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.hgtags b/.hgtags index 145b55d..6d497b9 100644 --- a/.hgtags +++ b/.hgtags @@ -12,3 +12,5 @@ d70c5ad29163306f50979a95b5aebbe9a93cfe76 2.0-BETA 40b681ffc5cd609320e3f8ffc8eb6aa3bfdfbf19 before_merge_changesAfter3_0_2 260f35b9c6cad113f242c83c89be9cdac802f610 3.1.0 1348c22b125861ecb9da95b23f20314b167ee155 4.0.0 +1348c22b125861ecb9da95b23f20314b167ee155 4.0.0 +9c62aaa83b9db6ad69740a6bb46d6529e0e60b78 4.0.0 From 435ca63d1b3689cf20b78229469167bead9d9e53 Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Tue, 28 Oct 2014 18:53:11 +0100 Subject: [PATCH 14/15] ev4 to epics URI --- documentation/pvDataCPP.html | 34 ++++++++++++++--------------- documentation/pvDataCPPCookbook.txt | 4 ++-- src/factory/StandardField.cpp | 14 ++++++------ src/pv/standardField.h | 2 +- src/pv/standardPVField.h | 2 +- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html index 638385e..c430a2c 100644 --- a/documentation/pvDataCPP.html +++ b/documentation/pvDataCPP.html @@ -257,7 +257,7 @@ structure int userTag easy way -ev4:nt/NTScalarArray:1.0 +epics:nt/NTScalarArray:1.0 string[] value alarm_t alarm int severity @@ -277,7 +277,7 @@ via standardField:

It produces :
-ev4:nt/NTScalarArray:1.0
+epics:nt/NTScalarArray:1.0
     string[] value
     alarm_t alarm
         int severity
@@ -305,7 +305,7 @@ A hard way to create an structure with an enumerated value field and a time stam
 
     StructureConstPtr ntEnumHard =
     fieldCreate->createFieldBuilder()->
-        setId("ev4:nt/NTEnum:1.0")->
+        setId("epics:nt/NTEnum:1.0")->
         add("value", enum_t)->
         addNestedStructure("timeStamp")->
             setId("time_t")->
@@ -318,7 +318,7 @@ A hard way to create an structure with an enumerated value field and a time stam
 
It produces:
-ev4:nt/NTEnum:1.0
+epics:nt/NTEnum:1.0
     enum_t value
         int index
         string[] choices
@@ -335,7 +335,7 @@ fields: alarm and timeStamp:

It produces:
-ev4:nt/NTEnum
+epics:nt/NTEnum
     enum_t value
         int index
         string[] choices
@@ -375,7 +375,7 @@ union
         int userTag
 
 structure with value field being a union
-ev4:nt/NTUnion:1.0
+epics:nt/NTUnion:1.0
     union value
         double doubleValue
         int intValue
@@ -473,7 +473,7 @@ structure
 
This produces:
-ev4:nt/NTScalar:1.0
+epics:nt/NTScalar:1.0
     double value 100000
     alarm_t alarm
         int severity 0
@@ -506,7 +506,7 @@ from get 100000
 
This produces:
-ev4:nt/NTScalarArray:1.0
+epics:nt/NTScalarArray:1.0
     double[] value [0,1,2,3,4,5,6,7,8,9]
     alarm_t alarm
         int severity 0
@@ -527,7 +527,7 @@ via getData 0 1 2 3 4 5 6 7 8 9
 
This produces:
-ev4:nt/NTEnum:1.0
+epics:nt/NTEnum:1.0
     enum_t value
         int index 0
         string[] choices []
@@ -613,7 +613,7 @@ structure
 
This produces:
-ev4:nt/NTUnion:1.0
+epics:nt/NTUnion:1.0
     union value
         time_t
             long secondsPastEpoch 1000
@@ -628,7 +628,7 @@ ev4:nt/NTUnion:1.0
         int nanoseconds 0
         int userTag 0
 0x60a2c8
-ev4:nt/NTUnion:1.0
+epics:nt/NTUnion:1.0
     union value
         double  100000
     alarm_t alarm
@@ -660,7 +660,7 @@ ev4:nt/NTUnion:1.0
 
This produces:
-ev4:nt/NTUnion:1.0
+epics:nt/NTUnion:1.0
     any value
         time_t
             long secondsPastEpoch 1000
@@ -675,7 +675,7 @@ ev4:nt/NTUnion:1.0
         int nanoseconds 0
         int userTag 0
 0x60a2c8
-ev4:nt/NTUnion:1.0
+epics:nt/NTUnion:1.0
     any value
         double  100000
     alarm_t alarm
@@ -735,7 +735,7 @@ ev4:nt/NTUnion:1.0
 This produces:
 
 introspection
-ev4:nt/NTUnion:1.0
+epics:nt/NTUnion:1.0
     union value
         double doubleValue
         double[] doubleArrayValue
@@ -771,7 +771,7 @@ ev4:nt/NTUnion:1.0
         int userTag
 0x60a2c8
 data
-ev4:nt/NTUnion:1.0
+epics:nt/NTUnion:1.0
     union value
         (none)
     alarm_t alarm
@@ -784,7 +784,7 @@ ev4:nt/NTUnion:1.0
         int userTag 0
 0x60a2c8
 select valueDouble
-ev4:nt/NTUnion:1.0
+epics:nt/NTUnion:1.0
     union value
         double  1.55
     alarm_t alarm
@@ -798,7 +798,7 @@ ev4:nt/NTUnion:1.0
 0x60a2c8
 value = 1.55
 select structValue
-ev4:nt/NTUnion:1.0
+epics:nt/NTUnion:1.0
     union value
         structure
             double doubleValue 1.65
diff --git a/documentation/pvDataCPPCookbook.txt b/documentation/pvDataCPPCookbook.txt
index 6021e09..d408bc3 100644
--- a/documentation/pvDataCPPCookbook.txt
+++ b/documentation/pvDataCPPCookbook.txt
@@ -28,11 +28,11 @@ StructureConstPtr enum_t =
 // create a structure (cntd.)
 StructureConstPtr ntEnum = 
     getFieldCreate()->createFieldBuilder()->
-        setId("uri:ev4:nt/2012/pwd/NTEnum")->
+        setId("epics:nt/NTEnum:1.0")->
         add("value", enum_t)->
         addNestedStructure("timeStamp")->
             setId("time_t")->
-            add("secsPastEpoch", pvLong)->
+            add("secondsPastEpoch", pvLong)->
             add("nanoseconds", pvInt)->
             add("userTag", pvInt)->
             endNested()->
diff --git a/src/factory/StandardField.cpp b/src/factory/StandardField.cpp
index efc3086..d3009fa 100644
--- a/src/factory/StandardField.cpp
+++ b/src/factory/StandardField.cpp
@@ -503,28 +503,28 @@ StructureConstPtr StandardField::scalar(
     ScalarType type,string  const &properties)
 {
     ScalarConstPtr field = fieldCreate->createScalar(type); // scalar_t
-    return createProperties("ev4:nt/NTScalar:1.0",field,properties);
+    return createProperties("epics:nt/NTScalar:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::regUnion(
     UnionConstPtr const &field,
         string const & properties)
 {
-   return createProperties("ev4:nt/NTUnion:1.0",field,properties);
+   return createProperties("epics:nt/NTUnion:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::variantUnion(
     string const & properties)
 {
     UnionConstPtr field =  fieldCreate->createVariantUnion();
-    return createProperties("ev4:nt/NTUnion:1.0",field,properties);
+    return createProperties("epics:nt/NTUnion:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::scalarArray(
     ScalarType elementType, string  const &properties)
 {
     ScalarArrayConstPtr field = fieldCreate->createScalarArray(elementType); // scalar_t[]
-    return createProperties("ev4:nt/NTScalarArray:1.0",field,properties);
+    return createProperties("epics:nt/NTScalarArray:1.0",field,properties);
 }
 
 
@@ -533,7 +533,7 @@ StructureConstPtr StandardField::structureArray(
 {
     StructureArrayConstPtr field = fieldCreate->createStructureArray(
         structure);
-    return createProperties("ev4:nt/NTStructureArray:1.0",field,properties);
+    return createProperties("epics:nt/NTStructureArray:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::unionArray(
@@ -541,7 +541,7 @@ StructureConstPtr StandardField::unionArray(
 {
     UnionArrayConstPtr field = fieldCreate->createUnionArray(
         punion);
-    return createProperties("ev4:nt/NTUnionArray:1.0",field,properties);
+    return createProperties("epics:nt/NTUnionArray:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::enumerated()
@@ -560,7 +560,7 @@ StructureConstPtr StandardField::enumerated()
 StructureConstPtr StandardField::enumerated(string  const &properties)
 {
     StructureConstPtr field = enumerated(); // enum_t
-    return createProperties("ev4:nt/NTEnum:1.0",field,properties);
+    return createProperties("epics:nt/NTEnum:1.0",field,properties);
 }
 
 StructureConstPtr StandardField::alarm()
diff --git a/src/pv/standardField.h b/src/pv/standardField.h
index f0dbf90..9dcf7ba 100644
--- a/src/pv/standardField.h
+++ b/src/pv/standardField.h
@@ -122,7 +122,7 @@ public:
      */
     StructureConstPtr enumerated();
     /** Create a structure that has an enumerated structure value field
-     * The id for the structure is "ev4:nt/NTEnum:1.0".
+     * The id for the structure is "epics:nt/NTEnum:1.0".
      * @param properties A comma separated list of properties.
      * This is some combination of "alarm,timeStamp,display,control,valueAlarm".
      * @return The const shared pointer to the structure.
diff --git a/src/pv/standardPVField.h b/src/pv/standardPVField.h
index 5b35afe..cad6c2e 100644
--- a/src/pv/standardPVField.h
+++ b/src/pv/standardPVField.h
@@ -84,7 +84,7 @@ public:
     PVStructurePtr enumerated(StringArray const &choices);
     /**
      * Create a structure that has an enumerated structure value field.
-     * The id for the structure is "ev4:nt/NTEnum:1.0".
+     * The id for the structure is "epics:nt/NTEnum:1.0".
      * @param choices This is a StringArray of choices.
      * @param properties A comma separated list of properties.
      * @return The const shared pointer to the structure.

From 587f81f5115ce5c785eff876c5b591eee352f98f Mon Sep 17 00:00:00 2001
From: Matej Sekoranja 
Date: Tue, 28 Oct 2014 19:36:57 +0100
Subject: [PATCH 15/15] win32 in vs2013 compilation fix

---
 documentation/RELEASE_NOTES.html |  6 +++---
 documentation/RELEASE_NOTES.md   |  4 ++--
 src/factory/Convert.cpp          |  3 ++-
 src/misc/parseToPOD.cpp          | 15 +++++++++++++--
 testApp/copy/testPVCopy.cpp      | 20 ++++++++++----------
 5 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 59bf2d2..70a2f0f 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -34,8 +34,8 @@ For example:

is replaced by

  PVDoublePtr pvValue;
-  cout << pvValue=>dumpValue(cout) << endl
-  cout << pvValue->getField()->dump(cout) << endl;
+  cout << *pvValue << endl
+  cout << *pvValue->getField() << endl;
 

union is a new basic type.

There are two new basic types: union_t and unionArray.

@@ -55,4 +55,4 @@ only on pvData, i. e. it no longer has any knowledge of PVRecord.

This is for is for use by code that implements pvAccess monitors. This is prototype and is subject to debate.

Release 3.0.2

-

This was the starting point for RELEASE_NOTES

\ No newline at end of file +

This was the starting point for RELEASE_NOTES

diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 5a66e64..760892c 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -53,8 +53,8 @@ For example: is replaced by PVDoublePtr pvValue; - cout << pvValue=>dumpValue(cout) << endl - cout << pvValue->getField()->dump(cout) << endl; + cout << *pvValue << endl + cout << *pvValue->getField() << endl; union is a new basic type. diff --git a/src/factory/Convert.cpp b/src/factory/Convert.cpp index ffeff40..ce00129 100644 --- a/src/factory/Convert.cpp +++ b/src/factory/Convert.cpp @@ -50,7 +50,8 @@ void Convert::getString(string *buf,PVField const *pvField,int /*indentLevel*/) { // TODO indextLevel ignored std::ostringstream strm; - strm << pvField->dumpValue(strm) << std::endl; + pvField->dumpValue(strm); + strm << std::endl; // PrinterPlain p; // p.setStream(strm); // p.print(*pvField); diff --git a/src/misc/parseToPOD.cpp b/src/misc/parseToPOD.cpp index 8180a6f..fa9bc85 100644 --- a/src/misc/parseToPOD.cpp +++ b/src/misc/parseToPOD.cpp @@ -27,7 +27,7 @@ using std::string; #endif #if EPICS_VERSION_INT < VERSION_INT(3,15,0,1) -/* integer conversion primatives added to epicsStdlib.c in 3.15.0.1 */ +/* integer conversion primitives added to epicsStdlib.c in 3.15.0.1 */ #define S_stdlib_noConversion 1 /* No digits to convert */ #define S_stdlib_extraneous 2 /* Extraneous characters */ @@ -249,7 +249,18 @@ epicsParseFloat(const char *str, float *to, char **units) } #endif -#if defined(NEED_LONGLONG) && (defined(__vxworks) || defined (_WIN32)) +// MS Visual Studio 2013 defines strtoll, etc. +#if defined(_WIN32) +# if (_MSC_VER >= 1800) +# define WIN_NEEDS_OLL_FUNC 0 +# else +# define WIN_NEEDS_OLL_FUNC 1 +# endif +#else +# define WIN_NEEDS_OLL_FUNC 0 +#endif + +#if defined(NEED_LONGLONG) && (defined(__vxworks) || WIN_NEEDS_OLL_FUNC) static long long strtoll(const char *ptr, char ** endp, int base) { diff --git a/testApp/copy/testPVCopy.cpp b/testApp/copy/testPVCopy.cpp index fc2fc63..8a7d886 100644 --- a/testApp/copy/testPVCopy.cpp +++ b/testApp/copy/testPVCopy.cpp @@ -214,7 +214,7 @@ static void scalarTest() CreateRequest::shared_pointer createRequest = CreateRequest::create(); pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "value"; testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); @@ -222,7 +222,7 @@ static void scalarTest() valueNameMaster = "value"; pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "value"; testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); @@ -230,7 +230,7 @@ static void scalarTest() valueNameMaster = "value"; pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "value"; testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); @@ -253,7 +253,7 @@ static void arrayTest() valueNameMaster = request = "value"; pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "value"; testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy); @@ -261,7 +261,7 @@ static void arrayTest() valueNameMaster = "value"; pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "value"; testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy); @@ -269,7 +269,7 @@ static void arrayTest() valueNameMaster = "value"; pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "value"; testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy); @@ -320,7 +320,7 @@ static void powerSupplyTest() valueNameMaster = request = "power.value"; pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "power.value"; testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); @@ -328,7 +328,7 @@ static void powerSupplyTest() valueNameMaster = "power.value"; pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "power.value"; testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); @@ -336,7 +336,7 @@ static void powerSupplyTest() valueNameMaster = "power.value"; pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "power.value"; testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); @@ -344,7 +344,7 @@ static void powerSupplyTest() valueNameMaster = "power.value"; pvRequest = createRequest->createRequest(request); if(debug) { cout << "request " << request << endl; } - if(debug) { cout << "pvRequest\n" << pvRequest->dumpValue(cout) << endl; } + if(debug) { cout << "pvRequest\n" << *pvRequest << endl; } pvCopy = PVCopy::create(pvMaster,pvRequest,""); valueNameCopy = "power.value"; testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);