diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html index 6660eea..f9fda39 100644 --- a/documentation/pvDataCPP.html +++ b/documentation/pvDataCPP.html @@ -10,22 +10,35 @@ + span.opt { color: grey } + span.nterm { font-style:italic } + span.term { font-family:courier } + span.user { font-family:courier } + span.user:before { content:"<" } + span.user:after { content:">" } + .nonnorm { font-style:italic } + p.ed { color: #AA0000 } + span.ed { color: #AA0000 } + p.ed.priv { display: inline; } + span.ed.priv { display: inline; } + /*]]>*/ + +
pvDataCPP is the Java implementation of pvData, which is one of a related -set of products:
+pvDataCPP is the CPP implementation of pvData, which is one of a related set +of products:
Each of the products has a Java and a C++ implementation.
+Each of the products has a CPP and a C++ implementation.
The products are all part of the V4 implementation of Experimental Physics and Industrial Control System.
+This is the 20-Dec-2011 version of the C++ implementation of pvData. It is a +
This is the 15-Aug-2012 version of the C++ implementation of pvData. It is a complete implementation of pvData as currently defined.
-TODO
-CONTENTS
+The following is a list of unresolved issues for pvDataCPP:
+This product is available via an open source license
-This is the overview for pvDataCPP. Doxygen documentation is available at 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 pvIOC, which are +located via the same sourceforge site as this project.
+ +The Java and C++ implementation of pvData implement the same data model but +differ in implementation because of the differences between Java and C++.
+ +It is a good idea to read all of pvDataJava.html but read at least the +first two chapters:
+The material in these two chapters is NOT repeated in this documentation.
+ +Doxygen documentation is available at doxygenDoc
-pvData is one of a set of related projects:
+All code in project pvDataCPP appears in namespace:
+namespace epics { namespace pvData {
+ // ...
+}}
+
+pvDataCPP introspection and data objects are designed to be shared. They are +made availiable via std::tr1::shared_ptr. In addition arrays are +implemented via std::vector. The following naming conventions are used +in typedefs:
As an example pvType.h includes the following definitions:
+typedef std::vector<double> DoubleArray;
+typedef std::tr1::shared_ptr<DoubleArray> DoubleArrayPtr;
+inline double * get(DoubleArray &value)
+{
+ return &value[0];
+}
+inline const double * get(const DoubleArray &value)
+{
+ return static_cast<const double *>(&value[0]);
+}
+typedef std::vector<double>::iterator DoubleArray_iterator;
+typedef std::vector<double>::const_iterator DoubleArray_const_iterator;
-pvData describes and implements structured data. Interspection interfaces -are used to describe the data and for each type of data a data interface -provides a container to hold the data.
- -pvData is modeled as a structured set of fields. A field has a name are a -type. The type must be one of:
+where
Introspection interface Field provides the name and type for the field. In -addition each type has an introspection interface: Scalar, ScalarArray, -Structure, and StructureArray.
- -Interface PVField provides access to the common information of every data -container. In addition every possible type has an interface for accessing the -data:
-pvData provides support, via pvData structures and associated support, for -the following:
-pvAccess provides client/server support for transmitting pvData objects. The -server must provide access to objects identified by name. Each object must have -a network wide unique name. A client issues a create channel request, -specifying the channel name in order to connect to the object on the server. -After the client has connected, it can issue the following types of request.
-Associated with each type of request is a create method. The method has an -argument that allows the client to specify options. This argument is a top -level PVStructure called a pvRequest. The pvRequest is sent to the server. The -server side looks at what is requested and creates a top level PVStructrure -that will hold the data that is transfered between client and server. It then -sends the introspection info to the client side of pvAccess, which also creates -a top level PVStructure for holding data. At this time the client is notified -that it can start making requests. Thus when data is passed between client and -server it flows between the two top level PVStructures without requiring the -creation on new objects.
+pvAccess provides many of the features of systems like CORBA and ICE -(Internet Communication Engine) but is designed to provide the following -features:
-IOC means Input/Output Controller, which is an EPICS term. A pvIOC is -modeled after an EPICS IOC but supports pvData instead of flat record -structures. At the present time the only implementation is in Java and called -javaIOC. The c++ implementaion will be called pvIOC and will be able to run in -an existing EPICS IOC.
- -Like an EPICS IOC a pvIOC provides the followig features:
-For pvAccess, the pvIOC provides the following:
-PVData is one of a set of related projects: pvData, pvAccess, and javaIOC. -It describes and implements the data that the other projects 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 javaIOC will become pvIOC.
- -pvData (Process Variable Data) defines and implements an efficent way to -store, access, and transmit memory resident structured data.
-The javaIOC implements a Process Variable (PV) Database, which is a memory -resident database holding pvData with the following features:
-pvData was initially created to support the javaIOC and was part of the -javaIOC project. It is now a separate project that is used by the javaIOC. In -addition to the javaIOC, pvData is intended for use by 1) channel access -clients, 2) Interface between client and network, 3) Interface between network -and channel access server, 4) Interface between server and IOC database. Since -it is an interface to data, it could also be used by other systems, e.g. TANGO, -TINE, etc. A high level Physics application can hold data as pvData. By -starting a channel access server, the data can made available to network -clients.
- -pvData contains everything required to support Channel Access and Channel -Access clients and servers.
- -This project has many concepts that are similar to EPICS (Experimental -Physics and Industrial Control System). This C++ implementation uses the EPICS -build system and also EPICS libCom. The directory structure for this project is -a standard EPICS application. The following source directories appear under -pvDataApp:
-This section describes a meta language for describing pvData. Currently -there are no plans for a parser for the meta language. It is used for -documentation. The toString introspection and data methods described below do -present data in a format similar to the metadata syntax. The meta language is -used to describe both introspection interfaces and data interfaces.
- -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 fieldDef defined as follows:
-type fieldName value // comment- -
where value is present for data -objects and // indicates the the -rest of the line is a comment.
- -type is one of the following:
-structure fieldName - fieldDef - ... -- or -
xxx_t fieldName - // if data object then following appear - fieldDef - ... -- For structure fieldName each - fieldDef must have a unique - fieldName within the structure For "xxx_t fieldName" xxx_t must be a - previously structure definition of the form: -
structure xxx_t - ...-
structure[] fieldName - structureDef - ... --
or
-xxx_t[] fieldName-
-
Thus a structure array is an array where each element is a structure - but all elements have the same introspection interface. For introspection - the structureDef appears once without any data valuies.
-The above is used to describe introspection objects. Data objects are -describe in a similar way but each scalar field and each array field has data -values. The definition of the data values depends on the type. For scalars the -data value is whatever is valid for the type.
-For scalar arrays the syntax is:
-= [value,...,value]- -
where each value is a valid -scalar data value depending on the type. Thus it is a comma separated set of -values enclosed in [] White space is -permitted surrounding each comma.
- -Define the following top level structure:
-structure timeStamp_t - long secondsPastEpoch - int nanoSeconds- -
Then the following introspection objects can be defined:
-structure scalarDoubleExample // introspection object - double value - timeStamp_t timeStamp-or -
structure scalarDoubleExample // introspection object - double value - structure timeStamp - long secondsPastEpoch - int nanoSeconds- -
The following data objects can be defined:
-structure scalarDoubleExample // data object - double value 1.0 - timeStamp_t timeStamp - long secondsPastEpoch 0 - int nanoSeconds 0-or -
scalar arrayDoubleExample - double[] value [1.0,2.0] - structure timeStamp - long secondsPastEpoch 0 - int nanoSeconds 0- -
If the following interface is defined:
-structure point_t - double x - double y- -
Then the following introspection objects can be defined:
-structure lineExample - point_t begin - point_t end - -structure pointArrayExample - point_t[] points --or -
structure lineExample - structure begin - double x - double y - structure end - double x - double y - -structure pointArrayExample - structure[] points - structure point - double x - double y- -
And the following data objects can be defined:
-structure lineExample - point_t begin - double x 0.0 - double y 0.0 - point_t end - double x 10 - double y 10 - -structure pointArrayExample - point_t[] value - structure point - double x 0.0 - double y 0.0 - structure point - double x 10.0 - double y 10.0- -
or
-structure lineExample - structure begin - double x 0 - double y 0 - structure end - double x 10 - double y 10 - -structure pointArrayExample - structure[] value - structure point - double x 0.0 - double y 0.0 - structure point - double x 10.0 - double y 10.0-
Directory pvDataApp/pv has header files that completely describe pvData. The implementation is provided in directory pvDataApp/factory. Test programs -appears on testApp/pvTest.
+appears in testApp/pv. + +NOTES:
+A PVStructure is a field that contains an array of subfields. Each field has -code for accessing the field. The interface for each field is PVField or an -interface that extends PVField. Each field also has an introspection interface, -which is Field or an extension of Field. This section describes the complete -set of data and introspection interfaces for pvData.
+code for accessing the field. The interface for each field is an interface that +extends PVField. Each field also has an introspection interface, which an +extension of Field. This section describes the complete set of C++ +introspection and data interfaces for pvData. -A class FieldCreate creates introspection objects. A class PVDataCreate -creates data objects. A class Convert provides a rich set of methods for -converting and copying data between fields.
+Class FieldCreate creates introspection objects. Class PVDataCreate creates +data objects. Class Convert provides a rich set of methods for converting and +copying data between fields.
Directory pvDataApp/pv has the following header files:
This provides C/C++ definitions for the pvData primitive types: boolean, -byte, short, int, long, float, double, and string. Because pvData is network -data, the C++ implementation must implement the proper semantics for the -primitive types.
+byte, short, int, long, ubyte,ushort, uint,u long,float, double, and string. +Because pvData is network data, the C++ implementation must implement the +proper semantics for the primitive types. -pvType.h provides the proper semantics. It has the definitions:
-typedef bool boolean; -typedef int8_t byte; +pvType.h provides the proper semantics.
+ +It has the definitions:
+typedef uint8_t boolean; typedef int8_t int8; typedef int16_t int16; typedef int32_t int32; typedef int64_t int64; +typedef uint8_t uint8; +typedef uint16_t uint16; typedef uint32_t uint32; typedef uint64_t uint64; // float and double are types typedef std::string String; -typedef bool * BooleanArray; -typedef int8 * ByteArray; -typedef int16 * ShortArray; -typedef int32 * IntArray; -typedef int64 * LongArray; -typedef float * FloatArray; -typedef double * DoubleArray; -typedef String* StringArray; +/** + * A boolean array. + */ +typedef std::vector<uint8> BooleanArray; +typedef std::tr1::shared_ptr<BooleanArray> BooleanArrayPtr; +/* get is same is ubyte*/ +typedef std::vector<uint8>::iterator BooleanArray_iterator; +typedef std::vector<uint8>::const_iterator BooleanArray_const_iterator; -// convenience definition for toString methods -typedef std::string * StringBuilder;+/** + * A byte array. + */ +typedef std::vector<int8> ByteArray; +typedef std::tr1::shared_ptr<ByteArray> ByteArrayPtr; +inline int8 * get(ByteArray &value); +inline int8 const * get(ByteArray const &value); +inline int8 * get(ByteArrayPtr &value); +inline int8 const * get(ByteArrayPtr const &value); +inline ByteArray & getVector(ByteArrayPtr &value); +inline ByteArray const & getVector(ByteArrayPtr const &value); +typedef std::vector<int8>::iterator ByteArray_iterator; +typedef std::vector<int8>::const_iterator ByteArray_const_iterator; + +/* similar definitions are present for ALL the primitive types */ +
where
This subsection describes pvIntrospect.h
+This subsection describes pvIntrospect.h This file is quite big so rather +than showing the entire file, it will be described in parts.
-Given a pvname, which consists of a record name and field name, it is -possible to introspect the field without requiring access to data. The -reflection and data interfaces are separate because the data may not be -available. For example when a pvAccess client connects to a 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 data array or structure be transported -over the network.
+A primary reason for pvData is to support network access to structured data. +pvAccess transports top level pvStructures. In addition a pvAccess server holds +a set of pvnames, where each pvname if a unique name in the local network.
-Given a pvname PV), it is possible to introspect the field without requiring +access to data. The reflection and data interfaces are separate because the +data may not be available. For example when a pvAccess client connects to a 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 data array or structure be +transported over the network.
+ +Types are defined as:
enum Type {
@@ -889,592 +347,589 @@ public:
static void toString(StringBuilder buf,const Type type);
};
-
enum ScalarType {
pvBoolean,
pvByte, pvShort, pvInt, pvLong,
+ pvUByte, pvUShort, pvUInt, pvULong,
pvFloat,pvDouble,
pvString;
};
-class ScalarTypeFunc {
+namespace ScalarTypeFunc {
public:
- static bool isInteger(ScalarType type);
- static bool isNumeric(ScalarType type);
- static bool isPrimitive(ScalarType type);
- static ScalarType getScalarType(String value);
+ bool isInteger(ScalarType type);
+ bool isUInteger(ScalarType type);
+ bool isNumeric(ScalarType type);
+ bool isPrimitive(ScalarType type);
+ ScalarType getScalarType(String value);
const char* name(ScalarType);
- static void toString(StringBuilder buf,ScalarType scalarType);
+ void toString(StringBuilder buf,ScalarType scalarType);
};
-Type is one of the following:
+Type is one of the following:
ScalarType is one of the -following:
+ScalarType is one of the following:
TypeFunction is a set of -convenience methods for Type
+TypeFunction is a set of convenience methods for Type
ScalarTypeFunction is a set of -convenience methods for ScalarType
+ScalarTypeFunction is a set of convenience methods for ScalarType
This section describes the reflection interfaces which provide the following:
-class Field; +class Field; class Scalar; class ScalarArray; class Structure; class StructureArray; typedef std::tr1::shared_ptr<const Field> FieldConstPtr; -typedef FieldConstPtr * FieldConstPtrArray; +typedef std::vector<FieldConstPtr> FieldConstPtrArray; typedef std::tr1::shared_ptr<const Scalar> ScalarConstPtr; typedef std::tr1::shared_ptr<const ScalarArray> ScalarArrayConstPtr; typedef std::tr1::shared_ptr<const Structure> StructureConstPtr; typedef std::tr1::shared_ptr<const StructureArray> StructureArrayConstPtr; -protected:class Field : public std::tr1::enable_shared_from_this<Field> { +class Field : + virtual public Serializable, + public std::tr1::enable_shared_from_this<Field> +{ public: - typedef std::tr1::shared_ptr<Field> shared_pointer; - typedef std::tr1::shared_ptr<const Field> const_shared_pointer; - - String getFieldName() const{return m_fieldName;} + POINTER_DEFINITIONS(Field); + virtual ~Field(); Type getType() const{return m_type;} + virtual String getID() const = 0; virtual void toString(StringBuilder buf) const{toString(buf,0);} virtual void toString(StringBuilder buf,int indentLevel) const; - void renameField(String newName); - Field(String fieldName,Type type); - virtual ~Field(); + ... }; class Scalar : public Field{ public: - typedef std::tr1::shared_ptr<Scalar> shared_pointer; - typedef std::tr1::shared_ptr<const Scalar> const_shared_pointer; - typedef Scalar& reference; - typedef const Scalar& const_reference; + POINTER_DEFINITIONS(Scalar); + virtual ~Scalar(); + typedef Scalar& reference; + typedef const Scalar& const_reference; - 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(); + ScalarType getScalarType() const {return scalarType;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; + virtual void toString(StringBuilder buf,int indentLevel) const; + virtual String getID() const; + virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; + virtual void deserialize(ByteBuffer *buffer, DeserializableContol *control); ... }; class ScalarArray : public Field{ public: - typedef std::tr1::shared_ptr<ScalarArray> shared_pointer; - typedef std::tr1::shared_ptr<const ScalarArray> const_shared_pointer; - typedef ScalarArray& reference; - typedef const ScalarArray& const_reference; + POINTER_DEFINITIONS(ScalarArray); + typedef ScalarArray& reference; + typedef const ScalarArray& const_reference; - 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(); + ScalarType getElementType() const {return elementType;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; + virtual String getID() const; + virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; + virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control); ... }; class StructureArray : public Field{ public: - typedef std::tr1::shared_ptr<StructureArray> shared_pointer; - typedef std::tr1::shared_ptr<const StructureArray> const_shared_pointer; - typedef StructureArray& reference; - typedef const StructureArray& const_reference; + POINTER_DEFINITIONS(StructureArray); + typedef StructureArray& reference; + typedef const StructureArray& const_reference; - const Structure& structure() const {return *pstructure;} - StructureConstPtr getStructure() const {return pstructure;} - virtual void toString(StringBuilder buf,int indentLevel=0) const; + StructureConstPtr getStructure() const {return pstructure;} + virtual void toString(StringBuilder buf,int indentLevel=0) const; + virtual String getID() const; + virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; + virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control); + ... }; class Structure : public Field { public: - typedef std::tr1::shared_ptr<Structure> shared_pointer; - typedef std::tr1::shared_ptr<const Structure> const_shared_pointer; - typedef Structure& reference; - typedef const Structure& const_reference; + POINTER_DEFINITIONS(Structure); + typedef Structure& reference; + typedef const Structure& const_reference; - int getNumberFields() const {return numberFields;} - FieldConstPtr getField(String fieldName) const; - int getFieldIndex(String fieldName) const; - FieldConstPtrArray getFields() const {return fields;} - void appendField(FieldConstPtr field); - void appendFields(int numberFields,FieldConstPtrArray fields); - void removeField(int index); - virtual void toString(StringBuilder buf) const{toString(buf,0);} + std::size_t getNumberFields() const {return numberFields;} + FieldConstPtr getField(String const & fieldName) const; + FieldConstPtr getField(std::size_t index) const; + std::size_t getFieldIndex(String const &fieldName) const; + FieldConstPtrArray const & getFields() const {return fields;} + StringArray const & getFieldNames() const; + void renameField(std::size_t fieldIndex,String newName); + String getFieldName(std::size_t fieldIndex); virtual void toString(StringBuilder buf,int indentLevel) const; -protected: - Structure(String fieldName, int numberFields,FieldConstPtrArray fields); - virtual ~Structure(); + virtual String getID() const; + virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const; + virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control); ... }; -class FieldCreate : NoDefaultMethods { +class FieldCreate { 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; + static FieldCreatePtr getFieldCreate(); + ScalarConstPtr createScalar(ScalarType scalarType) const + ScalarArrayConstPtr createScalarArray(ScalarType elementType) const; + StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const; + StructureConstPtr createStructure ( + StringArray const & fieldNames, + FieldConstPtrArray const & fields) const; + StructureConstPtr createStructure ( + String id, + StringArray const & fieldNames, + FieldConstPtrArray const & fields) const; + StructureConstPtr appendField( + StructureConstPtr const & structure, + String fieldName, FieldConstPtr const & field) const; + StructureConstPtr appendFields( + StructureConstPtr const & structure, + StringArray const & fieldNames, + FieldConstPtrArray const & fields) const; + FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const; + ... }; -extern FieldCreate * getFieldCreate();- -The following methods are common to all of the reflection class -descriptions:
+extern FieldCreatePtr getFieldCreate();
Field has the methods:
+Scalar has the methods:
+ScalarArray has the methods:
+StructureArray has the -methods:
+Structure has the methods:
+FieldCreate has the methods:
+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:
+Field objects for standard fields. For each type of field a method is provided. +Each creates a structure that has a field named "value" and a set of properyt +fields, 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 value 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,
- String("value,alarm,timeStamp"));
+ "value,alarm,timeStamp");
Will result in a Field definition that has the form:
structure example
double value
- structure alarm
- structure severity
- int index
- string[] choices
- structure timeStamp
- long secondsPastEpoch
- int nanoSeconds
+ alarm_t alarm
+ int severity
+ int status
+ string message
+ timeStamp_t timeStamp
+ long secondsPastEpoch
+ int nanoSeconds
+ int userTag
In addition there are methods that create each of the property structures, i.e. the methods named: alarm, .... enumeratedAlarm."
standardField.h contains:
-class StandardField : private NoDefaultMethods {
+class StandardField;
+typedef std::tr1::shared_ptr<StandardField> StandardFieldPtr;
+
+class StandardField {
public:
- StandardField();
+ static StandardFieldPtr getStandardField();
~StandardField();
- ScalarConstPtr scalar(String fieldName,ScalarType type);
- StructureConstPtr scalar(String fieldName,
- ScalarType type,String properties);
- ScalarArrayConstPtr scalarArray(String fieldName,
- ScalarType elementType);
- StructureConstPtr scalarArray(String fieldName,
+ StructureConstPtr scalar(ScalarType type,String properties);
+ StructureConstPtr scalarArray(
ScalarType elementType, String properties);
- StructureArrayConstPtr structureArray(String fieldName,
- StructureConstPtr structure);
- StructureConstPtr structureArray(String fieldName,
- StructureConstPtr structure,String properties);
- StructureConstPtr structure(String fieldName,
- int numFields,FieldConstPtrArray fields);
- StructureConstPtr enumerated(String fieldName);
- StructureConstPtr enumerated(String fieldName, String properties);
- ScalarConstPtr scalarValue(ScalarType type);
- StructureConstPtr scalarValue(ScalarType type,String properties);
- ScalarArrayConstPtr scalarArrayValue(ScalarType elementType);
- StructureConstPtr scalarArrayValue(ScalarType elementType,
- String properties);
- StructureArrayConstPtr structureArrayValue(StructureConstPtr structure);
- StructureConstPtr structureArrayValue(StructureConstPtr structure,
- String properties);
- StructureConstPtr structureValue(
- int numFields,FieldConstPtrArray fields);
- StructureConstPtr enumeratedValue(StringArray choices);
- StructureConstPtr enumeratedValue(StringArray choices,
- String properties);
+ StructureConstPtr structureArray(
+ StructureConstPtr const & structure,String properties);
+ StructureConstPtr enumerated();
+ StructureConstPtr enumerated(String properties);
StructureConstPtr alarm();
StructureConstPtr timeStamp();
StructureConstPtr display();
StructureConstPtr control();
StructureConstPtr booleanAlarm();
StructureConstPtr byteAlarm();
+ StructureConstPtr ubyteAlarm();
StructureConstPtr shortAlarm();
+ StructureConstPtr ushortAlarm();
StructureConstPtr intAlarm();
+ StructureConstPtr uintAlarm();
StructureConstPtr longAlarm();
+ StructureConstPtr ulongAlarm();
StructureConstPtr floatAlarm();
StructureConstPtr doubleAlarm();
StructureConstPtr enumeratedAlarm();
-private:
- static void init();
-};
-
-extern StandardField * getStandardField();
-
-Where
+ ...
+};
This section defines the Java Interfaces for accessing the data within a PV -record.
+This subsection describes pvData.h This file is quite big so rather than +showing the entire file, it will be described in parts.
-These are typedefs for Array and Ptr for the various pvData class +definitions, i.e. typdefs for "std::vector" and "std::tr1::shared_ptr".
+class PVAuxInfo; +class PostHandler; + +class PVField; +class PVScalar; + +class PVScalarArray; + +class PVStructure; +class PVStructureArray; + +typedef std::tr1::shared_ptr<PVAuxInfo> PVAuxInfoPtr; + +typedef std::tr1::shared_ptr<PostHandler> PostHandlerPtr; + +typedef std::tr1::shared_ptr<PVField> PVFieldPtr; +typedef std::vector<PVFieldPtr> PVFieldPtrArray; +typedef std::vector<PVFieldPtr>::iterator PVFieldPtrArray_iterator; +typedef std::vector<PVFieldPtr>::const_iterator PVFieldPtrArray_const__iterator; + +typedef std::tr1::shared_ptr<PVScalar> PVScalarPtr; +typedef std::tr1::shared_ptr<PVScalarArray> PVScalarArrayPtr; + +typedef std::tr1::shared_ptr<PVStructure> PVStructurePtr; +typedef std::vector<PVStructurePtr> PVStructurePtrArray; +typedef std::vector<PVStructurePtr>::iterator PVStructurePtrArray_iterator; +typedef std::vector<PVStructurePtr>::const_iterator PVStructurePtrArray_const__iterator; + +typedef std::tr1::shared_ptr<PVStructureArray> PVStructureArrayPtrPostHandler+ +
PostHandler is a class that must be implemented by any code that calls +setPostHandler. It's single virtual method. postPut is called whenever +PVField::postPut is called.
+class PostHandler :
+ public std::tr1::enable_shared_from_this<PostHandler>
+{
+public:
+ POINTER_DEFINITIONS(PostHandler);
+ virtual ~PostHandler(){}
+ virtual void postPut() = 0;
+};
+
+PVField is the base interface for accessing data. A data structure consists of a top level PVStructure. Every field of every structure of every top level structure has a PVField associated with it.
-class PostHandler {
-public:
- virtual void postPut() = 0;
-};
-
-class PVField
-: public Serializable,
- private NoDefaultMethods
+class PVField
+: virtual public Serializable,
+ public std::tr1::enable_shared_from_this<PVField>
{
public:
- virtual ~PVField();
- virtual void message(String message,MessageType messageType) ;
- virtual void setRequester(Requester *prequester);
- int getFieldOffset() ;
- int getNextFieldOffset() ;
- int getNumberFields() ;
- PVAuxInfo * getPVAuxInfo();
- bool isImmutable() ;
- virtual void setImmutable();
- FieldConstPtr getField() ;
- PVStructure * getParent() ;
- bool renameField(String newName);
- void postPut() ;
- void setPostHandler(PostHandler *postHandler);
- virtual bool equals(PVField &pv);
- virtual void toString(StringBuilder buf) ;
- virtual void toString(StringBuilder buf,int indentLevel) ;
-protected:
- PVField(PVStructure *parent,FieldConstPtr field);
- void setParent(PVStructure *parent);
-private:
-};
+ POINTER_DEFINITIONS(PVField);
+ virtual ~PVField();
+ virtual void message(String message,MessageType messageType);
+ String getFieldName() const ;
+ virtual void setRequester(RequesterPtr const &prequester);
+ std::size_t getFieldOffset() const;
+ std::size_t getNextFieldOffset() const;
+ std::size_t getNumberFields() const;
+ PVAuxInfoPtr & getPVAuxInfo()
+ bool isImmutable() const;
+ virtual void setImmutable();
+ const FieldConstPtr & getField() const ;
+ PVStructure * getParent() const
+ void replacePVField(const PVFieldPtr& newPVField);
+ void renameField(String newName);
+ void postPut() ;
+ void setPostHandler(PostHandlerPtr const &postHandler);
+ virtual bool equals(PVField &pv);
+ virtual void toString(StringBuilder buf) ;
+ virtual void toString(StringBuilder buf,int indentLevel);
+ ...
+}
-PostHandler is a class that must -be implemented by any code that calls setPostHandler. It's single virtual -method. postPut is called whenever -PVField::postPut is called.
- -Serializable, and -NoDefaultMethods are described in a later section.
- -The public methods for PVField -are:
+The public methods for PVField are:
AuxInfo (Auxillary Information) is information about a field that is application specific. It will not be available outside the application that @@ -1486,459 +941,583 @@ information. Each Field and each PVField can have have an arbitrary number of auxInfos. An auxInfo is a (key,PVScalar) pair where key is a string.
class PVAuxInfo : private NoDefaultMethods {
public:
+ typedef std::map<String,PVScalarPtr> PVInfoMap;
+ typedef std::map<String,PVScalarPtr>::iterator PVInfoIter;
+ typedef std::pair<String,PVScalarPtr> PVInfoPair;
+
PVAuxInfo(PVField *pvField);
~PVAuxInfo();
PVField * getPVField();
- PVScalar * createInfo(String key,ScalarType scalarType);
- PVScalarMap getInfos();
- PVScalar * getInfo(String key);
+ PVScalarPtr createInfo(String key,ScalarType scalarType);
+ PVScalarPtr getInfo(String key);
+ PVInfoMap & getInfoMap();
void toString(StringBuilder buf);
void toString(StringBuilder buf,int indentLevel);
-private:
+ ...
};
where
This is the base class for all scalar data.
class PVScalar : public PVField {
public:
+ POINTER_DEFINITIONS(PVScalar);
virtual ~PVScalar();
- ScalarConstPtr getScalar() ;
-protected:
- PVScalar(PVStructure *parent,ScalarConstPtr scalar);
-};
+ typedef PVScalar &reference;
+ typedef const PVScalar& const_reference;
+ const ScalarConstPtr getScalar() const ;
+ ...
+}
-where
+The interfaces for primitive data types are:
template<typename T>
class PVScalarValue : public PVScalar {
public:
- typedef std::tr1::shared_ptr<PVScalarValue> shared_pointer;
- typedef std::tr1::shared_ptr<const PVScalarValue> const_shared_pointer;
-
+ POINTER_DEFINITIONS(PVScalarValue);
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
-
virtual ~PVScalarValue() {}
- virtual T get() = 0;
+ virtual T get() const = 0;
virtual void put(T value) = 0;
-protected:
- PVScalarValue(PVStructure *parent,ScalarConstPtr scalar)
- : PVScalar(parent,scalar) {}
-private:
-};
-
-typedef PVScalarValue<bool> PVBoolean;
-typedef PVScalarValue<int8> PVByte;
-typedef PVScalarValue<int16> PVShort;
-typedef PVScalarValue<int32> PVInt;
-typedef PVScalarValue<int64> PVLong;
-typedef PVScalarValue<float> PVFloat;
-typedef PVScalarValue<double> PVDouble;
+ ...
+}
// PVString is special case, since it implements SerializableArray
class PVString : public PVScalarValue<String>, SerializableArray {
public:
virtual ~PVString() {}
-protected:
- PVString(PVStructure *parent,ScalarConstPtr scalar)
- : PVScalarValue<String>(parent,scalar) {}
+ ...
};
-where
+PVArray is the base interface for -all the other PV Array interfaces. It extends PVField and provides the -additional methods:
+PVArray is the base interface for all the other PV Array interfaces. It +extends PVField and provides the additional methods:
class PVArray : public PVField, public SerializableArray {
public:
+ POINTER_DEFINITIONS(PVArray);
virtual ~PVArray();
- int getLength() ;
- void setLength(int length);
- int getCapacity() ;
- bool isCapacityMutable() ;
+ virtual void setImmutable();
+ std::size_t getLength() const;
+ virtual void setLength(std::size_t length);
+ std::size_t getCapacity() const;
+ bool isCapacityMutable() const;
void setCapacityMutable(bool isMutable);
- virtual void setCapacity(int capacity) = 0;
-protected:
- PVArray(PVStructure *parent,FieldConstPtr field);
- void setCapacityLength(int capacity,int length);
+ virtual void setCapacity(std::size_t capacity) = 0;
+ ...
};
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:
+This is the argument to one of the get methods of PVValueArray.
template<typename T>
class PVArrayData {
+private:
+ std::vector<T> init;
public:
- typedef std::tr1::shared_ptr<PVArrayData> shared_pointer;
- typedef std::tr1::shared_ptr<const PVArrayData> const_shared_pointer;
-
+ POINTER_DEFINITIONS(PVArrayData);
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
+ std::vector<T> & data;
+ std::size_t offset;
+ PVArrayData()
+ : data(init)
+ {}
+};
- pointer data;
- int offset;
-};
+PVScalarArray is the base class for scalar array data. PVValueArray is a +templete for the various scalar array data classes. There is a class for each +possible scalar type, i. e. PVBooleanArray, ..., PVStringArray.
+class PVScalarArray : public PVArray {
public:
- typedef std::tr1::shared_ptr<PVScalarArray> shared_pointer;
- typedef std::tr1::shared_ptr<const PVScalarArray> const_shared_pointer;
-
+ POINTER_DEFINITIONS(PVScalarArray);
virtual ~PVScalarArray();
- ScalarArrayConstPtr getScalarArray() ;
+ typedef PVScalarArray &reference;
+ typedef const PVScalarArray& const_reference;
+ const ScalarArrayConstPtr getScalarArray() const ;
+ ...
+}
-protected:
- PVScalarArray(PVStructure *parent,ScalarArrayConstPtr scalarArray);
-private:
-};
-template<typename T>
+where
+This is a template class plus instances for PVBooleanArray, ..., +PVStringArray.
+template<typename T>
class PVValueArray : public PVScalarArray {
public:
- typedef std::tr1::shared_ptr<PVValueArray> shared_pointer;
- typedef std::tr1::shared_ptr<const PVValueArray> const_shared_pointer;
-
+ POINTER_DEFINITIONS(PVValueArray);
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef PVArrayData<T> ArrayDataType;
+ typedef std::vector<T> vector;
+ typedef const std::vector<T> const_vector;
+ typedef std::tr1::shared_ptr<vector> shared_vector;
+ typedef PVValueArray & reference;
+ typedef const PVValueArray & const_reference;
virtual ~PVValueArray() {}
- virtual int get(int offset, int length, ArrayDataType *data) = 0;
- virtual int put(int offset,int length, pointer from, int fromOffset) = 0;
- virtual void shareData(pointer value,int capacity,int length) = 0;
+ virtual std::size_t get(
+ std::size_t offset, std::size_t length, ArrayDataType &data) = 0;
+ virtual std::size_t put(std::size_t offset,
+ std::size_t length, const_pointer from, std::size_t fromOffset) = 0;
+ virtual std::size_t put(std::size_t offset,
+ std::size_t length, const_vector &from, std::size_t fromOffset);
+ virtual void shareData(
+ shared_vector const & value,
+ std::size_t capacity,
+ std::size_t length) = 0;
+ virtual pointer get() = 0;
+ virtual pointer get() const = 0;
+ virtual vector const & getVector() = 0;
+ virtual shared_vector const & getSharedVector() = 0;
protected:
- PVValueArray(PVStructure *parent,ScalarArrayConstPtr scalar)
- : PVScalarArray(parent,scalar) {}
-private:
+ PVValueArray(ScalarArrayConstPtr const & scalar)
+ : PVScalarArray(scalar) {}
+ friend class PVDataCreate;
};
-typedef PVArrayData<bool> BooleanArrayData;
-typedef PVValueArray<bool> PVBooleanArray;
+
+template<typename T>
+std::size_t PVValueArray<T>::put(
+ std::size_t offset,
+ std::size_t length,
+ const_vector &from,
+ std::size_t fromOffset)
+{ return put(offset,length, &from[0], fromOffset); }
+
+/**
+ * Definitions for the various scalarArray types.
+ */
+typedef PVArrayData<uint8> BooleanArrayData;
+typedef PVValueArray<uint8> PVBooleanArray;
+typedef std::tr1::shared_ptr<PVBooleanArray> PVBooleanArrayPtr;
typedef PVArrayData<int8> ByteArrayData;
typedef PVValueArray<int8> PVByteArray;
+typedef std::tr1::shared_ptr<PVByteArray> PVByteArrayPtr;
typedef PVArrayData<int16> ShortArrayData;
typedef PVValueArray<int16> PVShortArray;
+typedef std::tr1::shared_ptr<PVShortArray> PVShortArrayPtr;
typedef PVArrayData<int32> IntArrayData;
typedef PVValueArray<int32> PVIntArray;
+typedef std::tr1::shared_ptr<PVIntArray> PVIntArrayPtr;
typedef PVArrayData<int64> LongArrayData;
typedef PVValueArray<int64> PVLongArray;
+typedef std::tr1::shared_ptr<PVLongArray> PVLongArrayPtr;
+typedef PVArrayData<uint8> UByteArrayData;
+typedef PVValueArray<uint8> PVUByteArray;
+typedef std::tr1::shared_ptr<PVUByteArray> PVUByteArrayPtr;
+
+typedef PVArrayData<uint16> UShortArrayData;
+typedef PVValueArray<uint16> PVUShortArray;
+typedef std::tr1::shared_ptr<PVUShortArray> PVUShortArrayPtr;
+
+typedef PVArrayData<uint32> UIntArrayData;
+typedef PVValueArray<uint32> PVUIntArray;
+typedef std::tr1::shared_ptr<PVUIntArray> PVUIntArrayPtr;
+
+typedef PVArrayData<uint64> ULongArrayData;
+typedef PVValueArray<uint64> PVULongArray;
+typedef std::tr1::shared_ptr<PVULongArray> PVULongArrayPtr;
typedef PVArrayData<float> FloatArrayData;
typedef PVValueArray<float> PVFloatArray;
+typedef std::tr1::shared_ptr<PVFloatArray> PVFloatArrayPtr;
typedef PVArrayData<double> DoubleArrayData;
typedef PVValueArray<double> PVDoubleArray;
+typedef std::tr1::shared_ptr<PVDoubleArray> PVDoubleArrayPtr;
typedef PVArrayData<String> StringArrayData;
-typedef PVValueArray<String> PVStringArray;
+typedef PVValueArray<String> PVStringArray;
+typedef std::tr1::shared_ptr<PVStringArray> PVStringArrayPtr;
-Get "exposes" it's internal array by setting data.data and data.offset. 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 without requiring an intermediate array.
+where
+Both get and put return the number of elements actually transfered. The 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)
- {
- int len = pv->getLength();
- if(lenArray<len) len = lenArray;
- DoubleArrayData data;
- int offset = 0;
- while(offset < len) {
- int num = pv->get(offset,(len-offset),&data);
- doubleArray from = &data.data[data.offset];
- doubleArray to = &to[offset]
- int numbytes = num*sizeof(double);
- memcopy(from,to,numBytes);
- offset += num;
- }
- }
+void getArray(PVDoubleArrayPtr & pv,DoubleArray const & to)
+{
+ size_t len = pv->getLength();
+ if(to.size()<len) to.resize(len);
+ DoubleArrayData data;
+ size_t offset = 0;
+ while(offset<len) {
+ size_t num = pv->get(offset,(len-offset),data);
+ DoubleArray &from = data.data;
+ size_t fromOffset = data.offset;
+ for(size_t i=0; i<num; i++) to[i+offset] = from[i + fromOffset];
+ offset += num;
+ }
+}
-shareData results in the PVArray using the primitive array that is passed to -this method. This is most useful for immutable arrays. In this case the caller -must set the PVArray to be immutable. In the PVArray is not immutable 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 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 choices is immutable. Allowing the choices -internal String[] to be shared between all the instances 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.
+ -The interface for a structure is:
class PVStructure : public PVField,public BitSetSerializable {
public:
-
-};virtual ~PVStructure();
- StructureConstPtr getStructure();
- PVFieldPtrArray getPVFields();
- PVField *getSubField(String fieldName);
- PVField *getSubField(int fieldOffset);
- void appendPVField(PVField *pvField);
- void appendPVFields(int numberFields,PVFieldPtrArray pvFields);
+ POINTER_DEFINITIONS(PVStructure);
+ virtual ~PVStructure();
+ typedef PVStructure & reference;
+ typedef const PVStructure & const_reference;
+ virtual void setImmutable();
+ StructureConstPtr getStructure() const;
+ const PVFieldPtrArray & getPVFields() const;
+ PVFieldPtr getSubField(String fieldName) const;
+ PVFieldPtr getSubField(std::size_t fieldOffset) const;
+ void appendPVField(
+ String fieldName,
+ PVFieldPtr const & pvField);
+ void appendPVFields(
+ StringArray const & fieldNames,
+ PVFieldPtrArray const & pvFields);
void removePVField(String fieldName);
- PVBoolean *getBooleanField(String fieldName);
- PVByte *getByteField(String fieldName);
- PVShort *getShortField(String fieldName);
- PVInt *getIntField(String fieldName);
- PVLong *getLongField(String fieldName);
- PVFloat *getFloatField(String fieldName);
- PVDouble *getDoubleField(String fieldName);
- PVString *getStringField(String fieldName);
- PVStructure *getStructureField(String fieldName);
- PVScalarArray *getScalarArrayField(
- String fieldName,ScalarType elementType);
- PVStructureArray *getStructureArrayField(String fieldName);
- String getExtendsStructureName();
+ PVBooleanPtr getBooleanField(String fieldName) ;
+ PVBytePtr getByteField(String fieldName) ;
+ PVShortPtr getShortField(String fieldName) ;
+ PVIntPtr getIntField(String fieldName) ;
+ PVLongPtr getLongField(String fieldName) ;
+ PVUBytePtr getUByteField(String fieldName) ;
+ PVUShortPtr getUShortField(String fieldName) ;
+ PVUIntPtr getUIntField(String fieldName) ;
+ PVULongPtr getULongField(String fieldName) ;
+ PVFloatPtr getFloatField(String fieldName) ;
+ PVDoublePtr getDoubleField(String fieldName) ;
+ PVStringPtr getStringField(String fieldName) ;
+ PVStructurePtr getStructureField(String fieldName) ;
+ PVScalarArrayPtr getScalarArrayField(
+ String fieldName,ScalarType elementType) ;
+ PVStructureArrayPtr getStructureArrayField(String fieldName) ;
+ String getExtendsStructureName() const;
bool putExtendsStructureName(
String extendsStructureName);
virtual void serialize(
- ByteBuffer *pbuffer,SerializableControl *pflusher) const;
+ ByteBuffer *pbuffer,SerializableControl *pflusher) const ;
virtual void deserialize(
ByteBuffer *pbuffer,DeserializableControl *pflusher);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher,BitSet *pbitSet) const;
virtual void deserialize(ByteBuffer *pbuffer,
DeserializableControl*pflusher,BitSet *pbitSet);
- PVStructure(PVStructure *parent,StructureConstPtr structure);
- PVStructure(
- PVStructure *parent,
- StructureConstPtr structure,
- PVFieldPtrArray pvFields);
+ PVStructure(StructureConstPtr const & structure);
+ PVStructure(StructureConstPtr const & structure,PVFieldPtrArray const & pvFields);
};
where
The interface for an array of structures is:
-class StructureArrayData {
-public:
- PVStructurePtrArray data;
- int offset;
-};
+typedef PVArrayData<PVStructurePtr> StructureArrayData;
-class PVStructureArray : public PVArray {
+class PVStructureArray : public PVArray
+{
public:
+ POINTER_DEFINITIONS(PVStructureArray);
+ typedef PVStructurePtr value_type;
+ typedef PVStructurePtr* pointer;
+ typedef const PVStructurePtr* const_pointer;
+ typedef PVArrayData<PVStructurePtr> ArrayDataType;
+ typedef std::vector<PVStructurePtr> vector;
+ typedef const std::vector<PVStructurePtr> const_vector;
+ typedef std::tr1::shared_ptr<vector> shared_vector;
+ typedef PVStructureArray &reference;
+ typedef const PVStructureArray& const_reference;
+
virtual ~PVStructureArray() {}
- virtual StructureArrayConstPtr getStructureArray() = 0;
- virtual int append(int number) = 0;
- virtual bool remove(int offset,int number) = 0;
- virtual void compress() = 0;
- virtual int get(int offset, int length,
- StructureArrayData *data) = 0;
- virtual int put(int offset,int length,
- PVStructurePtrArray from, int fromOffset) = 0;
- virtual void shareData( PVStructurePtrArray value,int capacity,int length) = 0;
-protected:
- PVStructureArray(PVStructure *parent,
- StructureArrayConstPtr structureArray);
-};
+ virtual void setCapacity(size_t capacity);
+ virtual void setLength(std::size_t length);
+ virtual StructureArrayConstPtr getStructureArray() const ;
+ virtual std::size_t append(std::size_t number);
+ virtual bool remove(std::size_t offset,std::size_t number);
+ virtual void compress();
+ virtual std::size_t get(std::size_t offset, std::size_t length,
+ StructureArrayData &data);
+ virtual std::size_t put(std::size_t offset,std::size_t length,
+ const_vector const & from, std::size_t fromOffset);
+ virtual void shareData(
+ shared_vector const & value,
+ std::size_t capacity,
+ std::size_t length);
+ virtual void serialize(ByteBuffer *pbuffer,
+ SerializableControl *pflusher) const;
+ virtual void deserialize(ByteBuffer *buffer,
+ DeserializableControl *pflusher);
+ virtual void serialize(ByteBuffer *pbuffer,
+ SerializableControl *pflusher, std::size_t offset, std::size_t count) const ;
+ virtual pointer get() { return &((*value.get())[0]); }
+ virtual pointer get() const { return &((*value.get())[0]); }
+ virtual vector const & getVector() {return *value;}
+ virtual shared_vector const & getSharedVector() {return value;}
+ ...
+}
where
The other methods are similar to the methods for other array types.
-PVDataCreate is an interface that provides methods that create PVField interfaces. A factory is provided that creates PVDataCreate.
class PVDataCreate {
public:
- PVField *createPVField(PVStructure *parent,
- FieldConstPtr field);
- PVField *createPVField(PVStructure *parent,
- String fieldName,PVField * fieldToClone);
- PVScalar *createPVScalar(PVStructure *parent,ScalarConstPtr scalar);
- PVScalar *createPVScalar(PVStructure *parent,
- String fieldName,ScalarType scalarType);
- PVScalar *createPVScalar(PVStructure *parent,
- String fieldName,PVScalar * scalarToClone);
- PVScalarArray *createPVScalarArray(PVStructure *parent,
- ScalarArrayConstPtr scalarArray);
- PVScalarArray *createPVScalarArray(PVStructure *parent,
- String fieldName,ScalarType elementType);
- PVScalarArray *createPVScalarArray(PVStructure *parent,
- String fieldName,PVScalarArray * scalarArrayToClone);
- PVStructureArray *createPVStructureArray(PVStructure *parent,
- StructureArrayConstPtr structureArray);
- PVStructure *createPVStructure(PVStructure *parent,
- StructureConstPtr structure);
- PVStructure *createPVStructure(PVStructure *parent,
- String fieldName,int numberFields,FieldConstPtrArray fields);
- PVStructure *createPVStructure(PVStructure *parent,
- String fieldName,int numberFields,PVFieldPtrArray pvFields);
- PVStructure *createPVStructure(PVStructure *parent,
- String fieldName,PVStructure *structToClone);
-protected:
- PVDataCreate();
- friend PVDataCreate * getPVDataCreate();
+ static PVDataCreatePtr getPVDataCreate();
+ PVFieldPtr createPVField(FieldConstPtr const & field);
+ PVFieldPtr createPVField(PVFieldPtr const & fieldToClone);
+ PVScalarPtr createPVScalar(ScalarConstPtr const & scalar);
+ PVScalarPtr createPVScalar(ScalarType scalarType);
+ PVScalarPtr createPVScalar(PVScalarPtr const & scalarToClone);
+ PVScalarArrayPtr createPVScalarArray(ScalarArrayConstPtr const & scalarArray);
+ PVScalarArrayPtr createPVScalarArray(ScalarType elementType);
+ PVScalarArrayPtr createPVScalarArray(PVScalarArrayPtr const & scalarArrayToClone);
+ PVStructureArrayPtr createPVStructureArray(StructureArrayConstPtr const & structureArray);
+ PVStructurePtr createPVStructure(StructureConstPtr const & structure);
+ PVStructurePtr createPVStructure(
+ StringArray const & fieldNames,PVFieldPtrArray const & pvFields);
+ PVStructurePtr createPVStructure(PVStructurePtr const & structToClone);
+ ...
};
-extern PVDataCreate * getPVDataCreate();
+extern PVDataCreatePtr getPVDataCreate();
where
A class StandardPVField has methods for creating standard data fields. Like class StandardField it has two forms of the methods which create a field, one @@ -1985,54 +1564,25 @@ without properties and one with properties. Again the properties is some combination of alarm, timeStamp, control, display, and valueAlarm. And just like StandardField there are methods to create the standard properties. The methods are:
-class StandardPVField : private NoDefaultMethods {
-public:
- StandardPVField();
- ~StandardPVField();
- PVScalar * scalar(PVStructure *parent,String fieldName,ScalarType type);
- PVStructure * scalar(PVStructure *parent,
- String fieldName,ScalarType type,String properties);
- PVScalarArray * scalarArray(PVStructure *parent,
- String fieldName,ScalarType elementType);
- PVStructure * scalarArray(PVStructure *parent,
- String fieldName,ScalarType elementType, String properties);
- PVStructureArray * structureArray(PVStructure *parent,
- String fieldName,StructureConstPtr structure);
- PVStructure* structureArray(PVStructure *parent,
- String fieldName,StructureConstPtr structure,String properties);
- PVStructure * enumerated(PVStructure *parent,
- String fieldName,StringArray choices, int number);
- PVStructure * enumerated(PVStructure *parent,
- String fieldName,StringArray choices, int number, String properties);
- PVScalar * scalarValue(PVStructure *parent,ScalarType type);
- PVStructure * scalarValue(PVStructure *parent,
- ScalarType type,String properties);
- PVScalarArray * scalarArrayValue(PVStructure *parent,ScalarType elementType);
- PVStructure * scalarArrayValue(PVStructure *parent,
- ScalarType elementType, String properties);
- PVStructureArray * structureArrayValue(PVStructure *parent,
- StructureConstPtr structure);
- PVStructure * structureArrayValue(PVStructure *parent,
- StructureConstPtr structure,String properties);
- PVStructure * enumeratedValue(PVStructure *parent,StringArray choices);
- PVStructure * enumeratedValue(PVStructure *parent,
- StringArray choices, String properties);
- PVStructure * alarm(PVStructure *parent);
- PVStructure * timeStamp(PVStructure *parent);
- PVStructure * display(PVStructure *parent);
- PVStructure * control(PVStructure *parent);
- PVStructure * booleanAlarm(PVStructure *parent);
- PVStructure * byteAlarm(PVStructure *parent);
- PVStructure * shortAlarm(PVStructure *parent);
- PVStructure * intAlarm(PVStructure *parent);
- PVStructure * longAlarm(PVStructure *parent);
- PVStructure * floatAlarm(PVStructure *parent);
- PVStructure * doubleAlarm(PVStructure *parent);
- PVStructure * enumeratedAlarm(PVStructure *parent);
- PVStructure * powerSupply(PVStructure *parent);
-};
+class StandardPVField; +typedef std::tr1::shared_ptr<StandardPVField> StandardPVFieldPtr; -+ +Convert
+class StandardPVField : private NoDefaultMethods { +public: + static StandardPVFieldPtr getStandardPVField(); + ~StandardPVField(); + PVStructurePtr scalar(ScalarType type,String properties); + PVStructurePtr scalarArray(ScalarType elementType, String properties); + PVStructurePtr structureArray(StructureConstPtr const &structure,String properties); + PVStructurePtr enumerated(StringArray const &choices); + PVStructurePtr enumerated(StringArray const &choices, String properties); + ... +} + + +extern StandardPVFieldPtr getStandardPVField();
NOTE about copying immutable array fields. If an entire immutable array field is copied to another array that has the same elementType, both offsets @@ -2070,6 +1620,7 @@ Thus the source and target share the same primitive array.
static inline bool operator!=(PVField& a, PVField& b) {return !(a==b);} + bool operator==(const Field&, const Field&); bool operator==(const Scalar&, const Scalar&); bool operator==(const ScalarArray&, const ScalarArray&); @@ -2086,210 +1637,209 @@ static inline bool operator!=(const Structure& a, const Structure& b) {return !(a==b);} static inline bool operator!=(const StructureArray& a, const StructureArray& b) {return !(a==b);} +class Convert; +typedef std::tr1::shared_ptr<Convert> ConvertPtr; -class Convert : NoDefaultMethods { +class Convert { public: - Convert(); + static ConvertPtr getConvert(); ~Convert(); - void getFullName(StringBuilder buf,PVField *pvField); + void getFullName(StringBuilder buf,PVFieldPtr const & pvField); + bool equals(PVFieldPtr const &a,PVFieldPtr const &b); bool equals(PVField &a,PVField &b); - void getString(StringBuilder buf,PVField * pvField,int indentLevel); - void getString(StringBuilder buf,PVField *pvField); - void fromString(PVScalar *pv, String from); - int fromString(PVScalarArray *pv, String from); - int fromStringArray(PVScalarArray *pv, int offset, int length, - StringArray from, int fromOffset); - int toStringArray(PVScalarArray *pv, int offset, int length, - StringArray to, int toOffset); - bool isCopyCompatible(FieldConstPtr from, FieldConstPtr to); - void copy(PVField *from,PVField *to); + void getString(StringBuilder buf,PVFieldPtr const & pvField,int indentLevel); + void getString(StringBuilder buf,PVFieldPtr const & pvField); + void getString(StringBuilder buf,PVField const * pvField,int indentLevel); + void getString(StringBuilder buf,PVField const * pvField); + std::size_t fromString( + PVStructurePtr const &pv, + StringArray const & from, + std::size_t fromStartIndex = 0); + void fromString(PVScalarPtr const & pv, String from); + std::size_t fromString(PVScalarArrayPtr const & pv, String from); + std::size_t fromStringArray( + PVScalarArrayPtr const & pv, + std::size_t offset, std::size_t length, + StringArray const & from, + std::size_t fromOffset); + std::size_t toStringArray(PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + StringArray & to, + std::size_t toOffset); + bool isCopyCompatible(FieldConstPtr const & from, FieldConstPtr const & to); + void copy(PVFieldPtr const & from, PVFieldPtr const & to); bool isCopyScalarCompatible( - ScalarConstPtr from, ScalarConstPtr to); - void copyScalar(PVScalar *from, PVScalar *to); - bool isCopyScalarArrayCompatible(ScalarArrayConstPtr from, - ScalarArrayConstPtr to); - int copyScalarArray(PVScalarArray *from, int offset, - PVScalarArray *to, int toOffset, int length); + ScalarConstPtr const & from, + ScalarConstPtr const & to); + void copyScalar(PVScalarPtr const & from, PVScalarPtr const & to); + bool isCopyScalarArrayCompatible( + ScalarArrayConstPtr const & from, + ScalarArrayConstPtr const & to); + std::size_t copyScalarArray( + PVScalarArrayPtr const & from, + std::size_t offset, + PVScalarArrayPtr const & to, + std::size_t toOffset, + std::size_t length); bool isCopyStructureCompatible( - StructureConstPtr from, StructureConstPtr to); - void copyStructure(PVStructure *from, PVStructure *to); + StructureConstPtr const & from, StructureConstPtr const & to); + void copyStructure(PVStructurePtr const & from, PVStructurePtr const & to); bool isCopyStructureArrayCompatible( - StructureArrayConstPtr from, StructureArrayConstPtr to); + StructureArrayConstPtr const & from, StructureArrayConstPtr const & to); void copyStructureArray( - PVStructureArray *from, PVStructureArray *to); - int8 toByte(PVScalar *pv); - int16 toShort(PVScalar *pv); - int32 toInt(PVScalar *pv); - int64 toLong(PVScalar *pv); - float toFloat(PVScalar *pv); - double toDouble(PVScalar *pv); - String toString(PVScalar *pv); - void fromByte(PVScalar *pv,int8 from); - void fromShort(PVScalar *pv,int16 from); - void fromInt(PVScalar *pv, int32 from); - void fromLong(PVScalar *pv, int64 from); - void fromFloat(PVScalar* pv, float from); - void fromDouble(PVScalar *pv, double from); - int toByteArray(PVScalarArray *pv, int offset, int length, - ByteArray to, int toOffset); - int toShortArray(PVScalarArray *pv, int offset, int length, - ShortArray to, int toOffset); - int toIntArray(PVScalarArray *pv, int offset, int length, - IntArray to, int toOffset); - int toLongArray(PVScalarArray *pv, int offset, int length, - LongArray to, int toOffset); - int toFloatArray(PVScalarArray *pv, int offset, int length, - FloatArray to, int toOffset); - int toDoubleArray(PVScalarArray *pv, int offset, int length, - DoubleArray to, int toOffset); - int fromByteArray(PVScalarArray *pv, int offset, int length, - ByteArray from, int fromOffset); - int fromShortArray(PVScalarArray *pv, int offset, int length, - ShortArray from, int fromOffset); - int fromIntArray(PVScalarArray *pv, int offset, int length, - IntArray from, int fromOffset); - int fromLongArray(PVScalarArray *pv, int offset, int length, - LongArray from, int fromOffset); - int fromFloatArray(PVScalarArray *pv, int offset, int length, - FloatArray from, int fromOffset); - int fromDoubleArray(PVScalarArray *pv, int offset, int length, - DoubleArray from, int fromOffset); - void newLine(StringBuilder buf, int indentLevel); -}; + PVStructureArrayPtr const & from, PVStructureArrayPtr const & to); + int8 toByte(PVScalarPtr const & pv); + int16 toShort(PVScalarPtr const & pv); + int32 toInt(PVScalarPtr const & pv); + int64 toLong(PVScalarPtr const & pv); + uint8 toUByte(PVScalarPtr const & pv); + uint16 toUShort(PVScalarPtr const & pv); + uint32 toUInt(PVScalarPtr const & pv); + uint64 toULong(PVScalarPtr const & pv); + float toFloat(PVScalarPtr const & pv); + double toDouble(PVScalarPtr const & pv); + String toString(PVScalarPtr const & pv); + void fromByte(PVScalarPtr const & pv,int8 from); + void fromShort(PVScalarPtr const & pv,int16 from); + void fromInt(PVScalarPtr const & pv, int32 from); + void fromLong(PVScalarPtr const & pv, int64 from); + void fromUByte(PVScalarPtr const & pv,uint8 from); + void fromUShort(PVScalarPtr const & pv,uint16 from); + void fromUInt(PVScalarPtr const & pv, uint32 from); + void fromULong(PVScalarPtr const & pv, uint64 from); + void fromFloat(PVScalarPtr const & pv, float from); + void fromDouble(PVScalarPtr const & pv, double from); + std::size_t toByteArray(PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + int8* to, + std::size_t toOffset); + std::size_t toShortArray(PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + int16* to, + std::size_t toOffset); + std::size_t toIntArray(PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + int32* to, + std::size_t toOffset); + std::size_t toLongArray(PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + int64* to, + std::size_t toOffset); + std::size_t toUByteArray(PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + uint8* to, + std::size_t toOffset); + std::size_t toUShortArray(PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + uint16* to, + std::size_t toOffset); + std::size_t toUIntArray( + PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + uint32* to, + std::size_t toOffset); + std::size_t toULongArray( + PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + uint64* to, + std::size_t toOffset); + std::size_t toFloatArray( + PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + float* to, + std::size_t toOffset); + std::size_t toDoubleArray( + PVScalarArrayPtr const & pv, + std::size_t offset, + std::size_t length, + double* to, std::size_t + toOffset); + std::size_t fromByteArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const int8* from, std::size_t fromOffset); + std::size_t fromByteArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const ByteArray & from, std::size_t fromOffset); + std::size_t fromShortArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const int16* from, std::size_t fromOffset); + std::size_t fromShortArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const ShortArray & from, std::size_t fromOffset); + std::size_t fromIntArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const int32* from, std::size_t fromOffset); + std::size_t fromIntArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const IntArray & from, std::size_t fromOffset); + std::size_t fromLongArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const int64* from, std::size_t fromOffset); + std::size_t fromLongArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const LongArray & from, std::size_t fromOffset); + std::size_t fromUByteArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const uint8* from, std::size_t fromOffset); + std::size_t fromUByteArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const UByteArray & from, std::size_t fromOffset); + std::size_t fromUShortArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const uint16* from, std::size_t fromOffset); + std::size_t fromUShortArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const UShortArray & from, std::size_t fromOffset); + std::size_t fromUIntArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const uint32* from, std::size_t fromOffset); + std::size_t fromUIntArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const UIntArray & from, std::size_t fromOffset); + std::size_t fromULongArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const uint64* from, std::size_t fromOffset); + std::size_t fromULongArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const ULongArray & from, std::size_t fromOffset); + std::size_t fromFloatArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const float* from, std::size_t fromOffset); + std::size_t fromFloatArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const FloatArray & from, std::size_t fromOffset); + std::size_t fromDoubleArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const double* from, std::size_t fromOffset); + std::size_t fromDoubleArray( + PVScalarArrayPtr & pv, std::size_t offset, std::size_t length, + const DoubleArray & from, std::size_t fromOffset); + void newLine(StringBuilder buf, int indentLevel); + ... +} -extern Convert * getConvert(); +extern ConvertPtr getConvert();The array methods all return the number of elements copied or converted. -This can be less than len if the -PVField array contains less than len elements.
+This can be less than len if the PVField array contains less than len +elements. -newLine is a convenience method -for code that implements toString It +
newLine is a convenience method for code that implements toString It generates a newline and inserts blanks at the beginning of the newline.
-All code in project pvDataCPP appears in namespace:
-namespace epics { namespace pvData {
- // ...
-}}
-
-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 {
-protected:
- // allow by derived objects
- NoDefaultMethods(){};
- ~NoDefaultMethods(){}
-private:
- // do not implment
- NoDefaultMethods(const NoDefaultMethods&);
- NoDefaultMethods & operator=(const NoDefaultMethods &);
-};
-
-Introspection objects are meant to be shared. They are all made available -via std::tri::shared_pointer.
- -All PVData data objects must publically extend PVField, which does not allow -default methods but does have a virtual destructor. It is expected that each -data object is "owned" by some entity. For example a pvIOC (not implemented) -database will own all records and thus all PVData data objects in the database. -It is the ONLY entity that will create and destroy the data objects. All other -code only receives pointers to the data objects. Before a record is deleted any -code that is connected to a record is notified before 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.
- -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 via -"delete".
-Assume that code wants to print two fields from a PVStructure:
-The following code uses introspection to get the desired information.
-void getValueAndTimeStamp(PVStructurePtr pvStructure,StringBuilder buf) {
- PVField *valuePV = pvStructure->getSubField(String("value"));
- if(valuePV==0) {
- buf += "value field not found";
- return;
- }
- buf += "value ";
- valuePV->toString(buf);
- PVField *timeStampPV = pvStructure->getSubField(String("timeStamp"));
- if(timeStampPV==0) {
- buf += "timeStamp field not found";
- return;
- }
- buf += " timeStamp ";
- timeStampPV->toString(buf);
-}
-
-Example of creating a scalar field.
- PVDataCreate *pvDataCreate = getPVDataCreate();
- PVDouble *pvValue = pvDataCreate->createPVScalar(
- 0,
- String("value"),
- pvDouble);
-
-Create an alarm structure the hard way
- FieldCreate *fieldCreate = getFieldCreate();
- PVDataCreate *pvDataCreate = getPVDataCreate();
- FieldConstPtrArray fields = new FieldConstPtr[2];
- fields[0] = fieldCreate->createScalar(String("severity"),pvInt);
- fields[1] = fieldCreate->createScalar(String("message"),pvString);
- StructureConstPtralarmField = fieldCreate->createStructure(String("alarm"),2,fields);
-
-Create an alarm structure the easy way.
-StandardPVField *standardPVField = getStandardPVField(); - PVStructure *pvAlarm = standardPVField->alarm(parent);- -
Create a PVStructure with field name example that has a double value field -and a timeStamp and alarm. Do it the easy way.
- StandardPVField *standardPVField = getStandardPVField();
- PVStructure *pvStructure = standardPVField->scalar(
- 0, //parent is null
- String("example"),
- String("timeStamp,alarm"))
-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 @@ -2297,82 +1847,105 @@ substructure. All other fields in the structure containing a value field are considered properties of the value field. The fieldname is also the property name. The value field can have any type, i.e. scalar, scalarArray, or structure. Typical property fields are timeStamp, alarm, display, control, and -history The timeStamp is a special case. If it appears anywhere in the -structure hieraracy above a value field it is a property of the value field. -
+history. The timeStamp is a special case. If it appears anywhere in the +structure hieraracy above a value field it is a property of the value field.For example the following top level structure has a single value field. The value field has properties alarm, timeStamp, and display.
structure counterOutput
- structure alarm
- structure timeStamp
double value
- structure display
+ alarm_t
+ int severity 0
+ int status 0
+ string message
+ double value
+ display_t
+ double limitLow 0.0
+ double limitHigh 10.0
string description "Sample Description"
string format "%f"
- string units volts
- structure limit
- double low 0.0
- double high 10.0
+ string units volts
The following example has three value fields each with properties alarm and timeStamp. Voltage, Current, and Power each have a different alarms but all share the timeStamp.
-structure powerSupplyValueStructure
+structure powerSupplyValue
double value
- structure alarm
+ alarm_t
+ int severity 0
+ int status 0
+ string message
structure powerSupplySimple
- structure alarm
- structure timeStamp
- powerSupplyValueStructure voltage
- powerSupplyValueStructure power
- powerSupplyValueStructure current
+ alarm_t
+ int severity 0
+ int status 0
+ string message
+ timeStamp_t
+ long secondsPastEpoch
+ int nanoSeconds
+ int userTag
+ powerSupplyValue_t voltage
+ double value
+ alarm_t
+ int severity 0
+ int status 0
+ string message
+ powerSupplyValue_t power
+ double value
+ alarm_t
+ int severity 0
+ int status 0
+ string message
+ powerSupplyValue_t current
+ double value
+ alarm_t
+ int severity 0
+ int status 0
+ string message
-The following field names have special meaning, i.e. support properties for general purpose clients.
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.
+that that support the PVData data model. For example a powerSupport record can +have fields power, voltage, current that each support the PVData data model. + -Except for enumerated, each property has two files: a property.h and a -pvProperty.h . For example: timeStamp.h -and pvTimeStamp.h In each case the +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 +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) {
+void example(PVFieldPtr const &pvField) {
Alarm alarm;
PVAlarm pvAlarm;
bool result;
@@ -2426,13 +1998,13 @@ stack. For example the following is permitted:
...
}
-timeStamp
+timeStamp
A timeStamp is represented by the following structure
structure timeStamp
- int64 secondsPartEpoch
- int32 nanoSeconds
- int32 userTag
+ long secondsPartEpoch
+ int nanoSeconds
+ int userTag
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 @@ -2443,39 +2015,47 @@ 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 pvTimeStamp.h timeStamp.h defines a time stamp -independent of pvData, i.e. it is a generally useful class for manipulating -timeStamps. pvTimeStamp.h is a class -that can be attached to a time stamp pvData structure. It provides get and set -methods to get/set a TimeStamp as defined by timeStamp.h
+Two header files are provided for manipulating time stamps:
+This provides
extern int32 milliSecPerSec;
extern int32 microSecPerSec;
-extern int32 ;
+extern int32 nanoSecPerSec;
extern int64 posixEpochAtEpicsEpoch;
class TimeStamp {
public:
- TimeStamp();
- TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0);
+ TimeStamp()
+ :secondsPastEpoch(0), nanoSeconds(0), userTag(0) {}
+ TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0,int32 userTag = 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();
- int64 getEpicsSecondsPastEpoch() const;
- int32 getNanoSeconds() const;
- int32 getUserTag() const;
- void setUserTag(int userTag);
- void put(int64 secondsPastEpoch,int32 nanoSeconds = 0);
+ int64 getSecondsPastEpoch() const {return secondsPastEpoch;}
+ int64 getEpicsSecondsPastEpoch() const {
+ return secondsPastEpoch - posixEpochAtEpicsEpoch;
+ }
+ int32 getNanoSeconds() const {return nanoSeconds;}
+ int32 getUserTag() const {return userTag;}
+ void setUserTag(int userTag) {this->userTag = userTag;}
+ void put(int64 secondsPastEpoch,int32 nanoSeconds = 0) {
+ this->secondsPastEpoch = secondsPastEpoch;
+ this->nanoSeconds = nanoSeconds;
+ normalize();
+ }
void put(int64 milliseconds);
void getCurrent();
double toSeconds() const ;
@@ -2491,56 +2071,53 @@ public:
TimeStamp & operator+=(double seconds);
TimeStamp & operator-=(double seconds);
int64 getMilliseconds(); // milliseconds since epoch
-};
+ ...
+}
where
class PVTimeStamp {
public:
PVTimeStamp();
//default constructors and destructor are OK
//This class should not be extended
//returns (false,true) if pvField(isNot, is valid timeStamp structure
- bool attach(PVField *pvField);
+ bool attach(PVFieldPtr const &pvField);
void detach();
bool isAttached();
// following throw logic_error if not attached to PVField
@@ -2581,51 +2158,50 @@ public:
where
An alarm structure is defined as follows:
structure alarm - int32 severity - int32 status - String message+ int severity + int status + string message
Note that neither severity or status is 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.
+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 pvAlarm.h alarm.h defines a time stamp independent -of pvData, i.e. it is a generally useful class for manipulating alarms. pvAlarm.h is a class that can be attached -to a time stamp pvData structure. It provides get and set methods to get/set a -Alarm as defined by alarm.h
+Two header files are provided for manipulating alarms:
+enum AlarmSeverity {
noAlarm,minorAlarm,majorAlarm,invalidAlarm,undefinedAlarm
};
@@ -2642,10 +2218,10 @@ public:
static StringArray getSeverityNames();
};
-
-enum AlarmStatus {
- noStatus,deviceStatus,driverStatus,recordStatus,
- dbStatus,confStatus,undefinedStatus,clientStatus
+class AlarmStatusFunc {
+public:
+ static AlarmStatus getStatus(int value);
+ static StringArray getStatusNames();
};
class Alarm {
@@ -2662,134 +2238,135 @@ public:
Alarm Severity defines the possible alarm severities:
Alarm Status defines the possible choices for alarm status:
Alarm has the methods:
class PVAlarm {
public:
PVAlarm() : pvSeverity(0),pvMessage(0) {}
//default constructors and destructor are OK
//returns (false,true) if pvField(isNot, is valid enumerated structure
//An automatic detach is issued if already attached.
- bool attach(PVField *pvField);
+ bool attach(PVFieldPtr const &pvField);
void detach();
bool isAttached();
// each of the following throws logic_error is not attached to PVField
// set returns false if field is immutable
- void get(Alarm &) const;
+ void get(Alarm & alarm) const;
bool set(Alarm const & alarm);
};
where
Control information is represented by the following structure
structure control - structure limit - double low - double high+ double limitLow + double limitHigh + double minStep -
Two header files are provided for manipulating controls: control.h and pvControl.h control.h defines a time stamp independent -of pvData, i.e. it is a generally useful class for manipulating controls. pvControl.h is a class that can be -attached to a time stamp pvData structure. It provides get and set methods to -get/set a Control as defined by control.h
+Two header files are provided for manipulating control:
+class Control {
public:
Control();
//default constructors and destructor are OK
double getLow() const;
double getHigh() const;
+ double getMinStep() const;
void setLow(double value);
void setHigh(double value);
+ void setMinStep(double value);
};
where
class PVControl {
public:
PVControl();
//default constructors and destructor are OK
//returns (false,true) if pvField(isNot, is valid enumerated structure
//An automatic detach is issued if already attached.
- bool attach(PVField *pvField);
+ bool attach(PVFieldPtr const &pvField);
void detach();
bool isAttached();
// each of the following throws logic_error is not attached to PVField
@@ -2800,50 +2377,48 @@ public:
where
Display information is represented by the following structure
structure display
- structure limit
- double low
- double high
+ double limitLow
+ double limitHigh
string description
string format
string units
-Two header files are provided for manipulating controls: display.h and pvDisplay.h display.h defines display information -independent of pvData, i.e. it is a generally useful class for manipulating -display infomation. pvDisplay.h is a -class that can be attached to a display pvData structure. It provides get and -set methods to get/set a Diaplay as defined by diaplay.h
+Two header files are provided for manipulating display:
+class Display {
public:
Display();
@@ -2862,38 +2437,38 @@ public:
where
class PVDisplay {
public:
PVDisplay()
: pvDescription(0),pvFormat(),pvUnits(),pvLow(),pvHigh() {}
//default constructors and destructor are OK
//An automatic detach is issued if already attached.
- bool attach(PVField *pvField);
+ bool attach(PVFieldPtr const&pvField);
void detach();
bool isAttached();
// each of the following throws logic_error is not attached to PVField
@@ -2904,37 +2479,34 @@ public:
where
An enumerated structure is a structure that has fields:
structure
- int32 index
+ int index
string[] choices
-For enumerated structures a single header file pvEnumerted.h is available
+For enumerated structures a single header file pvEnumerted.h is available
class PVEnumerated {
public:
PVEnumerated();
@@ -2942,7 +2514,7 @@ public:
//This class should not be extended
//returns (false,true) if pvField(isNot, is valid enumerated structure
//An automatic detach is issued if already attached.
- bool attach(PVField *pvField);
+ bool attach(PVFieldPtr const &pvField);
void detach();
bool isAttached();
// each of the following throws logic_error is not attached to PVField
@@ -2953,48 +2525,117 @@ public:
bool choicesMutable();
StringArray getChoices();
int32 getNumberChoices();
- bool setChoices(StringArray choices,int32 numberChoices);
+ bool setChoices(StringArray &choices,int32 numberChoices);
};
where
Assume that code wants to print two fields from a PVStructure:
+The following code uses introspection to get the desired information.
+void getValueAndTimeStamp(PVStructurePtr pvStructure,StringBuilder buf) {
+ PVFieldPtr valuePV = pvStructure->getSubField(String("value"));
+ if(valuePV.get()==NULL) {
+ buf += "value field not found";
+ return;
+ }
+ buf += "value ";
+ valuePV->toString(&buf);
+ PVFieldPtr timeStampPV = pvStructure->getSubField(String("timeStamp"));
+ if(timeStampPV.get()==NULL) {
+ buf += "timeStamp field not found";
+ return;
+ }
+ buf += " timeStamp ";
+ timeStampPV->toString(&buf);
+}
+
+Example of creating a scalar field.
+PVDataCreatePtr pvDataCreate = getPVDataCreate(); + PVDoublePtr pvValue = static_pointer_cast<PVDouble>( + pvDataCreate->createPVScalar(pvDouble));+ +
Create a structure with a value and an alarm the hard way
+FieldCreatePtr fieldCreate = getFieldCreate(); + PVDataCreatePtr pvDataCreate = getPVDataCreate(); + FieldConstPtrArray fields; + StringArray names; + fields.resize(3); + names.resize(3); + fields[0] = fieldCreate->createScalar(pvInt); + fields[1] = fieldCreate->createScalar(pvInt); + fields[2] = fieldCreate->createScalar(pvString); + names[0] = "severity"; + names[0] = "status"; + names[0] = "message"; + StructureConstPtr alarmField = + fieldCreate->createStructure(names,fields); + fields.resize(2); + names.resize(2); + fields[0] = fieldCreate->createScalar(pvDouble); + fields[1] = alarmField; + names[0] = "value"; + names[0] = "alarm"; + StructureConstPtr structure = + fieldCreate->createStructure(names,fields); + PVStructurePtr pv = pvDataCreate->createPVStructure(structure);+ +
Create an alarm structure the easy way.
+StandardPVFieldPtr standardPVField = getStandardPVField(); + PVStructurePtr pv = standardPVField->scalar(pvDouble,"alarm");+ +
Create a PVStructure with field name example that has a double value field , +timeStamp, alarm, and display. Do it the easy way.
+StandardPVFieldPtr standardPVField = getStandardPVField(); + PVStructurePtr pvStructure = standardPVField->scalar( + pvDouble,"timeStamp,alarm.display");+ +
Directory factory has code that implements everything described by the files in directory pv
@@ -3014,64 +2655,63 @@ PVDataCreate and implements getPVDataCreate. implements getConvert.Other files implement PVData base classes
-This package provides utility code:
Note that directory testApp/misc has test code for all the classes in misc. The test code also can be used as examples.
-This is adapted from the java.util.BitSet. bitSet.h is:
-class BitSet /*: public Serializable*/ {
+class BitSet : public Serializable {
public:
+ static BitSet::shared_pointer create(uint32 nbits);
BitSet();
BitSet(uint32 nbits);
virtual ~BitSet();
@@ -3085,6 +2725,7 @@ public:
int32 nextClearBit(uint32 fromIndex) const;
bool isEmpty() const;
uint32 cardinality() const;
+ uint32 size() const;
BitSet& operator&=(const BitSet& set);
BitSet& operator|=(const BitSet& set);
BitSet& operator^=(const BitSet& set);
@@ -3100,114 +2741,181 @@ private:
where
Clears all of the bits in this bitSet whose corresponding bit is set in the specified bitSet.
A ByteBuffer is used to serialize and deserialize primitive data. File byteBuffer.h is:
class ByteBuffer {
public:
- ByteBuffer(int size = 32, int byteOrder = EPICS_BYTE_ORDER);
+ ByteBuffer(std::size_t size, int byteOrder = EPICS_BYTE_ORDER)
~ByteBuffer();
- ByteBuffer* clear();
- ByteBuffer* flip();
- ByteBuffer* rewind();
+ void setEndianess(int byteOrder);
+ const char* getBuffer();
+ void clear();
+ void flip();
+ void rewind();
+ std::size_t getPosition();
+ void setPosition(std::size_t pos);
+ std::size_t getLimit();
+ void setLimit(std::size_t limit);
+ std::size_t getRemaining();
+ std::size_t getSize();
+ template<typename T>
+ void put(T value)
+ template<typename T>
+ void put(std::size_t index, T value);
+ template<typename T>
+ T get()
+ template<typename T>
+ T get(std::size_t index)
+ void put(const char* src, std::size_t src_offset, std::size_t count);
+ void get(char* dest, std::size_t dest_offset, std::size_t count);
+ template<typename T>
+ inline void putArray(T* values, std::size_t count)
+ template<typename T>
+ inline void getArray(T* values, std::size_t count)
+ template<typename T>
+ inline bool reverse();
+ inline void align(std::size_t size)
+ void putBoolean( bool value);
+ void putByte ( int8 value);
+ void putShort ( int16 value);
+ void putInt ( int32 value);
+ void putLong ( int64 value);
+ void putFloat ( float value);
+ void putDouble (double value);
+ void putBoolean(std::size_t index, bool value);
+ void putByte (std::size_t index, int8 value);
+ void putShort (std::size_t index, int16 value);
+ void putInt (std::size_t index, int32 value);
+ void putFloat (std::size_t index, float value);
+ void putDouble (std::size_t index, double value);
bool getBoolean();
- int8 getByte();
- int16 getShort();
- int32 getInt();
- int64 getLong();
- float getFloat();
- double getDouble();
- void get(char* dst, int offset, int count);
- ByteBuffer* put(const char* src, int offset, int count);
- ByteBuffer* putBoolean(bool value);
- ByteBuffer* putByte(int8 value);
- ByteBuffer* putShort(int16 value);
- ByteBuffer* putInt(int32 value);
- ByteBuffer* putLong(int64 value);
- ByteBuffer* putFloat(float value);
- ByteBuffer* putDouble(double value);
- inline int getSize() const;
- inline int getArrayOffset() const;
- inline int getPosition() const;
- inline int getLimit() const;
- inline int getRemaining() const;
- inline int getByteOrder() const;
- inline const char* getArray() const;
- // TODO must define arrays
-private:
+ int8 getByte ();
+ int16 getShort ();
+ int32 getInt ();
+ int64 getLong ();
+ float getFloat ();
+ double getDouble ();
+ bool getBoolean(std::size_t index);
+ int8 getByte (std::size_t index);
+ int16 getShort (std::size_t index);
+ int32 getInt (std::size_t index);
+ int64 getLong (std::size_t index);
+ float getFloat (std::size_t index);
+ double getDouble (std::size_t index);
+ const char* getArray();
+ ...
};
-x
+class Destroyable {
+public:
+ POINTER_DEFINITIONS(Destroyable);
+ virtual void destroy() = 0;
+ virtual ~Destroyable() {};
+};
-/*
+ * Throwing exceptions w/ file+line# and, when possibly, a stack trace
+ *
+ * THROW_EXCEPTION1( std::bad_alloc );
+ *
+ * THROW_EXCEPTION2( std::logic_error, "my message" );
+ *
+ * THROW_EXCEPTION( mySpecialException("my message", 42, "hello", ...) );
+ *
+ * Catching exceptions
+ *
+ * catch(std::logic_error& e) {
+ * fprintf(stderr, "%s happened\n", e.what());
+ * PRINT_EXCEPTION2(e, stderr);
+ * cout<<SHOW_EXCEPTION(e);
+ * }
+ *
+ * If the exception was not thrown with the above THROW_EXCEPTION*
+ * the nothing will be printed.
+ */
+
+This class provides coordinates activity between threads. One thread can wait for the event and the other signals the event.
-class Event : private NoDefaultMethods {
+class Event;
+typedef std::tr1::shared_ptr<Event> EventPtr;
+
+class Event {
public:
- Event(bool full);
+ POINTER_DEFINITIONS(Event);
+ explicit Event(bool = false);
~Event();
void signal();
bool wait (); /* blocks until full */
@@ -3215,61 +2923,51 @@ public:
bool tryWait (); /* false if empty */
private:
epicsEventId id;
-};
+};
where
File epicsException.h describes:
-class BaseException : public std::exception {
-public:
- BaseException(const char* message, const char* file,
- int line, std::exception* cause = 0);
- virtual ~BaseException();
- virtual const char* what();
- void toString(std::string& str, unsigned int depth = 0);
- static inline void getStackTrace(
- std::string* trace, unsigned int skip_frames = 0, unsigned int max_frames = 63)
-private:
- // ...
-}
-
-x
- -An Executor is a thread that can execute commands. The user can request that a single command be executed.
-class ExecutorNode; - +class Command; +class Executor; +typedef std::tr1::shared_ptr<Command> CommandPtr; +typedef std::tr1::shared_ptr<Executor> ExecutorPtr; + class Command { public: + POINTER_DEFINITIONS(Command); + virtual ~Command(){} virtual void command() = 0; -}; - -class Executor : private NoDefaultMethods { -public: +private: + CommandPtr next; + friend class Executor; +}; + +class Executor : public Runnable{ +public: + POINTER_DEFINITIONS(Executor); Executor(String threadName,ThreadPriority priority); ~Executor(); - ExecutorNode * createNode(Command *command); - void execute(ExecutorNode *node); -private: - class ExecutorPvt *pImpl; + void execute(CommandPtr const &node); + virtual void run(); + ... };Command is a class that must be implemented by the code that calls execute. @@ -3278,131 +2976,18 @@ execute.
Executor has the methods:
LinkedList implements a double linked list that requires a user to 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 except via -linkedList.
- -A node can only be on one list at a time but can be put, at different times, -on different lists as long as they all hold the same type of objects. An -exception is thrown if an attempt is made to put a node on a list if the node -is already on a list.
-template <typename T>
-class LinkedList;
-
-template <typename T>
-class LinkedListNode : private LinkedListVoidNode {
-public:
- LinkedListNode(T &object) : LinkedListVoidNode(&object){}
- ~LinkedListNode() {}
- T &getObject() { return *static_cast<T *>(LinkedListVoidNode::getObject());}
- bool isOnList() {return LinkedListVoidNode::isOnList();}
- friend class LinkedList<T>;
-};
-
-template <typename T>
-class LinkedList : private LinkedListVoid {
-public:
- LinkedList() : LinkedListVoid() {}
- ~LinkedList() {}
- int getLength();
- void addTail(LinkedListNode<T> &listNode);
- void addHead(LinkedListNode<T> &listNode);
- void insertAfter(LinkedListNode<T> &listNode,LinkedListNode<T> &addNode);
- void insertBefore(LinkedListNode<T> &listNode,LinkedListNode<T> &addNode);
- LinkedListNode<T> *removeTail();
- LinkedListNode<T> *removeHead();
- void remove(LinkedListNode<T> &listNode);
- LinkedListNode<T> *getHead();
- LinkedListNode<T> *getTail();
- LinkedListNode<T> *getNext(LinkedListNode<T> &listNode);
- LinkedListNode<T> *getPrev(LinkedListNode<T> &listNode);
- bool isEmpty();
-};
-
-LinkedListNode has the methods:
-LinkedList has the methods:
-lock.h is:
-class Mutex {
-public:
- Mutex();
- ~Mutex();
- void lock();
- void unlock();
-};
-
+lock.h
+typedef epicsMutex Mutex;
class Lock : private NoDefaultMethods {
public:
@@ -3411,6 +2996,7 @@ public:
void lock();
void unlock();
bool ownsLock() ;
+ ...
};
Lock is as easy to use as Java synchronize. To protect some object just
@@ -3441,74 +3027,79 @@ once. This can be implemented as follows:
// initialization
}
-class MessageNode {
+Definitions
+
+A messageQueue is for use by code that wants to handle messages without
+blocking higher priority threads.
+class MessageNode;
+class MessageQueue;
+typedef std::tr1::shared_ptr<MessageNode> MessageNodePtr;
+typedef std::vector<MessageNodePtr> MessageNodePtrArray;
+typedef std::tr1::shared_ptr<MessageQueue> MessageQueuePtr;
+
+class MessageNode {
public:
String getMessage() const;
MessageType getMessageType() const;
void setMessageNull();
};
-class MessageQueue : private NoDefaultMethods {
+class MessageQueue : public Queue<MessageNode> {
public:
- MessageQueue(int size);
- ~MessageQueue();
- MessageNode *get();
+ POINTER_DEFINITIONS(MessageQueue);
+ static MessageQueuePtr create(int size);
+ MessageQueue(MessageNodePtrArray &nodeArray);
+ virtual ~MessageQueue();
+ MessageNodePtr &get();
// must call release before next get
void release();
// return (false,true) if message (was not, was) put into queue
bool put(String message,MessageType messageType,bool replaceLast);
- bool isEmpty() const;
- bool isFull() const;
+ bool isEmpty() ;
+ bool isFull() ;
int getClearOverrun();
+ ...
};
-MessageQueue
-
-This is for use by code that wants to handle messages without blocking
-higher priority threads.
-
A messageNode is a class with two public data members:
A messageQueue is an interface with public methods:
Look at miscTest/testMessageQueue.cpp for an example.
-If a class privately extends this class then the compiler can not create any of the following: default constructor, default copy constructror, or default @@ -3527,7 +3118,90 @@ assignment contructor.
NoDefaultMethods & operator=(const NoDefaultMethods &); }; -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 +free element becomes avalable.
+template <typename T>
+class Queue
+{
+public:
+ POINTER_DEFINITIONS(Queue);
+ typedef std::tr1::shared_ptr<T> queueElementPtr;
+ typedef std::vector<queueElementPtr> queueElementPtrArray;
+ Queue(queueElementPtrArray &);
+ virtual ~Queue();
+ void clear();
+ int capacity();
+ int getNumberFree();
+ int getNumberUsed();
+ queueElementPtr & getFree();
+ void setUsed(queueElementPtr &element);
+ queueElementPtr & getUsed();
+ void releaseUsed(queueElementPtr &element);
+ ...
+};
+
+testApp/misc/testQueue.cpp provides an example of how to define a queue.
+ +The queue methods are:
+A queue is created as follows:
+ class MyClass;
+ typedef MyQueueElement<MyClass> MyElement;
+ typedef MyQueue<MyClass> MyQueue;
+ int numElement = 5;
+ ...
+ MyClass *array[numElements];
+ for(int i=0; i<numElements; i++) {
+ array[i] = new MyClass();
+ }
+ MyQueue *queue = new MyQueue(array,numElements);
+
+A producer calls getFree and setUsed via code like the following:
+ MyClass *getFree() {
+ MyElement *element = queue->getFree();
+ if(element==0) return 0;
+ return element->getObject();
+ }
+
+A consumer calls getUsed and releaseUsed via code like the following:
+ while(true) {
+ MyElement *element = queue->getUsed();
+ if(element==0) break;
+ MyClass *myClass = element->getObject();
+ // do something with myClass
+ queue->releaseUsed(element);
+ }
+
+A PVField extends Requester. Requester is present so that when database errors are found there is someplace to send a message.
@@ -3535,29 +3209,85 @@ errors are found there is someplace to send a message. infoMessage,warningMessage,errorMessage,fatalErrorMessage }; -extern StringArray messageTypeName; - +extern String getMessageTypeName(MessageType messageType); +extern const size_t messageTypeCount; class Requester { public: + POINTER_DEFINITIONS(Requester); + virtual ~Requester(){} virtual String getRequesterName() = 0; virtual void message(String message,MessageType messageType) = 0; };where
class SerializableControl;
+ class DeserializableControl;
+ class Serializable;
+ class BitSetSerializable;
+ class SerializableArray;
+ class BitSet;
+ class Field;
+
+ class SerializableControl {
+ public:
+ virtual ~SerializableControl(){}
+ virtual void flushSerializeBuffer() =0;
+ virtual void ensureBuffer(std::size_t size) =0;
+ virtual void alignBuffer(std::size_t alignment) =0;
+ virtual void cachedSerialize(
+ std::tr1::shared_ptr<const Field> const & field,
+ ByteBuffer* buffer) = 0;
+ };
+
+ class DeserializableControl {
+ public:
+ virtual ~DeserializableControl(){}
+ virtual void ensureData(std::size_t size) =0;
+ virtual void alignData(std::size_t alignment) =0;
+ virtual std::tr1::shared_ptr<const Field> cachedDeserialize(ByteBuffer* buffer) = 0;
+ };
+
+ class Serializable {
+ public:
+ virtual ~Serializable(){}
+ virtual void serialize(ByteBuffer *buffer,
+ SerializableControl *flusher) const = 0;
+ virtual void deserialize(ByteBuffer *buffer,
+ DeserializableControl *flusher) = 0;
+ };
+
+ class BitSetSerializable {
+ public:
+ virtual ~BitSetSerializable(){}
+ virtual void serialize(ByteBuffer *buffer,
+ SerializableControl *flusher,BitSet *bitSet) const = 0;
+ virtual void deserialize(ByteBuffer *buffer,
+ DeserializableControl *flusher,BitSet *bitSet) = 0;
+ };
+
+
+ class SerializableArray : virtual public Serializable {
+ public:
+ virtual ~SerializableArray(){}
+ virtual void serialize(ByteBuffer *buffer,
+ SerializableControl *flusher, std::size_t offset, std::size_t count) const = 0;
+ };
+
+This is a helper class for serialization, which is required for sending and receiving pvData over the nerwork.
@@ -3574,96 +3304,31 @@ public: SerializableControl* flusher); static String deserializeString(ByteBuffer* buffer, DeserializableControl* control); -private: -}; - -class SerializableControl { -public: - virtual void flushSerializeBuffer() =0; - virtual void ensureBuffer(int size) =0; -}; -class DeserializableControl { - -public: - virtual void ensureData(int size) =0; -}; -class Serializable { -public: - virtual void serialize(ByteBuffer *buffer, - SerializableControl *flusher) = 0; - virtual void deserialize(ByteBuffer *buffer, - DeserializableControl *flusher) = 0; -}; -class BitSetSerializable { -public: - virtual void serialize(ByteBuffer *buffer, - SerializableControl *flusher,BitSet *bitSet) = 0; - virtual void deserialize(ByteBuffer *buffer, - DeserializableControl *flusher,BitSet *bitSet) = 0; -}; -class SerializableArray : public Serializable { -public: - virtual void serialize(ByteBuffer *buffer, - SerializableControl *flusher, int offset, int count) = 0; + ... };where
The following interfaces are called by pvAccess for transporting data over -the network. The abstract and base classes ensure that these methods are -properly implemented.
-x+
#define POINTER_DEFINITIONS(clazz) \ + typedef std::tr1::shared_ptr<clazz> shared_pointer; \ + typedef std::tr1::shared_ptr<const clazz> const_shared_pointer; \ + typedef std::tr1::weak_ptr<clazz> weak_pointer; \ + typedef std::tr1::weak_ptr<const clazz> const_weak_pointer;-
x
- -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.
-struct CDRCount {
- size_t cons, dtys;
- long refs;
-};
-
-class CDRMonitor : private NoDefaultMethods {
-public:
- static CDRMonitor& get();
- CDRNode* addNode(CDRNode& next);
- CDRCount current();
- CDRNode* first();
- CDRNode* first();
- void show(FILE*)
- void show(std::ostream&) const;
-};
-class CDRNode : private NoDefaultMethods {
-public:
- CDRNode(const String& name);
- void construct();
- void destruct(){Lock x(guard);
- void incRef();
- void decRef();
- CDRNode* next();
- CDRCount get();
- void show(FILE*);
- void show(std::ostream&);
-};
-
-static inline CDRNode* getNode(CDRNodeInstance *inst);
-
-Status provides a way to pass status back to client code:
class Status : public epics::pvData::Serializable {
@@ -3697,31 +3362,31 @@ static inline CDRNode* getNode(CDRNodeInstance *inst);
The Status methods are:
The StatusCreate methods are:
enum ThreadPriority {
lowestPriority,
lowerPriority,
@@ -3730,15 +3395,9 @@ static inline CDRNode* getNode(CDRNodeInstance *inst);
highPriority,
higherPriority,
highestPriority
-};
-
-class ThreadPriorityFunc {
-public:
- static unsigned int const * const getEpicsPriorities();
- static int getEpicsPriority(ThreadPriority threadPriority);
};
-class Runnable {
public:
virtual void run() = 0;
@@ -3746,15 +3405,15 @@ public:
class Thread;
-class Thread : private NoDefaultMethods {
+class Thread : public epicsThread, private NoDefaultMethods {
public:
- Thread(String name,ThreadPriority priority,Runnable *runnableReady);
+ Thread(
+ String name,
+ ThreadPriority priority,
+ Runnable *runnableReady,
+ epicsThreadStackSizeClass stkcls=epicsThreadStackSmall);
~Thread();
- String getName();
- ThreadPriority getPriority();
- static void showThreads(StringBuilder buf);
- static void sleep(double seconds);
-private:
+ ...
};
Runnable must be implement by code that wants to be run via a thread. It has @@ -3765,27 +3424,18 @@ exception is thrown if run remains active when delete is called.
Thread has the methods:
delete pthread;
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. @@ -3793,78 +3443,96 @@ It starts with a loop of one iteration. If the total elapsed time is less then .1 seconds it increases the number of iterrations by a factor of 10. It keeps repeating until the elapsed time is greater than .1 seconds. It returns the average number of seconds per call.
-class TimeFunctionRequester {
-public:
+class TimeFunctionRequester;
+class TimeFunction;
+typedef std::tr1::shared_ptr<TimeFunctionRequester> TimeFunctionRequesterPtr;
+typedef std::tr1::shared_ptr<TimeFunction> TimeFunctionPtr;
+
+class TimeFunctionRequester {
+public:
+ POINTER_DEFINITIONS(TimeFunctionRequester);
+ virtual ~TimeFunctionRequester(){}
virtual void function() = 0;
-};
+};
-class TimeFunction : private NoDefaultMethods {
-public:
- TimeFunction(TimeFunctionRequester *requester);
- ~TimeFunction();
+
+class TimeFunction {
+public:
+ POINTER_DEFINITIONS(TimeFunction);
+ TimeFunction(TimeFunctionRequesterPtr const & requester);
+ ~TimeFunction();
double timeCall();
-private:
- TimeFunctionRequester *requester;
-};
+ ...
+};
TimeFunctionRequester must be implemented by code that wants to time how long a function takes. It has the single method:
TimeFunction has the methods:
This provides a general purpose timer. It allows a user callback to be called after a delay or periodically.
-class TimerCallback {
+class TimerCallback;
+class Timer;
+typedef std::tr1::shared_ptr<TimerCallback> TimerCallbackPtr;
+typedef std::tr1::shared_ptr<Timer> TimerPtr;
+
+
+class TimerCallback {
public:
+ POINTER_DEFINITIONS(TimerCallback);
+ TimerCallback();
+ virtual ~TimerCallback(){}
virtual void callback() = 0;
virtual void timerStopped() = 0;
};
-class TimerNode : private NoDefaultMethods {
-public:
- TimerNode(TimerCallback *timerCallback);
- ~TimerNode();
- void cancel();
- bool isScheduled();
-private:
-};
-
-class Timer : private NoDefaultMethods {
+class Timer : private Runnable {
public:
+ POINTER_DEFINITIONS(Timer);
Timer(String threadName, ThreadPriority priority);
- ~Timer();
- void scheduleAfterDelay(TimerNode &timerNode,double delay);
- void schedulePeriodic(TimerNode &timerNode,double delay,double period);
-private:
+ virtual ~Timer();
+ virtual void run();
+ void scheduleAfterDelay(
+ TimerCallbackPtr const &timerCallback,
+ double delay);
+ void schedulePeriodic(
+ TimerCallbackPtr const &timerCallback,
+ double delay,
+ double period));
+ void cancel(TimerCallbackPtr const &timerCallback);
+ bool isScheduled(TimerCallbackPtr const &timerCallback);
+ void toString(StringBuilder builder);
+ ...
};
TimerCallback must be implemented by the user. It has the following methods:
In order to schedule a callback client code must allocate a TimerNode It can be used to schedule multiple callbacks. It has the methods:
delete timerNode;
Timer has the methods:
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 -free element becomes avalable.
-template <typename T>
-class QueueElement : private QueueElementVoid {
-public:
- T *getObject() { return static_cast<T *>(QueueElementVoid::getObject());}
-protected:
-};
-
-template <typename T>
-class Queue : private QueueVoid {
-public:
- Queue(T *array[],int number);
- ~Queue();
- void clear();
- int getNumberFree();
- int capacity();
- QueueElement<T> *getFree();
- void setUsed(QueueElement<T> *queueElement);
- QueueElement<T> *getUsed();
- void releaseUsed(QueueElement<T> *queueElement);
-};
-
-miscTest/queueTest.cpp provides an example of how to define a queue.
- -The queue methods are:
-A queue is created as follows:
- class MyClass;
- typedef MyQueueElement<MyClass> MyElement;
- typedef MyQueue<MyClass> MyQueue;
- int numElement = 5;
- ...
- MyClass *array[numElements];
- for(int i=0; i<numElements; i++) {
- array[i] = new MyClass();
- }
- MyQueue *queue = new MyQueue(array,numElements);
-
-A producer calls getFree and setUsed via code like the following:
- MyClass *getFree() {
- MyElement *element = queue->getFree();
- if(element==0) return 0;
- return element->getObject();
- }
-
-A consumer calls getUsed and releaseUsed via code like the following:
- while(true) {
- MyElement *element = queue->getUsed();
- if(element==0) break;
- MyClass *myClass = element->getObject();
- // do something with myClass
- queue->releaseUsed(element);
- }
-The following is also provided:
class BitSetUtil : private NoDefaultMethods {
@@ -3998,8 +3583,7 @@ public:
This provides functions that operate on a BitSet for a PVStructure. It
currently has only one method:
MultiChoice defines an array of strings and a bit set that selects an -arbitrary set of the choices. This will be implemented if the java version is -accepted.
-NOT DONE+