diff --git a/documentation/pvDataCpp.html b/documentation/pvDataCpp.html index c8f781f..628f779 100644 --- a/documentation/pvDataCpp.html +++ b/documentation/pvDataCpp.html @@ -10,11 +10,11 @@

EPICS pvDataCPP
Overview
-2010.12.06

+2010.12.13

TODO

CONTENTS + +
+ +

-

Introduction

+

Introduction


This product is available via the open source license described at the end of this document.

-

PVData is one of a set of related projects. It describes and implements -the 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 projects pvAccess and javaIOC, -which are located via the same sourceforge site as this project. Project -PVAccess provides network support for transporting pvData. Project javaIOC -provides a memory resident "smart" database of pvData data.

+

PVData is one of a set of related projects: pvData, pvAccess, and javaIOC. +It describes and implements the data that the other project use. 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 +pvAccess and javaIOC, which are located via the same sourceforge site as this +project. Project PVAccess provides network support for transporting pvData. +Project javaIOC provides a memory resident "smart" database of pvData +data.

This document describes the C++ implementation of pvData, which was first implemented in Java. A C++ implementation of pvAccess is being developed in parallel with pvDataCPP. In the future a C++ implementation of javaIOC will -be developed and the name javaIOV will become pvIOC.

+be developed and the name javaIOC will become pvIOC.

pvData (Process Variable Data) defines and implements an efficent way to store, access, and transmit memory resident structured data.

-
definition
+
description
The header files pvIntrospect.h and pvData.h provide the C++ description of pvData.
implementation
-
Ditrectory factory provides a complete C++ definition for pvData. It - also proivides abstract and base classes that allow specialized +
Directory factory provides a complete C++ definition for pvData. It + also proivides abstract and base classes that support specialized implementations of the data classes.
efficient
Small memory footprint, low cpu overhead, and concise code base.
@@ -70,42 +235,30 @@ store, access, and transmit memory resident structured data.

data transfer
The separation of introspection and data interfaces allows for efficient network data transfer. At connection time introspection - information can be passed from server to client. Each side can create a - data instance. The data is transferred between these instances. The - data in the network buffers does not have to be self describing since - each side has the introspection information.
+ information is passed from server to client. Each side creates a data + instance. The data is transferred between these instances. The data in + the network packets does not have to be self describing since each side + has the introspection information.
memory resident
pvData only defines memory resident data.
structured data
pvData has four types: scalar, scalar array, structure, and structure array. A scalar can be one of the following: boolean, byte, short, int, long, float, double, string. A scalar array is a one dimensional array - with the element type being a scalar. A structure is an ordered set of - fields where each field has a name and type. A structure array is a one - dimensional array of structures where each element has the same - introspection interface. Since a field can have type structure complex - structures are supported. No other types are needed since structures - can be defined that simulate types.
+ with the element type being one of the scalar types. A structure is an + ordered set of fields where each field has a name and type. A structure + array is a one dimensional array of structures where each element has + the same introspection interface. Since a field can have type structure + complex structures are supported. No other types are needed since + structures can be defined that simulate complex types.

The javaIOC implements a Process Variable (PV) Database, which is a memory -resident database holding pvData, has the following features:

+resident database holding pvData with the following features:

pvData was initially created to support the javaIOC and was part of the @@ -140,14 +293,15 @@ appear under pvDataApp:


-

PVData Meta Language

+

PVData Meta Language


This section describes a meta language for describing pvData. Currently there are no plans for any software, e.g. a parser, for the meta language. It -is only meant for documentation.

+is only meant for documentation. Note that the toString methods described +below do present data in this format.

-

Definition

+

Definition

PVData supports structured data. All data appears as a top level structure. A structure has an ordered set of fields where each field has a @@ -255,7 +409,7 @@ is permitted surrounding each comma.

For a structure the syntax is:

   { fieldValue,...,fieldValue }
-

where each fieldValueY is a +

where each fieldValue is a valid field value depending on the type. Thus it is a comma separated set of values enclosed in {} White space is permitted surrounding each comma.

@@ -263,7 +417,7 @@ is permitted surrounding each comma.

A structureArray was the form:

    [ {structureValue},...,{structureValue}]
-

Example

+

Example

Define the following top level structure:

structure timeStamp
@@ -276,7 +430,7 @@ is permitted surrounding each comma.

timeStamp timeStamp scalar arrayDoubleExample - double[] value = {1.0,2.0} + double[] value = [1.0,2.0] timeStamp timeStamp structure point @@ -295,10 +449,10 @@ structure structureArrayExample ]

-

PV - User Description

+

PV - User Description


-

Overview

+

Overview

Directory pvDataApp/pv has header files that completely describe pvData. The implementation is provided in directory pvDataApp/factory. Test programs @@ -311,7 +465,7 @@ interface, which is Field or an extension of Field. This section describes the complete set of data and introspection interfaces for pvData.

A class FieldCreate creates introspection objects. A class PVDataCreate -createsdata objects. A class Convert provides a rich set of methods for +creates data objects. A class Convert provides a rich set of methods for converting and copying data between fields.

Directory pvDataApp/pv has the following header files:

@@ -323,14 +477,14 @@ converting and copying data between fields.

convert.h
The facility that converts between data fields.
standardField.h
-
Provides access to introspection interfaces for standard field like - timeStamp, alarm, etc.
+
Provides access to introspection interfaces for standard + introspection structures like timeStamp, alarm, etc.
standardPVField.h
-
Cteates data interfaces for standard data fields like timeStamp, +
Cteates data interfaces for standard data structures like timeStamp, alarm, etc.
-

Process Variable Reflection

+

Process Variable Reflection

This subsection describes pvIntrospect.h

@@ -341,18 +495,19 @@ available. For example when a client connects to a PV, the client library can obtain the reflection information without obtaining any data. Only when a client issues an I/O request will data be available. This separation is especially important for arrays and structures so that a client can discover -the type without requiring that a large array or structure be transported -over the network.

+the type without requiring that a large data array or structure be +transported over the network.

-

Type

+

Type Description

-

The types are defined by the Java definitions:

+

Types are defined as:

enum Type {
     scalar,
     scalarArray,
     structure,
     structureArray;
 };
+
 class TypeFunc {
 public:
     static void toString(StringBuilder buf,const Type type);
@@ -365,6 +520,7 @@ enum ScalarType {
     pvFloat,pvDouble,
     pvString;
 };
+
 class ScalarTypeFunc {
 public:
     static bool isInteger(ScalarType type);
@@ -382,7 +538,9 @@ following:

scalarArray
An array where every element has the same scalar type.
structure
-
A structure where each field can have a dfferent type.
+
A structure where each field has a name and a type. Within a + structure each field name must be unique but the type can be + different.
structureArray
An array where each element is a structure. Each element has the same structure introspection interface.
@@ -433,81 +591,10 @@ style="font-family: courier;">ScalarType

Convert the scalar type to a string.
-

Reflection

+

Reflection Description

-

This section defines the complete set of Java PV reflection interfaces.

-
    
-class Field :  private NoDefaultMethods {
-public:
-   virtual ~Field();
-   Field(String fieldName,Type type);
-   static ConstructDestructCallback *getConstructDestructCallback();
-   int getReferenceCount() const;
-   String getFieldName() const;
-   Type getType() const;
-   virtual void toString(StringBuilder buf) const{toString(buf,0);}
-   virtual void toString(StringBuilder buf,int indentLevel) const;
-private:
-};
-
-class Scalar : public Field{
-public:
-   Scalar(String fieldName,ScalarType scalarType);
-   virtual ~Scalar();
-   ScalarType getScalarType() const {return scalarType;}
-   virtual void toString(StringBuilder buf) const{toString(buf,0);}
-   virtual void toString(StringBuilder buf,int indentLevel) const;
-private:
-};
-class ScalarArray : public Field{
-public:
-   ScalarArray(String fieldName,ScalarType scalarType);
-   virtual ~ScalarArray();
-   ScalarType  getElementType() const {return elementType;}
-   virtual void toString(StringBuilder buf) const{toString(buf,0);}
-   virtual void toString(StringBuilder buf,int indentLevel) const;
-private:
-};
-
-class StructureArray : public Field{
-public:
-   StructureArray(String fieldName,StructureConstPtr structure);
-   virtual ~StructureArray();
-   StructureConstPtr  getStructure() const {return pstructure;}
-   virtual void toString(StringBuilder buf) const{toString(buf,0);}
-   virtual void toString(StringBuilder buf,int indentLevel) const;
-private:
-};
-
-class Structure : public Field {
-public:
-   Structure(String fieldName, int numberFields,FieldConstPtrArray fields);
-   virtual ~Structure();
-   int getNumberFields() const {return numberFields;}
-   FieldConstPtr getField(String fieldName) const;
-   int getFieldIndex(String fieldName) const;
-   FieldConstPtrArray getFields() const {return fields;}
-   virtual void toString(StringBuilder buf) const{toString(buf,0);}
-   virtual void toString(StringBuilder buf,int indentLevel) const;
-private:
-};
-
-class FieldCreate : NoDefaultMethods {
-public:
-   FieldConstPtr  create(String fieldName,FieldConstPtr  field) const;
-   ScalarConstPtr  createScalar(String fieldName,ScalarType scalarType) const;
-   ScalarArrayConstPtr createScalarArray(String fieldName,
-       ScalarType elementType) const;
-   StructureConstPtr createStructure (String fieldName,
-       int numberFields,FieldConstPtrArray fields) const;
-   StructureArrayConstPtr createStructureArray(String fieldName,
-       StructureConstPtr structure) const;
-private:
-};
-
-extern FieldCreate * getFieldCreate();
- -

The above definitions support the following:

+

This section describes the reflection interfaces which provide the +following:

Field
A field: @@ -522,9 +609,9 @@ extern FieldCreate * getFieldCreate();
ScalarArray
The element type is a scalarType
StructureArray
-
The field holds PVStructure[]. Each element has the same Structure - interspection interface. A client can only get/put entire PVStructure - elements NOT subfields of array elements.
+
The field holds an array of structures. Each element has the same + Structure interspection interface. A client can only get/put entire + PVStructure elements NOT subfields of array elements.
Structure
Has fields that can be any of the supported types.
FieldCreate
@@ -533,18 +620,166 @@ extern FieldCreate * getFieldCreate();
getFieldCreate
Gets a pointer to the single instance of FieldCreate.
+
    
+class Field :  private NoDefaultMethods {
+public:
+   static ConstructDestructCallback *getConstructDestructCallback();
+   int getReferenceCount() const;
+   String getFieldName() const;
+   Type getType() const;
+   virtual void toString(StringBuilder buf) const{toString(buf,0);}
+   virtual void toString(StringBuilder buf,int indentLevel) const;
+};
 
-

Standard Fields

+class Scalar : public Field{ +public: + ScalarType getScalarType() const {return scalarType;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; +protected: + Scalar(String fieldName,ScalarType scalarType); + virtual ~Scalar(); +... +}; -

The file standardField.h has a class description for getting Field objects -for standard fields. For each type of standard object two methods are -defined: one with no properties and with properties. The property field is a -comma separated string of property names of the following: alarm, timeStamp, -display, control, and valueAlarm. An example is "alarm,timeStamp,valueAlarm". -The method with properties creates a structure with fields named fieldName -and each of the property names. Each property field is a structure defining -the property. The details about each property is given in the section named -"Property". For example the call:

+class ScalarArray : public Field{ +public: + ScalarType getElementType() const {return elementType;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; +protected: + ScalarArray(String fieldName,ScalarType scalarType); + virtual ~ScalarArray(); +... +}; + +class StructureArray : public Field{ +public: + StructureConstPtr getStructure() const {return pstructure;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; +protected: + StructureArray(String fieldName,StructureConstPtr structure); + virtual ~StructureArray(); +... +}; + +class Structure : public Field { +public: + int getNumberFields() const {return numberFields;} + FieldConstPtr getField(String fieldName) const; + int getFieldIndex(String fieldName) const; + FieldConstPtrArray getFields() const {return fields;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; +protected: + Structure(String fieldName, int numberFields,FieldConstPtrArray fields); + virtual ~Structure(); +... +}; + +class FieldCreate : NoDefaultMethods { +public: + FieldConstPtr create(String fieldName,FieldConstPtr field) const; + ScalarConstPtr createScalar(String fieldName,ScalarType scalarType) const; + ScalarArrayConstPtr createScalarArray(String fieldName, + ScalarType elementType) const; + StructureConstPtr createStructure (String fieldName, + int numberFields,FieldConstPtrArray fields) const; + StructureArrayConstPtr createStructureArray(String fieldName, + StructureConstPtr structure) const; +}; + +extern FieldCreate * getFieldCreate();
+ +

The following methods are common to all of the reflection class +descriptions:

+
+
Constructor and Destructor
+
Note that all constructors and destructors are protected or private. + The only way to create instances is via FieldCreate. The implementation + manages all storage and automatically calls delete when no client is + attached. A few details are discussed in a later section.
+
toString
+
Many classes provide this (actually two methods). This method is + called to get a string that uses the metadata syntax described in a + previous section.
+
+ +

Field has the methods:

+
+
getConstructDestructCallback
+
This gets a interface that provides methods that return the total + number of object instances of Field that have been created and deleted. + This is provided to help locate memory leaks.
+
getReferenceCount
+
Get the total number of current references to this field + instance.
+
getFieldName
+
Get the name of the field.
+
getType
+
Get the field type.
+
+ +

Scalarhas the methods:

+
+
getScalarType
+
Get that scalar type.
+
+ +

ScalarArrayhas the methods:

+
+
getElementType
+
Get the element type.
+
+ +

StructureArrayhas the +methods:

+
+
getStructure
+
Get the introspection interface that each element shares,
+
+ +

Structurehas the methods:

+
+
getNumberFields
+
Get the number of immediate subfields.
+
getField
+
Given a name get the introspection interface for the field.
+
getFieldIndex
+
Given a name get the index, within the array returned by the next + method, of the field.
+
getFields
+
Get the array of introspection interfaces for the field,
+
+ +

FieldCreatehas the methods:

+
+
create
+
Given a field name and an existing introspection interface create a + new introspection object. The existing introspection interface can be + any of the allowed types.
+
createScalar
+
Create a scalar introspection instance.
+
createScalarArray
+
Create a scalar array introspection instance.
+
createStructure
+
Create a structure introspection instance.
+
createStructureArray
+
Create a structure array introspection instance.
+
+ +

Standard Fields

+ +

The file standardField.h has a class description for creating or sharing +Field objects for standard fields. For each type of standard object two +methods are defined: one with no properties and with properties. The property +field is a comma separated string of property names of the following: alarm, +timeStamp, display, control, and valueAlarm. An example is +"alarm,timeStamp,valueAlarm". The method with properties creates a structure +with fields named fieldName and each of the property names. Each property +field is a structure defining the property. The details about each property +is given in the section named "Property". For example the call:

    StructureConstPtr example = standardField->scalar(
         String("value"),
         pvDouble,
@@ -564,7 +799,7 @@ the property. The details about each property is given in the section named
 

In addition there are methods that create each of the property structures, i.e. the methods named: alarm, .... enumeratedAlarm."

-

pvIntrospect.h contains:

+

standardField.h contains:

class StandardField : private NoDefaultMethods {
 public:
     StandardField();
@@ -654,8 +889,8 @@ extern StandardField * getStandardField();
structureArrayValue
structureValue
enumeratedValue
-
These are all like the version without the "Value" suffix except that - the field name will always be "value"
+
These are all like the version without the "Value" suffix. The field + name will always be "value"
alarm
timeStamp
display
@@ -673,12 +908,12 @@ extern StandardField * getStandardField();
defined. -

PVField - Data Interfaces

+

PVField - Data Interfaces

This section defines the Java Interfaces for accessing the data within a PV record.

-

PVField

+

PVField

PVField is the base interface for accessing data. A data structure consists of a top level PVStructure. Every field of every structure of every @@ -721,13 +956,13 @@ private: };

PostHandler is a class that -must bed implemented by any code that calls setPostHandler. It's single +must be implemented by any code that calls setPostHandler. It's single virtual method. postPut is called whenever PVField::postPut is called.

Requester,Serializable, and -NoDefaultMethods were described in a previous section.

+NoDefaultMethods are described in a later section.

The public methods for PVField are:

@@ -737,7 +972,7 @@ are:

call to one of the methods of PVDataCreate
getConstructDestructCallback
-
Provides access to the number of timers that been created and +
Provides access to the number of PVFields that been created and destroyed.
setRequester
Sets a requester to be called when message or getRequesterName are @@ -782,9 +1017,16 @@ are:

toString
Converts the field data to a string. This is mostly for debugging purposes.
+
operator==
+
Compare this field with another field. The result will be true only + if the fields have exactly the same field types and if the data values + are equal.
+
operator!=
+
The inverse of operator== + .
-

PVAuxInfo

+

PVAuxInfo

AuxInfo (Auxillary Information) is information about a field that is application specific. It will not be available outside the application that @@ -822,7 +1064,7 @@ private:

Print all the auxInfos
-

PVScalar and extensions

+

PVScalar and extensions

class PVScalar : public PVField {
 public:
     virtual ~PVScalar();
@@ -831,7 +1073,7 @@ protected:
     PVScalar(PVStructure *parent,ScalarConstPtr scalar);
 };
-
Primitive PVField types
+
Primitive PVField types

The interfaces for primitive data types are:

class PVBoolean : public PVScalar {
@@ -920,7 +1162,7 @@ protected:
 private:
 };
-

PVArray and Extensions

+

PVArray and Extensions

PVArray is the base interface for all the other PV Array interfaces. It extends PVField and provides the @@ -948,13 +1190,13 @@ private: };

getLength
-
Get the current length. This is less that or equal to the +
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.
getCapacity
-
Get the capacity, i.e. this is the sized of the underlying data +
Get the capacity, i.e. this is the size of the underlying data array.
setCapacity
Set the capacity. The semantics are implementation dependent but @@ -967,7 +1209,7 @@ private:
Specify if the capacity can be changed.
-
PVArray Extensions
+
PVArray Extensions

The interface for each array type has get and put methods which have the same arguments except for the data type. For example PVDoubleArray is:

@@ -997,8 +1239,7 @@ private: The caller is responsible for copying the array elements. This violates the principle that objects should not expose their internal data but is done for efficency. For example it makes it possible to copy between arrays with -identical element types via a call to System.arraycopy without requiring an -intermediate array.

+identical element types without requiring an intermediate array.

Both get and put return the number of elements actually transfered. The arguments are:

@@ -1022,7 +1263,7 @@ arguments are:

The caller must be prepared to make multiple calls to retrieve or put an entire array. A caller should accept or put partial arrays. For example the following reads an entire array:

-
    void doubleArray getArray(PVDoubleArray *pv,doubleArray to,int lenArray)
+
    void doubleArray getArray(PVDoubleArray *pv,doubleArray *to,int lenArray)
     {
         int len = pv->getLength();
         if(lenArray<len) len = lenArray;
@@ -1030,8 +1271,8 @@ following reads an entire array:

int offset = 0; while(offset < len) { int num = pv->get(offset,(len-offset),&data); - double *from = &data.data[data.offset]; - double *to = &to[offset] + doubleArray from = &data.data[data.offset]; + doubleArray to = &to[offset] int numbytes = num*sizeof(double); memcopy(from,to,numBytes); offset += num; @@ -1045,19 +1286,17 @@ then it is the applications responsibility to coordinate access to the array. Again this violates the principle that objects should not expose their internal data but is important for immutable arrays. For example pvData and the javaIOC define many enumerated structures where an enumerated structure -has three fields: index, choice, and choices. Choices is a PVStringArray that -holds the enumerated choices. Index is a PVInt that is the index of the -currently selected choice and choice is a PVString which is the currently +has two fields: index and choices. Choices is a PVStringArray that holds the +enumerated choices. Index is a PVInt that is the index of the currently selected choice. For many enumerated structures the choices is immutable. Allowing the choices internal String[] to be shared between all the instances -of an enumerated structure saves on storage. An example is alarmSeverity. -Another reason for allowing shared data is so that an application which -processes an array can be separated into multiple modules that directly -access the internal data array of a PVArray. This can be required for -minimizing CPU overhead. In this case it is the applications responsibility -to coordinate access to the array.

+of an enumerated structure saves on storage. Another reason for allowing +shared data is so that an application which processes an array can be +separated into multiple modules that directly access the internal data array +of a PVArray. This can be required for minimizing CPU overhead. In this case +it is the applications responsibility to coordinate access to the array.

-
Complete set of PVArray Extensions
+
Complete set of PVArray Extensions
class PVScalarArray : public PVArray {
 public:
     virtual ~PVScalarArray();
@@ -1234,12 +1473,7 @@ protected:
 private:
 };
-

Notes about PVStructureArray: A client can only access the data in the -elements of the array via the get and put methods, i.e. it is not possible to -access subfields indirectly. PVStructureArray.getNumberFields() returns 1, -i.e. the field looks like a leaf field.

- -

PVStructure

+

PVStructure

The interface for a structure is:

class PVStructure : public PVField,public BitSetSerializable {
@@ -1352,7 +1586,7 @@ private:
     
Specify the structure that this structure extends.
-

PVStructureArray

+

PVStructureArray

The interface for an array of structures is:

class StructureArrayData {
@@ -1384,8 +1618,14 @@ private:
 };

where

+
+
getStructureArray
+
Get the introspection interface shared by each element.
+
-

PVDataCreate

+

The other methods are similar to the methods for other array types.

+ +

PVDataCreate

PVDataCreate is an interface that provides methods that create PVField interfaces. A factory is provided that creates PVDataCreate.

@@ -1451,12 +1691,9 @@ extern PVDataCreate * getPVDataCreate();
structToClone. The newly created sub-fields will have the same values and auxInfos as the original. If structToClone is null then the new structure is initialized to have 0 sub-fields. -
flattenPVStructure
-
Create an array of PVFields for the fields in the PVStructure. The - order is according to fieldOffset.
-

Standard Data Fields

+

Standard Data Fields

A class StandardPVField has methods for creating standard data fields. Like class StandardField it has two forms of the methods which create a @@ -1511,7 +1748,7 @@ public: PVStructure * powerSupply(PVStructure *parent); };

-

Convert

+

Convert

NOTE about copying immutable array fields. If an entire immutable array field is copied to another array that has the same elementType, both offsets @@ -1624,10 +1861,11 @@ for code that implements toString It generates a newline and inserts blanks at the beginning of the newline.


-

Namespace, Typedefs, and Memory Management

+

Namespace, Typedefs, and Memory +Management


-

Namespace

+

Namespace

All include and definition files in project pvDataCPP appear in namespace:

@@ -1635,7 +1873,7 @@ It generates a newline and inserts blanks at the beginning of the newline.

// ... }}
-

typedefs

+

typedefs

Directory misc has an include file pvTypes.h:

typedef signed char int8;
@@ -1669,10 +1907,10 @@ description is:

It is hoped that all modern C++ compilers will properly handle the integer typedefs but if not than there is a good chance that it can be supported by -changes to pvInterspect.h.

+changes to pvInterspect.h without any changes to other code.

std::string is used to implement pvString. This works because std::string -implement COW (Copy On Write) semantics. Thus once created a String can be +implements COW (Copy On Write) semantics. Thus once created a String can be treated like an immutable object, which is what pvData require.

The remaining definitions are:

@@ -1696,8 +1934,7 @@ typedef StructureArray const * StructureArrayConstPtr;

These are definitions for introspection objects. All introspecton objects are immutable and always accessed via pointers.

-

File pvData.h, which is also described in the next section has the -typedefs:

+

File pvData.h has the typedefs:

typedef std::map<String,PVScalar * > PVScalarMap;
 typedef PVScalarMap::const_iterator PVScalarMapIter;
 typedef PVStructure * PVStructurePtr;
@@ -1732,11 +1969,11 @@ typedef String * StringArray;
An array of the specified type NOT a pointer to the type.
-

Memory Managemment

+

Memory Managemment

-

NoDefaultMethods

+

NoDefaultMethods

-

Any class that does not allow the compiler to generate default methods can +

Any class that does not want the compiler to generate default methods can privately extend the following class which is defined in file noDefaultMethods.h:

class NoDefaultMethods {
@@ -1750,19 +1987,19 @@ private:
     NoDefaultMethods & operator=(const NoDefaultMethods &);
 };
-

PVData introspection objects

+

PVData introspection objects

Introspection objects are meant to be shared. The constructors and -destructors are all private so that an introspection object can only be -created via a call to one of the FieldCreate methods described below. The -introspection implementation, together with AbstractPVField keeps reference -counts and automatically deletes objects when the reference count goes to 0. -Code that uses introspection objects always accesses introspection objects -via pointers never via references or direct access to the object. When a -PVData data object is destroyed then pointers to the introspection objects -associated with the data object are no longer valid.

+destructors are all private or protected so that an introspection object can +only be created via a call to one of the FieldCreate methods described below. +The introspection implementation, together with AbstractPVField keeps +reference counts and automatically deletes objects when the reference count +goes to 0. Code that uses introspection objects always accesses introspection +objects via pointers never via references or direct access to the object. +When a PVData data object is destroyed then pointers to the introspection +objects associated with the data object are no longer valid.

-

PVData data objects

+

PVData data objects

All PVData data objects must publically extend AbstractPVField, which does not allow default methods but does have a virtual destructor. It is expected @@ -1775,10 +2012,11 @@ the record is deleted. After deletion all pointers to data in the record are invalid. Similarly pvAccess creates and destroys PVData objects and notifies clients before destroying PVData data objects.

-

Other code in this project

+

Other code in this project

-

If a class is pure data, e. g. TimeStamp, then it acts list like a -primitive object.

+

The classes in property, i.e. alarm, timeStamp, display, and control are +all meant to be free copied and shared. They can be created on the stack. In +most cases it is not necessary to create them on the heap.

Other clases privately extend NoDefaultClasses and are not normally meant to be extended. Thus they can only be created via "new" and must be destroyed @@ -1789,10 +2027,10 @@ via "delete". These classes normally implement the static method:

destructed. This can be used to monitor memory usage.


-

Examples

+

Examples


-

Accessing PVData

+

Accessing PVData

Assume that code wants to print two fields from a PVStructure:

@@ -1803,7 +2041,7 @@ destructed. This can be used to monitor memory usage.

The following code uses introspection to get the desired information.

-
void getValueAndTimeStamp(PVStructure pvStructure,Stringbuffer buf) {
+
void getValueAndTimeStamp(PVStructurePtr pvStructure,Stringbuffer buf) {
    PVField *valuePV = pvStructure->getSubField(String("value"));
    if(valuePV==0) {
        buf += "value field not found";
@@ -1820,11 +2058,11 @@ destructed. This can be used to monitor memory usage.

timeStampPV->toString(buf); }
-

Creating PVData

+

Creating PVData

Example of creating a scalar field.

    PVDataCreate *pvDataCreate = getPVDataCreate();
-    PVDouble pvValue = pvDataCreate.createPVScalar(
+    PVDouble *pvValue = pvDataCreate->createPVScalar(
       0,
       String("value"),
       pvDouble);
@@ -1850,10 +2088,10 @@ and a timeStamp and alarm. Do it the easy way.

String("timeStamp,alarm"))

-

Property

+

Property


-

Definition of Property

+

Definition of Property

Only fields named "value" have properties. A record can have multiple value fields, which can appear in the top level structure of a record or in a @@ -1864,7 +2102,7 @@ structure. Typical property fields are timeStamp, alarm, display, control, and history

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

+The value field has propertiess alarm, timeStamp, and display.

structure counterOutput
     structure alarm
     structure timeStamp
@@ -1891,7 +2129,7 @@ structure powerSupplySimple
     powerSupplyValueStructure power
     powerSupplyValueStructure current
-

Standard Properties

+

Standard Properties

The following field names have special meaning, i.e. support properties for general purpose clients.

@@ -1933,7 +2171,7 @@ for 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.
@@ -1955,12 +2193,58 @@ examples are:

It can write a value to hardware. Etc. -

The model allows for device records. A device record has fields that are -structures that support the PVData data model. For example a powerSupport -record can have fields power, voltage, current that each support the PVData -data model.

+

The model allows for device records. A device record has structure fields +that support the PVData data model. For example a powerSupport record can +have fields power, voltage, current that each support the PVData data model. +

-

timeStamp

+

Overview of Property +Support

+ +

Except for enumerated, each properey has two files: a property.h and a +pvProperty.h . For example: timeStamp.h and pvTimeStamp.h In each case the property.h +file defined methods for manipulating the property data and the pvProperty.h +provides methods to transfer the property data to/from a pvData structure. +

+ +

All methods copy data via copy by value semantics, i.e. not by pointer or +by reference. No property class calls new or delete and all allow the compiler to +generate default methods. All allow a class instance to be generated on the +stack. For example the following is permitted:

+
void example(PVField *pvField) {
+    Alarm alarm;
+    PVAlarm pvAlarm;
+    bool result;
+    result = pvAlarm.attach(pvField);
+    assert(result);
+    Alarm al;
+    al.setMessage(String("testMessage"));
+    al.setSeverity(majorAlarm);
+    result = pvAlarm.set(al);
+    assert(result);
+    alarm = pvAlarm.get();
+     ...
+}
+ +

timeStamp

+ +

A timeStamp is represented by the following structure

+
structure timeStamp
+    int64 secondsPartEpoch
+    int32 nanoSeconds
+ +

The Epoch is the posix epoch, i.e. Jan 1, 1970 00:00:00 UTC. Both the +seconds and nanoSeconds are signed integers and thus can be negative. Since +the 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, i. e. it has is 0<=nanoSeconds<nanoSecPerSec..

Two header files are provided for manipulating time stamps: timeStamp.h and timeStamp.h

-

timeStamp.h

+

timeStamp.h

+ +

This provides

extern int32 milliSecPerSec;
 extern int32 microSecPerSec;
-extern int32 nanoSecPerSec;
+extern int32 ;
 extern int64 posixEpochAtEpicsEpoch;
 
 class TimeStamp {
@@ -2009,8 +2296,71 @@ public:
 };

where

+
+
TimeStamp()
+
The defauly constuctor. 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
+
Adjust seconds and nanoSeconds so that + 0<=nanoSeconds<nanoSecPerSec.
+
fromTime_t
+
Set time from standard C time.
+
toTime_t
+
Convert timeStamp to standard C time.
+
getSecondsPastEpoch
+
Get the number of seconds since the epoch.
+
getEpicsSecondsPastEpoch
+
Get the number of EPICS seconds since the epoch. EPICS uses Jan 1, + 1990 00:00:00 UTC as the epoch.
+
getNanoSeconds
+
Get the number of nanoSeconds. This is always normalized.
+
put(int64 secondsPastEpoch,int32 + nanoSeconds = 0)
+
Set the timeStamp value. If necessary it will be normalized.
+
put(int64 milliseconds)
+
Set the timeStamp with a value the is the number of milliSeconds + since the epoch.
+
getCurrent()
+
Set the timeStamp to the current time.
+
toSeconds()
+
Convert the timeStamp to a value that is the number of seconds since + the epocj
+
operator =
+
operator!=
+
operator<=
+
operator<
+
operator>=
+
operator>
+
Standard C++ operators.
+
getMilliseconds
+
Get the nunber of milliseconds since the epoch.
+
-

pvTimeStamp.h

+

The TimeStamp class provides arithmetic operations on time stamps. The +result is always kept in normalized form, which means that the nano second +portion is 0≤=nano<nanoSecPerSec. Note that it is OK to have timeStamps +for times previous to the epoch.

+ +

TimeStamp acts like a primitive. It can be allocated on the stack and the +compiler is free to generate default methods, i.e. copy constructor, +assignment constructor, and destructor.

+ +

One use for TimeStamp is to time how long a section of code takes to +execute. This is done as follows:

+
    TimeStamp startTime;
+    TimeStamp endTime;
+    ...
+    startTime.getCurrent();
+    // code to measure time
+    endTime.getCurrent();
+    double time = TimeStamp::diff(endTime,startTime);
+ +

pvTimeStamp.h

class PVTimeStamp {
 public:
     PVTimeStamp();
@@ -2019,15 +2369,45 @@ public:
     //returns (false,true) if pvField(isNot, is valid timeStamp structure
     bool attach(PVField *pvField);
     void detach();
-    // following throw logic_error is not attached to PVField
+    // following throw logic_error if not attached to PVField
     // a set returns false if field is immutable
     TimeStamp get() const;
     bool set(TimeStamp timeStamp);
 };

where

+
+
PVTimeStamp
+
The default constructor. Attach must be called before get or set can + be called.
+
attach
+
Attempts to attach to pvField It returns (false,true) if + a timeStamp structure is found. It looks first at pvField itself and if + is not an appropriate pvData structure but the field name is value it + looks up the parent structure tree.
+
detach
+
Detach from the pvData structure.
+
get
+
Copies data from the pvData structure to a TimeStamp. An exception is + thrown if not attached to a pvData structure.
+
set
+
Copies data from TimeStamp to the pvData structure. An exception is + thrown if not attached to a pvData structure.
+
-

alarm

+

alarm

+ +

An pvData alarm structure is defined as follows:

+
structure alarm
+    int32 severity
+    String message
+ +

Note that severity is NOT defined as an enumerated structure. The reason +is performance, i. e. prevent passing the array of choice strings everywhere. +The file alarm.h provides the +choice strings. Thus all code that needs to know about alarms share the exact +same choice strings.

Two header files are provided for manipulating alarms: alarm.h and alarm.h

-

alarm.h

+

alarm.h

enum AlarmSeverity {
  noAlarm,minorAlarm,majorAlarm,invalidAlarm
 };
@@ -2060,9 +2440,32 @@ public:
     void setSeverity(AlarmSeverity value);
 };
-

where

+

Alarm Severity defines the possible alarm severities

-

pvAlarm.h

+

AlarmSeverity has the methods:

+
+
getSeverity
+
Get the alarm severity corresponding to the integer value.
+
getSeverityNames
+
Get the array of severity choices.
+
+ +

Alarm has the methods:

+
+
Alarm
+
The constructor. It sets the severity to no alarm and the message to + "".
+
getMessage
+
Get the message.
+
setMessage
+
Set the message.
+
getSeverity
+
Get the severity.
+
setSeverity
+
Set the severity.
+
+ +

pvAlarm.h

class PVAlarm {
 public:
     PVAlarm() : pvSeverity(0),pvMessage(0) {}
@@ -2078,8 +2481,34 @@ public:
 };

where

+
+
PVAlarm
+
The default constructor. Attach must be called before get or set can + be called.
+
attach
+
Attempts to attach to pvField It returns (false,true) if + it found an appropriate pvData structure. It looks first a pvField + itself and if is not an appropriate pvData structure but the field name + is value it looks to see if the parent structure has an appropriate sub + structure.
+
detach
+
Just detaches from the pvData structure.
+
get
+
Copies data from the pvData structure to an Alarm. An exception is + thrown if not attached to a pvData structure.
+
set
+
Copies data from Alarm to the pvData structure. An exception is + thrown if not attached to a pvData structure.
+
-

control

+

control

+ +

Control information is represented by the following structure

+
structure control
+    structure limit
+        double low
+        double high

Two header files are provided for manipulating controls: control.h and control.h

-

control.h

+

control.h

class Control {
 public:
     Control();
@@ -2103,8 +2532,21 @@ public:
 };

where

+
+
Control
+
The default constructure.
+
getLow
+
Get the low limit.
+
getHigh
+
Get the high limit.
+
setLow
+
Set the low limit.
+
setHigh
+
Set the high limit.
+
-

pvControl.h

+

pvControl.h

class PVControl {
 public:
     PVControl();
@@ -2120,8 +2562,37 @@ public:
 };

where

+
+
PVControl
+
The default constructor. Attach must be called before get or set can + be called.
+
attach
+
Attempts to attach to pvField It returns (false,true) if + it found an appropriate pvData structure. It looks first a pvField + itself and if is not an appropriate pvData structure but the field name + is value it looks to see if the parent structure has an appropriate sub + structure.
+
detach
+
Just detaches from the pvData structure.
+
get
+
Copies data from the pvData structure to a Control. An exception is + thrown if not attached to a pvData structure.
+
set
+
Copies data from Control to the pvData structure. An exception is + thrown if not attached to a pvData structure.
+
-

display

+

display

+ +

Display information is represented by the following structure

+
structure display
+    structure limit
+        double low
+        double high
+    string description
+    string format
+    string units

Two header files are provided for manipulating controls: display.h and diaplay.h

-

display.h

+

display.h

class Display {
 public:
     Display();
@@ -2151,8 +2622,33 @@ public:
 };

where

+
+
Control
+
The default constructure.
+
getLow
+
Get the low limit.
+
getHigh
+
Get the high limit.
+
setLow
+
Set the low limit.
+
setHigh
+
Set the high limit.
+
getDescription
+
Get the description.
+
setDescription
+
Set the description.
+
getFormat
+
Get the format.
+
setFormat
+
Set the format.
+
getUnits
+
Get the units.
+
setUnits
+
Set the units.
+
-

pvDisplay.h

+

pvDisplay.h

class PVDisplay {
 public:
     PVDisplay()
@@ -2168,9 +2664,33 @@ public:
 };

where

-

+
+
PVDisplay
+
The default constructor. Attach must be called before get or set can + be called.
+
attach
+
Attempts to attach to pvField It returns (false,true) if + it found an appropriate pvData structure. It looks first a pvField + itself and if is not an appropriate pvData structure but the field name + is value it looks to see if the parent structure has an appropriate sub + structure.
+
detach
+
Just detaches from the pvData structure.
+
get
+
Copies data from the pvData structure to a Display. An exception is + thrown if not attached to a pvData structure.
+
set
+
Copies data from Display to the pvData structure. An exception is + thrown if not attached to a pvData structure.
+
-

pvEnumerated

+

pvEnumerated

+ +

An enumerated structure is a structure that has fields:

+
structure
+    int32 index
+    string[] choices

For enumerated structures a single header file pvEnumerted.h is available

@@ -2195,17 +2715,50 @@ public: };

where

+
+
PVEnumerated
+
The default constructor. Attach must be called before any get or set + method can be called.
+
attach
+
Attempts to attach to pvField It returns (false,true) if + pvField (is not, is) an enumerated structure.
+
detach
+
Just detaches from the pvData structure.
+
setIndex
+
Set the index field in the pvData structure. An exception is thrown + if not attached to a pvData structure.
+
getIndex
+
Get the index field in the pvData structure.
+
getChoice
+
Get the String value corresponding to the current index field in the + pvData structure. An exception is thrown if not attached to a pvData + structure.
+
choicesMutable
+
Can the choices be changed? Note that this is often true. An + exception is thrown if not attached to a pvData structure.
+
getChoices
+
Get the array of choices. An exception is thrown if not attached to a + pvData structure.
+
getNumberChoices
+
Get the number of choices. An exception is thrown if not attached to + a pvData structure.
+
setChoices
+
Change the choices. An exception is thrown if not attached to a + pvData structure.
+

-

PVData Abstract and Base Classes

+

PVData Abstract and Base +Classes


-

Overview

+

Overview

-

This package provides classes that implement everything defined in package -org.epics.pvData.pv

+

Drectory factory has code that implements everything described by the +include files in directory pv

-

Factory

+

Factories

FieldCreateFactory automatically creates a single instance of FieldCreate and provides a method to get the interface.

@@ -2215,38 +2768,38 @@ PVDataCreate and provides a method to get the interface.

PVAuxInfoImpl implements auxInfo.

-

ConvertFactory automatically creates a single instance of Convert and -provides a method to get the interface.

+

Convert automatically creates a single instance of Convert and provides a +method to get the interface.

-

Abstract Classes for PVField

+

Abstract Classes for PVField

-

AbstractPVField

+

AbstractPVField

This is an abstract base class for implementing PVField interfaces. It MUST be the base class for any class that extends PVField.

-

AbstractPVScalar

+

AbstractPVScalar

This is an abstract base class for implementing scalar data fields. It MUST be the base class for any class that implements a scalar data field.

-

AbstractPVArray

+

AbstractPVArray

This is an abstract base class for implementing array data fields. It MUST be the base class for any class implements array data fields.

-

AbstractPVScalarArray

+

AbstractPVScalarArray

This is an abstract base class for implementing scalar array data fields. It MUST be the base class for any class implements scalar array data fields.

-

BasePVStructure

+

BasePVStructure

BasePVStructure is a base class for any code that implements PVStructure. Any code that implements PVStructure MUST extend this class.

-

Base Classes For PVScalar

+

Base Classes For PVScalar

For each scalar type there is a base class that implements it. The complete list is:

@@ -2261,7 +2814,7 @@ complete list is:

BasePVString
-

Base Classes for PVArray

+

Base Classes for PVArray

For each scalar array type there is a base class that implements it. The complete list is:

@@ -2278,10 +2831,10 @@ complete list is:


-

Miscellanous Classes

+

Miscellanous Classes


-

Overview

+

Overview

This package provides utility code:

@@ -2324,14 +2877,15 @@ complete list is:

timer.h
An implementation of Timer that does not require an object to be created for each timer request.
-
timeStamp.h
-
Usefull methods for a timeStamp.
queue.h
A queue implementation that allows the latest queue element to continue to be used when no free element is available.
-

BitSet

+

Note that directory testApp/misc has test code for all the classes in +misc. The test code also can be used as examples.

+ +

BitSet

This is adapted from the java.util.BitSet. bitSet.h is:

class BitSet /*: public Serializable*/ {
@@ -2427,7 +2981,7 @@ private:
     
Show the current values of the bitSet.
-

ByteBuffer

+

ByteBuffer

A ByteBuffer is used to serialize and deserialize primitive data. File byteBuffer.h is:

@@ -2467,7 +3021,7 @@ private:

x

-

Event

+

Event

This class provides coordinates activity between threads. One thread can wait for the event and the other signals the event.

@@ -2503,7 +3057,7 @@ private:
returns (false,true) if the event is (empty,full)
-

Exception

+

Exception

File epicsException.h describes:

class BaseException : public std::exception {
@@ -2521,7 +3075,7 @@ private:
 
 

x

-

Executor

+

Executor

An Executor is a thread that can execute commands. The user can request that a single command be executed.

@@ -2564,12 +3118,12 @@ to execute.

nothing is done. -

Linked List

+

Linked List

LinkedList implements a double linked list that requires a user to -allocate the nodes. It is more efficent that std::list. linkedList.h is +allocate the nodes. It is more efficent that std::list. linkedList.h is a template that is both a complete description and definition. It uses -linkedListVoid for method definitions. linkedListVoid is not\ meant for use +linkedListVoid for method definitions. linkedListVoid is not meant for use except via linkedList. Note, however, that linkedListVoid does have both a node and a list static method getConstructDestructCallback, which allows access to how many nodes and lists have been created and destroyed.

@@ -2669,27 +3223,31 @@ public:
isEmpty
Is the list empty.
contains
-
Does the list contain the specified object.
+
Does the list contain the specified object?
-

Lock and Mutex

+

Lock and Mutex

-

lock.h contains:

+

lock.h is:

class Mutex  {
 public:
-    Mutex();
-    ~Mutex();
-    void lock();
-    void unlock();
+    Mutex() : id(epicsMutexMustCreate()){}
+    ~Mutex() { epicsMutexDestroy(id) ;}
+    void lock(){epicsMutexMustLock(id);}
+    void unlock(){epicsMutexUnlock(id);}
 private:
+    epicsMutexId id;
 };
 
 
 class Lock : private NoDefaultMethods {
 public:
-    explicit Lock(Mutex *pm);
-    ~Lock();
+    explicit Lock(Mutex *pm)
+    : mutexPtr(pm)
+    {mutexPtr->lock();}
+    ~Lock(){mutexPtr->unlock();}
 private:
+    Mutex *mutexPtr;
 };

This is a complete description and definition of lock and mutex. These @@ -2721,9 +3279,9 @@ once. This can be implemented as follows:

// initialization }
-

Message Queue

+

Message Queue

-

Definitions

+

Definitions

class MessageNode {
 public:
     String getMessage() const;
@@ -2745,7 +3303,7 @@ public:
     int getClearOverrun();
 };
-

MessageQueue

+

MessageQueue

This is for use by code that wants to handle messages without blocking higher priority threads.

@@ -2786,7 +3344,7 @@ higher priority threads.

Look at miscTest/testMessageQueue.cpp for an example.

-

NoDefaultMethods

+

NoDefaultMethods

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

NoDefaultMethods & operator=(const NoDefaultMethods &); };
-

pvType

+

pvType

This provides typedefs for integers and String.

typedef signed char int8;
@@ -2833,7 +3391,7 @@ typedef String* StringArray;
An array of Strings.
-

Requester

+

Requester

A PVField extends Requester. Requester is present so that when database errors are found there is someplace to send a message.

@@ -2863,7 +3421,7 @@ public:
Gives a message to the requester.
-

Serialize

+

Serialize

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

@@ -2934,7 +3492,8 @@ properly implemented.

x

-

Show Constructors and Destructors

+

Show Constructors and +Destructors

This is a facility that allows a class to report how many objects of that class have been created and destroyed. This can help find memory leaks.

@@ -2983,7 +3542,7 @@ usage of a particular class.

registered classes. It can be called as folows:

   getShowConstructDestruct()->constuctDestructTotals(fd);
-

Status

+

Status

Status provides a way to pass status back to client code. It is new and not currently used by pvData but may be in the future. It is used by code @@ -3014,9 +3573,9 @@ that uses pvData.

status optimization. -

Thread

+

Thread

-

ThreadPriority

+

ThreadPriority

enum ThreadPriority {
     lowestPriority,
     lowerPriority,
@@ -3033,7 +3592,7 @@ public:
     static int getEpicsPriority(ThreadPriority threadPriority);
 };
-

Thread

+

Thread

class Runnable {
 public:
     virtual void run() = 0;
@@ -3085,7 +3644,7 @@ exception is thrown if run remains active when delete is called. 

seconds. -

Time Function Call

+

Time Function Call

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. @@ -3127,7 +3686,7 @@ long a function takes. It has the single method:

one second to call it ntimes. -

Timer

+

Timer

This provides a general purpose timer. It allows a user callback to be called after a delay or periodically.

@@ -3210,146 +3769,7 @@ can be used to schedule multiple callbacks. It has the methods:

Schedule a periodic callback.
-

TimeStamp

- -

TimeStamp is a class for accessing a timeStamp that consists of the number -of seconds since the epoch and the number of nanoseconds within the current -second. The epoch is the posix epoch which is Jan 1, 1970 at 00:00:00 -Universal Time Coordinated.

- -

The seconds since the epoch is kept as an int64 and the nano seconds is -kept as in int32.

- -

The implementation of some of the methods (getCurrent, fromTime_t, and -toTime_t) use epicsTime from EPICS base and will thus have a problem when the -epics secPastEpoch overflows, which will happen in about 2126.

- -

The TimeStamp class provides arithmetic operations on time stamps. The -result is always kept in normalized form, which means that the nano second -portion is 0≤=nano<nanoSecPerSec. Note that it is OK to have timeStamps -for times previous to the epoch.

- -

TimeStamp acts like a primitive. It can be allocated on the stack and the -compiler is free to generate default methods, i.e. copy constructor, -assignment constructor, and destructor.

- -

One use for TimeStamp is to time how long a section of code takes to -execute. This is done as follows:

-
    TimeStamp startTime;
-    TimeStamp endTime;
-    ...
-    startTime.getCurrent();
-    // code to measure time
-    endTime.getCurrent();
-    double time = TimeStamp::diff(endTime,startTime);
- -

TimeStamp is described as:

-
extern int32 milliSecPerSec;
-extern int32 microSecPerSec;
-extern int32 nanoSecPerSec;
-extern int64 posixEpochAtEpicsEpoch;
-
-class TimeStamp {
-public:
-    TimeStamp();
-    TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0);
-    //default constructors and destructor are OK
-    //This class should not be extended
-    void normalize();
-    void fromTime_t(const time_t &);
-    void toTime_t(time_t &) const;
-    int64 getSecondsPastEpoch() const;
-    int64 getEpicsSecondsPastEpoch() const;
-    int32 getNanoSeconds() const;
-    void put(int64 secondsPastEpoch,int32 nanoSeconds = 0);
-    void put(int64 milliseconds);
-    void getCurrent();
-    double toSeconds() const ;
-    bool operator==(TimeStamp const &) const;
-    bool operator!=(TimeStamp const &) const;
-    bool operator<=(TimeStamp const &) const;
-    bool operator< (TimeStamp const &) const;
-    bool operator>=(TimeStamp const &) const;
-    bool operator> (TimeStamp const &) const;
-    static double diff(TimeStamp const & a,TimeStamp const & b);
-    TimeStamp & operator+=(int64 seconds);
-    TimeStamp & operator-=(int64 seconds);
-    TimeStamp & operator+=(double seconds);
-    TimeStamp & operator-=(double seconds);
-    int64 getMilliseconds(); //milliseconds since epoch
-private:
-};
- -

TimeStamp has the methods:

-
-
Timer
-
The default constructor sets both seconds and nano seconds to 0. The - other constructor shown above will call normalize.
-
normalize
-
Adjust seconds and nano seconds so that - 0<=nano<nanoSecPerSec
-
fromTime_t
-
Set the timeStamp value from "time_t", which is defined - <ctime>, i.e. by the standard C++ library and also as part of - standard C.
-
toTime_t
-
Convert the timeStamp to "time_t". From time_t, using that standard - C++ library <ctime> it is easy to get a "struct tm" that has the - the time broken into parts. For example: -
    TimeStamp current;
-    current.getCurrent();
-    time_t tt;
-    current.toTime_t(tt);
-    struct tm ctm;
-    memcpy(&ctm,localtime(&tt),sizeof(struct tm));
-    fprintf(auxfd,
-        "%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d nanoSeconds isDst %s\n",
-        ctm.tm_year+1900,ctm.tm_mon + 1,ctm.tm_mday,
-        ctm.tm_hour,ctm.tm_min,ctm.tm_sec,
-        current.getNanoSeconds(),
-        (ctm.tm_isdst==0) ? "false" : "true");
-

prints something like:

-
2010.12.01 07:39:48 807264972 nanoSeconds isDst false
-
-
getSecondsPastEpoch
-
Gets the number of seconds since Jan 1 1970 UTC.
-
getEpicsSecondsPastEpoch
-
Gets the number of seconds since Jan 1 1990 UTC.
-
getNanoSeconds
-
Get the number of nano seconds. This is always - 0<=value<nanoSecPerSec
-
put
-
Set the timeStamp value. The result will always be normalized.
-
getCurrent
-
Get the current time.
-
toSeconds
-
Get the value as a double. It is the number of seconds since the - epoch.
-
operator==
-
Compare equal.
-
operator!=
-
Compare not equal.
-
operator<=
-
Is value <= arg.
-
operator<
-
Is value < arg.
-
operator>=
-
Is value >= arg.
-
operator>
-
Is value > arg.
-
diff
-
The result is (a-b) in seconds.
-
operator+=
-
Add the argument to the timeStamp. The argument can be an integer or - a double. The result will be normalized.
-
operator-=
-
Subtract the argument from the timeStamp. The argument can be an - integer or a double. The result will be normalized.
-
getMilliseconds
-
Get the timeStamp as number of milliseconds since the epoch.
-
- -

Queue

+

Queue

This provides a queue which has an immutable capacity. When the queue is full the user code is expected to keep using the current element until a new @@ -3431,15 +3851,18 @@ public: }


-

pvMisc

+

pvMisc


-

BitSetUtil

+

BitSetUtil

The following is also provided:

-
NOT DONE
+
class BitSetUtil : private NoDefaultMethods {
+public:
+    static bool compress(BitSet *bitSet,PVStructure *pvStructure);
+};
-

This provides functions that operate of a BitSet for a PVStructure. It +

This provides functions that operate on a BitSet for a PVStructure. It currently has only one method:

entire structures if the structure offset bit is set.
-

MultiChoice

+

MultiChoice

MultiChoice defines an array of strings and a bit set that selects an -arbitrary set of the choices.

+arbitrary set of the choices. This will be implemented if the java version is +accepted.

NOT DONE
- -

where

-
-
getBitMask
-
Returns the bitMask.
-
getChoices
-
Returns the complete set of choices..
-
getSelectedChoices
-
Returns the interface for getting the selected choices..
-
setBit
-
Select the choice for specified bit..
-
clear
-
Clear the bitMask, i.e. no choices are selected..
-
registerChoice
-
Register a new choice. If thed choice already exists then it''s index - is returned. If not it is appended to the choices.
-

-

License Agreement

+

License Agreement


Copyright (c) 2008 Martin R. Kraimer
 Copyright (c) 2007 Control System Laboratory,
diff --git a/pvDataApp/Makefile b/pvDataApp/Makefile
index 65794bd..5d06118 100644
--- a/pvDataApp/Makefile
+++ b/pvDataApp/Makefile
@@ -20,7 +20,6 @@ INC += event.h
 INC += thread.h
 INC += executor.h
 INC += showConstructDestruct.h
-INC += timeStamp.h
 INC += timeFunction.h
 INC += timer.h
 INC += queueVoid.h
@@ -36,7 +35,6 @@ LIBSRCS += linkedListVoid.cpp
 LIBSRCS += event.cpp
 LIBSRCS += thread.cpp
 LIBSRCS += executor.cpp
-LIBSRCS += timeStamp.cpp
 LIBSRCS += timeFunction.cpp
 LIBSRCS += timer.cpp
 LIBSRCS += queueVoid.cpp
@@ -93,6 +91,7 @@ INC += pvControl.h
 INC += display.h
 INC += pvDisplay.h
 INC += pvEnumerated.h
+INC += timeStamp.h
 INC += pvTimeStamp.h
 
 LIBSRCS += alarm.cpp 
@@ -100,6 +99,7 @@ LIBSRCS += pvAlarm.cpp
 LIBSRCS += pvControl.cpp 
 LIBSRCS += pvDisplay.cpp 
 LIBSRCS += pvEnumerated.cpp 
+LIBSRCS += timeStamp.cpp
 LIBSRCS += pvTimeStamp.cpp
 
 SRC_DIRS += $(PVDATA)/pvMisc
diff --git a/pvDataApp/factory/BasePVStructure.h b/pvDataApp/factory/BasePVStructure.h
index 10a8c77..d205d4f 100644
--- a/pvDataApp/factory/BasePVStructure.h
+++ b/pvDataApp/factory/BasePVStructure.h
@@ -517,20 +517,12 @@ namespace epics { namespace pvData {
 
     bool PVStructure::operator==(PVField &obj)
     {
-        PVStructure &b = dynamic_cast(obj);
-        PVFieldPtrArray bFields = b.pImpl->pvFields;
-        PVFieldPtrArray pvFields = pImpl->pvFields;
-        int len = b.pImpl->numberFields;
-        if(len!=pImpl->numberFields) return false;
-        for (int i = 0; i < len; i++) {
-            if (!(*pvFields[i]==*bFields[i])) return false;
-        }
-        return true;
+        return getConvert()->equals(this,&obj);
     }
 
     bool PVStructure::operator!=(PVField  &pv)
     {
-        return !(*this==pv);
+        return !(getConvert()->equals(this,&pv));
     }
 
     static PVField *findSubField(String fieldName,PVStructure *pvStructure) {
diff --git a/pvDataApp/factory/Convert.cpp b/pvDataApp/factory/Convert.cpp
index 1aa17a1..3ce20e4 100644
--- a/pvDataApp/factory/Convert.cpp
+++ b/pvDataApp/factory/Convert.cpp
@@ -127,14 +127,14 @@ void Convert::fromString(PVScalar *pvScalar, String from)
     ScalarType scalarType = scalar->getScalarType();
     switch(scalarType) {
         case pvBoolean: {
-                PVBoolean *pv = (PVBoolean *)pvScalar;
+                PVBoolean *pv = static_cast(pvScalar);
                 bool value = 
                   ((from.compare("true")==0) ? true : false);
                 pv->put(value);
                 return;
             }
         case pvByte : {
-                PVByte *pv = (PVByte*)pvScalar;
+                PVByte *pv = static_cast(pvScalar);
                 int ival;
                 sscanf(from.c_str(),"%d",&ival);
                 int8 value = ival;
@@ -142,7 +142,7 @@ void Convert::fromString(PVScalar *pvScalar, String from)
                 return;
             }
         case pvShort : {
-                PVShort *pv = (PVShort*)pvScalar;
+                PVShort *pv = static_cast(pvScalar);
                 int ival;
                 sscanf(from.c_str(),"%d",&ival);
                 int16 value = ival;
@@ -150,7 +150,7 @@ void Convert::fromString(PVScalar *pvScalar, String from)
                 return;
             }
         case pvInt : {
-                PVInt *pv = (PVInt*)pvScalar;
+                PVInt *pv = static_cast(pvScalar);
                 int ival;
                 sscanf(from.c_str(),"%d",&ival);
                 int32 value = ival;
@@ -158,7 +158,7 @@ void Convert::fromString(PVScalar *pvScalar, String from)
                 return;
             }
         case pvLong : {
-                PVLong *pv = (PVLong*)pvScalar;
+                PVLong *pv = static_cast(pvScalar);
                 int64 ival;
                 sscanf(from.c_str(),"%lld",&ival);
                 int64 value = ival;
@@ -166,21 +166,21 @@ void Convert::fromString(PVScalar *pvScalar, String from)
                 return;
             }
         case pvFloat : {
-                PVFloat *pv = (PVFloat*)pvScalar;
+                PVFloat *pv = static_cast(pvScalar);
                 float value;
                 sscanf(from.c_str(),"%f",&value);
                 pv->put(value);
                 return;
             }
         case pvDouble : {
-                PVDouble*pv = (PVDouble*)pvScalar;
+                PVDouble*pv = static_cast(pvScalar);
                 double value;
                 sscanf(from.c_str(),"%lf",&value);
                 pv->put(value);
                 return;
             }
         case pvString: {
-                PVString *value = (PVString*)pvScalar;
+                PVString *value = static_cast(pvScalar);
                 value->put(from);
                 return;
             }
@@ -227,13 +227,21 @@ bool Convert::isCopyCompatible(FieldConstPtr from, FieldConstPtr to)
     if(from->getType()!=to->getType()) return false;
     switch(from->getType()) {
     case scalar: 
-        return isCopyScalarCompatible((ScalarConstPtr)from,(ScalarConstPtr)to);
+        return isCopyScalarCompatible(
+            static_cast(from),
+            static_cast(to));
     case scalarArray:
-        return isCopyScalarArrayCompatible((ScalarArrayConstPtr)from,(ScalarArrayConstPtr)to);
+        return isCopyScalarArrayCompatible(
+            static_cast(from),
+            static_cast(to));
     case structure:
-        return isCopyStructureCompatible((StructureConstPtr)from,(StructureConstPtr)to);
+        return isCopyStructureCompatible(
+            static_cast(from),
+            static_cast(to));
     case structureArray:
-        return isCopyStructureArrayCompatible((StructureArrayConstPtr)from,(StructureArrayConstPtr)to);
+        return isCopyStructureArrayCompatible(
+            static_cast(from),
+            static_cast(to));
     }
     String message("Convert::isCopyCompatible should never get here");
     throw std::logic_error(message);
@@ -243,21 +251,23 @@ void Convert::copy(PVField *from,PVField *to)
 {
     switch(from->getField()->getType()) {
     case scalar: 
-        copyScalar((PVScalar *)from,(PVScalar *)to);
+        copyScalar(
+            static_cast(from),static_cast(to));
         return;
     case scalarArray: {
-        PVScalarArray  *fromArray = (PVScalarArray *)from;
-        PVScalarArray  *toArray = (PVScalarArray *)to;
+        PVScalarArray  *fromArray = static_cast(from);
+        PVScalarArray  *toArray = static_cast(to);
         int length = copyScalarArray(fromArray,0,toArray,0,fromArray->getLength());
         if(toArray->getLength()!=length) toArray->setLength(length);
         return;
     }
     case structure:
-        copyStructure((PVStructure *)from,(PVStructure *)to);
+        copyStructure(static_cast(from) ,
+             static_cast(to));
         return;
     case structureArray: {
-    	PVStructureArray  *fromArray = (PVStructureArray *)from;
-        PVStructureArray  *toArray = (PVStructureArray *)to;
+    	PVStructureArray  *fromArray = static_cast(from);
+        PVStructureArray  *toArray = static_cast(to);
         copyStructureArray(fromArray,toArray);
         return;
     }
@@ -294,57 +304,57 @@ void Convert::copyScalar(PVScalar *from, PVScalar *to)
                     throw std::invalid_argument(message);
                 }
             }
-            PVBoolean *data = (PVBoolean*)from;
+            PVBoolean *data = static_cast(from);
             if(toType==pvString) {
-                PVString *dataTo = (PVString*)to;
+                PVString *dataTo = static_cast(to);
                 String buf("");
                 data->toString(&buf);
                 dataTo->put(buf);
             } else {
                 bool value = data->get();
-                PVBoolean *dataTo = (PVBoolean*)to;
+                PVBoolean *dataTo = static_cast(to);
                 dataTo->put(value);
             }
             break;
         }
     case pvByte : {
-            PVByte *data = (PVByte*)from;
+            PVByte *data = static_cast(from);
             int8 value = data->get();
             convert->fromByte(to,value);
             break;
         }
     case pvShort : {
-            PVShort *data = (PVShort*)from;
+            PVShort *data = static_cast(from);
             short value = data->get();
             convert->fromShort(to,value);
             break;
         } 
     case pvInt :{
-            PVInt *data = (PVInt*)from;
+            PVInt *data = static_cast(from);
             int value = data->get();
             convert->fromInt(to,value);
             break;
         }    
     case pvLong : {
-            PVLong *data = (PVLong*)from;
+            PVLong *data = static_cast(from);
             long value = data->get();
             convert->fromLong(to,value);
             break;
         }  
     case pvFloat : {
-            PVFloat *data = (PVFloat*)from;
+            PVFloat *data = static_cast(from);
             float value = data->get();
             convert->fromFloat(to,value);
             break;
         }     
     case pvDouble : {
-            PVDouble *data = (PVDouble*)from;
+            PVDouble *data = static_cast(from);
             double value = data->get();
             convert->fromDouble(to,value);
             break;
         }  
     case pvString: {
-            PVString *data = (PVString*)from;
+            PVString *data = static_cast(from);
             String value = data->get();
             convert->fromString(to,value);
             break;
@@ -389,8 +399,8 @@ int Convert::copyScalarArray(PVScalarArray *from, int offset,
     && ScalarTypeFunc::isNumeric(toElementType)) {
         return copyNumericArray(from,offset,to,toOffset,length);
     } else if(toElementType==pvBoolean && fromElementType==pvBoolean) {
-        PVBooleanArray *pvfrom = (PVBooleanArray*)from;
-        PVBooleanArray *pvto = (PVBooleanArray*)to;
+        PVBooleanArray *pvfrom = static_cast(from);
+        PVBooleanArray *pvto = static_cast(to);
         while(length>0) {
             int num = 0;
             BooleanArray data = 0;
@@ -407,8 +417,8 @@ int Convert::copyScalarArray(PVScalarArray *from, int offset,
             }
         }
     } else if(toElementType==pvString && fromElementType==pvString) {
-        PVStringArray *pvfrom = (PVStringArray*)from;
-        PVStringArray *pvto = (PVStringArray*)to;
+        PVStringArray *pvfrom = static_cast(from);
+        PVStringArray *pvto = static_cast(to);
         while(length>0) {
             int num = 0;
             String *data;
@@ -425,7 +435,7 @@ int Convert::copyScalarArray(PVScalarArray *from, int offset,
             }
         }
     } else if(toElementType==pvString) {
-        PVStringArray *pvto = (PVStringArray*)to;
+        PVStringArray *pvto = static_cast(to);
         ncopy = from->getLength();
         if(ncopy>length) ncopy = length;
         int num = ncopy;
@@ -437,7 +447,7 @@ int Convert::copyScalarArray(PVScalarArray *from, int offset,
         }
         return ncopy;
     } else if(fromElementType==pvString) {
-        PVStringArray *pvfrom = (PVStringArray*)from;
+        PVStringArray *pvfrom = static_cast(from);
         while(length>0) {
             int num = 0;
             String *data = 0;
@@ -473,19 +483,28 @@ bool Convert::isCopyStructureCompatible(
         if(fromType!=toType) return false;
         switch(fromType) {
         case scalar:
-            if(!convert->isCopyScalarCompatible((ScalarConstPtr)from,(ScalarConstPtr)to)) return false;
+            if(!convert->isCopyScalarCompatible(
+                static_cast(from),
+                static_cast(to)))
+                return false;
             break;
         case scalarArray:
-            if(!isCopyScalarArrayCompatible((ScalarArrayConstPtr)from,(ScalarArrayConstPtr)to))
+            if(!isCopyScalarArrayCompatible(
+                static_cast(from),
+                static_cast(to)))
                 return false;
             break;
         case structure:
-            if(!isCopyStructureCompatible((StructureConstPtr)from,(StructureConstPtr)to))
+            if(!isCopyStructureCompatible(
+                static_cast(from),
+                static_cast(to)))
                 return false;
             break;
         case structureArray:
-            if(!isCopyStructureArrayCompatible((StructureArrayConstPtr)from,
-                (StructureArrayConstPtr)to)) return false;
+            if(!isCopyStructureArrayCompatible(
+                static_cast(from),
+                static_cast(to)))
+                return false;
         }
     }
     return true;
@@ -516,11 +535,13 @@ void Convert::copyStructure(PVStructure *from, PVStructure *to)
             if(fieldIndex->getType()==scalar
             && fieldChoices->getFieldName().compare("choices")
             && fieldChoices->getType()==scalarArray) {
-                PVScalar *pvScalar = (PVScalar*)fromDatas[0];
-                PVScalarArray *pvArray = (PVScalarArray*)fromDatas[1];
+                PVScalar *pvScalar = static_cast(fromDatas[0]);
+                PVScalarArray *pvArray =
+                    static_cast(fromDatas[1]);
                 if((pvScalar->getScalar()->getScalarType()==pvInt)
                 && (pvArray->getScalarArray()->getElementType()==pvString)) {
-                   PVScalarArray* toArray = (PVScalarArray*)toDatas[1];
+                   PVScalarArray* toArray = 
+                       static_cast(toDatas[1]);
                    copyScalarArray(pvArray,0,toArray,0,pvArray->getLength());
                    PVScalar *toScalar = (PVScalar*)toDatas[0];
                    copyScalar(pvScalar,toScalar);
@@ -540,21 +561,28 @@ void Convert::copyStructure(PVStructure *from, PVStructure *to)
         }
         switch(fromType) {
         case scalar:
-            copyScalar((PVScalar*)fromData,(PVScalar*)toData);
+            copyScalar(
+                static_cast(fromData),
+                static_cast(toData));
             break;
         case scalarArray: {
-            PVScalarArray *fromArray = (PVScalarArray*)fromData;
-            PVScalarArray *toArray = (PVScalarArray*)toData;
-            int length = copyScalarArray(fromArray,0,toArray,0,fromArray->getLength());
+            PVScalarArray *fromArray = static_cast(fromData);
+            PVScalarArray *toArray = static_cast(toData);
+            int length = copyScalarArray(
+                fromArray,0,toArray,0,fromArray->getLength());
             if(toArray->getLength()!=length) toArray->setLength(length);
             break;
         }
         case structure:
-            copyStructure((PVStructure*)fromData,(PVStructure*)toData);
+            copyStructure(
+                static_cast(fromData),
+                static_cast(toData));
             break;
         case structureArray: {
-        	PVStructureArray *fromArray = (PVStructureArray*)fromData;
-            PVStructureArray *toArray = (PVStructureArray*)toData;
+            PVStructureArray *fromArray = 
+                static_cast(fromData);
+            PVStructureArray *toArray = 
+                static_cast(toData);
             copyStructureArray(fromArray,toArray);
             break;
         }
@@ -614,27 +642,27 @@ int8 Convert::toByte(PVScalar * pv)
         case pvBoolean:
            throw std::logic_error(String("boolean can not be converted to byte"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             return value->get();
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             return value->get();
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             return value->get();
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             return value->get();
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             return value->get();
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             return value->get();
         }
         case pvString:
@@ -651,27 +679,27 @@ int16 Convert::toShort(PVScalar * pv)
         case pvBoolean:
            throw std::logic_error(String("boolean can not be converted to short"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             return value->get();
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             return value->get();
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             return value->get();
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             return value->get();
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             return value->get();
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             return value->get();
         }
         case pvString:
@@ -688,27 +716,27 @@ int32 Convert::toInt(PVScalar * pv)
         case pvBoolean:
            throw std::logic_error(String("boolean can not be converted to int"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             return value->get();
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             return value->get();
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             return value->get();
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             return value->get();
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             return value->get();
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             return value->get();
         }
         case pvString:
@@ -725,27 +753,27 @@ int64 Convert::toLong(PVScalar * pv)
         case pvBoolean:
            throw std::logic_error(String("boolean can not be converted to long"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             return value->get();
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             return value->get();
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             return value->get();
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             return value->get();
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             return value->get();
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             return value->get();
         }
         case pvString:
@@ -762,27 +790,27 @@ float Convert::toFloat(PVScalar * pv)
         case pvBoolean:
            throw std::logic_error(String("boolean can not be converted to float"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             return value->get();
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             return value->get();
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             return value->get();
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             return value->get();
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             return value->get();
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             return value->get();
         }
         case pvString:
@@ -799,27 +827,27 @@ double Convert::toDouble(PVScalar * pv)
         case pvBoolean:
            throw std::logic_error(String("boolean can not be converted to double"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             return value->get();
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             return value->get();
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             return value->get();
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             return value->get();
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             return value->get();
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             return value->get();
         }
         case pvString:
@@ -836,31 +864,31 @@ void Convert::fromByte(PVScalar *pv,int8 from)
         case pvBoolean:
            throw std::logic_error(String("byte can not be converted to boolean"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             value->put(from); return;
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             value->put(from); return;
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             value->put(from); return;
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             value->put(from); return;
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             value->put(from); return;
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             value->put(from); return;
         }
         case pvString: {
-            PVString *value = (PVString *)pv;
+            PVString *value = static_cast(pv);
             char buffer[20];
             int ival = from;
             sprintf(buffer,"%d",ival);
@@ -880,31 +908,31 @@ void  Convert::fromShort(PVScalar *pv,int16 from)
         case pvBoolean:
            throw std::logic_error(String("short can not be converted to boolean"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             value->put(from); return;
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             value->put(from); return;
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             value->put(from); return;
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             value->put(from); return;
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             value->put(from); return;
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             value->put(from); return;
         }
         case pvString: {
-            PVString *value = (PVString *)pv;
+            PVString *value = static_cast(pv);
             char buffer[20];
             int ival = from;
             sprintf(buffer,"%d",ival);
@@ -924,31 +952,31 @@ void  Convert::fromInt(PVScalar *pv, int32 from)
         case pvBoolean:
            throw std::logic_error(String("int can not be converted to boolean"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             value->put(from); return;
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             value->put(from); return;
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             value->put(from); return;
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             value->put(from); return;
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             value->put(from); return;
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             value->put(from); return;
         }
         case pvString: {
-            PVString *value = (PVString *)pv;
+            PVString *value = static_cast(pv);
             char buffer[20];
             int ival = from;
             sprintf(buffer,"%d",ival);
@@ -968,31 +996,31 @@ void  Convert::fromLong(PVScalar *pv, int64 from)
         case pvBoolean:
            throw std::logic_error(String("long can not be converted to boolean"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             value->put(from); return;
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             value->put(from); return;
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             value->put(from); return;
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             value->put(from); return;
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             value->put(from); return;
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             value->put(from); return;
         }
         case pvString: {
-            PVString *value = (PVString *)pv;
+            PVString *value = static_cast(pv);
             char buffer[20];
             int64 ival = from;
             sprintf(buffer,"%lld",ival);
@@ -1012,31 +1040,31 @@ void  Convert::fromFloat(PVScalar* pv, float from)
         case pvBoolean:
            throw std::logic_error(String("float can not be converted to boolean"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             value->put(from); return;
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             value->put(from); return;
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             value->put(from); return;
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             value->put(from); return;
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             value->put(from); return;
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             value->put(from); return;
         }
         case pvString: {
-            PVString *value = (PVString *)pv;
+            PVString *value = static_cast(pv);
             char buffer[20];
             double dval = from;
             sprintf(buffer,"%g",dval);
@@ -1056,31 +1084,31 @@ void  Convert::fromDouble(PVScalar *pv, double from)
         case pvBoolean:
            throw std::logic_error(String("double can not be converted to boolean"));
         case pvByte: {
-            PVByte *value = (PVByte *)pv;
+            PVByte *value = static_cast(pv);
             value->put(from); return;
         }
         case pvShort: {
-            PVShort *value = (PVShort *)pv;
+            PVShort *value = static_cast(pv);
             value->put(from); return;
         }
         case pvInt: {
-            PVInt *value = (PVInt *)pv;
+            PVInt *value = static_cast(pv);
             value->put(from); return;
         }
         case pvLong: {
-            PVLong *value = (PVLong *)pv;
+            PVLong *value = static_cast(pv);
             value->put(from); return;
         }
         case pvFloat: {
-            PVFloat *value = (PVFloat *)pv;
+            PVFloat *value = static_cast(pv);
             value->put(from); return;
         }
         case pvDouble: {
-            PVDouble *value = (PVDouble *)pv;
+            PVDouble *value = static_cast(pv);
             value->put(from); return;
         }
         case pvString: {
-            PVString *value = (PVString *)pv;
+            PVString *value = static_cast(pv);
             char buffer[20];
             double dval = from;
             sprintf(buffer,"%g",dval);
@@ -1177,57 +1205,57 @@ static bool scalarEquals(PVScalar *a,PVScalar *b)
     if(ascalarType!=bscalarType) return false;
     switch(ascalarType) {
         case pvBoolean: {
-            PVBoolean *pa = (PVBoolean *)a;
-            PVBoolean *pb = (PVBoolean *)b;
+            PVBoolean *pa = static_cast(a);
+            PVBoolean *pb = static_cast(b);
             bool avalue = pa->get();
             bool bvalue = pb->get();
             return ((avalue==bvalue) ? true : false);
         }
         case pvByte: {
-            PVByte *pa = (PVByte *)a;
-            PVByte *pb = (PVByte *)b;
+            PVByte *pa = static_cast(a);
+            PVByte *pb = static_cast(b);
             int8 avalue = pa->get();
             int8 bvalue = pb->get();
             return ((avalue==bvalue) ? true : false);
         }
         case pvShort: {
-            PVShort *pa = (PVShort *)a;
-            PVShort *pb = (PVShort *)b;
+            PVShort *pa = static_cast(a);
+            PVShort *pb = static_cast(b);
             int16 avalue = pa->get();
             int16 bvalue = pb->get();
             return ((avalue==bvalue) ? true : false);
         }
         case pvInt: {
-            PVInt *pa = (PVInt *)a;
-            PVInt *pb = (PVInt *)b;
+            PVInt *pa = static_cast(a);
+            PVInt *pb = static_cast(b);
             int32 avalue = pa->get();
             int32 bvalue = pb->get();
             return ((avalue==bvalue) ? true : false);
         }
         case pvLong: {
-            PVLong *pa = (PVLong *)a;
-            PVLong *pb = (PVLong *)b;
+            PVLong *pa = static_cast(a);
+            PVLong *pb = static_cast(b);
             int64 avalue = pa->get();
             int64 bvalue = pb->get();
             return ((avalue==bvalue) ? true : false);
         }
         case pvFloat: {
-            PVFloat *pa = (PVFloat *)a;
-            PVFloat *pb = (PVFloat *)b;
+            PVFloat *pa = static_cast(a);
+            PVFloat *pb = static_cast(b);
             float avalue = pa->get();
             float bvalue = pb->get();
             return ((avalue==bvalue) ? true : false);
         }
         case pvDouble: {
-            PVDouble *pa = (PVDouble *)a;
-            PVDouble *pb = (PVDouble *)b;
+            PVDouble *pa = static_cast(a);
+            PVDouble *pb = static_cast(b);
             double avalue = pa->get();
             double bvalue = pb->get();
             return ((avalue==bvalue) ? true : false);
         }
         case pvString: {
-            PVString *pa = (PVString *)a;
-            PVString *pb = (PVString *)b;
+            PVString *pa = static_cast(a);
+            PVString *pb = static_cast(b);
             String avalue = pa->get();
             String bvalue = pb->get();
             return ((avalue==bvalue) ? true : false);
@@ -1247,8 +1275,8 @@ static bool arrayEquals(PVScalarArray *a,PVScalarArray *b)
     int length = a->getLength();
     switch(aType) {
         case pvBoolean: {
-            PVBooleanArray *aarray = (PVBooleanArray *)a;
-            PVBooleanArray *barray = (PVBooleanArray *)b;
+            PVBooleanArray *aarray = static_cast(a);
+            PVBooleanArray *barray = static_cast(b);
             BooleanArrayData adata = BooleanArrayData();
             BooleanArrayData bdata = BooleanArrayData();
             aarray->get(0,length,&adata);
@@ -1261,8 +1289,8 @@ static bool arrayEquals(PVScalarArray *a,PVScalarArray *b)
             return true;
         }
         case pvByte: {
-            PVByteArray *aarray = (PVByteArray *)a;
-            PVByteArray *barray = (PVByteArray *)b;
+            PVByteArray *aarray = static_cast(a);
+            PVByteArray *barray = static_cast(b);
             ByteArrayData adata = ByteArrayData();
             ByteArrayData bdata = ByteArrayData();
             aarray->get(0,length,&adata);
@@ -1275,8 +1303,8 @@ static bool arrayEquals(PVScalarArray *a,PVScalarArray *b)
             return true;
         }
         case pvShort: {
-            PVShortArray *aarray = (PVShortArray *)a;
-            PVShortArray *barray = (PVShortArray *)b;
+            PVShortArray *aarray = static_cast(a);
+            PVShortArray *barray = static_cast(b);
             ShortArrayData adata = ShortArrayData();
             ShortArrayData bdata = ShortArrayData();
             aarray->get(0,length,&adata);
@@ -1289,8 +1317,8 @@ static bool arrayEquals(PVScalarArray *a,PVScalarArray *b)
             return true;
         }
         case pvInt: {
-            PVIntArray *aarray = (PVIntArray *)a;
-            PVIntArray *barray = (PVIntArray *)b;
+            PVIntArray *aarray = static_cast(a);
+            PVIntArray *barray = static_cast(b);
             IntArrayData adata = IntArrayData();
             IntArrayData bdata = IntArrayData();
             aarray->get(0,length,&adata);
@@ -1303,8 +1331,8 @@ static bool arrayEquals(PVScalarArray *a,PVScalarArray *b)
             return true;
         }
         case pvLong: {
-            PVLongArray *aarray = (PVLongArray *)a;
-            PVLongArray *barray = (PVLongArray *)b;
+            PVLongArray *aarray = static_cast(a);
+            PVLongArray *barray = static_cast(b);
             LongArrayData adata = LongArrayData();
             LongArrayData bdata = LongArrayData();
             aarray->get(0,length,&adata);
@@ -1317,8 +1345,8 @@ static bool arrayEquals(PVScalarArray *a,PVScalarArray *b)
             return true;
         }
         case pvFloat: {
-            PVFloatArray *aarray = (PVFloatArray *)a;
-            PVFloatArray *barray = (PVFloatArray *)b;
+            PVFloatArray *aarray = static_cast(a);
+            PVFloatArray *barray = static_cast(b);
             FloatArrayData adata = FloatArrayData();
             FloatArrayData bdata = FloatArrayData();
             aarray->get(0,length,&adata);
@@ -1331,8 +1359,8 @@ static bool arrayEquals(PVScalarArray *a,PVScalarArray *b)
             return true;
         }
         case pvDouble: {
-            PVDoubleArray *aarray = (PVDoubleArray *)a;
-            PVDoubleArray *barray = (PVDoubleArray *)b;
+            PVDoubleArray *aarray = static_cast(a);
+            PVDoubleArray *barray = static_cast(b);
             DoubleArrayData adata = DoubleArrayData();
             DoubleArrayData bdata = DoubleArrayData();
             aarray->get(0,length,&adata);
@@ -1345,8 +1373,8 @@ static bool arrayEquals(PVScalarArray *a,PVScalarArray *b)
             return true;
         }
         case pvString: {
-            PVStringArray *aarray = (PVStringArray *)a;
-            PVStringArray *barray = (PVStringArray *)b;
+            PVStringArray *aarray = static_cast(a);
+            PVStringArray *barray = static_cast(b);
             StringArrayData adata = StringArrayData();
             StringArrayData bdata = StringArrayData();
             aarray->get(0,length,&adata);
@@ -1403,23 +1431,20 @@ static bool structureEquals(PVStructure *a,PVStructure *b)
 
 bool convertEquals(PVField *a,PVField *b)
 {
-    void * avoid = (void *)a;
-    void * bvoid = (void *)b;
+    void * avoid = static_cast(a);
+    void * bvoid = static_cast(b);
     if(avoid==bvoid) return true;
     Type atype = a->getField()->getType();
     Type btype = b->getField()->getType();
     if(atype!=btype) return false;
-    if(atype==scalar) return scalarEquals((PVScalar *)a,(PVScalar *)b);
-    if(atype==scalarArray) {
-         return arrayEquals((PVScalarArray *)a,(PVScalarArray *)b);
-    }
-    if(atype==structureArray) {
-         return structureArrayEquals(
-             (PVStructureArray *)a,(PVStructureArray *)b);
-    }
-    if(atype==structure) {
-        return structureEquals((PVStructure *)a,(PVStructure *)b);
-    }
+    if(atype==scalar) return scalarEquals(
+        static_cast(a),static_cast(b));
+    if(atype==scalarArray) return arrayEquals(
+        static_cast(a),static_cast(b));
+    if(atype==structureArray) return structureArrayEquals(
+        static_cast(a),static_cast(b));
+    if(atype==structure) return structureEquals(
+        static_cast(a),static_cast(b));
     String message("should not get here");
     throw std::logic_error(message);
 }
@@ -1434,7 +1459,7 @@ int convertFromByteArray(PVScalarArray *pv, int offset, int len,int8 from[], int
          throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         while (len > 0) {
             int n = pvdata->put(offset, len, from, fromOffset);
             if (n == 0)
@@ -1447,10 +1472,10 @@ int convertFromByteArray(PVScalarArray *pv, int offset, int len,int8 from[], int
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         int16 data[1];
         while (len > 0) {
-            data[0] = (int16) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1461,10 +1486,10 @@ int convertFromByteArray(PVScalarArray *pv, int offset, int len,int8 from[], int
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         int32 data[1];
         while (len > 0) {
-            data[0] = (int32) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1475,10 +1500,10 @@ int convertFromByteArray(PVScalarArray *pv, int offset, int len,int8 from[], int
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         int64 data[1];
         while (len > 0) {
-            data[0] = (int64) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1489,10 +1514,10 @@ int convertFromByteArray(PVScalarArray *pv, int offset, int len,int8 from[], int
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         float data[1];
         while (len > 0) {
-            data[0] = (float) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1503,10 +1528,10 @@ int convertFromByteArray(PVScalarArray *pv, int offset, int len,int8 from[], int
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         double data[1];
         while (len > 0) {
-            data[0] = (double) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1535,7 +1560,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
         throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         ByteArrayData data = ByteArrayData();
         while (len > 0) {
             int num = 0;
@@ -1552,7 +1577,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         ShortArrayData data = ShortArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1560,7 +1585,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
             ShortArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] =  dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1569,7 +1594,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         IntArrayData data = IntArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1577,7 +1602,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
             IntArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] =  dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1586,7 +1611,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         LongArrayData data = LongArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1595,7 +1620,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
             LongArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1604,7 +1629,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         FloatArrayData data = FloatArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1612,7 +1637,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
             FloatArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1621,7 +1646,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         DoubleArrayData data = DoubleArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1630,7 +1655,7 @@ int convertToByteArray(PVScalarArray * pv, int offset, int len,int8 to[], int to
             DoubleArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1657,10 +1682,10 @@ int convertFromShortArray(PVScalarArray *pv, int offset, int len,int16 from[], i
          throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         int8 data[1];
         while (len > 0) {
-            data[0] = (int8) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1671,7 +1696,7 @@ int convertFromShortArray(PVScalarArray *pv, int offset, int len,int16 from[], i
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         while (len > 0) {
             int n = pvdata->put(offset, len, from, fromOffset);
             if (n == 0)
@@ -1684,10 +1709,10 @@ int convertFromShortArray(PVScalarArray *pv, int offset, int len,int16 from[], i
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         int32 data[1];
         while (len > 0) {
-            data[0] = (int32) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1698,10 +1723,10 @@ int convertFromShortArray(PVScalarArray *pv, int offset, int len,int16 from[], i
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         int64 data[1];
         while (len > 0) {
-            data[0] = (int64) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1712,10 +1737,10 @@ int convertFromShortArray(PVScalarArray *pv, int offset, int len,int16 from[], i
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         float data[1];
         while (len > 0) {
-            data[0] = (float) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1726,10 +1751,10 @@ int convertFromShortArray(PVScalarArray *pv, int offset, int len,int16 from[], i
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         double data[1];
         while (len > 0) {
-            data[0] = (double) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1758,7 +1783,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
         throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         ByteArrayData data = ByteArrayData();
         while (len > 0) {
             int num = 0;
@@ -1775,7 +1800,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         ShortArrayData data = ShortArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1783,7 +1808,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
             ShortArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] =  dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1792,7 +1817,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         IntArrayData data = IntArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1800,7 +1825,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
             IntArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1809,7 +1834,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         LongArrayData data = LongArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1818,7 +1843,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
             LongArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] =  dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1827,7 +1852,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         FloatArrayData data = FloatArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1835,7 +1860,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
             FloatArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] =  dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1844,7 +1869,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         DoubleArrayData data = DoubleArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -1853,7 +1878,7 @@ int convertToShortArray(PVScalarArray * pv, int offset, int len,int16 to[], int
             DoubleArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -1880,10 +1905,10 @@ int convertFromIntArray(PVScalarArray *pv, int offset, int len,int32 from[], int
          throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         int8 data[1];
         while (len > 0) {
-            data[0] = (int8) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1894,10 +1919,10 @@ int convertFromIntArray(PVScalarArray *pv, int offset, int len,int32 from[], int
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         int16 data[1];
         while (len > 0) {
-            data[0] = (int16) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1908,7 +1933,7 @@ int convertFromIntArray(PVScalarArray *pv, int offset, int len,int32 from[], int
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         while (len > 0) {
             int n = pvdata->put(offset, len, from, fromOffset);
             if (n == 0)
@@ -1921,10 +1946,10 @@ int convertFromIntArray(PVScalarArray *pv, int offset, int len,int32 from[], int
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         int64 data[1];
         while (len > 0) {
-            data[0] = (int64) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1935,10 +1960,10 @@ int convertFromIntArray(PVScalarArray *pv, int offset, int len,int32 from[], int
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         float data[1];
         while (len > 0) {
-            data[0] = (float) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1949,10 +1974,10 @@ int convertFromIntArray(PVScalarArray *pv, int offset, int len,int32 from[], int
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         double data[1];
         while (len > 0) {
-            data[0] = (double) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -1981,7 +2006,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
         throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         ByteArrayData data = ByteArrayData();
         while (len > 0) {
             int num = 0;
@@ -1998,7 +2023,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         ShortArrayData data = ShortArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2006,7 +2031,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
             ShortArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2015,7 +2040,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         IntArrayData data = IntArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2023,7 +2048,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
             IntArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] =  dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2032,7 +2057,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         LongArrayData data = LongArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2041,7 +2066,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
             LongArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2050,7 +2075,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         FloatArrayData data = FloatArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2058,7 +2083,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
             FloatArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2067,7 +2092,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         DoubleArrayData data = DoubleArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2076,7 +2101,7 @@ int convertToIntArray(PVScalarArray * pv, int offset, int len,int32 to[], int to
             DoubleArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2103,10 +2128,10 @@ int convertFromLongArray(PVScalarArray *pv, int offset, int len,int64 from[], in
          throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         int8 data[1];
         while (len > 0) {
-            data[0] = (int8) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2117,10 +2142,10 @@ int convertFromLongArray(PVScalarArray *pv, int offset, int len,int64 from[], in
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         int16 data[1];
         while (len > 0) {
-            data[0] = (int16) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2131,10 +2156,10 @@ int convertFromLongArray(PVScalarArray *pv, int offset, int len,int64 from[], in
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         int32 data[1];
         while (len > 0) {
-            data[0] = (int32) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2145,7 +2170,7 @@ int convertFromLongArray(PVScalarArray *pv, int offset, int len,int64 from[], in
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         while (len > 0) {
             int n = pvdata->put(offset, len, from, fromOffset);
             if (n == 0)
@@ -2158,10 +2183,10 @@ int convertFromLongArray(PVScalarArray *pv, int offset, int len,int64 from[], in
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         float data[1];
         while (len > 0) {
-            data[0] = (float) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2172,10 +2197,10 @@ int convertFromLongArray(PVScalarArray *pv, int offset, int len,int64 from[], in
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         double data[1];
         while (len > 0) {
-            data[0] = (double) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2204,7 +2229,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
         throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         ByteArrayData data = ByteArrayData();
         while (len > 0) {
             int num = 0;
@@ -2221,7 +2246,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         ShortArrayData data = ShortArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2229,7 +2254,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
             ShortArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2238,7 +2263,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         IntArrayData data = IntArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2246,7 +2271,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
             IntArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2255,7 +2280,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         LongArrayData data = LongArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2264,7 +2289,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
             LongArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2273,7 +2298,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         FloatArrayData data = FloatArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2281,7 +2306,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
             FloatArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2290,7 +2315,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         DoubleArrayData data = DoubleArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2299,7 +2324,7 @@ int convertToLongArray(PVScalarArray * pv, int offset, int len,int64 to[], int t
             DoubleArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2326,10 +2351,10 @@ int convertFromFloatArray(PVScalarArray *pv, int offset, int len,float from[], i
          throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         int8 data[1];
         while (len > 0) {
-            data[0] = (int8) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2340,10 +2365,10 @@ int convertFromFloatArray(PVScalarArray *pv, int offset, int len,float from[], i
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         int16 data[1];
         while (len > 0) {
-            data[0] = (int16) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2354,10 +2379,10 @@ int convertFromFloatArray(PVScalarArray *pv, int offset, int len,float from[], i
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         int32 data[1];
         while (len > 0) {
-            data[0] = (int32) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2368,10 +2393,10 @@ int convertFromFloatArray(PVScalarArray *pv, int offset, int len,float from[], i
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         int64 data[1];
         while (len > 0) {
-            data[0] = (int64) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2382,7 +2407,7 @@ int convertFromFloatArray(PVScalarArray *pv, int offset, int len,float from[], i
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         while (len > 0) {
             int n = pvdata->put(offset, len, from, fromOffset);
             if (n == 0)
@@ -2395,10 +2420,10 @@ int convertFromFloatArray(PVScalarArray *pv, int offset, int len,float from[], i
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         double data[1];
         while (len > 0) {
-            data[0] = (double) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2427,7 +2452,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
         throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         ByteArrayData data = ByteArrayData();
         while (len > 0) {
             int num = 0;
@@ -2444,7 +2469,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         ShortArrayData data = ShortArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2452,7 +2477,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
             ShortArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2461,7 +2486,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         IntArrayData data = IntArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2469,7 +2494,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
             IntArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2478,7 +2503,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         LongArrayData data = LongArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2487,7 +2512,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
             LongArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2496,7 +2521,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         FloatArrayData data = FloatArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2504,7 +2529,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
             FloatArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2513,7 +2538,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         DoubleArrayData data = DoubleArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2522,7 +2547,7 @@ int convertToFloatArray(PVScalarArray * pv, int offset, int len,float to[], int
             DoubleArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2549,10 +2574,10 @@ int convertFromDoubleArray(PVScalarArray *pv, int offset, int len,double from[],
          throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         int8 data[1];
         while (len > 0) {
-            data[0] = (int8) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2563,10 +2588,10 @@ int convertFromDoubleArray(PVScalarArray *pv, int offset, int len,double from[],
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         int16 data[1];
         while (len > 0) {
-            data[0] = (int16) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2577,10 +2602,10 @@ int convertFromDoubleArray(PVScalarArray *pv, int offset, int len,double from[],
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         int32 data[1];
         while (len > 0) {
-            data[0] = (int32) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2591,10 +2616,10 @@ int convertFromDoubleArray(PVScalarArray *pv, int offset, int len,double from[],
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         int64 data[1];
         while (len > 0) {
-            data[0] = (int64) from[fromOffset];
+            data[0] = from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2605,10 +2630,10 @@ int convertFromDoubleArray(PVScalarArray *pv, int offset, int len,double from[],
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         float data[1];
         while (len > 0) {
-            data[0] = (float) from[fromOffset];
+            data[0] =  from[fromOffset];
             if (pvdata->put(offset, 1, data, 0) == 0)
                 return ntransfered;
             --len;
@@ -2619,7 +2644,7 @@ int convertFromDoubleArray(PVScalarArray *pv, int offset, int len,double from[],
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         while (len > 0) {
             int n = pvdata->put(offset, len, from, fromOffset);
             if (n == 0)
@@ -2650,7 +2675,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
         throw std::invalid_argument(message);
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         ByteArrayData data = ByteArrayData();
         while (len > 0) {
             int num = 0;
@@ -2667,7 +2692,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         ShortArrayData data = ShortArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2675,7 +2700,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
             ShortArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2684,7 +2709,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         IntArrayData data = IntArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2692,7 +2717,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
             IntArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2701,7 +2726,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         LongArrayData data = LongArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2710,7 +2735,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
             LongArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2719,7 +2744,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         FloatArrayData data = FloatArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2727,7 +2752,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
             FloatArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2736,7 +2761,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         DoubleArrayData data = DoubleArrayData();
         while (len > 0) {
             int num = pvdata->get(offset, len, &data);
@@ -2745,7 +2770,7 @@ int convertToDoubleArray(PVScalarArray * pv, int offset, int len,double to[], in
             DoubleArray dataArray = data.data;
             int dataOffset = data.offset;
             for (int i = 0; i < num; i++)
-                to[i + toOffset] = (int8) dataArray[i + dataOffset];
+                to[i + toOffset] = dataArray[i + dataOffset];
             len -= num;
             offset += num;
             toOffset += num;
@@ -2768,7 +2793,7 @@ int convertFromStringArray(PVScalarArray *pv, int offset, int len,String from[],
     int ntransfered = 0;
     switch (elemType) {
     case pvBoolean: {
-        PVBooleanArray *pvdata = (PVBooleanArray*) pv;
+        PVBooleanArray *pvdata = static_cast(pv);
         bool data[1];
         while (len > 0) {
             String fromString = from[fromOffset];
@@ -2783,7 +2808,7 @@ int convertFromStringArray(PVScalarArray *pv, int offset, int len,String from[],
         return ntransfered;
     }
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         int8 data[1];
         while (len > 0) {
             String fromString = from[fromOffset];
@@ -2800,7 +2825,7 @@ int convertFromStringArray(PVScalarArray *pv, int offset, int len,String from[],
         return ntransfered;
     }
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         int16 data[1];
         while (len > 0) {
             String fromString = from[fromOffset];
@@ -2817,7 +2842,7 @@ int convertFromStringArray(PVScalarArray *pv, int offset, int len,String from[],
         return ntransfered;
     }
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         int32 data[1];
         while (len > 0) {
             String fromString = from[fromOffset];
@@ -2834,7 +2859,7 @@ int convertFromStringArray(PVScalarArray *pv, int offset, int len,String from[],
         return ntransfered;
     }
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         int64 data[1];
         while (len > 0) {
             String fromString = from[fromOffset];
@@ -2851,7 +2876,7 @@ int convertFromStringArray(PVScalarArray *pv, int offset, int len,String from[],
         return ntransfered;
     }
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         float data[1];
         while (len > 0) {
             String fromString = from[fromOffset];
@@ -2868,7 +2893,7 @@ int convertFromStringArray(PVScalarArray *pv, int offset, int len,String from[],
         return ntransfered;
     }
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         double data[1];
         while (len > 0) {
             String fromString = from[fromOffset];
@@ -2885,7 +2910,7 @@ int convertFromStringArray(PVScalarArray *pv, int offset, int len,String from[],
         return ntransfered;
     }
     case pvString:
-        PVStringArray *pvdata = (PVStringArray*) pv;
+        PVStringArray *pvdata = static_cast(pv);
         while (len > 0) {
             int n = pvdata->put(offset, len, from, fromOffset);
             if (n == 0)
@@ -2909,7 +2934,7 @@ int convertToStringArray(PVScalarArray * pv, int offset, int len,String to[], in
     int num = ncopy;
     switch (elementType) {
     case pvBoolean: {
-        PVBooleanArray *pvdata = (PVBooleanArray*) pv;
+        PVBooleanArray *pvdata = static_cast(pv);
         BooleanArrayData data = BooleanArrayData();
         for (int i = 0; i < num; i++) {
             if (pvdata->get(offset + i, 1, &data) == 1) {
@@ -2923,7 +2948,7 @@ int convertToStringArray(PVScalarArray * pv, int offset, int len,String to[], in
     }
     break;
     case pvByte: {
-        PVByteArray *pvdata = (PVByteArray*) pv;
+        PVByteArray *pvdata = static_cast(pv);
         ByteArrayData data = ByteArrayData();
         char cr[30];
         for (int i = 0; i < num; i++) {
@@ -2939,7 +2964,7 @@ int convertToStringArray(PVScalarArray * pv, int offset, int len,String to[], in
     }
     break;
     case pvShort: {
-        PVShortArray *pvdata = (PVShortArray*) pv;
+        PVShortArray *pvdata = static_cast(pv);
         ShortArrayData data = ShortArrayData();
         char cr[30];
         for (int i = 0; i < num; i++) {
@@ -2955,7 +2980,7 @@ int convertToStringArray(PVScalarArray * pv, int offset, int len,String to[], in
     }
     break;
     case pvInt: {
-        PVIntArray *pvdata = (PVIntArray*) pv;
+        PVIntArray *pvdata = static_cast(pv);
         IntArrayData data = IntArrayData();
         char cr[30];
         for (int i = 0; i < num; i++) {
@@ -2971,7 +2996,7 @@ int convertToStringArray(PVScalarArray * pv, int offset, int len,String to[], in
     }
     break;
     case pvLong: {
-        PVLongArray *pvdata = (PVLongArray*) pv;
+        PVLongArray *pvdata = static_cast(pv);
         LongArrayData data = LongArrayData();
         char cr[30];
         for (int i = 0; i < num; i++) {
@@ -2987,7 +3012,7 @@ int convertToStringArray(PVScalarArray * pv, int offset, int len,String to[], in
     }
     break;
     case pvFloat: {
-        PVFloatArray *pvdata = (PVFloatArray*) pv;
+        PVFloatArray *pvdata = static_cast(pv);
         FloatArrayData data = FloatArrayData();
         char cr[30];
         for (int i = 0; i < num; i++) {
@@ -3003,7 +3028,7 @@ int convertToStringArray(PVScalarArray * pv, int offset, int len,String to[], in
     }
     break;
     case pvDouble: {
-        PVDoubleArray *pvdata = (PVDoubleArray*) pv;
+        PVDoubleArray *pvdata = static_cast(pv);
         DoubleArrayData data = DoubleArrayData();
         char cr[30];
         for (int i = 0; i < num; i++) {
@@ -3019,7 +3044,7 @@ int convertToStringArray(PVScalarArray * pv, int offset, int len,String to[], in
     }
     break;
     case pvString: {
-        PVStringArray *pvdata = (PVStringArray*) pv;
+        PVStringArray *pvdata = static_cast(pv);
         while (num > 0) {
             int numnow = 0;
             StringArray dataArray = 0;
@@ -3156,7 +3181,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel)
     *buffer += " ";
     switch(type) {
     case pvBoolean: {
-            PVBooleanArray *pvdata = (PVBooleanArray*)pv;
+            PVBooleanArray *pvdata = static_cast(pv);
             BooleanArrayData data = BooleanArrayData();
             *buffer += "[";
             for(int i=0; i < pvdata->getLength(); i++) {
@@ -3177,7 +3202,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel)
             break;
         }
     case pvByte: {
-            PVByteArray *pvdata = (PVByteArray*)pv;
+            PVByteArray *pvdata = static_cast(pv);
             ByteArrayData data = ByteArrayData();
             *buffer += "[";
             for(int i=0; i < pvdata->getLength(); i++) {
@@ -3196,7 +3221,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel)
             break;
         }
     case pvShort: {
-            PVShortArray *pvdata = (PVShortArray*)pv;
+            PVShortArray *pvdata = static_cast(pv);
             ShortArrayData data = ShortArrayData();
             *buffer += "[";
             for(int i=0; i < pvdata->getLength(); i++) {
@@ -3215,7 +3240,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel)
             break;
         }
     case pvInt: {
-            PVIntArray *pvdata = (PVIntArray*)pv;
+            PVIntArray *pvdata = static_cast(pv);
             IntArrayData data = IntArrayData();
             *buffer += "[";
             for(int i=0; i < pvdata->getLength(); i++) {
@@ -3234,7 +3259,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel)
             break;
         }
     case pvLong: {
-            PVLongArray *pvdata = (PVLongArray*)pv;
+            PVLongArray *pvdata = static_cast(pv);
             LongArrayData data = LongArrayData();
             *buffer += "[";
             for(int i=0; i < pvdata->getLength(); i++) {
@@ -3253,7 +3278,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel)
             break;
         }
     case pvFloat: {
-            PVFloatArray *pvdata = (PVFloatArray*)pv;
+            PVFloatArray *pvdata = static_cast(pv);
             FloatArrayData data = FloatArrayData();
             *buffer += "[";
             for(int i=0; i < pvdata->getLength(); i++) {
@@ -3272,7 +3297,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel)
             break;
         }
     case pvDouble: {
-            PVDoubleArray *pvdata = (PVDoubleArray*)pv;
+            PVDoubleArray *pvdata = static_cast(pv);
             DoubleArrayData data = DoubleArrayData();
             *buffer += "[";
             for(int i=0; i < pvdata->getLength(); i++) {
@@ -3291,7 +3316,7 @@ void convertArray(StringBuilder buffer,PVScalarArray * pv,int indentLevel)
             break;
         }
     case pvString: {
-    	PVStringArray *pvdata = (PVStringArray*)pv;
+    	PVStringArray *pvdata = static_cast(pv);
     	StringArrayData data = StringArrayData();
     	*buffer += "[";
     	for(int i=0; i < pvdata->getLength(); i++) {
diff --git a/pvDataApp/property/pvAlarm.cpp b/pvDataApp/property/pvAlarm.cpp
index c7138e1..eb4b418 100644
--- a/pvDataApp/property/pvAlarm.cpp
+++ b/pvDataApp/property/pvAlarm.cpp
@@ -19,6 +19,10 @@ bool PVAlarm::attach(PVField *pvField)
 {
     PVStructure *pvStructure = 0;
     if(pvField->getField()->getFieldName().compare("alarm")!=0) {
+        if(pvField->getField()->getFieldName().compare("value")!=0) {
+            pvField->message(noAlarmFound,errorMessage);
+            return false;
+        }
         PVStructure *pvParent = pvField->getParent();
         if(pvParent==0) {
             pvField->message(noAlarmFound,errorMessage);
diff --git a/pvDataApp/property/pvControl.cpp b/pvDataApp/property/pvControl.cpp
index 1d58501..19f3bc3 100644
--- a/pvDataApp/property/pvControl.cpp
+++ b/pvDataApp/property/pvControl.cpp
@@ -19,6 +19,10 @@ bool PVControl::attach(PVField *pvField)
 {
     PVStructure *pvStructure = 0;
     if(pvField->getField()->getFieldName().compare("control")!=0) {
+        if(pvField->getField()->getFieldName().compare("value")!=0) {
+            pvField->message(noControlFound,errorMessage);
+            return false;
+        }
         PVStructure *pvParent = pvField->getParent();
         if(pvParent==0) {
             pvField->message(noControlFound,errorMessage);
diff --git a/pvDataApp/property/pvDisplay.cpp b/pvDataApp/property/pvDisplay.cpp
index 146957b..6b1165c 100644
--- a/pvDataApp/property/pvDisplay.cpp
+++ b/pvDataApp/property/pvDisplay.cpp
@@ -19,6 +19,10 @@ bool PVDisplay::attach(PVField *pvField)
 {
     PVStructure *pvStructure = 0;
     if(pvField->getField()->getFieldName().compare("display")!=0) {
+        if(pvField->getField()->getFieldName().compare("value")!=0) {
+            pvField->message(noDisplayFound,errorMessage);
+            return false;
+        }
         PVStructure *pvParent = pvField->getParent();
         if(pvParent==0) {
             pvField->message(noDisplayFound,errorMessage);
diff --git a/pvDataApp/property/pvTimeStamp.cpp b/pvDataApp/property/pvTimeStamp.cpp
index 22e7ca7..b358896 100644
--- a/pvDataApp/property/pvTimeStamp.cpp
+++ b/pvDataApp/property/pvTimeStamp.cpp
@@ -24,7 +24,19 @@ bool PVTimeStamp::attach(PVField *pvField)
             pvField->message(noTimeStamp,errorMessage);
             return false;
         }
-        pvStructure = pvParent->getStructureField(String("timeStamp"));
+        if(pvField->getField()->getFieldName().compare("value")!=0) {
+            pvField->message(noTimeStamp,errorMessage);
+            return false;
+        }
+        // look up the tree for a timeSyamp
+        while(pvParent!=0) {
+            PVStructure *pvs = pvParent->getStructureField(String("timeStamp"));
+            if(pvs!=0) {
+                pvStructure = pvs;
+                break;
+            }
+            pvParent = pvParent->getParent();
+        }
         if(pvStructure==0) {
             pvField->message(noTimeStamp,errorMessage);
             return false;
diff --git a/pvDataApp/misc/timeStamp.cpp b/pvDataApp/property/timeStamp.cpp
similarity index 100%
rename from pvDataApp/misc/timeStamp.cpp
rename to pvDataApp/property/timeStamp.cpp
diff --git a/pvDataApp/misc/timeStamp.h b/pvDataApp/property/timeStamp.h
similarity index 100%
rename from pvDataApp/misc/timeStamp.h
rename to pvDataApp/property/timeStamp.h
diff --git a/pvDataApp/pv/pvIntrospect.h b/pvDataApp/pv/pvIntrospect.h
index 1d7902e..a4812f4 100644
--- a/pvDataApp/pv/pvIntrospect.h
+++ b/pvDataApp/pv/pvIntrospect.h
@@ -60,14 +60,15 @@ public:
 
 class Field :  private NoDefaultMethods {
 public:
-   virtual ~Field();
-   Field(String fieldName,Type type);
    static ConstructDestructCallback *getConstructDestructCallback();
    int getReferenceCount() const;
    String getFieldName() const;
    Type getType() const;
    virtual void toString(StringBuilder buf) const{toString(buf,0);}
    virtual void toString(StringBuilder buf,int indentLevel) const;
+protected:
+   Field(String fieldName,Type type);
+   virtual ~Field();
 private:
    class FieldPvt *pImpl;
    void incReferenceCount() const;
@@ -77,55 +78,64 @@ private:
    friend class PVFieldPvt;
    friend class StandardField;
    friend class BasePVStructureArray;
+   friend class FieldCreate;
 };
 
 
 class Scalar : public Field{
 public:
-   Scalar(String fieldName,ScalarType scalarType);
-   virtual ~Scalar();
    ScalarType getScalarType() const {return scalarType;}
    virtual void toString(StringBuilder buf) const{toString(buf,0);}
    virtual void toString(StringBuilder buf,int indentLevel) const;
+protected:
+   Scalar(String fieldName,ScalarType scalarType);
+   virtual ~Scalar();
 private:
    ScalarType scalarType;
+   friend class FieldCreate;
 };
 
 class ScalarArray : public Field{
 public:
-   ScalarArray(String fieldName,ScalarType scalarType);
-   virtual ~ScalarArray();
    ScalarType  getElementType() const {return elementType;}
    virtual void toString(StringBuilder buf) const{toString(buf,0);}
    virtual void toString(StringBuilder buf,int indentLevel) const;
+protected:
+   ScalarArray(String fieldName,ScalarType scalarType);
+   virtual ~ScalarArray();
 private:
    ScalarType elementType;
+   friend class FieldCreate;
 };
 
 class StructureArray : public Field{
 public:
-   StructureArray(String fieldName,StructureConstPtr structure);
-   virtual ~StructureArray();
    StructureConstPtr  getStructure() const {return pstructure;}
    virtual void toString(StringBuilder buf) const{toString(buf,0);}
    virtual void toString(StringBuilder buf,int indentLevel) const;
+protected:
+   StructureArray(String fieldName,StructureConstPtr structure);
+   virtual ~StructureArray();
 private:
     StructureConstPtr pstructure;
+   friend class FieldCreate;
 };
 
 class Structure : public Field {
 public:
-   Structure(String fieldName, int numberFields,FieldConstPtrArray fields);
-   virtual ~Structure();
    int getNumberFields() const {return numberFields;}
    FieldConstPtr getField(String fieldName) const;
    int getFieldIndex(String fieldName) const;
    FieldConstPtrArray getFields() const {return fields;}
    virtual void toString(StringBuilder buf) const{toString(buf,0);}
    virtual void toString(StringBuilder buf,int indentLevel) const;
+protected:
+   Structure(String fieldName, int numberFields,FieldConstPtrArray fields);
+   virtual ~Structure();
 private:
     int numberFields;
     FieldConstPtrArray  fields;
+   friend class FieldCreate;
 };
 
 class FieldCreate : NoDefaultMethods {
diff --git a/test/testLinkedListAux b/test/testLinkedListAux
index 307693d..4164288 100644
--- a/test/testLinkedListAux
+++ b/test/testLinkedListAux
@@ -1,20 +1,20 @@
 
 Time test
-diff 86.701878 milliSeconds
-time per iteration 86.701878 microseconds
-time per addTail/removeHead 0.043351 microseconds
+diff 84.008528 milliSeconds
+time per iteration 84.008528 microseconds
+time per addTail/removeHead 0.042004 microseconds
 
 Time test locked
-diff 608.700458 milliSeconds
-time per iteration 608.700458 microseconds
-time per addTail/removeHead 0.304350 microseconds
+diff 580.331337 milliSeconds
+time per iteration 580.331337 microseconds
+time per addTail/removeHead 0.290166 microseconds
 
 Time std::list test
-diff 2209.051253 milliSeconds
-time per iteration 2209.051253 microseconds
-time per addTail/removeHead 1.104526 microseconds
+diff 2156.999667 milliSeconds
+time per iteration 2156.999667 microseconds
+time per addTail/removeHead 1.078500 microseconds
 
 Time std::list test locked
-diff 2720.724619 milliSeconds
-time per iteration 2720.724619 microseconds
-time per addTail/removeHead 1.360362 microseconds
+diff 2675.507176 milliSeconds
+time per iteration 2675.507176 microseconds
+time per addTail/removeHead 1.337754 microseconds
diff --git a/test/testThreadAux b/test/testThreadAux
index 530c9d9..d30c923 100644
--- a/test/testThreadAux
+++ b/test/testThreadAux
@@ -1 +1 @@
-time per call 25.270516 microseconds
+time per call 41.228039 microseconds
diff --git a/test/testTimeStampAux b/test/testTimeStampAux
index 806bd7b..c36d1a4 100644
--- a/test/testTimeStampAux
+++ b/test/testTimeStampAux
@@ -1,5 +1,5 @@
-current 1291814737 128832482 milliSec 1291814737128
-2010.12.08 08:25:37 128832482 nanoSeconds isDst false
+current 1292263902 816951231 milliSec 1292263902816
+2010.12.13 13:11:42 816951231 nanoSeconds isDst false
 fromTime_t
-current 1291814737 0 milliSec 1291814737000
-2010.12.08 08:25:37 0 nanoSeconds isDst false
+current 1292263902 0 milliSec 1292263902000
+2010.12.13 13:11:42 0 nanoSeconds isDst false
diff --git a/test/testTimerAux b/test/testTimerAux
index 81aaca8..fdc6d1a 100644
--- a/test/testTimerAux
+++ b/test/testTimerAux
@@ -1,6 +1,6 @@
-one requested 0.400000  diff 0.400202 seconds
-two requested 0.200000  diff 0.200183 seconds
-one requested 0.200000  diff 0.200157 seconds
-two requested 0.400000  diff 0.400198 seconds
-one requested 0.000000  diff 0.000025 seconds
-two requested 0.000000  diff 0.000042 seconds
+one requested 0.400000  diff 0.400294 seconds
+two requested 0.200000  diff 0.200352 seconds
+one requested 0.200000  diff 0.200359 seconds
+two requested 0.400000  diff 0.400304 seconds
+one requested 0.000000  diff 0.000035 seconds
+two requested 0.000000  diff 0.000053 seconds