From 665092df5aad09ef55645cd3865b016d85f632be Mon Sep 17 00:00:00 2001
From: Marty Kraimer TODO This product is available via the open source
license described at the end of this document. pvData is one of a set of related projects: 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: 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
@@ -266,7 +475,7 @@ pvDataApp: This section describes a meta language for describing pvData. Currently
@@ -274,7 +483,7 @@ there are no plans for a parser for the meta language. It is used for
documentation. Also the toString introspection and data methods described below
present data in this format. 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
Define the following top level structure: Directory pvDataApp/pv has header files that completely describe pvData. The
implementation is provided in directory pvDataApp/factory. Test programs
@@ -459,7 +667,7 @@ converting and copying data between fields. This provides C/C++ definitions for the pvData primitive types: boolean,
byte, short, int, long, float, double, and string. Because pvData is network
@@ -517,7 +725,7 @@ typedef std::string * StringBuilder;
This subsection describes pvIntrospect.hEPICS pvDataCPP
+2011.02.18
-2011.01.31
@@ -25,150 +23,361 @@
-
-
-
+
+
+
-
-
-
-
-
-
-
-Introduction
+Preface
+
+
+pvData
+
+Introspection
+
+
+
+
+
+
+ Data
+
+
+
+
+Property Structures
+
+
+
+
+pvAccess
+
+
+
+
+
+
+
+
+ Multiple small objects are automatically combined into a single network
+ packet.
+ Large objects automatically span network packets.pvIOC
+
+
+
+
+
+
+
+
+Introduction
+
+
-PVData Meta Language
+PVData Meta Language
Definition
+Definition
structure[] fieldName
structureDef
...
-
Thus a structure array is an array where each element is a structure but
all elements have the same introspection interface. For introspection the
@@ -385,7 +593,7 @@ 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.Example
+Example
structure timeStamp
@@ -422,10 +630,10 @@ structure[] structureArrayExample
double y 10.0
-PV - User Description
+PV - User Description
-Overview
+Overview
pvType
+pvType
Process Variable Reflection
+Process Variable Reflection
Types are defined as:
enum Type {
@@ -623,7 +831,7 @@ style="font-family: courier;">ScalarType
This section describes the reflection interfaces which provide the following:
@@ -852,7 +1060,7 @@ methods: structure->incReferenceCount() must be called before this method. -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 @@ -990,12 +1198,12 @@ extern StandardField * getStandardField(); the section on Properties for a description of how these are defined. -
This section defines the Java Interfaces for accessing the data within a PV record.
-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 @@ -1102,7 +1310,7 @@ are:
. -AuxInfo (Auxillary Information) is information about a field that is application specific. It will not be available outside the application that @@ -1139,7 +1347,7 @@ private:
class PVScalar : public PVField {
public:
virtual ~PVScalar();
@@ -1148,7 +1356,7 @@ protected:
PVScalar(PVStructure *parent,ScalarConstPtr scalar);
};
-The interfaces for primitive data types are:
class PVBoolean : public PVScalar {
@@ -1237,7 +1445,7 @@ protected:
private:
};
-PVArray is the base interface for all the other PV Array interfaces. It extends PVField and provides the @@ -1283,7 +1491,7 @@ private:
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:
@@ -1370,7 +1578,7 @@ 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. -class PVScalarArray : public PVArray {
public:
virtual ~PVScalarArray();
@@ -1547,7 +1755,7 @@ protected:
private:
};
-The interface for a structure is:
class PVStructure : public PVField,public BitSetSerializable {
@@ -1660,7 +1868,7 @@ private:
The interface for an array of structures is:
class StructureArrayData {
@@ -1733,7 +1941,7 @@ introspection interface must be used. The following shows an example:
Note that incReferenceCount is called before each element is created.
-PVDataCreate
+PVDataCreate
PVDataCreate is an interface that provides methods that create PVField
interfaces. A factory is provided that creates PVDataCreate.
@@ -1815,7 +2023,7 @@ extern PVDataCreate * getPVDataCreate();
before calling this method.
-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 @@ -1870,7 +2078,7 @@ public: PVStructure * powerSupply(PVStructure *parent); }; -
NOTE about copying immutable array fields. If an entire immutable array field is copied to another array that has the same elementType, both offsets @@ -1984,18 +2192,18 @@ 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 {
// ...
}}
-As described above pvType.h provides C++ typdefs for the pvData primitive types.
@@ -2047,9 +2255,9 @@ typedef String * StringArray;Any class that does not want the compiler to generate default methods can privately extend the following class which is defined in file @@ -2065,7 +2273,7 @@ private: NoDefaultMethods & operator=(const NoDefaultMethods &); }; -
Introspection objects are meant to be shared. The constructors and destructors are all private or protected so that an introspection object can @@ -2085,7 +2293,7 @@ field is a structure then it is a recursive call. When the reference count for a field becomes 0 the field is deleted. Note than user code should never call decReferenceCount since the destructor for PVField calls it.
-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 @@ -2098,7 +2306,7 @@ 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 @@ -2109,10 +2317,10 @@ 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:
Example of creating a scalar field.
PVDataCreate *pvDataCreate = getPVDataCreate();
@@ -2170,10 +2378,10 @@ and a timeStamp and alarm. Do it the easy way.
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 @@ -2213,7 +2421,7 @@ structure powerSupplySimple powerSupplyValueStructure power powerSupplyValueStructure current -
The following field names have special meaning, i.e. support properties for general purpose clients.
@@ -2281,7 +2489,7 @@ examples are: 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 @@ -2310,7 +2518,7 @@ stack. For example the following is permitted:
... } -A timeStamp is represented by the following structure
structure timeStamp @@ -2336,7 +2544,7 @@ 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 -timeStamp.h
+timeStamp.h
This provides
extern int32 milliSecPerSec; @@ -2438,7 +2646,7 @@ execute. This is done as follows: endTime.getCurrent(); double time = TimeStamp::diff(endTime,startTime);-pvTimeStamp.h
+pvTimeStamp.h
class PVTimeStamp { public: PVTimeStamp(); @@ -2477,7 +2685,7 @@ public: thrown if not attached to a pvData structure.
An alarm structure is defined as follows:
structure alarm @@ -2499,7 +2707,7 @@ style="font-family: courier;">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 -alarm.h
+alarm.h
enum AlarmSeverity { noAlarm,minorAlarm,majorAlarm,invalidAlarm }; @@ -2545,7 +2753,7 @@ public:
class PVAlarm {
public:
PVAlarm() : pvSeverity(0),pvMessage(0) {}
@@ -2585,7 +2793,7 @@ public:
if not attached to a pvData structure.
-control
+control
Control information is represented by the following structure
structure control
@@ -2603,7 +2811,7 @@ attached to a time stamp pvData structure. It provides get and set methods to
get/set a Control as defined by control.h
-control.h
+control.h
class Control {
public:
Control();
@@ -2628,7 +2836,7 @@ public:
class PVControl {
public:
PVControl();
@@ -2668,7 +2876,7 @@ public:
thrown if not attached to a pvData structure.
-display
+display
Display information is represented by the following structure
structure display
@@ -2689,7 +2897,7 @@ 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
-display.h
+display.h
class Display {
public:
Display();
@@ -2732,7 +2940,7 @@ public:
class PVDisplay {
public:
PVDisplay()
@@ -2772,7 +2980,7 @@ public:
thrown if not attached to a pvData structure.
-pvEnumerated
+pvEnumerated
An enumerated structure is a structure that has fields:
structure
@@ -2839,7 +3047,7 @@ public:
-PVData Factories
+PVData Factories
Directory factory has code that implements everything described by the files
@@ -2874,10 +3082,10 @@ the other classes described in pvData.cpp. Each is included and used by
PVDataCreate.
-Miscellanous Classes
+Miscellanous Classes
-Overview
+Overview
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*/ {
@@ -3019,7 +3227,7 @@ private:
A ByteBuffer is used to serialize and deserialize primitive data. File byteBuffer.h is:
@@ -3059,7 +3267,7 @@ private:x
-This class provides coordinates activity between threads. One thread can wait for the event and the other signals the event.
@@ -3091,7 +3299,7 @@ private:File epicsException.h describes:
class BaseException : public std::exception {
@@ -3109,7 +3317,7 @@ private:
x
-Executor
+Executor
An Executor is a thread that can execute commands. The user can request that
a single command be executed.
@@ -3148,7 +3356,7 @@ execute.
nothing is done.
-Linked List
+Linked List
LinkedList implements a double linked list that requires a user to allocate
the nodes. It is more efficent that std::list. linkedList.h is a template that
@@ -3166,34 +3374,33 @@ class LinkedList;
template <typename T>
class LinkedListNode : private LinkedListVoidNode {
public:
- LinkedListNode(T *object);
- ~LinkedListNode();
- T *getObject();
- bool isOnList();
+ 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();
- ~LinkedList();
+ LinkedList() : LinkedListVoid() {}
+ ~LinkedList() {}
int getLength();
- void addTail(LinkedListNode<T> *node);
- void addHead(LinkedListNode<T> *node);
- void insertAfter(LinkedListNode<T> *node,
- LinkedListNode<T> *addNode);
- void insertBefore(LinkedListNode<T> *node,
- LinkedListNode<T> *addNode);
+ 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);
- void remove(T *object);
+ void remove(LinkedListNode<T> &listNode);
LinkedListNode<T> *getHead();
LinkedListNode<T> *getTail();
- LinkedListNode<T> *getNext(LinkedListNode<T> *node);
- LinkedListNode<T> *getPrev(LinkedListNode<T> *node;
+ LinkedListNode<T> *getNext(LinkedListNode<T> &listNode);
+ LinkedListNode<T> *getPrev(LinkedListNode<T> &listNode);
bool isEmpty();
- bool contains(T *object);
-};
+};
+
LinkedListNode has the methods:
lock.h is:
class Mutex {
public:
- Mutex() : id(epicsMutexMustCreate()){}
- ~Mutex() { epicsMutexDestroy(id) ;}
- void lock(){epicsMutexMustLock(id);}
- void unlock(){epicsMutexUnlock(id);}
-private:
- epicsMutexId id;
+ Mutex();
+ ~Mutex();
+ void lock();
+ void unlock();
};
class Lock : private NoDefaultMethods {
public:
- explicit Lock(Mutex *pm)
- : mutexPtr(pm)
- {mutexPtr->lock();}
- ~Lock(){mutexPtr->unlock();}
-private:
- Mutex *mutexPtr;
+ explicit Lock(Mutex &pm);
+ ~Lock();
+ void lock();
+ void unlock();
+ bool ownsLock() ;
};
-This is a complete description and definition of lock and mutex. These make -it easy to have a lock that is as easy to use as Java synchronize. To protect -some object just create a Mutex for the object and then in any method to be -synchronized just have code like:
+Lock is as easy to use as Java synchronize. To protect some object just +create a Mutex for the object and then in any method to be synchronized just +have code like:
class SomeClass {
private
Mutex mutex;
@@ -3289,7 +3492,7 @@ public
...
void method()
{
- Lock xx(&mutex);
+ Lock xx(mutex);
...
}
@@ -3300,14 +3503,14 @@ the current code block completes.
once. This can be implemented as follows:
static void init(void) {
static Mutex mutex;
- Lock xx(&mutex);
+ Lock xx(mutex);
if(alreadyInitialized) return;
// initialization
}
-class MessageNode {
public:
String getMessage() const;
@@ -3328,7 +3531,7 @@ public:
int getClearOverrun();
};
-This is for use by code that wants to handle messages without blocking higher priority threads.
@@ -3369,7 +3572,7 @@ higher priority threads.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 @@ -3388,7 +3591,7 @@ assignment contructor.
NoDefaultMethods & operator=(const NoDefaultMethods &); }; -A PVField extends Requester. Requester is present so that when database errors are found there is someplace to send a message.
@@ -3418,7 +3621,7 @@ public:This is a helper class for serialization, which is required for sending and receiving pvData over the nerwork.
@@ -3489,81 +3692,74 @@ properly implemented.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.
-typedef int64 (*getTotal)();
-
-class ConstructDestructCallback : private NoDefaultMethods {
-public:
- String getConstructName();
- int64 getTotalConstruct();
- int64 getTotalDestruct();
- int64 getTotalReferenceCount();
-private:
+struct CDRCount {
+ size_t cons, dtys;
+ long refs;
};
-class ShowConstructDestruct : private NoDefaultMethods {
+class CDRMonitor : private NoDefaultMethods {
public:
- static void registerCallback(
- String name,
- getTotalFunc construct,
- getTotalFunc destruct,
- getTotalFunc reference,
- deleteStaticFunc deleteFunc);
- ConstructDestructCallback* getConstructDestructCallback(String name);
- void constuctDestructTotals(FILE *fd);
- static void showDeleteStaticExit(FILE *fd);
-private:
+ 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&);
};
-extern ShowConstructDestruct* getShowConstructDestruct();
+static inline CDRNode* getNode(CDRNodeInstance *inst);
+
-ConstructDestructCallback is implemented by ShowConstructDestruct. MARTY -EDIT how many instances of the class has been created and how many destroyed. -The clas must implement this class and register it with ShowConstructDestruct. -To see an example of how this is implemented look at misc/thread.cpp.
+The public methods of ConstructDestructCallback are:
-The public methods of ShowConstructDestruct are:
-Status provides a way to pass status back to client code. It is new and not -currently used by pvData but may be in the future. It is used by code that uses -pvData.
+Status provides a way to pass status back to client code:
+class Status : public epics::pvData::Serializable {
+ public:
+ enum StatusType {
+ /** Operation completed successfully. */
+ STATUSTYPE_OK,
+ /** Operation completed successfully, but there is a warning message. */
+ STATUSTYPE_WARNING,
+ /** Operation failed due to an error. */
+ STATUSTYPE_ERROR,
+ /** Operation failed due to an unexpected error. */
+ STATUSTYPE_FATAL
+ };
+ static const char* StatusTypeName[];
+ static Status OK;
+ Status();
+ Status(StatusType type, epics::pvData::String message);
+ Status(StatusType type, epics::pvData::String message, epics::pvData::String stackDump);
+ ~Status()
+ StatusType getType() const;
+ String getMessage() const;
+ String getStackDump() const;
+ bool isOK() const;
+ bool isSuccess() const;
+ String toString() const;
+ void toString(StringBuilder buffer, int indentLevel = 0) const;
+ void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
+ void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
+};
+
The Status methods are:
enum ThreadPriority {
lowestPriority,
lowerPriority,
@@ -3608,7 +3804,7 @@ public:
static int getEpicsPriority(ThreadPriority threadPriority);
};
-class Runnable {
public:
virtual void run() = 0;
@@ -3655,7 +3851,7 @@ exception is thrown if run remains active when delete is called.
TimeFunction is a facility that measures the average number of seconds a function call requires. When timeCall is called, it calls function in a loop. @@ -3697,7 +3893,7 @@ long a function takes. It has the single method:
one second to call it ntimes. -This provides a general purpose timer. It allows a user callback to be called after a delay or periodically.
@@ -3720,8 +3916,8 @@ class Timer : private NoDefaultMethods { public: Timer(String threadName, ThreadPriority priority); ~Timer(); - void scheduleAfterDelay(TimerNode *timerNode,double delay); - void schedulePeriodic(TimerNode *timerNode,double delay,double period); + void scheduleAfterDelay(TimerNode &timerNode,double delay); + void schedulePeriodic(TimerNode &timerNode,double delay,double period); private: }; @@ -3772,7 +3968,7 @@ be used to schedule multiple callbacks. It 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 @@ -3853,11 +4049,10 @@ public: queue->releaseUsed(element); }
The following is also provided:
class BitSetUtil : private NoDefaultMethods {
@@ -3886,7 +4081,7 @@ currently has only one method:
entire structures if the structure offset bit is set.
-MultiChoice
+MultiChoice
MultiChoice defines an array of strings and a bit set that selects an
arbitrary set of the choices. This will be implemented if the java version is
@@ -3894,7 +4089,7 @@ accepted.
NOT DONE
-License Agreement
+License Agreement
Copyright (c) 2008 Martin R. Kraimer
Copyright (c) 2007 Control System Laboratory,