From 358923d0641e50c5d0e417d3b638d5cfde4e6cde Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Thu, 2 Dec 2010 15:28:09 -0500 Subject: [PATCH] started on documentation and changes to misc as a result --- documentation/pvDataCpp.html | 3358 ++++++++++++++++++++++ pvDataApp/misc/Makefile | 1 + pvDataApp/misc/bitSet.h | 4 - pvDataApp/misc/event.cpp | 13 +- pvDataApp/misc/event.h | 14 +- pvDataApp/misc/executor.cpp | 56 +- pvDataApp/misc/executor.h | 10 +- pvDataApp/misc/linkedList.h | 33 +- pvDataApp/misc/linkedListVoid.cpp | 28 +- pvDataApp/misc/linkedListVoid.h | 1 + pvDataApp/misc/lock.h | 36 +- pvDataApp/misc/pvType.h | 18 +- pvDataApp/misc/requester.cpp | 20 + pvDataApp/misc/requester.h | 28 +- pvDataApp/misc/showConstructDestruct.cpp | 33 +- pvDataApp/misc/showConstructDestruct.h | 4 +- pvDataApp/misc/thread.cpp | 108 +- pvDataApp/misc/thread.h | 18 +- pvDataApp/misc/timeStamp.cpp | 46 +- pvDataApp/misc/timeStamp.h | 14 +- pvDataApp/misc/timer.cpp | 114 +- pvDataApp/misc/timer.h | 12 +- pvDataApp/miscTest/testLinkedList.cpp | 12 +- pvDataApp/miscTest/testThread.cpp | 12 +- pvDataApp/miscTest/testTimeStamp.cpp | 26 + pvDataApp/miscTest/testTimer.cpp | 16 +- pvDataApp/pv/MakefileBack | 15 - pvDataApp/pv/convert.h | 138 +- pvDataApp/pv/pvData.h | 942 +++--- pvDataApp/pv/pvIntrospect.h | 236 +- pvDataApp/pv/standardField.h | 100 +- pvDataApp/pv/standardPVField.h | 94 +- test/testIntrospect | 2 + test/testIntrospectGold | 2 + test/testLinkedListAux | 28 +- test/testPVAuxInfo | 2 + test/testPVAuxInfoGold | 2 + test/testPVData | 2 + test/testPVDataGold | 2 + test/testPVStructureArray | 2 + test/testPVStructureArrayGold | 2 + test/testThreadAux | 2 +- test/testTimeStampAux | 6 +- test/testTimer | 2 + test/testTimerAux | 12 +- test/testTimerGold | 2 + 46 files changed, 4515 insertions(+), 1113 deletions(-) create mode 100644 documentation/pvDataCpp.html create mode 100644 pvDataApp/misc/requester.cpp delete mode 100644 pvDataApp/pv/MakefileBack diff --git a/documentation/pvDataCpp.html b/documentation/pvDataCpp.html new file mode 100644 index 0000000..d35f143 --- /dev/null +++ b/documentation/pvDataCpp.html @@ -0,0 +1,3358 @@ + + + + + + EPICS pvDataCPP + + + +

EPICS pvDataCPP
+Overview
+2010.12.02

+ +

TODO

+ +CONTENTS +
+ +

Introduction

+
+ +

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

+ +

PVData is one of a set of related projects. It describes and implements +the data that the other projects support. Thus it is not useful by itself but +understanding pvData is required in order to understand the other projects. +The reader should also become familar with projects pvAccess and javaIOC, +which are located via the same sourceforge site as this project. Project +PVAccess provides network support for transporting pvData. Project javaIOC +provides a memory resident "smart" database of pvData data.

+ +

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

+ +

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

+
+
definition
+
The header files pvIntrospect.h and pvData.h provide the C++ + description of pvData.
+
implementation
+
Ditrectory factory provides a complete C++ definition for pvData. It + also proivides abstract and base classes that allow specialized + implementations of the data classes.
+
efficient
+
Small memory footprint, low cpu overhead, and concise code base.
+
data storage
+
pvData defines separate introspection and data interfaces. The + introspection interfaces provide access to immutable objects, which + allows introspection instances to be freely shared. The introspection + interface for a process variable can be accessed without requiring + access to the data.
+
data access
+
Client code can access pvData via the introspection and data + interfaces. For "well known" data, e.g. timeStamp, specialized + interfaces can be provided without requiring any changes to the core + software.
+
data transfer
+
The separation of introspection and data interfaces allows for + efficient network data transfer. At connection time introspection + information can be passed from server to client. Each side can create a + data instance. The data is transferred between these instances. The + data in the network buffers does not have to be self describing since + each side has the introspection information.
+
memory resident
+
pvData only defines memory resident data.
+
structured data
+
pvData has four types: scalar, scalar array, structure, and structure + array. A scalar can be one of the following: boolean, byte, short, int, + long, float, double, string. A scalar array is a one dimensional array + with the element type being a scalar. A structure is an ordered set of + fields where each field has a name and type. A structure array is a one + dimensional array of structures where each element has the same + introspection interface. Since a field can have type structure complex + structures are supported. No other types are needed since structures + can be defined that simulate types.
+
+ +

The javaIOC implements a Process Variable (PV) Database, which is a memory +resident database holding pvData, has 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:

+
+
misc
+
Support for pvData. This support is described in a major section + below.
+
pv
+
The C++ introspection and data descriptions for pvData.
+
factory
+
The C++ definitions for pvData.
+
property
+
Support code for "standard" pvData structures, e.g. timeStamp and + alarm.
+
+
+ +

Namespace, Typedefs, and Memory Management

+
+ +

Namespace

+ +

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

+
namespace epics { namespace pvData {
+     // ...
+}}
+ +

typedefs

+ +

Directory misc has an include file pvTypes.h:

+
typedef signed char int8;
+typedef short       int16;
+typedef int         int32;
+typedef long long   int64;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+
+typedef std::string String;
+typedef std::string * StringBuilder;
+typedef String* StringArray;
+ +

The integer typedefs provide the definitions for various sizes of integer +values. The relationship between these definitions and the ScalarType +description is:

+
+
pvBoolean
+
bool
+
pvByte
+
int8
+
pvShort
+
int16
+
pvInt
+
int32
+
pvLong
+
int64
+
pvString
+
String
+
+ +

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

+ +

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

+ +

The remaining definitions are:

+
+
StringBuilder
+
This acts like the java StringBuilder when is is passed as an + argument to a function.
+
StringArray
+
This is an array with each element being a String.
+
+ +

File pvInterspect.h, which is described in the next section has the +typedefs:

+
typedef Field const * FieldConstPtr;
+typedef FieldConstPtr * FieldConstPtrArray;
+typedef Scalar const * ScalarConstPtr;
+typedef ScalarArray const * ScalarArrayConstPtr;
+typedef Structure const * StructureConstPtr;
+typedef StructureArray const * StructureArrayConstPtr;
+ +

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

+ +

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

+
typedef std::map<String,PVScalar * > PVScalarMap;
+typedef PVScalarMap::const_iterator PVScalarMapIter;
+typedef PVStructure * PVStructurePtr;
+typedef PVStructurePtr* PVStructurePtrArray;
+typedef PVField* PVFieldPtr;
+typedef PVFieldPtr * PVFieldPtrArray;
+typedef bool * BooleanArray;
+typedef int8 * ByteArray;
+typedef int16 * ShortArray;
+typedef int32 * IntArray;
+typedef int64 * LongArray;
+typedef float * FloatArray;
+typedef double * DoubleArray;
+typedef String * StringArray;
+ +

where

+
+
PVScalarMap and PVScalarMapIter
+
A map and iterator that maps field names to PVScalars.
+
PVStructurePtr
+
A pointer to a PVStructure.
+
PVStructurePtrArray
+
A pointer to PVStructurePtr[], e. g. an array of pointers to a + PVStructure.
+
PVFieldPtr
+
A pointer to a PVField
+
PVFieldPtrArray
+
A pointer to a PVFieldPtr[], e. g. an array of pointers to a + PVField.
+
BooleanArray, ByteArray, ..., + StringArray
+
An array of the specified type NOT a pointer to the type.
+
+ +

Memory Managemment

+ +

NoDefaultMethods

+ +

Any class that does not allow 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 &);
+};
+ +

PVData introspection objects

+ +

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

+ +

PVData data objects

+ +

All PVData data objects must publically extend AbstractPVField, which does +not allow default methods but does have a virtual destructor. It is expected +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.

+ +

Other code in this project

+ +

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

+ +

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". These classes normally implement the static method:

+
    static ConstructDestructCallback *getConstructDestructCallback();
+ +

This provides access to how many objects have been constructed and +destructed. This can be used to monitor memory usage.

+

+
 
+
+ +

Miscellanous Classes

+
+ +

Overview

+ +

This package provides utility code:

+
+
bitSet.h
+
An implementation of BitSet that can be serialized.
+
byteBuffer.h
+
Used to serialize objects.
+
event.h
+
Signal and wait for an event.
+
exception.h
+
Exception with stack trace.
+
executor.h
+
Provides a thread for executing commands.
+
linkedList.h
+
A double linked list facility that requires the user to allocate a + node. It is more efficient that std::list and does not require the + implementation to allocate storage for the nodes.
+
lock.h
+
Support for locking and unlocking.
+
messageQueue.h
+
Support for queuing messages to give to requesters.
+
noDefaultMethods.h
+
When privately extended prevents compiler from implementing default + methods.
+
pvType.h
+
Provides architecture independent definitions for integers and + String.
+
requester.h
+
Allows messages to be sent to a requester.
+
serialize.h
+
Support for serializing objects.
+
showConstructDestruct.h
+
Provides support monitoring memory usage for objects of a class.
+
status.h
+
A way to pass status information to a client.
+
thread.h
+
Provides thread support.
+
timeFunction.h
+
Time how long a function call requires.
+
timer.h
+
An implementation of Timer that does not require an object to be + created for each timer request.
+
timeStamp.h
+
Usefull methods for a timeStamp.
+
queue.h
+
A queue implementation that allows the latest queue element to + continue to be used when no free element is available.
+
+ +

BitSet

+ +

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

+
class BitSet /*: public Serializable*/ {
+public:
+    BitSet();
+    BitSet(uint32 nbits);
+    virtual ~BitSet();
+    void flip(uint32 bitIndex);
+    void set(uint32 bitIndex);
+    void clear(uint32 bitIndex);
+    void set(uint32 bitIndex, bool value);
+    bool get(uint32 bitIndex) const;
+    void clear();
+    int32 nextSetBit(uint32 fromIndex) const;
+    int32 nextClearBit(uint32 fromIndex) const;
+    bool isEmpty() const;
+    uint32 cardinality() const;
+    BitSet& operator&=(const BitSet& set);
+    BitSet& operator|=(const BitSet& set);
+    BitSet& operator^=(const BitSet& set);
+    BitSet& operator-=(const BitSet& set);
+    BitSet& operator=(const BitSet &set);
+    void or_and(const BitSet& set1, const BitSet& set2);
+    bool operator==(const BitSet &set) const;
+    bool operator!=(const BitSet &set) const;
+    void toString(StringBuilder buffer);
+    void toString(StringBuilder buffer, int indentLevel) const;
+private:
+};
+ +

where

+
+
BitSet()
+
Creates a bitSet of initial size 64 bits. All bits initially + false.
+
BitSet(uint32 nbits)
+
Creates a bitSet with the initial of the specified number of bits. + All bits initially false.
+
~BitSet()
+
Destructor.
+
flip(uint32 bitIndex)
+
Flip the specified bit.
+
set(uint32 bitIndex)
+
Set the specified bit true.
+
clear(uint32 bitIndex)
+
Set the specified bit false.
+
set(uint32 bitIndex, bool value)
+
Set the specified bit to value.
+
get(uint32 bitIndex)
+
Return the state of the specified bit.
+
clear()
+
Set all bits to false.
+
nextSetBit(uint32 fromIndex)
+
Get the index of the next true bit beginning with the specified + bit.
+
nextClearBit(uint32 fromIndex)
+
Get the index of the next false bit beginning with the specified + bit.
+
isEmpty()
+
Return (false,true) if (at least one bit true, all bits are + false)
+
cardinality()
+
Return the number of true bits.
+
operator&=(const BitSet& set)
+
Performs a logical and of this target bit set with the argument bit + set. This bit set is modified so that each bit in it has the value true + if and only if it both initially had the value true and the + corresponding bit in the bit set argument also had the value.
+
operator|=(const BitSet& set)
+
Performs a logical or of this target bit set with the argument bit + set.
+
operator^=(const BitSet& set)
+
Performs a logical exclusive or of this target bit set with the + argument bit set.
+
operator-=(const BitSet& set)
+

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

+
+
operator=(const BitSet &set)
+
Assignment operator.
+
or_and(const BitSet& set1, const + BitSet& set2)
+
Perform AND operation on set1 and set2, and then OR this bitSet with + the result.
+
operator==(const BitSet &set)
+
Does this bitSet have the same values as the argument.
+
operator!=(const BitSet &set)
+
Is this bitSet different than the argument.
+
toString(StringBuilder buffer)
+
Show the current values of the bitSet.
+
toString(StringBuilder buffer, int + indentLevel)
+
Show the current values of the bitSet.
+
+ +

ByteBuffer

+ +

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();
+    ByteBuffer* clear();
+    ByteBuffer* flip();
+    ByteBuffer* rewind();
+    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:
+};
+ +

x

+ +

Event

+ +

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

+
class Event : private NoDefaultMethods {
+public:
+    Event(bool full);
+    ~Event();
+    static ConstructDestructCallback *getConstructDestructCallback();
+    void signal();
+    bool wait (); /* blocks until full */
+    bool wait ( double timeOut ); /* false if empty at time out */
+    bool tryWait (); /* false if empty */
+private:
+    epicsEventId id;
+};
+ +

where

+
+
Event
+
The constructor. The initial value can be full or empty. The normal + first state is empty.
+
getConstructDestructCallback
+
Provides access to number of events that have been created and + destroyed.
+
signal
+
The event becomes full. The current or next wait will complete.
+
wait
+
Wait until event is full or until timeout. The return value is + (false,true) if the wait completed because event (was not, was) full. A + false value normally means that that a timeout occured. It is also + returned if an error occurs or because the event is being deleted.
+
tryWait
+
returns (false,true) if the event is (empty,full)
+
+ +

Exception

+ +

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

+ +

Executor

+ +

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

+
class ExecutorNode;
+
+class Command {
+public:
+    virtual void command() = 0;
+};
+
+class Executor : private NoDefaultMethods {
+public:
+    Executor(String threadName,ThreadPriority priority);
+    ~Executor();
+    static ConstructDestructCallback *getConstructDestructCallback();
+    ExecutorNode * createNode(Command *command);
+    void execute(ExecutorNode *node);
+private:
+    class ExecutorPvt *pImpl;
+};
+ +

Command is a class that must be implemented by the code that calls +execute. It contains the single virtual method command, which is the command +to execute.

+ +

Executor has the methods:

+
+
Executor
+
The constructor. A thread name and priority must be specified.
+
~Executor
+
The destructor. If any commands remain in the execute list they are + not called. All ExecutorNodes that have been created are deleted.
+
getConstructDestructCallback
+
Provides access to the number of executors that been created and + destroyed.
+
createNode
+
Create a ExecutorNode that can be passed to execute.
+
execute
+
Request that command be executed. If it is already on the run list + nothing is done.
+
+ +

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 +template that is both a complete description and definition. It uses +linkedListVoid for method definitions. linkedListVoid is not\ meant for use +except via linkedList. Note, however, that linkedListVoid does have both a +node and a list static method getConstructDestructCallback, which allows +access to how many nodes and lists have been created and destroyed.

+ +

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);
+    ~LinkedListNode();
+    T *getObject();
+    bool isOnList();
+};
+template <typename T>
+class LinkedList : private LinkedListVoid {
+public:
+    LinkedList();
+    ~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);
+    LinkedListNode<T> *removeTail();
+    LinkedListNode<T> *removeHead();
+    void remove(LinkedListNode<T> *listNode);
+    void remove(T *object);
+    LinkedListNode<T> *getHead();
+    LinkedListNode<T> *getTail();
+    LinkedListNode<T> *getNext(LinkedListNode<T> *node);
+    LinkedListNode<T> *getPrev(LinkedListNode<T> *node;
+    bool isEmpty();
+    bool contains(T *object);
+};
+ +

LinkedListNode has the methods:

+
+
LinkedListNode
+
The constructor. The object must be specified.
+
~LinkedListNode
+
The destructor.
+
getObject
+
Returns the nobject.
+
isOnList
+
returns (false,true) if the node (is not, is) on a list.
+
+ +

LinkedList has the methods:

+
+
LinkedList
+
The constructor.
+
~LinkedList
+
The destructor.
+
getLength
+
Get the numbet of nodes currently on the list.
+
addTail
+
Add a node to the end of the list. An exception is thrown if the node + is already on a list.
+
addHead
+
Add a node to the beginning of the list. An exception is thrown if + the node is already on a list.
+
insertAfter
+
Insert addNode after node. An exception is thrown if the addNode is + already on a list or if node is not on this list..
+
insertBefore
+
Insert addNode before node. An exception is thrown if the addNode is + already on a list or if node is not on this list.
+
removeTail
+
Remove and return the last node. Null is returned if the list is + empty.
+
removeHead
+
Remove and return the first node. Null is returned if the list is + empty.
+
remove
+
Remove the specified node or object. An exception is thrown if the + node is not on a list.
+
getHead
+
Get the first list node. Null is returned if the list is empty.
+
getTail
+
Get the last list node. Null is returned if the list is empty.
+
getNext
+
Get the node after node. An exception is thrown if node is not on + this list. Null is returned if the is node is the last node on the + list.
+
getPrev
+
Get the node before node. An exception is thrown if node is not on + this list. Null is returned if the is node is the first node on the + list.
+
isEmpty
+
Is the list empty.
+
contains
+
Does the list contain the specified object.
+
+ +

Lock and Mutex

+ +

lock.h contains:

+
class Mutex  {
+public:
+    Mutex();
+    ~Mutex();
+    void lock();
+    void unlock();
+private:
+};
+
+
+class Lock : private NoDefaultMethods {
+public:
+    explicit Lock(Mutex *pm);
+    ~Lock();
+private:
+};
+ +

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:

+
class SomeClass {
+private
+    Mutex mutex;
+...
+public
+    SomeClass() : mutex(Mutex()) {}
+...
+    void method()
+    {
+        Lock xx(&mutex);
+        ...
+    }
+ +

The method will take the lock when xx is created and release the lock when +the current code block completes.

+ +

Another example of Lock is initialization code that must initialize only +once. This can be implemented as follows:

+
    static void init(void) {
+        static Mutex mutex = Mutex();
+        Lock xx(&mutex);
+        if(alreadyInitialized) return;
+        // initialization
+    }
+ +

Message Queue

+ +

Definitions

+
NOT IMPLEMENTED
+ +

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:

+
+
message
+
The message.
+
messageType
+
The message type.
+
+ +

A messageQueue is an interface with methods:

+
+
put
+
Put a new message into the queue. False is returned if the queue was + full and true otherwise.
+
isEmpty
+
Is the queue empty?
+
isFull
+
Is the queue full?
+
replaceFirst
+
Replace the oldest member in the queue.
+
replaceLast
+
Replace the newest member in the queue.
+
getClearOverrun
+
Get the number of times replaceFirst or replaceLast have been called + since the last call to getClearOverrun. The internal counter is reset + to 0.
+
+ +

MessageQueueFactory provides the public method:

+
+
create
+
Create a MessageQueue and return the interface.
+
+ +

An example is:

+
    private ExecutorNode executorNode;
+    ...
+      executorNode = executor.createNode(this);
+    ...
+
+    public void message(final String message, MessageType messageType) {
+        boolean execute = false;
+        synchronized(messageQueue) {
+            if(messageQueue.isEmpty()) execute = true;
+            if(messageQueue.isFull()) {
+                messageQueue.replaceLast(message, messageType);
+            } else {
+                messageQueue.put(message, messageType);
+            }
+        }
+        if(syncExec) {
+            iocExecutor.execute(executorNode);
+        }
+    }
+    ...
+    public run() { // handle messages
+        while(true) {
+            String message = null;
+            int numOverrun = 0;
+            synchronized(messageQueue) {
+                MessageNode messageNode = messageQueue.get();
+                numOverrun = messageQueue.getClearOverrun();
+                if(messageNode==null && numOverrun==0) break;
+                message = messageNode.message;
+            }
+            if(numOverrun>0) {
+                System.out.printf(String.format("%n%d missed messages&n", numOverrun));
+            }
+            if(message!=null) {
+               System.out.printf(String.format("%s%n",message));
+            }
+        }
+    }
+ +

NoDefaultMethods

+ +

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

+
/* This is based on Item 6 of
+ * Effective C++, Third Edition, Scott Meyers
+ */
+    class NoDefaultMethods {
+    protected:
+    // allow by derived objects
+    NoDefaultMethods(){};
+    ~NoDefaultMethods(){}
+    private:
+    // do not implment
+    NoDefaultMethods(const NoDefaultMethods&);
+    NoDefaultMethods & operator=(const NoDefaultMethods &);
+    };
+ +

pvType

+ +

This provides typedefs for integers and String.

+
typedef signed char int8;
+typedef short       int16;
+typedef int         int32;
+typedef long long   int64;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+
+typedef std::string String;
+typedef std::string * StringBuilder;
+typedef String* StringArray;
+ +

where

+
+
int8,...,int64
+
Hopefully all modern C++ compilers will support these definitions. If + not then only pvType.h will require changes rather than user code.
+
String
+
Since std::string implements copy on write semantics, it can be used + for support for immutable strings. This is what pvData supports.
+
StringBuilder
+
Acts like the Java StringBuilder class.
+
StringArray
+
An array of Strings.
+
+ +

Requester

+ +

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

+
enum MessageType {
+   infoMessage,warningMessage,errorMessage,fatalErrorMessage
+};
+
+extern StringArray messageTypeName;
+
+class Requester {
+public:
+    virtual String getRequesterName() = 0;
+    virtual void message(String message,MessageType messageType) = 0;
+};
+ +

where

+
+
+
MessageType
+
Type of message.
+
messageTypeName
+
An array of strings of the message type names, i.e. + String("info"),String("warning"),String("error"),String("fatalError").
+
getRequesterName
+
Returns the requester name.
+
message
+
Gives a message to the requester.
+
+ +

Serialize

+ +

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

+
class SerializeHelper : public NoDefaultMethods {
+public:
+    static void writeSize(int s, ByteBuffer* buffer,
+        SerializableControl* flusher);
+    static int readSize(ByteBuffer* buffer,
+        DeserializableControl* control);
+    static void serializeString(const String& value,
+        ByteBuffer* buffer,SerializableControl* flusher);
+    static void serializeSubstring(const String& value, int offset,
+        int count, ByteBuffer* buffer,
+        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

+
+
writeSize
+
Serialize the size.
+
readSize
+
Deserialize the size.
+
serializeString
+
Serialize a String.
+
serializeSubstring
+
Serialize a substring.
+
deserializeString
+
Deserialize a string.
+
+ +

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

x

+ +

Show Constructors and Destructors

+ +

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

+
typedef int64 (*getTotal)();
+
+class ConstructDestructCallback : private NoDefaultMethods {
+public:
+    ConstructDestructCallback(
+        String name,
+        getTotal construct,
+        getTotal destruct,
+        getTotal reference);
+    String getConstructName();
+    int64 getTotalConstruct();
+    int64 getTotalDestruct();
+    int64 getTotalReferenceCount();
+private:
+    ~ConstructDestructCallback();
+    String name;
+    getTotal construct;
+    getTotal destruct;
+    getTotal reference;
+};
+
+class ShowConstructDestruct : private NoDefaultMethods {
+public:
+    static void constuctDestructTotals(FILE *fd);
+    static void registerCallback(ConstructDestructCallback *callback);
+private:
+    ShowConstructDestruct();
+    friend ShowConstructDestruct* getShowConstructDestruct();
+};
+
+extern ShowConstructDestruct* getShowConstructDestruct();
+ +

ConstructDestructCallback is implemented by a class that keeps track of +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.

+ +

Classes that implement this class also include a static method that makes +ConstructDestructCallback available to code that wants look at the memory +usage of a particular class.

+ +

ShowConstructDestruct is the class that reports the memory uasge of all +registered classes. It can be called as folows:

+
   getShowConstructDestruct()->constuctDestructTotals(fd);
+ +

Status

+ +

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

+
NOT IMPLEMENTED
+ +

The Status methods are:

+
+
StatusType
+
An enum for the status type.
+
getType
+
Get the statusType.
+
getMessage
+
Get a message explaining the error.
+
getStackDump
+
Get a stack dump.
+
+ +

The StatusCreate methods are:

+
+
getStatusOK
+
Get a singleton that returns StatusType.OK and a null message and + stackDump.
+
createStatus
+
Create a new Status.
+
deserializeStatus
+
Use this method instead of Status.deserialize(), since this allows OK + status optimization.
+
+ +

Thread

+ +

ThreadPriority

+
enum ThreadPriority {
+    lowestPriority,
+    lowerPriority,
+    lowPriority,
+    middlePriority,
+    highPriority,
+    higherPriority,
+    highestPriority
+};
+
+class ThreadPriorityFunc {
+public:
+    static unsigned int const * const getEpicsPriorities();
+    static int getEpicsPriority(ThreadPriority threadPriority);
+};
+ +

Thread

+
class Runnable {
+public:
+    virtual void run() = 0;
+};
+
+class Thread;
+
+class Thread :  private NoDefaultMethods {
+public:
+    Thread(String name,ThreadPriority priority,Runnable *runnableReady);
+    ~Thread();
+    static ConstructDestructCallback *getConstructDestructCallback();
+    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 one virtual method: run. Run is the code that is run as a thread. When +run compeletes it can not be restarted. If code wants to delete a thread then +it MUST arrange that the run returns before the thread can be deleted. An +exception is thrown if run remains active when delete is called.

+ +

Thread has the methods:

+
+
Thread
+
The constructor. A thread name and priority must be specified. The + run methods of runnable is executed. When the run methods returns the + thread will no longer be active but the client code must still delete + the thread.
+
~Thread
+
The destructor. This is called as the result of: +
    delete pthread;
+
+
getConstructDestructCallback
+
Provides access to the number of threads that been created and + destroyed.
+
getName
+
Get the thread name.
+
getPriority
+
Get the thread priority.
+
showThreads
+
Get a String that has the name and priority of all currently + allocated threads.
+
sleep
+
Make the current thread sleep for the specified number of + seconds.
+
+ +

Time Function Call

+ +

TimeFunction is a facility that measures the average number of seconds a +function call requires. When timeCall is called, it calls function in a loop. +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:
+    virtual void function() = 0;
+};
+
+class TimeFunction : private NoDefaultMethods {
+public:
+    TimeFunction(TimeFunctionRequester *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:

+
+
function
+
This is the function.
+
+ +

TimeFunction has the methods:

+
+
TimeFunction
+
Constructor.
+
~TimeFunction
+
Destructor.
+
timeCall
+
Time how long it takes to execute the function. It starts by calling + the function one time. If it takes < 1 seconds to doubles the number + of times to call the function. It repeats this until it takes at least + one second to call it ntimes.
+
+ +

Timer

+ +

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

+
class TimerCallback {
+public:
+    virtual void callback() = 0;
+    virtual void timerStopped() = 0;
+};
+
+class TimerNode : private NoDefaultMethods {
+public:
+    TimerNode(TimerCallback *timerCallback);
+    ~TimerNode();
+    static ConstructDestructCallback *getConstructDestructCallback();
+    void cancel();
+    bool isScheduled();
+private:
+};
+
+class Timer : private NoDefaultMethods {
+public:
+    Timer(String threadName, ThreadPriority priority);
+    ~Timer();
+    static ConstructDestructCallback *getConstructDestructCallback();
+    void scheduleAfterDelay(TimerNode *timerNode,double delay);
+    void schedulePeriodic(TimerNode *timerNode,double delay,double period);
+private:
+};
+ +

TimerCallback must be implemented by the user. It has the following +methods:

+
+
callback
+
This is called when a timer expires. This is called with no locks + held. When called a delay timer is no longer on the queue but a + periodioc timer is on a queue. Thus the callback for a delay timer can + issue a new schedule request but a periodic timer must not. Note the + explaination of TimerNode.cancel below.
+
timerStopped
+
Timer.stop was called when a timer request was queued. or if the + timer is stopped and a schedule request is made.
+
+ +

In order to schedule a callback client code must allocate a TimerNode It +can be used to schedule multiple callbacks. It has the methods:

+
+
TimerNode
+
The constructor. User code must create a TimeNode in order to call a + schedule method.
+
~TimerNode
+
The destructor. This is called as a result of the client calling: +
    delete timerNode;
+
+
getConstructDestructCallback
+
Provides access to the number of timerNodes that been created and + destroyed.
+
cancel
+
This is called to cancel a timer request. If a callback has been + dequeued but the callback not called when cancel is called then a + callback may still happen. New schedule requests can be made after a + cancel request has been made.
+
isScheduled
+
Is the timerNode scheduled to be called.
+
+ +

Timer has the methods:

+
+
Timer
+
The consttructor.
+
~Timer
+
The destructor. The queue is emptied and TimerCallback.timerStopped + is called for each element of the queue.
+
getConstructDestructCallback
+
Provides access to the number of timers that been created and + destroyed.
+
scheduleAfterDelay
+
A request to schedule a callback after a delay specified in + seconds.
+
schedulePeriodic
+
Schedule a periodic callback.
+
+ +

TimeStamp

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

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

TimeStamp is described as:

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

TimeStamp has the methods:

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

prints something like:

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

Queue

+ +

This provides a queue which has an immutable capacity, which is specified +when the queue is created. When the queue is full the user code is expected +to keep using the current el;ement until a new free element becomes avalable. +This is used by pvData.monitor.

+
NOT IMPLEMENTED
+ +

A queueCreate instance is created via a call like the following:

+
 QueueCreate<MyObject> queueCreate = new QueueCreate<MyObject>();
+ +

Once a queueCreate is available a queue instance is created via code like +the following:

+
Queue<MyObject> queue create(MyObject[] myObjects) {
+    QueueElement<MyObject>[] queueElements = new QueueElement[length];
+    for(int i=0; i<length; i++) {
+        QueueElement<MonitorElement> queueElement =
+                 queueCreate.createQueueElement(myObjects[i);
+        queueElements[i] = queueElement;
+    }
+    return queueCreate.create(queueElements);
+}
+ +

The queue methods are:

+
+
clear
+
Make the queue empty.
+
getNumberFree
+
Get the number of fee elements in the queue.
+
capacity
+
Get the capacity, i.e. the maximun number of elements the queue can + hold.
+
getFree
+
Get the next free element. Null is returned if no free elements are + available. If a non null value is returned then the element belongs to + the caller until setUsed is called.
+
setUsed
+
Set a queue element used. This must be the element returned by the + last call to getFree.
+
getUsed
+
Get the next used element of null if no more used elements are + available.
+
releaseUsed
+
Set a queue element free. This must be the element returned by the + last call to getUsed.
+
+ +

A producer calls getFree and setUsed via code like the following:

+
   MyObject getFree() {
+       QueueElement<MyObject> queueElement = queue.getFree();
+       if(queueElement==null) return null;
+       return queueElement.getObject();
+  }
+ +

A consumer calls getUsed and releaseUsed via code like the following:

+
     while(true) {
+         QueueElement<MyObject> queueElement = queue.getUsed();
+         if(queueElement==null) break;
+         MyObject myObject = queueElement.getObject();
+         // do something with myObject
+         queue.releaseUsed(queueElement);
+     }
+
+ +

PV - User Description

+
+ +

Overview

+ +

Directory pvDataApp/pv has header files that completely describe pvData. +The implementation is provided in directory pvDataApp/factory. Test programs +appears on pvDataApp/pvTest.

+ +

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.

+ +

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

+ +

Directory pvDataApp/pv has the following header files:

+
+
pvIntrospect.h
+
A cpmplete description of the introspection interfaces.
+
pvData.h
+
A complete description of the data interfaces.
+
convert.h
+
The facility that converts between data fields.
+
standardField.h
+
Provides access to introspection interfaces for standard field like + timeStamp, alarm, etc.
+
standardPVField.h
+
Cteates data interfaces for standard data fields like timeStamp, + alarm, etc.
+
+ +

Process Variable Reflection

+ +

This subsection describes pvIntrospect.h

+ +

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 client connects to a PV, the client library can +obtain the reflection information without obtaining any data. Only when a +client issues an I/O request will data be available. This separation is +especially important for arrays and structures so that a client can discover +the type without requiring that a large array or structure be transported +over the network.

+ +

Type

+ +

The types are defined by the Java definitions:

+
enum Type {
+    scalar,
+    scalarArray,
+    structure,
+    structureArray;
+};
+class TypeFunc {
+public:
+    static void toString(StringBuilder buf,const Type type);
+};
+
+
+enum ScalarType {
+    pvBoolean,
+    pvByte, pvShort, pvInt, pvLong,
+    pvFloat,pvDouble,
+    pvString;
+};
+class ScalarTypeFunc {
+public:
+    static bool isInteger(ScalarType type);
+    static bool isNumeric(ScalarType type);
+    static bool isPrimitive(ScalarType type);
+    static ScalarType getScalarType(String value);
+    static void toString(StringBuilder buf,ScalarType scalarType);
+};
+ +

Type is one of the +following:

+
+
scalar
+
A scalar of one of the scalar types.
+
scalarArray
+
An array where every element has the same scalar type.
+
structure
+
A structure where each field can have a dfferent type.
+
structureArray
+
An array where each element is a structure. Each element has the same + structure introspection interface.
+
+ +

ScalarType is one of the +following:

+
+
pvBoolean
+
Has the value false or true.
+
pvByte
+
A signed 8 bit integer.
+
pvShort
+
A signed 16 bit integer.
+
pvInt
+
A signed 32 bit integer.
+
pvLong
+
A signed 64 bit integer.
+
pvFloat
+
A IEEE float.
+
pvDouble
+
A IEEE double,
+
pvString
+
An immutable string.
+
+ +

TypeFunction is a set of +convenience methods for Type

+
+
toString
+
Convert the type to a string.
+
+ +

ScalarTypeFunction is a set of +convenience methods for ScalarType

+
+
isInteger
+
Is the scalarType an integer type, i.e. one of pvByte,...pvlong.
+
isNumeric
+
Is the scalarType numeric, i.e. pvByte,...,pvDouble.
+
isPrimitive
+
Is the scvalarType primitive, i.e. not pvString
+
getScalarType
+
Given a string of the form String("boolean"),...,String("string") + return the scalarType.
+
toString
+
Convert the scalar type to a string.
+
+ +

Reflection

+ +

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

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

The above definitions support the following:

+
+
Field
+
A field: +
+
Has a name.
+
Has a Type.
+
Can be converted to a string.
+
+
+
Scalar
+
A scalar has a scalarType
+
ScalarArray
+
The element type is a scalarType
+
StructureArray
+
The field holds PVStructure[]. Each element has the same Structure + interspection interface. A client can only get/put entire PVStructure + elements NOT subfields of array elements.
+
Structure
+
Has fields that can be any of the supported types.
+
FieldCreate
+
This is an interface that provides methods to create introspection + interfaces. A factory is provides to create FieldCreate.
+
getFieldCreate
+
Gets a pointer to the single instance of FieldCreate.
+
+ +

Standard Fields

+ +

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

+
    StructureConstPtr example = standardField->scalar(
+        String("value"),
+        pvDouble,
+        String("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
+ +

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

+ +

pvIntrospect.h contains:

+
class StandardField : private NoDefaultMethods {
+public:
+    StandardField();
+    ~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,
+        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,
+        StringArray choices);
+    StructureConstPtr enumerated(String fieldName,
+        StringArray choices, 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 alarm();
+    StructureConstPtr timeStamp();
+    StructureConstPtr display();
+    StructureConstPtr control();
+    StructureConstPtr booleanAlarm();
+    StructureConstPtr byteAlarm();
+    StructureConstPtr shortAlarm();
+    StructureConstPtr intAlarm();
+    StructureConstPtr longAlarm();
+    StructureConstPtr floatAlarm();
+    StructureConstPtr doubleAlarm();
+    StructureConstPtr enumeratedAlarm();
+private:
+    static void init();
+};
+
+extern StandardField * getStandardField();
+ +

Where

+
+
scalar
+
Create a scalar with the specified scalar type and name. If + properties are specified then a structure will be created with the + first element being a scalar with the specified scalar type and name + value. The other fields in the structure will be the corresponding + property structures.
+
scalarArray
+
Create a scalarArray with each element having the specified scalar + type and name. If properties are specified then a structure will be + created with the first element being a scalarArray with name value. The + other fields in the structure will be the corresponding property + structures.
+
structureArray
+
Create a structureArray with the specified structure interface and + name. If properties are specified then a structure will be created with + the first element being a structureArray with the specified structure + interface and name value. The other fields in the structure will be the + corresponding property structures.
+
structure
+
Create a structure with the specified name and fields specified by + numFields and fields. If properties are specified then a structure will + be created with the first element being a structure with the name value + and fields specified by numFields and fields. The other fields in the + structure will be the corresponding property structures.
+
enumerated
+
Create a structure with the specified name and fields for an + enumerated structure. If properties are specified then a structure will + be created with the first element being a structure with the name value + and fields for an enumerated structure. The other fields in the + structure will be the corresponding property structures.
+
scalarValue
+
scalarArrayValue
+
structureArrayValue
+
structureValue
+
enumeratedValue
+
These are all like the version without the "Value" suffix except that + the field name will always be "value"
+
alarm
+
timeStamp
+
display
+
control
+
booleanAlarm
+
byteAlarm
+
shortAlarm
+
intAlarm
+
longAlarm
+
floatAlarm
+
doubleAlarm
+
enumeratedAlarm
+
The above provide introspection interfaces fot standard properties. + See the section on Properties for a description of how these are + defined.
+
+ +

PVField - Data Interfaces

+ +

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

+ +

PVField

+ +

PVField is the base interface for accessing data. A data structure +consists of a top level PVStructure. Every field of every structure of every +top level structure has a PVField associated with it.

+
class PostHandler {
+public:
+    virtual void postPut() = 0;
+};
+
+
+class PVField
+: public Requester,
+  public Serializable,
+  private NoDefaultMethods
+{
+public:
+    virtual ~PVField();
+    static ConstructDestructCallback *getConstructDestructCallback();
+    virtual void setRequester(Requester *prequester);
+    int getFieldOffset() ;
+    int getNextFieldOffset() ;
+    int getNumberFields() ;
+    PVAuxInfo * getPVAuxInfo();
+    bool isImmutable() ;
+    void setImmutable();
+    FieldConstPtr getField() ;
+    PVStructure * getParent() ;
+    void replacePVField(PVField * newPVField);
+    void renameField(String  newName);
+    void postPut() ;
+    void setPostHandler(PostHandler *postHandler);
+    virtual void toString(StringBuilder buf) ;
+    virtual void toString(StringBuilder buf,int indentLevel) ;
+    virtual bool operator==(PVField &pv) = 0;
+    virtual bool operator!=(PVField &pv) = 0;
+protected:
+    PVField(PVStructure *parent,FieldConstPtr field);
+    void replaceStructure(PVStructure *pvStructure);
+private:
+};
+ +

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

+ +

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

+ +

The public methods for PVField +are:

+
+
~PVField
+
destructor which must be called by whatever created the PVfield via a + call to one of the methods of PVDataCreate
+
getConstructDestructCallback
+
Provides access to the number of timers that been created and + destroyed.
+
setRequester
+
Sets a requester to be called when message or getRequesterName are + called.
+
getFieldOffset
+
Get offset of the PVField field within top level structure. Every + field within the PVStructure has a unique offset. The top level + structure has an offset of 0. The first field within the structure has + offset equal to 1. The other offsets are determined by recursively + traversing each structure of the tree.
+
getNextFieldOffset
+
Get the next offset. If the field is a scalar or array field then + this is just offset + 1. If the field is a structure it is the offset + of the next field after this structure. Thus (nextOffset - offset) is + always equal to the total number of fields within the field.
+
getNumberFields
+
Get the total number of fields in this field. This is nextFieldOffset + - fieldOffset.
+
getPVAuxInfo
+
Get the PVAuxInfo for this field. PVAuxInfo is described below.
+
isImmutable
+
Is the field immutable?
+
setImmutable
+
Make the field immutable. Once a field is immutable it can never be + changed since there is no method to again make it mutable. This is an + important design decision since it allows immutable array fields to + share the internal primitive data array.
+
getField
+
Get the reflection interface for the data.
+
getParent
+
Get the interface for the parent or null if this is the top level + PVStructure.
+
replacePVField
+
Replace this PVField. This is called by support code that wants to + replace the default implementation of a data field with it's own + implementation.
+
renameField
+
Rename the field name.
+
postPut
+
If this field is a field of a record pvRecordField.postPut() is + called. If not a field of a record nothing happens.
+
toString
+
Converts the field data to a string. This is mostly for debugging + purposes.
+
+ +

PVAuxInfo

+ +

AuxInfo (Auxillary Information) is information about a field that is +application specific. It will not be available outside the application that +implements the database. In particular it will not be made available to +Channel Access. It is used by the database itself to override the default +implementation of fields. The JavaIOC uses it for attaching support code. +Database Configuration and other tools can use it for configuration +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:
+    PVAuxInfo(PVField *pvField);
+    ~PVAuxInfo();
+    static ConstructDestructCallback *getConstructDestructCallback();
+    PVField * getPVField();
+    PVScalar * createInfo(String key,ScalarType scalarType);
+    PVScalarMap getInfos();
+    PVScalar * getInfo(String key);
+    void toString(StringBuilder buf);
+    void toString(StringBuilder buf,int indentLevel);
+private:
+};
+ +

where

+
+
getPVField
+
Get the PVField to which this PVAuxInfo is attached.
+
createInfo
+
Create a new PVScalar of type scalarType.
+
getInfos
+
Get a map of all the auxInfos.
+
getInfo
+
Get the PVScalar with the specified key.
+
toString
+
Print all the auxInfos
+
+ +

PVScalar and extensions

+
class PVScalar : public PVField {
+public:
+    virtual ~PVScalar();
+    ScalarConstPtr getScalar() ;
+protected:
+    PVScalar(PVStructure *parent,ScalarConstPtr scalar);
+};
+ +
Primitive PVField types
+ +

The interfaces for primitive data types are:

+
class PVBoolean : public PVScalar {
+public:
+    virtual ~PVBoolean();
+    virtual bool get() = 0;
+    virtual void put(bool value) = 0;
+protected:
+    PVBoolean(PVStructure *parent,ScalarConstPtr scalar)
+    : PVScalar(parent,scalar) {}
+private:
+};
+
+class PVByte : public PVScalar {
+public:
+    virtual ~PVByte();
+    virtual int8 get() = 0;
+    virtual void put(int8 value) = 0;
+protected:
+    PVByte(PVStructure *parent,ScalarConstPtr scalar)
+    : PVScalar(parent,scalar) {}
+private:
+};
+
+class PVShort : public PVScalar {
+public:
+    virtual ~PVShort();
+    virtual int16 get() = 0;
+    virtual void put(int16 value) = 0;
+protected:
+    PVShort(PVStructure *parent,ScalarConstPtr scalar)
+    : PVScalar(parent,scalar) {}
+private:
+};
+class PVInt : public PVScalar{
+public:
+    virtual ~PVInt();
+    virtual int32 get() = 0;
+    virtual void put(int32 value) = 0;
+protected:
+    PVInt(PVStructure *parent,ScalarConstPtr scalar)
+    : PVScalar(parent,scalar) {}
+private:
+};
+
+class PVLong : public PVScalar {
+public:
+    virtual ~PVLong();
+    virtual int64 get() = 0;
+    virtual void put(int64 value) = 0;
+protected:
+    PVLong(PVStructure *parent,ScalarConstPtr scalar)
+    : PVScalar(parent,scalar) {}
+private:
+};
+
+class PVFloat : public PVScalar {
+public:
+    virtual ~PVFloat();
+    virtual float get() = 0;
+    virtual void put(float value) = 0;
+protected:
+    PVFloat(PVStructure *parent,ScalarConstPtr scalar)
+    : PVScalar(parent,scalar) {}
+private:
+};
+class PVDouble : public PVScalar {
+public:
+    virtual ~PVDouble();
+    virtual double get() = 0;
+    virtual void put(double value) = 0;
+protected:
+    PVDouble(PVStructure *parent,ScalarConstPtr scalar)
+    : PVScalar(parent,scalar) {}
+private:
+};
+
+class PVString : public PVScalar {
+public:
+    virtual ~PVString();
+    virtual String get() = 0;
+    virtual void put(String value) = 0;
+protected:
+    PVString(PVStructure *parent,ScalarConstPtr scalar)
+    : PVScalar(parent,scalar) {}
+private:
+};
+ +

PVArray and Extensions

+ +

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:
+    virtual ~PVArray();
+    int getLength() ;
+    void setLength(int length);
+    int getCapacity() ;
+    bool isCapacityMutable() ;
+    void setCapacityMutable(bool isMutable);
+    virtual void setCapacity(int capacity) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,
+        DeserializableControl *pflusher) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher, int offset, int count) = 0;
+protected:
+    PVArray(PVStructure *parent,FieldConstPtr field);
+    void setCapacityLength(int capacity,int length);
+private:
+    class PVArrayPvt * pImpl;
+};
+
+
getLength
+
Get the current length. This is less that or equal to the + capacity.
+
setLength
+
Set the length. If the PVField is not mutable then an exception is + thrown. If this is greater than the capacity setCapacity is called.
+
getCapacity
+
Get the capacity, i.e. this is the sized of the underlying data + array.
+
setCapacity
+
Set the capacity. The semantics are implementation dependent but + typical semantics are as follows: If the capacity is not mutable an + exception is thrown. A new data array is created and data is copied + from the old array to the new array.
+
isCapacityMutable
+
Is the capacity mutable
+
setCapacityMutable
+
Specify if the capacity can be changed.
+
+ +
PVArray Extensions
+ +

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

+
class DoubleArrayData {
+public:
+    DoubleArrayData(){}
+    ~DoubleArrayData(){};
+    DoubleArray data;
+    int offset;
+};
+
+class PVDoubleArray : public PVScalarArray {
+public:
+    virtual ~PVDoubleArray();
+    virtual void setCapacity(int capacity) = 0;
+    virtual int get(int offset, int length, DoubleArrayData *data) = 0;
+    virtual int put(int offset,int length, DoubleArray  from, int fromOffset) = 0;
+    virtual void shareData(DoubleArray value,int capacity,int length) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0;
+protected:
+    PVDoubleArray(PVStructure *parent,ScalarArrayConstPtr scalar);
+private:
+};
+ +

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 via a call to System.arraycopy without requiring an +intermediate array.

+ +

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

+
+
offset
+
The offset in the PV array.
+
len
+
The maximum number of elements to transfer. The number actually + transfered will be less than or equal to this value.
+
data
+
Get sets data.data to it's internal array and data.offset to the + offset into the array. The caller is responsible for the actual data + transfer.
+
from
+
The array from which the data is taken. This array is supplied by the + caller
+
fromOffset
+
The offset in from
+
+ +

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);
+            double *from = &data.data[data.offset];
+            double *to = &to[offset]
+            int numbytes = num*sizeof(double);
+            memcopy(from,to,numBytes);
+            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 three fields: index, choice, and choices. Choices is a PVStringArray that +holds the enumerated choices. Index is a PVInt that is the index of the +currently selected choice and choice is a PVString which is the currently +selected choice. For many enumerated structures the choices is immutable. +Allowing the choices internal String[] to be shared between all the instances +of an enumerated structure saves on storage. An example is alarmSeverity. +Another reason for allowing shared data is so that an application which +processes an array can be separated into multiple modules that directly +access the internal data array of a PVArray. This can be required for +minimizing CPU overhead. In this case it is the applications responsibility +to coordinate access to the array.

+ +
Complete set of PVArray Extensions
+
class PVScalarArray : public PVArray {
+public:
+    virtual ~PVScalarArray();
+    ScalarArrayConstPtr getScalarArray() ;
+    virtual void setCapacity(int capacity) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,
+        DeserializableControl *pflusher) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher, int offset, int count) = 0;
+protected:
+    PVScalarrray(PVStructure *parent,ScalarArrayConstPtr scalarArray);
+private:
+};
+
+class BooleanArrayData {
+public:
+    BooleanArray data;
+    int offset;
+};
+
+class PVBooleanArray : public PVScalarArray {
+public:
+    virtual ~PVBooleanArray();
+    virtual void setCapacity(int capacity) = 0;
+    virtual int get(int offset, int length, BooleanArrayData *data) = 0;
+    virtual int put(int offset,int length, BooleanArray from, int fromOffset) = 0;
+    virtual void shareData(BooleanArray value,int capacity,int length) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0;
+protected:
+    PVBooleanArrayclass ByteArrayData {
+public:
+    ByteArray data;
+    int offset;
+};
+
+class PVByteArray : public PVScalarArray {
+public:
+    virtual ~PVByteArray();
+    virtual void setCapacity(int capacity) = 0;
+    virtual int get(int offset, int length, ByteArrayData *data) = 0;
+    virtual int put(int offset,int length, ByteArray  from, int fromOffset) = 0;
+    virtual void shareData(ByteArray value,int capacity,int length) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0;
+protected:
+    PVByteArray(PVStructure *parent,ScalarArrayConstPtr scalar);
+private:
+};
+
+class ShortArrayData {
+public:
+    ShortArray data;
+    int offset;
+};
+
+class PVShortArray : public PVScalarArray {
+public:
+    virtual ~PVShortArray();
+    virtual void setCapacity(int capacity) = 0;
+    virtual int get(int offset, int length, ShortArrayData *data) = 0;
+    virtual int put(int offset,int length, ShortArray  from, int fromOffset) = 0;
+    virtual void shareData(ShortArray value,int capacity,int length) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0;
+protected:
+    PVShortArray(PVStructure *parent,ScalarArrayConstPtr scalar);
+private:
+};
+
+
+class IntArrayData {
+public:
+    IntArray data;
+    int offset;
+};
+
+class PVIntArray : public PVScalarArray {
+public:
+    virtual ~PVIntArray();
+    virtual void setCapacity(int capacity) = 0;
+    virtual int get(int offset, int length, IntArrayData *data) = 0;
+    virtual int put(int offset,int length, IntArray  from, int fromOffset)= 0;
+    virtual void shareData(IntArray value,int capacity,int length)= 0;
+    virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0;
+protected:
+    PVIntArray(PVStructure *parent,ScalarArrayConstPtr scalar);
+private:
+};
+
+class LongArrayData {
+public:
+    LongArray data;
+    int offset;
+};
+
+class PVLongArray : public PVScalarArray {
+public:
+    virtual ~PVLongArray();
+    virtual void setCapacity(int capacity) = 0;
+    virtual int get(int offset, int length, LongArrayData *data) = 0;
+    virtual int put(int offset,int length, LongArray  from, int fromOffset)= 0;
+    virtual void shareData(LongArray value,int capacity,int length)= 0;
+    virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0;
+protected:
+    PVLongArray(PVStructure *parent,ScalarArrayConstPtr scalar);
+private:
+};
+
+class FloatArrayData {
+public:
+    FloatArray data;
+    int offset;
+};
+
+class PVFloatArray : public PVScalarArray {
+public:
+    virtual ~PVFloatArray();
+    virtual void setCapacity(int capacity) = 0;
+    virtual int get(int offset, int length, FloatArrayData *data) = 0;
+    virtual int put(int offset,int length, FloatArray  from, int fromOffset)= 0;
+    virtual void shareData(FloatArray value,int capacity,int length)= 0;
+    virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0;
+protected:
+    PVFloatArray(PVStructure *parent,ScalarArrayConstPtr scalar);
+private:
+};
+
+
+class DoubleArrayData {
+public:
+    DoubleArrayData(){}
+    ~DoubleArrayData(){};
+    DoubleArray data;
+    int offset;
+};
+
+class PVDoubleArray : public PVScalarArray {
+public:
+    virtual ~PVDoubleArray();
+    virtual void setCapacity(int capacity) = 0;
+    virtual int get(int offset, int length, DoubleArrayData *data) = 0;
+    virtual int put(int offset,int length, DoubleArray  from, int fromOffset) = 0;
+    virtual void shareData(DoubleArray value,int capacity,int length) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0;
+protected:
+    PVDoubleArray(PVStructure *parent,ScalarArrayConstPtr scalar);
+private:
+};
+
+class StringArrayData {
+public:
+    StringArray data;
+    int offset;
+};
+
+class PVStringArray : public PVScalarArray {
+public:
+    virtual ~PVStringArray();
+    virtual void setCapacity(int capacity) = 0;
+    virtual int get(int offset, int length, StringArrayData *data) = 0;
+    virtual int put(int offset,int length, StringArray  from, int fromOffset)= 0;
+    virtual void shareData(StringArray value,int capacity,int length)= 0;
+    virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0;
+    virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0;
+protected:
+    PVStringArray(PVStructure *parent,ScalarArrayConstPtr scalar);
+private:
+};
+ +

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

+ +

PVStructure

+ +

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);
+    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();
+    bool putExtendsStructureName(
+        String extendsStructureName);
+    virtual bool operator==(PVField &pv) ;
+    virtual bool operator!=(PVField &pv) ;
+    virtual void serialize(
+        ByteBuffer *pbuffer,SerializableControl *pflusher) ;
+    virtual void deserialize(
+        ByteBuffer *pbuffer,DeserializableControl *pflusher);
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher, int offset, int count) ;
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher,BitSet *pbitSet) ;
+    virtual void deserialize(ByteBuffer *pbuffer,
+        DeserializableControl*pflusher,BitSet *pbitSet);
+protected:
+    PVStructure(PVStructure *parent,StructureConstPtr structure);
+private:
+    class PVStructurePvt * pImpl;
+};
+ +

where

+
+
getStructure
+
Get the introspection interface for the structure.
+
getPVFields
+
Returns the array of subfields. The set of subfields must all have + different field names.
+
getSubField(String fieldName)
+
Get a subField of a field. For a PVStructure a non-null result is + returned if fieldName is a field of the PVStructure. The fieldName can + be of the form name.name...
+
getSubField(int fieldOffset)
+
Get the field located a fieldOffset, where fieldOffset is relative to + the top level structure. This returns null if the specified field is + not located within this PVStructure.
+
appendPVField
+
Append pvField to the end of this PVStructure. This should NOT be + called if any code is attached to any of the fields in the top level + structure.
+
appendPVFields
+
Append an array of pvFields to the end of this structure. Note that + if the original number of fields is 0 than pvFields replaces the + original. Thus the caller must NOT reuse pvFields after calling this + method. This should NOT be called if any code is attached to any of the + fields in the top level structure
+
removePVField
+
Remove the specified field from this structure. This should NOT be + called if any code is attached to any of the fields in the top level + structure.
+
getBooleanField
+
Look for fieldName. If found and it has the correct type return the + interface. This and the following methods are convenience methods that + allow a user to get the interface to a subfield without requiring + introspection. fieldName can be of the form name.name...
+
getByteField
+
Look for fieldName. If found and it has the correct type return the + interface.
+
getShortField
+
Look for fieldName. If found and it has the correct type return the + interface.
+
getIntField
+
Look for fieldName. If found and it has the correct type return the + interface.
+
getLongField
+
Look for fieldName. If found and it has the correct type return the + interface.
+
getFloatField
+
Look for fieldName. If found and it has the correct type return the + interface.
+
getDoubleField
+
Look for fieldName. If found and it has the correct type return the + interface.
+
getStringField
+
Look for fieldName. If found and it has the correct type return the + interface.
+
getScalarArrayField
+
Look for fieldName. If found and it has the correct type return the + interface.
+
getStructureArrayField
+
Look for fieldName. If found and it has the correct type return the + interface.
+
getExtendsStructureName
+
Get the name of structure that this structure extends.
+
putExtendsStructureName
+
Specify the structure that this structure extends.
+
+ +

PVStructureArray

+ +

The interface for an array of structures is:

+
class StructureArrayData {
+public:
+    PVStructurePtrArray data;
+    int offset;
+};
+
+class PVStructureArray : public PVArray {
+public:
+    virtual ~PVStructureArray();
+    virtual StructureArrayConstPtr getStructureArray() = 0;
+    virtual void setCapacity(int capacity) = 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;
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher) = 0 ;
+    virtual void deserialize(ByteBuffer *buffer,
+        DeserializableControl *pflusher) = 0;
+    virtual void serialize(ByteBuffer *pbuffer,
+        SerializableControl *pflusher, int offset, int count) = 0;
+protected:
+    PVStructureArray(PVStructure *parent,
+        StructureArrayConstPtr structureArray);
+private:
+};
+ +

where

+ +

PVDataCreate

+ +

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,PVStructure *structToClone);
+protected:
+   PVDataCreate();
+   friend PVDataCreate * getPVDataCreate();
+};
+
+extern PVDataCreate * getPVDataCreate();
+ +

where

+
+
createPVField
+
The PVField is created reusing the Field interface. Two methods are + provided. Each calls the corresponding createPVScalar, createPVArray, + or createPVStructure depending in the type os the last argument.
+
createPVScalar
+
Creates an instance of a PVScalar. Three versions are supplied. The + first is passed an introspection interface. The second provides the + field name and the scalarType. The last provides a field name and a + PVScalar to clone. The newly created PVScalar will have the same + auxInfos as the original.
+
createPVScalarArray
+
Create an instance of a PVArray. Three versions are supplied. The + first is passed an introspection interface. The second provides the + field name and the elementType. The last provides a field name and a + PVArray to clone. The newly created PVArray will have the same auxInfos + as the original.
+
createPVStructureArray
+
Create a PVStructureArray. It must be passed a structureToClone. This + will become the Structure interface for ALL elements of the + PVStructureArray. It MUST be used to create any new array elements.
+
createPVStructure
+
Create an instance of a PVStructure. Four methods are provided. The + first method uses a previously created structure introspection + interface. The second uses a Field array to initialize the sub-fields. + The third initializes the subfields by cloning the fields contained in + structToClone. The newly created sub-fields will have the same values + and auxInfos as the original. If structToClone is null then the new + structure is initialized to have 0 sub-fields.
+
flattenPVStructure
+
Create an array of PVFields for the fields in the PVStructure. The + order is according to fieldOffset.
+
+ +

Standard Data Fields

+ +

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 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 thye standard +properties. The meythods 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);
+    PVStructure * enumerated(PVStructure *parent,
+        String fieldName,StringArray choices, 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);
+};
+ +

Convert

+ +

NOTE about copying immutable array fields. If an entire immutable array +field is copied to another array that has the same elementType, both offsets +are 0, and the length is the length of the source array, then the shareData +method of the target array is called and the target array is set immutable. +Thus the source and target share the same primitive array.

+ +

This section describes the supported conversions between data types.

+ +
class Convert : NoDefaultMethods {
+public:
+    Convert();
+    ~Convert();
+    void getFullName(StringBuilder buf,PVField *pvField);
+    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);
+    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);
+    bool isCopyStructureCompatible(
+        StructureConstPtr from, StructureConstPtr to);
+    void copyStructure(PVStructure *from, PVStructure *to);
+    bool isCopyStructureArrayCompatible(
+        StructureArrayConstPtr from, StructureArrayConstPtr 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);
+    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);
+};
+
+extern Convert * 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.

+ +

newLine is a convenience method +for code that implements toString +It generates a newline and inserts blanks at the beginning of the newline.

+
+ +

Examples

+
+ +

Accessing PVData

+ +

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

+
+
value
+
Must be a PVDouble.
+
timeStamp
+
Just look for field with this name.
+
+ +

The following code uses introspection to get the desired information.

+
void getValueAndTimeStamp(PVStructure pvStructure,Stringbuffer 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);
+}
+ +

Creating PVData

+ +

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(0);
+ +

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"))
+
+ +

pvMisc

+
+ +

BitSetUtil

+ +

The following is also provided:

+
NOT DONE
+ +

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

+
+
compress
+
Compress the bits in a BitSet related to a structure.
+ For each structure: +
    +
  1. If the bit for the structure is set then the bit for all + subfields of the structure are cleared.
  2. +
  3. If the bit for the structure is not set but all immediate + subfields have their bit set then the bit for the structure is set + and the bits for all subfields are cleared.
  4. +
+ Note that this is a recursive algorithm. That is if every immediate + subfield has it's offset bit set then the bits for ALL fields that + reside in the structure will be cleared.
+
Channel Access can call this before sending data. It can then pass + entire structures if the structure offset bit is set.
+
+ +

MultiChoice

+ +

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

+
NOT DONE
+ +

where

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

Property

+
+ +

Definition of Property

+ +

NOTE: The use of property is discouraged. But the Interfaces for standard +properties are encouraged.

+ +

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

+ +

For example the following record has a single value field. The value field +has propertys alarm, timeStamp, and display.

+
<record name = "counterOutput" >
+    <structure name = "alarm" extends = "alarm" />
+    <structure name = "timeStamp" extends = "timeStamp" />
+    <scalar name = "value" scalarType = "double" />
+    <structure name = "display" extends = "display" >
+        <scalar name = "description">Sample Description</scalar>
+        <scalar name = "format">%f</scalar>
+        <scalar name = "units">volts</scalar>
+        <structure name = "limit">
+            <scalar name ="low">0.0</scalar>
+            <scalar name ="high">10.0</scalar>
+        </structure>
+    </structure>
+</record>
+ +

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.

+
<record name = "psSimple">
+    <structure name = "alarm" extends = "alarm" />
+    <structure name = "timeStamp" extends = "timeStamp" />
+    <structure name = "voltage">
+        <scalar name = "value" scalarType = "double" />
+        <structure name = "alarm" extends = "alarm" />
+    </structure>
+    <structure name = "current">
+        <scalar name = "value" scalarType = "double" />
+        <structure name = "alarm" extends = "alarm" />
+    </structure>
+    <structure name = "power">
+        <scalar name = "value" scalarType = "double" />
+        <structure name = "alarm" extends = "alarm" />
+    </structure>
+</record>
+ +

Standard Properties

+ +

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

+
+
value
+
This is normally defined since most general purpose clients access + this field. All other fields in the structure support or describe the + value field. The type can any supported type but is usually one of the + following: +
+
scalar
+
One of boolean, byte, short, int, long, float, double, or + string
+
scalarArray
+
An array with the elementType being a scalar type
+
enumerated structure
+
A structure that includes fields named index, choice, and + choices. index is an int that selects a choice. choice is the + currently selected choice. choices is an array of strings that + defines the complete set of choices.
+
other
+
Other structure or array types can also be defined if clients + and support code agree on the meaning. Some examples are: 1) A + structure defining a 2D matrix, 2) A structure defining an image, + 3) A structure that simulates a remote method, ...
+
+
+
timeStamp
+
The timeStamp. The type MUST be a timeStamp structure. Also if the + PVData structure does not have a timeStamp then a search up the parent + tree is made to find a timeStamp.
+
alarm
+
The alarm. The type MUST be an alarm structure.
+
display
+
A display structure as described below. It provides display + characteristics for the value field.
+
control
+
A control structure as described below. It provides control + characteristics for the value field.
+
history
+
Provides a history buffer for the value field. Note that currently + PVData does not define history suppoprt.
+
other
+
Other standard properties can be defined.
+
+ +

In addition a structure can have additional fields that support the value +field but are not recognized by most general purpose client tools. Typical +examples are:

+
+
input
+
A field with support that changes the value field. This can be + anything. It can be a channel access link. It can obtain a value from + hardware. Etc.
+
valueAlarm
+
A field with support that looks for alarm conditions based on the + value.
+
output
+
A field with support that reads the current value and sends it + somewhere else. This can be anything. It can be a channel access link. + It can write a value to hardware. Etc.
+
+ +

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

+ +

PVProperty

+ +

Interface and factory for finding a field within a structure.

+
NOT DONE
+ + +

Enumeration

+ +

Enumerated is a convenience interface for a structure that happens to be +an enumerated structure, which is a structure that has fields index and +choices. Index is an integer and choices is an array of strings. Both index +selects one of the choices.

+
class Enumerated ;
+public:
+    //default constructors and destructor are OK
+    //This class should not be extended
+
+    //returns (false,true) if pvField(isNot, is valid enumerated structure
+    bool attach(PVField *pvField);
+    ~Enumerated();
+    // each of the following throws logic_error is not attached to PVField
+    void putIndex(int32 index);
+    int32 getIndex();
+    String getChoice();
+    bool choicesMutable();
+    StringArray getChoices();
+    int32 getNumberChoices();
+    // also throws logic_error of immutable
+    void putChoices(StringArray choices,int32 numberChoices);
+private:
+    PVInt *pvIndex;
+    PVStringArray *pvChoices;
+};
+ +

where

+
+
getIndex
+
Returns the interface for field index.
+
getChoice
+
Returns the choice for the current index.
+
getChoices
+
Returns the interface for field choices.
+
getPV
+
Returns the interface for the PVStructure for the enumerated + structure.
+
replacePVField
+
Replace the PVField implementation. The new implementation implements + interface Enumerated and also replaces the implementations of fields + index, choice, and choices. The new implementation updates index when + choice is changed and choice when index is changed. If choices is + changed the index is set to 0.
+
getEnumerated
+
If the field is an enumerated structure and replacePVField was called + for the field then interface Enumerated is returned.
+
+ +

Standard Properties

+ +

This section has structure definitions that support standard properties. +These definitions are defined in project javaIOC.

+ +

TimeStamp

+
<structure name = "timeStamp">
+  <scalar name = "secondsPastEpoch" scalarType = "long" />
+  <scalar name = "nanoSeconds" scalarType = "int" />
+</structure>
+ +

Alarm

+
<structure name = "alarmSeverity" extends = "enumerated" >
+  <array name = "choices"  immutable = "true" >none,minor,major,invalid</array>
+</structure>
+
+<structure name = "alarm">
+  <structure name = "severity" extends = "alarmSeverity" />
+  <scalar name = "message" scalarType = "string" />
+</structure>
+ +

Limits

+
<structure name = "byteLimit">
+    <scalar name = "low" scalarType = "byte" />
+    <scalar name = "high" scalarType = "byte" />
+</structure>
+
+<structure name = "shortLimit">
+    <scalar name = "low" scalarType = "short" />
+    <scalar name = "high" scalarType = "short" />
+</structure>
+
+<structure name = "intLimit">
+    <scalar name = "low" scalarType = "int" />
+    <scalar name = "high" scalarType = "int" />
+</structure>
+
+<structure name = "longLimit">
+    <scalar name = "low" scalarType = "long" />
+    <scalar name = "high" scalarType = "long" />
+</structure>
+
+<structure name = "floatLimit">
+    <scalar name = "low" scalarType = "float" />
+    <scalar name = "high" scalarType = "float" />
+</structure>
+
+<structure name = "doubleLimit">
+    <scalar name = "low" scalarType = "double" />
+    <scalar name = "high" scalarType = "double" />
+</structure>
+ +

Display

+
<structure name = "display">
+    <scalar name = "description" scalarType = "string" />
+    <scalar name = "format" scalarType = "string" />
+    <scalar name = "units" scalarType = "string" />
+    <structure name = "limit" extends = "doubleLimit" />
+</structure>
+ +

Control

+
<structure name = "control">
+    <structure name = "limit" extends = "doubleLimit" />
+    <scalar name = "minStep" scalarType = "double" />
+</structure>
+ +

Interfaces for Standard Properties

+ +

PVTimeStamp

+ +

The following priovides convient access to a timeStamp structure.

+
class PVTimeStamp {
+public:
+    //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);
+    // throws logic_error is not attached to PVField
+    TimeStamp &get();
+    // throws logic_error is not attached to PVField
+    void put (TimeStamp &timeStamp);
+private:
+    PVLong* pvSecs;
+    PVInt* pvNano;
+};
+ +

Alarm

+ +

The following provides convient access to the fields of an alarm +structure.

+
NOT DONE
+ +

Limits

+ +

Display

+ +

Control

+
+ +

PVData Abstract and Base Classes

+
+ +

Overview

+ +

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

+ +

Factory

+ +

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

+ +

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

+ +

PVAuxInfoImpl implements auxInfo.

+ +

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

+ +

Abstract Classes for PVField

+ +

AbstractPVField

+ +

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

+ +

AbstractPVScalar

+ +

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

+ +

AbstractPVArray

+ +

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

+ +

AbstractPVScalarArray

+ +

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

+ +

BasePVStructure

+ +

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

+ +

Base Classes For PVScalar

+ +

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

+
+
BasePVBoolean
+
BasePVByte
+
BasePVShort
+
BasePVInt
+
BasePVLong
+
BasePVFloat
+
BasePVDouble
+
BasePVString
+
+ +

Base Classes for PVArray

+ +

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

+
+
BasePVBooleanArray
+
BasePVByteArray
+
BasePVShortArray
+
BasePVIntArray
+
BasePVLongArray
+
BasePVFloatArray
+
BasePVDoubleArray
+
BasePVStringArray
+
BasePVStructureArray
+
+
+ +

License Agreement

+
+
Copyright (c) 2008 Martin R. Kraimer
+Copyright (c) 2007 Control System Laboratory,
+    (COSYLAB) Ljubljana Slovenia
+Copyright (c) 2010 Brookhaven National Laboratory
+
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+________________________________________________________________________
+
+This software is in part copyrighted by Brookhaven National Laboratory(BNL)
+
+In no event shall BNL be liable to any party for direct, indirect,
+special, incidental, or consequential damages arising out of the use of
+this software, its documentation, or any derivatives thereof, even if
+BNL has been advised of the possibility of such damage.
+
+BNL specifically disclaims any warranties, including, but not limited
+to, the implied warranties of merchantability, fitness for a particular
+purpose, and non-infringement.  This software is provided on an "as is"
+basis, and BNL has no obligation to provide maintenance, support,
+updates, enhancements, or modifications.
+
+________________________________________________________________________
+
+This software is in part copyrighted by the BERLINER SPEICHERRING
+GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H. (BESSY), BERLIN, GERMANY.
+
+In no event shall BESSY be liable to any party for direct, indirect,
+special, incidental, or consequential damages arising out of the use of
+this software, its documentation, or any derivatives thereof, even if
+BESSY has been advised of the possibility of such damage.
+
+BESSY specifically disclaims any warranties, including, but not limited
+to, the implied warranties of merchantability, fitness for a particular
+purpose, and non-infringement.  This software is provided on an "as is"
+basis, and BESSY has no obligation to provide maintenance, support,
+updates, enhancements, or modifications.
+
+________________________________________________________________________
+
+This software is in part copyrighted by the Deutsches Elektronen-Synchroton,
+    Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
+
+In no event shall DESY be liable to any party for direct, indirect,
+special, incidental, or consequential damages arising out of the use of
+this software, its documentation, or any derivatives thereof, even if
+DESY has been advised of the possibility of such damage.
+
+DESY specifically disclaims any warranties, including, but not limited
+to, the implied warranties of merchantability, fitness for a particular
+purpose, and non-infringement.  This software is provided on an "as is"
+basis, and DESY has no obligation to provide maintenance, support,
+updates, enhancements, or modifications.
+________________________________________________________________________
+ + diff --git a/pvDataApp/misc/Makefile b/pvDataApp/misc/Makefile index 5f13ed9..1d44f01 100644 --- a/pvDataApp/misc/Makefile +++ b/pvDataApp/misc/Makefile @@ -23,6 +23,7 @@ INC += timer.h LIBSRCS += byteBuffer.cpp LIBSRCS += bitSet.cpp +LIBSRCS += requester.cpp LIBSRCS += serializeHelper.cpp LIBSRCS += showConstructDestruct.cpp LIBSRCS += linkedListVoid.cpp diff --git a/pvDataApp/misc/bitSet.h b/pvDataApp/misc/bitSet.h index 8e957be..f477e1c 100644 --- a/pvDataApp/misc/bitSet.h +++ b/pvDataApp/misc/bitSet.h @@ -12,10 +12,6 @@ //#include "serialize.h" namespace epics { namespace pvData { - // TODO !!! - typedef unsigned long long uint64; - typedef std::string * StringBuilder; - /** * This class implements a vector of bits that grows as needed. Each * component of the bit set has a {@code bool} value. The diff --git a/pvDataApp/misc/event.cpp b/pvDataApp/misc/event.cpp index 31b19e7..ea0b4f1 100644 --- a/pvDataApp/misc/event.cpp +++ b/pvDataApp/misc/event.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -56,13 +57,17 @@ static void init() Event::~Event() { epicsEventDestroy(id); + id = 0; + Lock xx(globalMutex); totalDestruct++; } -Event::Event(EventInitialState initial) -: id(epicsEventCreate((initial==eventEmpty)?epicsEventEmpty : epicsEventFull)) + +Event::Event(bool full) +: id(epicsEventCreate(full?epicsEventFull : epicsEventEmpty)) { init(); + Lock xx(globalMutex); totalConstruct++; } @@ -74,23 +79,27 @@ ConstructDestructCallback *Event::getConstructDestructCallback() void Event::signal() { + if(id==0) throw std::logic_error(String("event was deleted")); epicsEventSignal(id); } bool Event::wait () { + if(id==0) throw std::logic_error(String("event was deleted")); epicsEventWaitStatus status = epicsEventWait(id); return status==epicsEventWaitOK ? true : false; } bool Event::wait ( double timeOut ) { + if(id==0) throw std::logic_error(String("event was deleted")); epicsEventWaitStatus status = epicsEventWaitWithTimeout(id,timeOut); return status==epicsEventWaitOK ? true : false; } bool Event::tryWait () { + if(id==0) throw std::logic_error(String("event was deleted")); epicsEventWaitStatus status = epicsEventTryWait(id); return status==epicsEventWaitOK ? true : false; } diff --git a/pvDataApp/misc/event.h b/pvDataApp/misc/event.h index 25e0edf..00dcdb0 100644 --- a/pvDataApp/misc/event.h +++ b/pvDataApp/misc/event.h @@ -16,22 +16,10 @@ namespace epics { namespace pvData { -enum EventWaitStatus { - eventWaitOK, - eventWaitTimeout, - eventWaitError -}; - -enum EventInitialState { - eventEmpty, - eventFull -}; - - class Event : private NoDefaultMethods { public: + explicit Event(bool = false); ~Event(); - Event(EventInitialState initial); static ConstructDestructCallback *getConstructDestructCallback(); void signal(); bool wait (); /* blocks until full */ diff --git a/pvDataApp/misc/executor.cpp b/pvDataApp/misc/executor.cpp index dcce275..bb96898 100644 --- a/pvDataApp/misc/executor.cpp +++ b/pvDataApp/misc/executor.cpp @@ -81,14 +81,13 @@ ConstructDestructCallback *Executor::getConstructDestructCallback() return pConstructDestructCallback; } -class ExecutorPvt : public RunnableReady { +class ExecutorPvt : public Runnable{ public: ExecutorPvt(String threadName,ThreadPriority priority); ~ExecutorPvt(); ExecutorNode * createNode(Command *command); void execute(ExecutorNode *node); - void destroy(); - virtual void run(ThreadReady *threadReady); + virtual void run(); private: ExecutorList *executorList; ExecutorList *runList; @@ -102,37 +101,39 @@ private: ExecutorPvt::ExecutorPvt(String threadName,ThreadPriority priority) : executorList(new ExecutorList()), runList(new ExecutorList()), - moreWork(new Event(eventEmpty)), - stopped(new Event(eventEmpty)), + moreWork(new Event(false)), + stopped(new Event(false)), mutex(Mutex()), alive(true), thread(new Thread(threadName,priority,this)) -{ - thread->start(); -} +{} ExecutorPvt::~ExecutorPvt() { + { + Lock xx(&mutex); + alive = false; + } + moreWork->signal(); + { + Lock xx(&mutex); + stopped->wait(); + } ExecutorListNode *node; while((node=executorList->removeHead())!=0) { delete node->getObject(); } + delete thread; delete stopped; delete moreWork; delete runList; delete executorList; - delete thread; } -void ExecutorPvt::run(ThreadReady *threadReady) +void ExecutorPvt::run() { - bool firstTime = true; while(alive) { ExecutorListNode * executorListNode = 0; - if(firstTime) { - firstTime = false; - threadReady->ready(); - } while(alive && runList->isEmpty()) { moreWork->wait(); } @@ -164,20 +165,6 @@ void ExecutorPvt::execute(ExecutorNode *node) if(isEmpty) moreWork->signal(); } -void ExecutorPvt::destroy() -{ - { - Lock xx(&mutex); - alive = false; - } - moreWork->signal(); - { - Lock xx(&mutex); - stopped->wait(); - } - delete this; -} - Executor::Executor(String threadName,ThreadPriority priority) : pImpl(new ExecutorPvt(threadName,priority)) { @@ -187,23 +174,14 @@ Executor::Executor(String threadName,ThreadPriority priority) } Executor::~Executor() { + delete pImpl; Lock xx(globalMutex); totalDestruct++; } -Executor *Executor::create(String threadName,ThreadPriority priority) -{ - return new Executor(threadName,priority); -} - ExecutorNode * Executor::createNode(Command*command) {return pImpl->createNode(command);} void Executor::execute(ExecutorNode *node) {pImpl->execute(node);} -void Executor::destroy() { - pImpl->destroy(); - delete this; -} - }} diff --git a/pvDataApp/misc/executor.h b/pvDataApp/misc/executor.h index b778cf7..1c70439 100644 --- a/pvDataApp/misc/executor.h +++ b/pvDataApp/misc/executor.h @@ -24,14 +24,12 @@ public: class Executor : private NoDefaultMethods { public: - static ConstructDestructCallback *getConstructDestructCallback(); - static Executor *create(String threadName,ThreadPriority priority); - ExecutorNode * createNode(Command *command); - void execute(ExecutorNode *node); - void destroy(); -private: Executor(String threadName,ThreadPriority priority); ~Executor(); + static ConstructDestructCallback *getConstructDestructCallback(); + ExecutorNode * createNode(Command *command); + void execute(ExecutorNode *node); +private: class ExecutorPvt *pImpl; }; diff --git a/pvDataApp/misc/linkedList.h b/pvDataApp/misc/linkedList.h index 757830d..abf41c5 100644 --- a/pvDataApp/misc/linkedList.h +++ b/pvDataApp/misc/linkedList.h @@ -17,8 +17,9 @@ class LinkedListNode : private LinkedListVoidNode { public: LinkedListNode(T *object) : LinkedListVoidNode(object){} ~LinkedListNode() {} - T *getObject() { return (T *)LinkedListVoidNode::getObject();} + T *getObject() { return static_cast(LinkedListVoidNode::getObject());} bool isOnList() {return LinkedListVoidNode::isOnList();} + friend class LinkedList; }; template @@ -29,49 +30,51 @@ public: int getLength() {return LinkedListVoid::getLength();} void addTail(LinkedListNode *listNode) { - LinkedListVoid::addTail((LinkedListVoidNode *)listNode); + LinkedListVoid::addTail(static_cast(listNode)); } void addHead(LinkedListNode *listNode) { - LinkedListVoid::addHead((LinkedListVoidNode *)listNode); + LinkedListVoid::addHead(static_cast(listNode)); } void insertAfter(LinkedListNode *listNode, LinkedListNode *addNode) { LinkedListVoid::insertAfter( - (LinkedListVoidNode *)listNode,(LinkedListVoidNode *)addNode); + static_cast(listNode), + static_cast(addNode)); } void insertBefore(LinkedListNode *listNode, LinkedListNode *addNode) { - LinkedListVoid::insertBefore((LinkedListVoidNode *)listNode, - (LinkedListVoidNode *)addNode); + LinkedListVoid::insertBefore( + static_cast(listNode), + static_cast(addNode)); } LinkedListNode *removeTail(){ - return (LinkedListNode*)LinkedListVoid::removeTail(); + return static_cast *>(LinkedListVoid::removeTail()); } LinkedListNode *removeHead(){ - return (LinkedListNode*)LinkedListVoid::removeHead(); + return static_cast *>(LinkedListVoid::removeHead()); } void remove(LinkedListNode *listNode){ - LinkedListVoid::remove((LinkedListVoidNode *)listNode); + LinkedListVoid::remove(static_cast(listNode)); } void remove(T *object){ LinkedListVoid::remove(object); } LinkedListNode *getHead(){ - return (LinkedListNode*)LinkedListVoid::getHead(); + return static_cast *>(LinkedListVoid::getHead()); } LinkedListNode *getTail(){ - return (LinkedListNode*)LinkedListVoid::getTail(); + return static_cast *>(LinkedListVoid::getTail()); } LinkedListNode *getNext(LinkedListNode *listNode){ - return (LinkedListNode*)LinkedListVoid::getNext( - (LinkedListVoidNode *)listNode); + return static_cast *>(LinkedListVoid::getNext( + static_cast(listNode))); } LinkedListNode *getPrev(LinkedListNode *listNode){ - return (LinkedListNode*)LinkedListVoid::getPrev( - (LinkedListVoidNode *)listNode); + return static_cast *>(LinkedListVoid::getPrev( + static_cast(listNode))); } bool isEmpty() { return LinkedListVoid::isEmpty();} bool contains(T *object) { return LinkedListVoid::contains(object);} diff --git a/pvDataApp/misc/linkedListVoid.cpp b/pvDataApp/misc/linkedListVoid.cpp index f6fd2c2..097b3a4 100644 --- a/pvDataApp/misc/linkedListVoid.cpp +++ b/pvDataApp/misc/linkedListVoid.cpp @@ -69,7 +69,7 @@ static void initPvt() LinkedListVoidNode::LinkedListVoidNode(void *object) -: object(object),before(0),after(0) +: object(object),before(0),after(0),linkedListVoid(0) { initPvt(); Lock xx(globalMutex); @@ -138,6 +138,7 @@ void LinkedListVoid::addTail(LinkedListVoidNode *node) if(node->before!=0 || node->after!=0) { throw std::logic_error(alreadyOnList); } + node->linkedListVoid = this; node->before = head->before; node->after = head; head->before->after = node; @@ -150,6 +151,7 @@ void LinkedListVoid::addHead(LinkedListVoidNode *node) if(node->before!=0 || node->after!=0) { throw std::logic_error(alreadyOnList); } + node->linkedListVoid = this; node->after = head->after; node->before = head; head->after->before = node; @@ -168,6 +170,10 @@ void LinkedListVoid::insertAfter(LinkedListVoidNode *node, if(newNode->before!=0 || newNode->after!=0) { throw std::logic_error(alreadyOnList); } + if(node->linkedListVoid!=this) { + throw std::logic_error(String("node not on this list")); + } + newNode->linkedListVoid = this; newNode->after = existingNode->after; newNode->before = existingNode; existingNode->after->before = newNode; @@ -186,6 +192,10 @@ void LinkedListVoid::insertBefore(LinkedListVoidNode *node, if(newNode->before!=0 || newNode->after!=0) { throw std::logic_error(alreadyOnList); } + if(node->linkedListVoid!=this) { + throw std::logic_error(String("node not on this list")); + } + newNode->linkedListVoid = this; newNode->after = existingNode; newNode->before = existingNode->before; existingNode->before->after = newNode; @@ -209,12 +219,15 @@ LinkedListVoidNode *LinkedListVoid::removeHead() return node; } -void LinkedListVoid::remove(LinkedListVoidNode *listNode) +void LinkedListVoid::remove(LinkedListVoidNode *node) { - LinkedListVoidNode *node = listNode; if(node->before==0 || node->after==0) { - throw std::logic_error(String("listNode not on list")); + throw std::logic_error(String("node not on list")); } + if(node->linkedListVoid!=this) { + throw std::logic_error(String("node not on this list")); + } + node->linkedListVoid = 0; LinkedListVoidNode *prev = node->before; LinkedListVoidNode *next = node->after; node->after = node->before = 0; @@ -233,6 +246,7 @@ void LinkedListVoid::remove(void * object) } node = getNext(node); } + throw std::logic_error(String("object not on this list")); } LinkedListVoidNode *LinkedListVoid::getHead() @@ -249,12 +263,18 @@ LinkedListVoidNode *LinkedListVoid::getTail() LinkedListVoidNode *LinkedListVoid::getNext(LinkedListVoidNode *listNode) { + if(listNode->linkedListVoid!=this) { + throw std::logic_error(String("node not on this list")); + } if(listNode->after==head) return 0; return listNode->after; } LinkedListVoidNode *LinkedListVoid::getPrev(LinkedListVoidNode *listNode) { + if(listNode->linkedListVoid!=this) { + throw std::logic_error(String("node not on this list")); + } if(listNode->before==head) return 0; return listNode->before; } diff --git a/pvDataApp/misc/linkedListVoid.h b/pvDataApp/misc/linkedListVoid.h index 4abacac..d19c648 100644 --- a/pvDataApp/misc/linkedListVoid.h +++ b/pvDataApp/misc/linkedListVoid.h @@ -28,6 +28,7 @@ private: void *object; LinkedListVoidNode *before; LinkedListVoidNode *after; + LinkedListVoid *linkedListVoid; // do not implement the following LinkedListVoidNode(const LinkedListVoidNode&); LinkedListVoidNode & operator=(const LinkedListVoidNode&); diff --git a/pvDataApp/misc/lock.h b/pvDataApp/misc/lock.h index 6cb928d..70e7a2d 100644 --- a/pvDataApp/misc/lock.h +++ b/pvDataApp/misc/lock.h @@ -14,25 +14,25 @@ namespace epics { namespace pvData { - class Mutex { - public: - Mutex() : id(epicsMutexMustCreate()){} - ~Mutex() { epicsMutexDestroy(id) ;}; - void lock(){epicsMutexMustLock(id);}\ - void unlock(){epicsMutexUnlock(id);} - private: - epicsMutexId id; - }; +class Mutex { +public: + Mutex() : id(epicsMutexMustCreate()){} + ~Mutex() { epicsMutexDestroy(id) ;} + void lock(){epicsMutexMustLock(id);} + void unlock(){epicsMutexUnlock(id);} +private: + epicsMutexId id; +}; - class Lock : private NoDefaultMethods { - public: - explicit Lock(Mutex *pm) - : mutexPtr(pm) - {mutexPtr->lock();} - ~Lock(){mutexPtr->unlock();} - private: - Mutex *mutexPtr; - }; +class Lock : private NoDefaultMethods { +public: + explicit Lock(Mutex *pm) + : mutexPtr(pm) + {mutexPtr->lock();} + ~Lock(){mutexPtr->unlock();} +private: + Mutex *mutexPtr; +}; }} #endif /* LOCK_H */ diff --git a/pvDataApp/misc/pvType.h b/pvDataApp/misc/pvType.h index b0fa1d3..5389366 100644 --- a/pvDataApp/misc/pvType.h +++ b/pvDataApp/misc/pvType.h @@ -10,16 +10,16 @@ namespace epics { namespace pvData { - typedef signed char int8; - typedef short int16; - typedef int int32; - typedef long long int64; - typedef unsigned int uint32; - typedef unsigned long long uint64; +typedef signed char int8; +typedef short int16; +typedef int int32; +typedef long long int64; +typedef unsigned int uint32; +typedef unsigned long long uint64; - typedef std::string String; - typedef std::string * StringBuilder; - typedef String* StringArray; +typedef std::string String; +typedef std::string * StringBuilder; +typedef String* StringArray; }} #endif /* PVTYPE_H */ diff --git a/pvDataApp/misc/requester.cpp b/pvDataApp/misc/requester.cpp new file mode 100644 index 0000000..dd36d01 --- /dev/null +++ b/pvDataApp/misc/requester.cpp @@ -0,0 +1,20 @@ +/* requester.cpp */ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * EPICS pvDataCPP is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ +#include +#include "requester.h" +namespace epics { namespace pvData { + +static std::string typeName[] = { + String("info"), + String("warning"), + String("error"), + String("fatalError") +}; + +StringArray messageTypeName = typeName; + +}} diff --git a/pvDataApp/misc/requester.h b/pvDataApp/misc/requester.h index ff3d7af..9f826c5 100644 --- a/pvDataApp/misc/requester.h +++ b/pvDataApp/misc/requester.h @@ -7,24 +7,22 @@ #include #ifndef REQUESTER_H #define REQUESTER_H -#include "pvIntrospect.h" +#include "pvType.h" namespace epics { namespace pvData { - class Requester; - - enum MessageType { - infoMessage,warningMessage,errorMessage,fatalErrorMessage - }; +class Requester; - static std::string messageTypeName[] = { - "info","warning","error","fatalError" - }; - - class Requester { - public: - virtual String getRequesterName() = 0; - virtual void message(String message,MessageType messageType) = 0; - }; +enum MessageType { + infoMessage,warningMessage,errorMessage,fatalErrorMessage +}; + +extern StringArray messageTypeName; + +class Requester { +public: + virtual String getRequesterName() = 0; + virtual void message(String message,MessageType messageType) = 0; +}; }} #endif /* REQUESTER_H */ diff --git a/pvDataApp/misc/showConstructDestruct.cpp b/pvDataApp/misc/showConstructDestruct.cpp index c39fcec..c6f6c61 100644 --- a/pvDataApp/misc/showConstructDestruct.cpp +++ b/pvDataApp/misc/showConstructDestruct.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "noDefaultMethods.h" #include "lock.h" @@ -62,6 +63,7 @@ ShowConstructDestruct::ShowConstructDestruct() {} void ShowConstructDestruct::constuctDestructTotals(FILE *fd) { + getShowConstructDestruct(); // make it initialize Lock xx(globalMutex); ListNode *node = list->getHead(); while(node!=0) { @@ -80,8 +82,33 @@ void ShowConstructDestruct::constuctDestructTotals(FILE *fd) void ShowConstructDestruct::registerCallback(ConstructDestructCallback *callback) { + static ConstructDestructCallback *listCallback = 0; + static ConstructDestructCallback *listNodeCallback = 0; Lock xx(globalMutex); - ListNode *listNode = new ListNode(callback); + ListNode *listNode = 0; + if(list==0) { + if(callback->getConstructName().compare("linkedListNode")==0) { + listNodeCallback = callback; + } else if(callback->getConstructName().compare("linkedList")==0) { + listCallback = callback; + } else { + throw std::logic_error(String("ShowConstructDestruct::registerCallback")); + } + return; + } + if(listCallback!=0) { + if(listNodeCallback==0) { + throw std::logic_error(String( + "ShowConstructDestruct::registerCallback expected listNodeCallback!=0")); + } + listNode = new ListNode(listNodeCallback); + list->addTail(listNode); + listNode = new ListNode(listCallback); + list->addTail(listNode); + listCallback = 0; + listNodeCallback = 0; + } + listNode = new ListNode(callback); list->addTail(listNode); } @@ -91,9 +118,9 @@ ShowConstructDestruct * getShowConstructDestruct() Lock xx(&mutex); if(pShowConstructDestruct==0) { globalMutex = new Mutex(); - list = new List(); pShowConstructDestruct = new ShowConstructDestruct(); - } + list = new List(); + } return pShowConstructDestruct; } diff --git a/pvDataApp/misc/showConstructDestruct.h b/pvDataApp/misc/showConstructDestruct.h index e7b1c54..f8fe20c 100644 --- a/pvDataApp/misc/showConstructDestruct.h +++ b/pvDataApp/misc/showConstructDestruct.h @@ -40,8 +40,8 @@ private: class ShowConstructDestruct : private NoDefaultMethods { public: - static void constuctDestructTotals(FILE *fd); - static void registerCallback(ConstructDestructCallback *callback); + void constuctDestructTotals(FILE *fd); + void registerCallback(ConstructDestructCallback *callback); private: ShowConstructDestruct(); friend ShowConstructDestruct* getShowConstructDestruct(); diff --git a/pvDataApp/misc/thread.cpp b/pvDataApp/misc/thread.cpp index 4c13f19..5c0dbff 100644 --- a/pvDataApp/misc/thread.cpp +++ b/pvDataApp/misc/thread.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -48,9 +49,7 @@ typedef LinkedList ThreadList; static volatile int64 totalConstruct = 0; static volatile int64 totalDestruct = 0; static Mutex *globalMutex = 0; -static void addThread(Thread *thread); -static void removeThread(Thread *thread); -static ThreadList *list; +static ThreadList *threadList; static int64 getTotalConstruct() { @@ -72,7 +71,7 @@ static void init() Lock xx(&mutex); if(globalMutex==0) { globalMutex = new Mutex(); - list = new ThreadList(); + threadList = new ThreadList(); pConstructDestructCallback = new ConstructDestructCallback( String("thread"), getTotalConstruct,getTotalDestruct,0); @@ -96,38 +95,37 @@ int ThreadPriorityFunc::getEpicsPriority(ThreadPriority threadPriority) { extern "C" void myFunc ( void * pPvt ); -class Runnable : public ThreadReady { +class ThreadPvt { public: - Runnable(Thread *thread,String name, - ThreadPriority priority, RunnableReady *runnable); - virtual ~Runnable(); - Thread *start(); + ThreadPvt(Thread *thread,String name, + ThreadPriority priority, Runnable*runnable); + virtual ~ThreadPvt(); void ready(); public: // only used within this source module Thread *thread; String name; ThreadPriority priority; - RunnableReady *runnable; - Event waitStart; + Runnable *runnable; bool isReady; + ThreadListElement *threadListElement; + Event *waitDone; epicsThreadId id; }; extern "C" void myFunc ( void * pPvt ) { - Runnable *runnable = (Runnable *)pPvt; - runnable->waitStart.signal(); - addThread(runnable->thread); - runnable->runnable->run(runnable); - removeThread(runnable->thread); + ThreadPvt *threadPvt = (ThreadPvt *)pPvt; + threadPvt->runnable->run(); + threadPvt->waitDone->signal(); } -Runnable::Runnable(Thread *thread,String name, - ThreadPriority priority, RunnableReady *runnable) +ThreadPvt::ThreadPvt(Thread *thread,String name, + ThreadPriority priority, Runnable *runnable) : thread(thread),name(name),priority(priority), runnable(runnable), - waitStart(eventEmpty), isReady(false), + threadListElement(new ThreadListElement(thread)), + waitDone(new Event()), id(epicsThreadCreate( name.c_str(), epicsPriority[priority], @@ -136,32 +134,35 @@ Runnable::Runnable(Thread *thread,String name, { init(); Lock xx(globalMutex); + threadList->addTail(threadListElement->node); totalConstruct++; } -Runnable::~Runnable() +ThreadPvt::~ThreadPvt() { + bool result = waitDone->wait(2.0); + if(!result) { + throw std::logic_error(String("delete thread but run did not return")); + String message("destroy thread "); + message += thread->getName(); + message += " but run did not return"; + throw std::logic_error(message); + } + if(!threadListElement->node->isOnList()) { + String message("destroy thread "); + message += thread->getName(); + message += " is not on threadlist"; + throw std::logic_error(message); + } + threadList->remove(threadListElement->node); + delete waitDone; + delete threadListElement; Lock xx(globalMutex); totalDestruct++; } - -Thread * Runnable::start() -{ - if(!waitStart.wait(10.0)) { - fprintf(stderr,"thread %s did not call ready\n",thread->getName().c_str()); - } - return thread; -} - - -void Runnable::ready() -{ - waitStart.signal(); -} - -Thread::Thread(String name,ThreadPriority priority,RunnableReady *runnableReady) -: pImpl(new Runnable(this,name,priority,runnableReady)) +Thread::Thread(String name,ThreadPriority priority,Runnable *runnable) +: pImpl(new ThreadPvt(this,name,priority,runnable)) { } @@ -176,12 +177,6 @@ ConstructDestructCallback *Thread::getConstructDestructCallback() return pConstructDestructCallback; } -void Thread::start() -{ - pImpl->start(); -} - - void Thread::sleep(double seconds) { epicsThreadSleep(seconds);; @@ -201,38 +196,15 @@ void Thread::showThreads(StringBuilder buf) { init(); Lock xx(globalMutex); - ThreadListNode *node = list->getHead(); + ThreadListNode *node = threadList->getHead(); while(node!=0) { Thread *thread = node->getObject()->thread; *buf += thread->getName(); *buf += " "; *buf += threadPriorityNames[thread->getPriority()]; *buf += "\n"; - node = list->getNext(node); + node = threadList->getNext(node); } } -void addThread(Thread *thread) -{ - Lock xx(globalMutex); - ThreadListElement *element = new ThreadListElement(thread); - list->addTail(element->node); -} - -void removeThread(Thread *thread) -{ - Lock xx(globalMutex); - ThreadListNode *node = list->getHead(); - while(node!=0) { - if(node->getObject()->thread==thread) { - list->remove(node); - delete node; - return; - } - node = list->getNext(node); - } - fprintf(stderr,"removeThread but thread %s did not in list\n", - thread->getName().c_str()); -} - }} diff --git a/pvDataApp/misc/thread.h b/pvDataApp/misc/thread.h index bfb1407..664a20d 100644 --- a/pvDataApp/misc/thread.h +++ b/pvDataApp/misc/thread.h @@ -8,6 +8,7 @@ #define THREAD_H #include "noDefaultMethods.h" #include "pvType.h" +#include "showConstructDestruct.h" namespace epics { namespace pvData { @@ -27,32 +28,25 @@ public: static int getEpicsPriority(ThreadPriority threadPriority); }; - -class ThreadReady { +class Runnable{ public: - virtual void ready() = 0; -}; - -class RunnableReady { -public: - virtual void run(ThreadReady *threadReady) = 0; + virtual void run() = 0; }; class Thread; class Thread : private NoDefaultMethods { public: - Thread(String name,ThreadPriority priority,RunnableReady *runnableReady); + Thread(String name,ThreadPriority priority,Runnable *runnable); ~Thread(); static ConstructDestructCallback *getConstructDestructCallback(); - void start(); String getName(); ThreadPriority getPriority(); static void showThreads(StringBuilder buf); static void sleep(double seconds); private: - class Runnable *pImpl; - friend class Runnable; + class ThreadPvt *pImpl; + friend class ThreadPvt; }; }} diff --git a/pvDataApp/misc/timeStamp.cpp b/pvDataApp/misc/timeStamp.cpp index d147a2c..064001e 100644 --- a/pvDataApp/misc/timeStamp.cpp +++ b/pvDataApp/misc/timeStamp.cpp @@ -24,8 +24,44 @@ int64 posixEpochAtEpicsEpoch = POSIX_TIME_AT_EPICS_EPOCH; TimeStamp::TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds) : secondsPastEpoch(secondsPastEpoch),nanoSeconds(nanoSeconds) -{} +{ + normalize(); +} +void TimeStamp::normalize() +{ + if(nanoSeconds>=0 && nanoSeconds=nanoSecPerSec) { + nanoSeconds -= nanoSecPerSec; + secondsPastEpoch++; + } + while(nanoSeconds<0) { + nanoSeconds += nanoSecPerSec; + secondsPastEpoch--; + } +} + +void TimeStamp::fromTime_t(const time_t & tt) +{ + epicsTimeStamp epicsTime; + epicsTimeFromTime_t(&epicsTime,tt); + secondsPastEpoch = epicsTime.secPastEpoch + posixEpochAtEpicsEpoch; + nanoSeconds = epicsTime.nsec; +} + +void TimeStamp::toTime_t(time_t &tt) const +{ + epicsTimeStamp epicsTime; + epicsTime.secPastEpoch = secondsPastEpoch-posixEpochAtEpicsEpoch; + epicsTime.nsec = nanoSeconds; + epicsTimeToTime_t(&tt,&epicsTime); +} + +void TimeStamp::put(int64 milliseconds) +{ + secondsPastEpoch = milliseconds/1000; + nanoSeconds = (milliseconds%1000)*1000000; +} void TimeStamp::getCurrent() { @@ -144,12 +180,4 @@ int64 TimeStamp::getMilliseconds() return secondsPastEpoch*1000 + nanoSeconds/1000000; } -void TimeStamp::put(int64 milliseconds) -{ - secondsPastEpoch = milliseconds/1000; - nanoSeconds = (milliseconds%1000)*1000000; -} - - - }} diff --git a/pvDataApp/misc/timeStamp.h b/pvDataApp/misc/timeStamp.h index f95654d..4398acc 100644 --- a/pvDataApp/misc/timeStamp.h +++ b/pvDataApp/misc/timeStamp.h @@ -6,6 +6,7 @@ */ #ifndef TIMESTAMP_H #define TIMESTAMP_H +#include #include "epicsTime.h" #include "pvType.h" @@ -20,10 +21,12 @@ class TimeStamp { public: TimeStamp() :secondsPastEpoch(0),nanoSeconds(0) {} + TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0); //default constructors and destructor are OK //This class should not be extended - TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0); - TimeStamp(epicsTimeStamp &epics); + void normalize(); + void fromTime_t(const time_t &); + void toTime_t(time_t &) const; int64 getSecondsPastEpoch() const {return secondsPastEpoch;} int64 getEpicsSecondsPastEpoch() const { return secondsPastEpoch - posixEpochAtEpicsEpoch; @@ -32,7 +35,9 @@ public: void put(int64 secondsPastEpoch,int32 nanoSeconds = 0) { this->secondsPastEpoch = secondsPastEpoch; this->nanoSeconds = nanoSeconds; + normalize(); } + void put(int64 milliseconds); void getCurrent(); double toSeconds() const ; bool operator==(TimeStamp const &) const; @@ -46,10 +51,7 @@ public: TimeStamp & operator-=(int64 seconds); TimeStamp & operator+=(double seconds); TimeStamp & operator-=(double seconds); - // milliseconds since epoch - int64 getMilliseconds(); - void put(int64 milliseconds); - + int64 getMilliseconds(); // milliseconds since epoch private: static int64 diffInt(TimeStamp const &left,TimeStamp const &right ); int64 secondsPastEpoch; diff --git a/pvDataApp/misc/timer.cpp b/pvDataApp/misc/timer.cpp index 5fbd531..48231ec 100644 --- a/pvDataApp/misc/timer.cpp +++ b/pvDataApp/misc/timer.cpp @@ -87,14 +87,14 @@ ConstructDestructCallback * Timer::getConstructDestructCallback() class TimerNodePvt; -typedef LinkedListNode ListNode; -typedef LinkedList List; +typedef LinkedListNode TimerListNode; +typedef LinkedList TimerList; class TimerNodePvt { public: TimerNode *timerNode; TimerCallback *callback; - ListNode *listNode; + TimerListNode *timerListNode; TimeStamp timeToRun; TimerPvt *timerPvt; double period; @@ -104,65 +104,63 @@ public: TimerNodePvt::TimerNodePvt(TimerNode *timerNode,TimerCallback *callback) : timerNode(timerNode),callback(callback), - listNode(new ListNode(this)),timeToRun(TimeStamp()), + timerListNode(new TimerListNode(this)),timeToRun(TimeStamp()), timerPvt(0), period(0.0) {} TimerNodePvt::~TimerNodePvt() { - delete listNode; + delete timerListNode; } -struct TimerPvt : public RunnableReady { +struct TimerPvt : public Runnable{ public: TimerPvt(String threadName,ThreadPriority priority); ~TimerPvt(); - virtual void run(ThreadReady *threadReady); + virtual void run(); public: // only used by this source module - List *list; + TimerList *timerList; Mutex mutex; Event *waitForWork; Event *waitForDone; - Thread *thread; volatile bool alive; + Thread *thread; }; TimerPvt::TimerPvt(String threadName,ThreadPriority priority) -: list(new List()), +: timerList(new TimerList()), mutex(Mutex()), - waitForWork(new Event(eventEmpty)), - waitForDone(new Event(eventEmpty)), - thread(new Thread(threadName,priority,this)), - alive(true) -{ - thread->start(); -} + waitForWork(new Event(false)), + waitForDone(new Event(false)), + alive(true), + thread(new Thread(threadName,priority,this)) +{} TimerPvt::~TimerPvt() { delete thread; delete waitForDone; delete waitForWork; - delete list; + delete timerList; } static void addElement(TimerPvt *timer,TimerNodePvt *node) { - List *list = timer->list; - ListNode *nextNode = list->getHead(); + TimerList *timerList = timer->timerList; + TimerListNode *nextNode = timerList->getHead(); if(nextNode==0) { - list->addTail(node->listNode); + timerList->addTail(node->timerListNode); return; } while(true) { - TimerNodePvt *listNode = nextNode->getObject(); - if((node->timeToRun)<(listNode->timeToRun)) { - list->insertBefore(listNode->listNode,node->listNode); + TimerNodePvt *timerListNode = nextNode->getObject(); + if((node->timeToRun)<(timerListNode->timeToRun)) { + timerList->insertBefore(timerListNode->timerListNode,node->timerListNode); return; } - nextNode = list->getNext(listNode->listNode); + nextNode = timerList->getNext(timerListNode->timerListNode); if(nextNode==0) { - list->addTail(node->listNode); + timerList->addTail(node->timerListNode); return; } } @@ -177,31 +175,22 @@ TimerNode::TimerNode(TimerCallback *callback) totalNodeConstruct++; } -TimerNode *TimerNode::create(TimerCallback *callback) -{ - return new TimerNode(callback); -} TimerNode::~TimerNode() { + cancel(); delete pImpl; Lock xx(globalMutex); totalNodeDestruct++; } -void TimerNode::destroy() -{ - cancel(); - delete this; -} - void TimerNode::cancel() { TimerPvt *timerPvt = pImpl->timerPvt; if(timerPvt==0) return; Lock xx(&timerPvt->mutex); if(pImpl->timerPvt==0) return; - pImpl->timerPvt->list->remove(pImpl); + pImpl->timerPvt->timerList->remove(pImpl); pImpl->timerPvt = 0; } @@ -210,13 +199,12 @@ bool TimerNode::isScheduled() TimerPvt *pvt = pImpl->timerPvt; if(pvt==0) return false; Lock xx(&pvt->mutex); - return pImpl->listNode->isOnList(); + return pImpl->timerListNode->isOnList(); } -void TimerPvt::run(ThreadReady *threadReady) +void TimerPvt::run() { - threadReady->ready(); TimeStamp currentTime; while(alive) { currentTime.getCurrent(); @@ -225,25 +213,25 @@ void TimerPvt::run(ThreadReady *threadReady) TimerNodePvt *nodeToCall = 0; { Lock xx(&mutex); - ListNode *listNode = list->getHead(); - if(listNode!=0) { - TimerNodePvt *timerNodePvt = listNode->getObject(); + TimerListNode *timerListNode = timerList->getHead(); + if(timerListNode!=0) { + TimerNodePvt *timerNodePvt = timerListNode->getObject(); timeToRun = &timerNodePvt->timeToRun; double diff = TimeStamp::diff( *timeToRun,currentTime); if(diff<=0.0) { nodeToCall = timerNodePvt; - list->removeHead(); + timerList->removeHead(); period = timerNodePvt->period; - if(period>0) { + if(period>0.0) { timerNodePvt->timeToRun += period; addElement(this,timerNodePvt); } else { timerNodePvt->timerPvt = 0; } - listNode = list->getHead(); - if(listNode!=0) { - timerNodePvt = listNode->getObject(); + timerListNode = timerList->getHead(); + if(timerListNode!=0) { + timerNodePvt = timerListNode->getObject(); timeToRun = &timerNodePvt->timeToRun; } else { timeToRun = 0; @@ -273,31 +261,21 @@ Timer::Timer(String threadName, ThreadPriority priority) totalTimerConstruct++; } -Timer * Timer::create(String threadName, ThreadPriority priority) -{ - return new Timer(threadName,priority); -} - Timer::~Timer() { - delete pImpl; - Lock xx(globalMutex); - totalTimerDestruct++; -} - -void Timer::destroy() -{ { Lock xx(&pImpl->mutex); pImpl->alive = false; - pImpl->waitForWork->signal(); - pImpl->waitForDone->wait(); } - List *list = pImpl->list; - ListNode *node = 0; - while((node = list->removeHead())!=0) { + pImpl->waitForWork->signal(); + pImpl->waitForDone->wait(); + TimerList *timerList = pImpl->timerList; + TimerListNode *node = 0; + while((node = timerList->removeHead())!=0) { node->getObject()->callback->timerStopped(); } - delete this; + delete pImpl; + Lock xx(globalMutex); + totalTimerDestruct++; } void Timer::scheduleAfterDelay(TimerNode *timerNode,double delay) @@ -307,7 +285,7 @@ void Timer::scheduleAfterDelay(TimerNode *timerNode,double delay) void Timer::schedulePeriodic(TimerNode *timerNode,double delay,double period) { TimerNodePvt *timerNodePvt = timerNode->pImpl; - if(timerNodePvt->listNode->isOnList()) { + if(timerNodePvt->timerListNode->isOnList()) { throw std::logic_error(String("already queued")); } if(!pImpl->alive) { @@ -323,7 +301,7 @@ void Timer::schedulePeriodic(TimerNode *timerNode,double delay,double period) Lock xx(&pImpl->mutex); timerNodePvt->timerPvt = pImpl; addElement(pImpl,timerNodePvt); - TimerNodePvt *first = pImpl->list->getHead()->getObject(); + TimerNodePvt *first = pImpl->timerList->getHead()->getObject(); if(first==timerNodePvt) isFirst = true; } if(isFirst) pImpl->waitForWork->signal(); diff --git a/pvDataApp/misc/timer.h b/pvDataApp/misc/timer.h index f71d3fa..00f3e88 100644 --- a/pvDataApp/misc/timer.h +++ b/pvDataApp/misc/timer.h @@ -27,28 +27,24 @@ public: class TimerNode : private NoDefaultMethods { public: + TimerNode(TimerCallback *timerCallback); + ~TimerNode(); static ConstructDestructCallback *getConstructDestructCallback(); - static TimerNode *create(TimerCallback *timerCallback); - void destroy(); void cancel(); bool isScheduled(); private: - TimerNode(TimerCallback *timerCallback); - ~TimerNode(); class TimerNodePvt *pImpl; friend class Timer; }; class Timer : private NoDefaultMethods { public: + Timer(String threadName, ThreadPriority priority); + ~Timer(); static ConstructDestructCallback *getConstructDestructCallback(); - static Timer * create(String threadName, ThreadPriority priority); - void destroy(); void scheduleAfterDelay(TimerNode *timerNode,double delay); void schedulePeriodic(TimerNode *timerNode,double delay,double period); private: - Timer(String threadName, ThreadPriority priority); - ~Timer(); class TimerPvt *pImpl; friend class TimerNode; }; diff --git a/pvDataApp/miscTest/testLinkedList.cpp b/pvDataApp/miscTest/testLinkedList.cpp index f05cb0f..0ab3ffc 100644 --- a/pvDataApp/miscTest/testLinkedList.cpp +++ b/pvDataApp/miscTest/testLinkedList.cpp @@ -352,7 +352,7 @@ static void testTimeLocked(FILE *auxFd) { } typedef std::list stdList; -static void testArrayListTime(FILE *auxFd) { +static void testStdListTime(FILE *auxFd) { TimeStamp startTime; TimeStamp endTime; int numNodes = 1000; @@ -362,7 +362,7 @@ static void testArrayListTime(FILE *auxFd) { for(int i=0; iconstuctDestructTotals(fd); return (0); } diff --git a/pvDataApp/miscTest/testThread.cpp b/pvDataApp/miscTest/testThread.cpp index c54ed55..35e5b15 100644 --- a/pvDataApp/miscTest/testThread.cpp +++ b/pvDataApp/miscTest/testThread.cpp @@ -43,7 +43,7 @@ private: Basic::Basic(Executor *executor) : executor(executor), executorNode(executor->createNode(this)), - wait(new Event(eventEmpty)) + wait(new Event()) { } @@ -55,7 +55,7 @@ void Basic::run() { executor->execute(executorNode); bool result = wait->wait(); - if(result==false) printf("basic::run wait returned true\n"); + if(result==false) printf("basic::run wait returned false\n"); } void Basic::command() @@ -65,14 +65,14 @@ void Basic::command() static void testBasic(FILE *fd) { - Executor *executor = Executor::create(String("basic"),middlePriority); + Executor *executor = new Executor(String("basic"),middlePriority); Basic *basic = new Basic(executor); basic->run(); delete basic; String buf(""); Thread::showThreads(&buf); fprintf(fd,"threads\n%s\n",buf.c_str()); - executor->destroy(); + delete executor; } class MyFunc : public TimeFunctionRequester { @@ -89,7 +89,7 @@ private: }; static void testThreadContext(FILE *fd,FILE *auxFd) { - Executor *executor = Executor::create(String("basic"),middlePriority); + Executor *executor = new Executor(String("basic"),middlePriority); Basic *basic = new Basic(executor); MyFunc myFunc(basic); TimeFunction timeFunction(&myFunc); @@ -97,7 +97,7 @@ static void testThreadContext(FILE *fd,FILE *auxFd) { perCall *= 1e6; fprintf(auxFd,"time per call %f microseconds\n",perCall); delete basic; - executor->destroy(); + delete executor; } int main(int argc, char *argv[]) { diff --git a/pvDataApp/miscTest/testTimeStamp.cpp b/pvDataApp/miscTest/testTimeStamp.cpp index 484174c..c148284 100644 --- a/pvDataApp/miscTest/testTimeStamp.cpp +++ b/pvDataApp/miscTest/testTimeStamp.cpp @@ -14,7 +14,9 @@ #include #include #include +#include #include +#include #include #include @@ -32,6 +34,30 @@ void testTimeStamp(FILE *fd,FILE *auxfd) current.getSecondsPastEpoch(), current.getNanoSeconds(), current.getMilliseconds()); + time_t tt; + current.toTime_t(tt); + struct tm ctm; + memcpy(&ctm,localtime(&tt),sizeof(struct tm)); + fprintf(auxfd, + "%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d nanoSeconds isDst %s\n", + ctm.tm_year+1900,ctm.tm_mon + 1,ctm.tm_mday, + ctm.tm_hour,ctm.tm_min,ctm.tm_sec, + current.getNanoSeconds(), + (ctm.tm_isdst==0) ? "false" : "true"); + tt = time(&tt); + current.fromTime_t(tt); + fprintf(auxfd,"fromTime_t\ncurrent %lli %i milliSec %lli\n", + current.getSecondsPastEpoch(), + current.getNanoSeconds(), + current.getMilliseconds()); + current.toTime_t(tt); + memcpy(&ctm,localtime(&tt),sizeof(struct tm)); + fprintf(auxfd, + "%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d %d nanoSeconds isDst %s\n", + ctm.tm_year+1900,ctm.tm_mon + 1,ctm.tm_mday, + ctm.tm_hour,ctm.tm_min,ctm.tm_sec, + current.getNanoSeconds(), + (ctm.tm_isdst==0) ? "false" : "true"); TimeStamp right; TimeStamp left; right.put(current.getSecondsPastEpoch(),current.getNanoSeconds()); diff --git a/pvDataApp/miscTest/testTimer.cpp b/pvDataApp/miscTest/testTimer.cpp index f5b1bc5..062e15c 100644 --- a/pvDataApp/miscTest/testTimer.cpp +++ b/pvDataApp/miscTest/testTimer.cpp @@ -33,12 +33,12 @@ class MyCallback : public TimerCallback { public: MyCallback(String name,FILE *fd,FILE *auxfd,Event *wait) : name(name),fd(fd),auxfd(auxfd),wait(wait), - timerNode(TimerNode::create(this)),timeStamp(TimeStamp()) + timerNode(new TimerNode(this)),timeStamp(TimeStamp()) { } ~MyCallback() { - timerNode->destroy(); + delete timerNode; } virtual void callback() { @@ -64,9 +64,9 @@ static void testBasic(FILE *fd, FILE *auxfd) { String one("one"); String two("two"); - Event *eventOne = new Event(eventEmpty); - Event *eventTwo = new Event(eventEmpty); - Timer *timer = Timer::create(String("timer"),middlePriority); + Event *eventOne = new Event(); + Event *eventTwo = new Event(); + Timer *timer = new Timer(String("timer"),middlePriority); MyCallback *callbackOne = new MyCallback( one,fd,auxfd,eventOne); MyCallback *callbackTwo = new MyCallback( @@ -83,11 +83,11 @@ static void testBasic(FILE *fd, FILE *auxfd) diff = TimeStamp::diff( callbackTwo->getTimeStamp(),currentTimeStamp); fprintf(auxfd,"two requested %f diff %f seconds\n",twoDelay,diff); - timer->destroy(); - delete callbackOne; + delete timer; delete callbackTwo; - delete eventOne; + delete callbackOne; delete eventTwo; + delete eventOne; } int main(int argc, char *argv[]) { diff --git a/pvDataApp/pv/MakefileBack b/pvDataApp/pv/MakefileBack deleted file mode 100644 index 88392ec..0000000 --- a/pvDataApp/pv/MakefileBack +++ /dev/null @@ -1,15 +0,0 @@ -TOP=../.. - -include $(TOP)/configure/CONFIG - -INC += pvIntrospect.h -INC += bitSet.h -INC += requester.h -INC += byteBuffer.h -INC += serialize.h -INC += pvData.h - -include $(TOP)/configure/RULES -#---------------------------------------- -# ADD RULES AFTER THIS LINE - diff --git a/pvDataApp/pv/convert.h b/pvDataApp/pv/convert.h index 2800b91..1544bc0 100644 --- a/pvDataApp/pv/convert.h +++ b/pvDataApp/pv/convert.h @@ -13,76 +13,76 @@ namespace epics { namespace pvData { - class Convert : NoDefaultMethods { - public: - Convert(); - ~Convert(); - void getFullName(StringBuilder buf,PVField *pvField); - 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); - 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); - bool isCopyStructureCompatible( - StructureConstPtr from, StructureConstPtr to); - void copyStructure(PVStructure *from, PVStructure *to); - bool isCopyStructureArrayCompatible( - StructureArrayConstPtr from, StructureArrayConstPtr 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); - 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); - }; +class Convert : NoDefaultMethods { +public: + Convert(); + ~Convert(); + void getFullName(StringBuilder buf,PVField *pvField); + 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); + 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); + bool isCopyStructureCompatible( + StructureConstPtr from, StructureConstPtr to); + void copyStructure(PVStructure *from, PVStructure *to); + bool isCopyStructureArrayCompatible( + StructureArrayConstPtr from, StructureArrayConstPtr 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); + 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); +}; - extern Convert * getConvert(); +extern Convert * getConvert(); }} #endif /* CONVERT_H */ diff --git a/pvDataApp/pv/pvData.h b/pvDataApp/pv/pvData.h index 37c2f5b..d190038 100644 --- a/pvDataApp/pv/pvData.h +++ b/pvDataApp/pv/pvData.h @@ -17,510 +17,510 @@ #include "showConstructDestruct.h" namespace epics { namespace pvData { - class PVAuxInfo; - class PostHandler; +class PVAuxInfo; +class PostHandler; - class PVField; - class PVScalar; - class PVBoolean; - class PVByte; - class PVShort; - class PVInt; - class PVLong; - class PVFloat; - class PVDouble; - class PVString; +class PVField; +class PVScalar; +class PVBoolean; +class PVByte; +class PVShort; +class PVInt; +class PVLong; +class PVFloat; +class PVDouble; +class PVString; - class PVScalarArray; - class PVBooleanArray; - class PVByteArray; - class PVShortArray; - class PVIntArray; - class PVLongArray; - class PVFloatArray; - class PVDoubleArray; - class PVStringArray; +class PVScalarArray; +class PVBooleanArray; +class PVByteArray; +class PVShortArray; +class PVIntArray; +class PVLongArray; +class PVFloatArray; +class PVDoubleArray; +class PVStringArray; - class PVStructure; - class PVStructureArray; +class PVStructure; +class PVStructureArray; - typedef std::map PVScalarMap; - typedef PVScalarMap::const_iterator PVScalarMapIter; - typedef PVStructure * PVStructurePtr; - typedef PVStructurePtr* PVStructurePtrArray; - typedef PVField* PVFieldPtr; - typedef PVFieldPtr * PVFieldPtrArray; - typedef bool * BooleanArray; - typedef int8 * ByteArray; - typedef int16 * ShortArray; - typedef int32 * IntArray; - typedef int64 * LongArray; - typedef float * FloatArray; - typedef double * DoubleArray; - typedef String * StringArray; +typedef std::map PVScalarMap; +typedef PVScalarMap::const_iterator PVScalarMapIter; +typedef PVStructure * PVStructurePtr; +typedef PVStructurePtr* PVStructurePtrArray; +typedef PVField* PVFieldPtr; +typedef PVFieldPtr * PVFieldPtrArray; +typedef bool * BooleanArray; +typedef int8 * ByteArray; +typedef int16 * ShortArray; +typedef int32 * IntArray; +typedef int64 * LongArray; +typedef float * FloatArray; +typedef double * DoubleArray; +//typedef String * StringArray; alreadt defined in pvType.h - class PVAuxInfo : private NoDefaultMethods { - public: - PVAuxInfo(PVField *pvField); - ~PVAuxInfo(); - static ConstructDestructCallback *getConstructDestructCallback(); - PVField * getPVField(); - PVScalar * createInfo(String key,ScalarType scalarType); - PVScalarMap getInfos(); - PVScalar * getInfo(String key); - void toString(StringBuilder buf); - void toString(StringBuilder buf,int indentLevel); - private: - class PVAuxInfoPvt *pImpl; - friend class PVDataCreate; - }; +class PVAuxInfo : private NoDefaultMethods { +public: + PVAuxInfo(PVField *pvField); + ~PVAuxInfo(); + static ConstructDestructCallback *getConstructDestructCallback(); + PVField * getPVField(); + PVScalar * createInfo(String key,ScalarType scalarType); + PVScalarMap getInfos(); + PVScalar * getInfo(String key); + void toString(StringBuilder buf); + void toString(StringBuilder buf,int indentLevel); +private: + class PVAuxInfoPvt *pImpl; + friend class PVDataCreate; +}; - class PostHandler { - public: - virtual void postPut() = 0; - }; +class PostHandler { +public: + virtual void postPut() = 0; +}; - class PVField - : public Requester, - public Serializable, - private NoDefaultMethods - { - public: - virtual ~PVField(); - static ConstructDestructCallback *getConstructDestructCallback(); - String getRequesterName() ; - virtual void message(String message,MessageType messageType) ; - virtual void setRequester(Requester *prequester); - int getFieldOffset() ; - int getNextFieldOffset() ; - int getNumberFields() ; - PVAuxInfo * getPVAuxInfo(); - bool isImmutable() ; - void setImmutable(); - FieldConstPtr getField() ; - PVStructure * getParent() ; - void replacePVField(PVField * newPVField); - void renameField(String newName); - void postPut() ; - void setPostHandler(PostHandler *postHandler); - virtual void toString(StringBuilder buf) ; - virtual void toString(StringBuilder buf,int indentLevel) ; - virtual bool operator==(PVField &pv) = 0; - virtual bool operator!=(PVField &pv) = 0; - protected: - PVField(PVStructure *parent,FieldConstPtr field); - void replaceStructure(PVStructure *pvStructure); - private: - class PVFieldPvt *pImpl; - static void computeOffset(PVField *pvField); - static void computeOffset(PVField *pvField,int offset); - friend class PVDataCreate; - }; +class PVField +: public Requester, + public Serializable, + private NoDefaultMethods +{ +public: + virtual ~PVField(); + static ConstructDestructCallback *getConstructDestructCallback(); + String getRequesterName() ; + virtual void message(String message,MessageType messageType) ; + virtual void setRequester(Requester *prequester); + int getFieldOffset() ; + int getNextFieldOffset() ; + int getNumberFields() ; + PVAuxInfo * getPVAuxInfo(); + bool isImmutable() ; + void setImmutable(); + FieldConstPtr getField() ; + PVStructure * getParent() ; + void replacePVField(PVField * newPVField); + void renameField(String newName); + void postPut() ; + void setPostHandler(PostHandler *postHandler); + virtual void toString(StringBuilder buf) ; + virtual void toString(StringBuilder buf,int indentLevel) ; + virtual bool operator==(PVField &pv) = 0; + virtual bool operator!=(PVField &pv) = 0; +protected: + PVField(PVStructure *parent,FieldConstPtr field); + void replaceStructure(PVStructure *pvStructure); +private: + class PVFieldPvt *pImpl; + static void computeOffset(PVField *pvField); + static void computeOffset(PVField *pvField,int offset); + friend class PVDataCreate; +}; - class PVScalar : public PVField { - public: - virtual ~PVScalar(); - ScalarConstPtr getScalar() ; - protected: - PVScalar(PVStructure *parent,ScalarConstPtr scalar); - }; +class PVScalar : public PVField { +public: + virtual ~PVScalar(); + ScalarConstPtr getScalar() ; +protected: + PVScalar(PVStructure *parent,ScalarConstPtr scalar); +}; - class PVArray : public PVField, public SerializableArray { - public: - virtual ~PVArray(); - int getLength() ; - void setLength(int length); - int getCapacity() ; - bool isCapacityMutable() ; - void setCapacityMutable(bool isMutable); - virtual void setCapacity(int capacity) = 0; - virtual void serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer, - DeserializableControl *pflusher) = 0; - virtual void serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) = 0; - protected: - PVArray(PVStructure *parent,FieldConstPtr field); - void setCapacityLength(int capacity,int length); - private: - class PVArrayPvt * pImpl; - }; +class PVArray : public PVField, public SerializableArray { +public: + virtual ~PVArray(); + int getLength() ; + void setLength(int length); + int getCapacity() ; + bool isCapacityMutable() ; + void setCapacityMutable(bool isMutable); + virtual void setCapacity(int capacity) = 0; + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer, + DeserializableControl *pflusher) = 0; + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher, int offset, int count) = 0; +protected: + PVArray(PVStructure *parent,FieldConstPtr field); + void setCapacityLength(int capacity,int length); +private: + class PVArrayPvt * pImpl; +}; - class PVScalarArray : public PVArray { - public: - virtual ~PVScalarArray(); - ScalarArrayConstPtr getScalarArray() ; - virtual void setCapacity(int capacity) = 0; - virtual void serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer, - DeserializableControl *pflusher) = 0; - virtual void serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) = 0; - protected: - PVScalarArray(PVStructure *parent,ScalarArrayConstPtr scalarArray); - private: - }; +class PVScalarArray : public PVArray { +public: + virtual ~PVScalarArray(); + ScalarArrayConstPtr getScalarArray() ; + virtual void setCapacity(int capacity) = 0; + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer, + DeserializableControl *pflusher) = 0; + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher, int offset, int count) = 0; +protected: + PVScalarArray(PVStructure *parent,ScalarArrayConstPtr scalarArray); +private: +}; - class StructureArrayData { - public: - PVStructurePtrArray data; - int offset; - }; +class StructureArrayData { +public: + PVStructurePtrArray data; + int offset; +}; - class PVStructureArray : public PVArray { - public: - virtual ~PVStructureArray(); - virtual StructureArrayConstPtr getStructureArray() = 0; - virtual void setCapacity(int capacity) = 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; - virtual void serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher) = 0 ; - virtual void deserialize(ByteBuffer *buffer, - DeserializableControl *pflusher) = 0; - virtual void serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) = 0; - protected: - PVStructureArray(PVStructure *parent, - StructureArrayConstPtr structureArray); - private: - }; - - - 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); - 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(); - bool putExtendsStructureName( - String extendsStructureName); - virtual bool operator==(PVField &pv) ; - virtual bool operator!=(PVField &pv) ; - virtual void serialize( - ByteBuffer *pbuffer,SerializableControl *pflusher) ; - virtual void deserialize( - ByteBuffer *pbuffer,DeserializableControl *pflusher); - virtual void serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher, int offset, int count) ; - virtual void serialize(ByteBuffer *pbuffer, - SerializableControl *pflusher,BitSet *pbitSet) ; - virtual void deserialize(ByteBuffer *pbuffer, - DeserializableControl*pflusher,BitSet *pbitSet); - protected: - PVStructure(PVStructure *parent,StructureConstPtr structure); - private: - class PVStructurePvt * pImpl; - }; - - class PVBoolean : public PVScalar { - public: - virtual ~PVBoolean(); - virtual bool get() = 0; - virtual void put(bool value) = 0; - protected: - PVBoolean(PVStructure *parent,ScalarConstPtr scalar) - : PVScalar(parent,scalar) {} - private: - }; - - class PVByte : public PVScalar { - public: - virtual ~PVByte(); - virtual int8 get() = 0; - virtual void put(int8 value) = 0; - protected: - PVByte(PVStructure *parent,ScalarConstPtr scalar) - : PVScalar(parent,scalar) {} - private: - }; - - class PVShort : public PVScalar { - public: - virtual ~PVShort(); - virtual int16 get() = 0; - virtual void put(int16 value) = 0; - protected: - PVShort(PVStructure *parent,ScalarConstPtr scalar) - : PVScalar(parent,scalar) {} - private: - }; - - class PVInt : public PVScalar{ - public: - virtual ~PVInt(); - virtual int32 get() = 0; - virtual void put(int32 value) = 0; - protected: - PVInt(PVStructure *parent,ScalarConstPtr scalar) - : PVScalar(parent,scalar) {} - private: - }; - - class PVLong : public PVScalar { - public: - virtual ~PVLong(); - virtual int64 get() = 0; - virtual void put(int64 value) = 0; - protected: - PVLong(PVStructure *parent,ScalarConstPtr scalar) - : PVScalar(parent,scalar) {} - private: - }; - - class PVFloat : public PVScalar { - public: - virtual ~PVFloat(); - virtual float get() = 0; - virtual void put(float value) = 0; - protected: - PVFloat(PVStructure *parent,ScalarConstPtr scalar) - : PVScalar(parent,scalar) {} - private: - }; - - class PVDouble : public PVScalar { - public: - virtual ~PVDouble(); - virtual double get() = 0; - virtual void put(double value) = 0; - protected: - PVDouble(PVStructure *parent,ScalarConstPtr scalar) - : PVScalar(parent,scalar) {} - private: - }; - - class PVString : public PVScalar { - public: - virtual ~PVString(); - virtual String get() = 0; - virtual void put(String value) = 0; - protected: - PVString(PVStructure *parent,ScalarConstPtr scalar) - : PVScalar(parent,scalar) {} - private: - }; - - class BooleanArrayData { - public: - BooleanArray data; - int offset; - }; - - class PVBooleanArray : public PVScalarArray { - public: - virtual ~PVBooleanArray(); - virtual void setCapacity(int capacity) = 0; - virtual int get(int offset, int length, BooleanArrayData *data) = 0; - virtual int put(int offset,int length, BooleanArray from, int fromOffset) = 0; - virtual void shareData(BooleanArray value,int capacity,int length) = 0; - virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0; - protected: - PVBooleanArray(PVStructure *parent,ScalarArrayConstPtr scalar); - private: - }; +class PVStructureArray : public PVArray { +public: + virtual ~PVStructureArray(); + virtual StructureArrayConstPtr getStructureArray() = 0; + virtual void setCapacity(int capacity) = 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; + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher) = 0 ; + virtual void deserialize(ByteBuffer *buffer, + DeserializableControl *pflusher) = 0; + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher, int offset, int count) = 0; +protected: + PVStructureArray(PVStructure *parent, + StructureArrayConstPtr structureArray); +private: +}; - class ByteArrayData { - public: - ByteArray data; - int offset; - }; +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); + 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(); + bool putExtendsStructureName( + String extendsStructureName); + virtual bool operator==(PVField &pv) ; + virtual bool operator!=(PVField &pv) ; + virtual void serialize( + ByteBuffer *pbuffer,SerializableControl *pflusher) ; + virtual void deserialize( + ByteBuffer *pbuffer,DeserializableControl *pflusher); + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher, int offset, int count) ; + virtual void serialize(ByteBuffer *pbuffer, + SerializableControl *pflusher,BitSet *pbitSet) ; + virtual void deserialize(ByteBuffer *pbuffer, + DeserializableControl*pflusher,BitSet *pbitSet); +protected: + PVStructure(PVStructure *parent,StructureConstPtr structure); +private: + class PVStructurePvt * pImpl; +}; - class PVByteArray : public PVScalarArray { - public: - virtual ~PVByteArray(); - virtual void setCapacity(int capacity) = 0; - virtual int get(int offset, int length, ByteArrayData *data) = 0; - virtual int put(int offset,int length, ByteArray from, int fromOffset) = 0; - virtual void shareData(ByteArray value,int capacity,int length) = 0; - virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0; - protected: - PVByteArray(PVStructure *parent,ScalarArrayConstPtr scalar); - private: - }; +class PVBoolean : public PVScalar { +public: + virtual ~PVBoolean(); + virtual bool get() = 0; + virtual void put(bool value) = 0; +protected: + PVBoolean(PVStructure *parent,ScalarConstPtr scalar) + : PVScalar(parent,scalar) {} +private: +}; - class ShortArrayData { - public: - ShortArray data; - int offset; - }; +class PVByte : public PVScalar { +public: + virtual ~PVByte(); + virtual int8 get() = 0; + virtual void put(int8 value) = 0; +protected: + PVByte(PVStructure *parent,ScalarConstPtr scalar) + : PVScalar(parent,scalar) {} +private: +}; - class PVShortArray : public PVScalarArray { - public: - virtual ~PVShortArray(); - virtual void setCapacity(int capacity) = 0; - virtual int get(int offset, int length, ShortArrayData *data) = 0; - virtual int put(int offset,int length, ShortArray from, int fromOffset) = 0; - virtual void shareData(ShortArray value,int capacity,int length) = 0; - virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0; - protected: - PVShortArray(PVStructure *parent,ScalarArrayConstPtr scalar); - private: - }; +class PVShort : public PVScalar { +public: + virtual ~PVShort(); + virtual int16 get() = 0; + virtual void put(int16 value) = 0; +protected: + PVShort(PVStructure *parent,ScalarConstPtr scalar) + : PVScalar(parent,scalar) {} +private: +}; - class IntArrayData { - public: - IntArray data; - int offset; - }; +class PVInt : public PVScalar{ +public: + virtual ~PVInt(); + virtual int32 get() = 0; + virtual void put(int32 value) = 0; +protected: + PVInt(PVStructure *parent,ScalarConstPtr scalar) + : PVScalar(parent,scalar) {} +private: +}; - class PVIntArray : public PVScalarArray { - public: - virtual ~PVIntArray(); - virtual void setCapacity(int capacity) = 0; - virtual int get(int offset, int length, IntArrayData *data) = 0; - virtual int put(int offset,int length, IntArray from, int fromOffset)= 0; - virtual void shareData(IntArray value,int capacity,int length)= 0; - virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0; - protected: - PVIntArray(PVStructure *parent,ScalarArrayConstPtr scalar); - private: - }; +class PVLong : public PVScalar { +public: + virtual ~PVLong(); + virtual int64 get() = 0; + virtual void put(int64 value) = 0; +protected: + PVLong(PVStructure *parent,ScalarConstPtr scalar) + : PVScalar(parent,scalar) {} +private: +}; - class LongArrayData { - public: - LongArray data; - int offset; - }; +class PVFloat : public PVScalar { +public: + virtual ~PVFloat(); + virtual float get() = 0; + virtual void put(float value) = 0; +protected: + PVFloat(PVStructure *parent,ScalarConstPtr scalar) + : PVScalar(parent,scalar) {} +private: +}; - class PVLongArray : public PVScalarArray { - public: - virtual ~PVLongArray(); - virtual void setCapacity(int capacity) = 0; - virtual int get(int offset, int length, LongArrayData *data) = 0; - virtual int put(int offset,int length, LongArray from, int fromOffset)= 0; - virtual void shareData(LongArray value,int capacity,int length)= 0; - virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0; - protected: - PVLongArray(PVStructure *parent,ScalarArrayConstPtr scalar); - private: - }; +class PVDouble : public PVScalar { +public: + virtual ~PVDouble(); + virtual double get() = 0; + virtual void put(double value) = 0; +protected: + PVDouble(PVStructure *parent,ScalarConstPtr scalar) + : PVScalar(parent,scalar) {} +private: +}; + +class PVString : public PVScalar { +public: + virtual ~PVString(); + virtual String get() = 0; + virtual void put(String value) = 0; +protected: + PVString(PVStructure *parent,ScalarConstPtr scalar) + : PVScalar(parent,scalar) {} +private: +}; + +class BooleanArrayData { +public: + BooleanArray data; + int offset; +}; + +class PVBooleanArray : public PVScalarArray { +public: + virtual ~PVBooleanArray(); + virtual void setCapacity(int capacity) = 0; + virtual int get(int offset, int length, BooleanArrayData *data) = 0; + virtual int put(int offset,int length, BooleanArray from, int fromOffset) = 0; + virtual void shareData(BooleanArray value,int capacity,int length) = 0; + virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0; +protected: + PVBooleanArray(PVStructure *parent,ScalarArrayConstPtr scalar); +private: +}; - class FloatArrayData { - public: - FloatArray data; - int offset; - }; +class ByteArrayData { +public: + ByteArray data; + int offset; +}; - class PVFloatArray : public PVScalarArray { - public: - virtual ~PVFloatArray(); - virtual void setCapacity(int capacity) = 0; - virtual int get(int offset, int length, FloatArrayData *data) = 0; - virtual int put(int offset,int length, FloatArray from, int fromOffset)= 0; - virtual void shareData(FloatArray value,int capacity,int length)= 0; - virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0; - protected: - PVFloatArray(PVStructure *parent,ScalarArrayConstPtr scalar); - private: - }; +class PVByteArray : public PVScalarArray { +public: + virtual ~PVByteArray(); + virtual void setCapacity(int capacity) = 0; + virtual int get(int offset, int length, ByteArrayData *data) = 0; + virtual int put(int offset,int length, ByteArray from, int fromOffset) = 0; + virtual void shareData(ByteArray value,int capacity,int length) = 0; + virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0; +protected: + PVByteArray(PVStructure *parent,ScalarArrayConstPtr scalar); +private: +}; + +class ShortArrayData { +public: + ShortArray data; + int offset; +}; + +class PVShortArray : public PVScalarArray { +public: + virtual ~PVShortArray(); + virtual void setCapacity(int capacity) = 0; + virtual int get(int offset, int length, ShortArrayData *data) = 0; + virtual int put(int offset,int length, ShortArray from, int fromOffset) = 0; + virtual void shareData(ShortArray value,int capacity,int length) = 0; + virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0; +protected: + PVShortArray(PVStructure *parent,ScalarArrayConstPtr scalar); +private: +}; + +class IntArrayData { +public: + IntArray data; + int offset; +}; + +class PVIntArray : public PVScalarArray { +public: + virtual ~PVIntArray(); + virtual void setCapacity(int capacity) = 0; + virtual int get(int offset, int length, IntArrayData *data) = 0; + virtual int put(int offset,int length, IntArray from, int fromOffset)= 0; + virtual void shareData(IntArray value,int capacity,int length)= 0; + virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0; +protected: + PVIntArray(PVStructure *parent,ScalarArrayConstPtr scalar); +private: +}; + +class LongArrayData { +public: + LongArray data; + int offset; +}; + +class PVLongArray : public PVScalarArray { +public: + virtual ~PVLongArray(); + virtual void setCapacity(int capacity) = 0; + virtual int get(int offset, int length, LongArrayData *data) = 0; + virtual int put(int offset,int length, LongArray from, int fromOffset)= 0; + virtual void shareData(LongArray value,int capacity,int length)= 0; + virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0; +protected: + PVLongArray(PVStructure *parent,ScalarArrayConstPtr scalar); +private: +}; - class DoubleArrayData { - public: - DoubleArrayData(){} - ~DoubleArrayData(){}; - DoubleArray data; - int offset; - }; +class FloatArrayData { +public: + FloatArray data; + int offset; +}; - class PVDoubleArray : public PVScalarArray { - public: - virtual ~PVDoubleArray(); - virtual void setCapacity(int capacity) = 0; - virtual int get(int offset, int length, DoubleArrayData *data) = 0; - virtual int put(int offset,int length, DoubleArray from, int fromOffset) = 0; - virtual void shareData(DoubleArray value,int capacity,int length) = 0; - virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0; - protected: - PVDoubleArray(PVStructure *parent,ScalarArrayConstPtr scalar); - private: - }; +class PVFloatArray : public PVScalarArray { +public: + virtual ~PVFloatArray(); + virtual void setCapacity(int capacity) = 0; + virtual int get(int offset, int length, FloatArrayData *data) = 0; + virtual int put(int offset,int length, FloatArray from, int fromOffset)= 0; + virtual void shareData(FloatArray value,int capacity,int length)= 0; + virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0; +protected: + PVFloatArray(PVStructure *parent,ScalarArrayConstPtr scalar); +private: +}; - class StringArrayData { - public: - StringArray data; - int offset; - }; +class DoubleArrayData { +public: + DoubleArrayData(){} + ~DoubleArrayData(){}; + DoubleArray data; + int offset; +}; - class PVStringArray : public PVScalarArray { - public: - virtual ~PVStringArray(); - virtual void setCapacity(int capacity) = 0; - virtual int get(int offset, int length, StringArrayData *data) = 0; - virtual int put(int offset,int length, StringArray from, int fromOffset)= 0; - virtual void shareData(StringArray value,int capacity,int length)= 0; - virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; - virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0; - protected: - PVStringArray(PVStructure *parent,ScalarArrayConstPtr scalar); - private: - }; +class PVDoubleArray : public PVScalarArray { +public: + virtual ~PVDoubleArray(); + virtual void setCapacity(int capacity) = 0; + virtual int get(int offset, int length, DoubleArrayData *data) = 0; + virtual int put(int offset,int length, DoubleArray from, int fromOffset) = 0; + virtual void shareData(DoubleArray value,int capacity,int length) = 0; + virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher) = 0; +protected: + PVDoubleArray(PVStructure *parent,ScalarArrayConstPtr scalar); +private: +}; - 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,PVStructure *structToClone); - protected: - PVDataCreate(); - friend PVDataCreate * getPVDataCreate(); - }; - extern PVDataCreate * getPVDataCreate(); +class StringArrayData { +public: + StringArray data; + int offset; +}; + +class PVStringArray : public PVScalarArray { +public: + virtual ~PVStringArray(); + virtual void setCapacity(int capacity) = 0; + virtual int get(int offset, int length, StringArrayData *data) = 0; + virtual int put(int offset,int length, StringArray from, int fromOffset)= 0; + virtual void shareData(StringArray value,int capacity,int length)= 0; + virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) = 0; + virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher)= 0; +protected: + PVStringArray(PVStructure *parent,ScalarArrayConstPtr scalar); +private: +}; + +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,PVStructure *structToClone); +protected: + PVDataCreate(); + friend PVDataCreate * getPVDataCreate(); +}; + +extern PVDataCreate * getPVDataCreate(); }} #endif /* PVDATA_H */ diff --git a/pvDataApp/pv/pvIntrospect.h b/pvDataApp/pv/pvIntrospect.h index 9bb6ab5..1d7902e 100644 --- a/pvDataApp/pv/pvIntrospect.h +++ b/pvDataApp/pv/pvIntrospect.h @@ -13,137 +13,137 @@ #include "showConstructDestruct.h" namespace epics { namespace pvData { - class Field; - class Scalar; - class ScalarArray; - class Structure; - class StructureArray; +class Field; +class Scalar; +class ScalarArray; +class Structure; +class StructureArray; - typedef Field const * FieldConstPtr; - typedef FieldConstPtr * FieldConstPtrArray; - typedef Scalar const * ScalarConstPtr; - typedef ScalarArray const * ScalarArrayConstPtr; - typedef Structure const * StructureConstPtr; - typedef StructureArray const * StructureArrayConstPtr; +typedef Field const * FieldConstPtr; +typedef FieldConstPtr * FieldConstPtrArray; +typedef Scalar const * ScalarConstPtr; +typedef ScalarArray const * ScalarArrayConstPtr; +typedef Structure const * StructureConstPtr; +typedef StructureArray const * StructureArrayConstPtr; - enum Type { - scalar, - scalarArray, - structure, - structureArray - }; +enum Type { + scalar, + scalarArray, + structure, + structureArray +}; - class TypeFunc { - public: - static void toString(StringBuilder buf,const Type type); - }; +class TypeFunc { +public: + static void toString(StringBuilder buf,const Type type); +}; - enum ScalarType { - pvBoolean, - pvByte, - pvShort, - pvInt, - pvLong, - pvFloat, - pvDouble, - pvString - }; +enum ScalarType { + pvBoolean, + pvByte, + pvShort, + pvInt, + pvLong, + pvFloat, + pvDouble, + pvString +}; - class ScalarTypeFunc { - public: - static bool isInteger(ScalarType type); - static bool isNumeric(ScalarType type); - static bool isPrimitive(ScalarType type); - static ScalarType getScalarType(String value); - static void toString(StringBuilder buf,ScalarType scalarType); - }; +class ScalarTypeFunc { +public: + static bool isInteger(ScalarType type); + static bool isNumeric(ScalarType type); + static bool isPrimitive(ScalarType type); + static ScalarType getScalarType(String value); + static void toString(StringBuilder buf,ScalarType scalarType); +}; - class Field : private NoDefaultMethods { - public: - virtual ~Field(); - Field(String fieldName,Type type); - static ConstructDestructCallback *getConstructDestructCallback(); - int getReferenceCount() const; - String getFieldName() const; - Type getType() const; - virtual void toString(StringBuilder buf) const{toString(buf,0);} - virtual void toString(StringBuilder buf,int indentLevel) const; - private: - class FieldPvt *pImpl; - void incReferenceCount() const; - void decReferenceCount() const; - friend class StructureArray; - friend class Structure; - friend class PVFieldPvt; - friend class StandardField; - friend class BasePVStructureArray; - }; +class Field : private NoDefaultMethods { +public: + virtual ~Field(); + Field(String fieldName,Type type); + static ConstructDestructCallback *getConstructDestructCallback(); + int getReferenceCount() const; + String getFieldName() const; + Type getType() const; + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; +private: + class FieldPvt *pImpl; + void incReferenceCount() const; + void decReferenceCount() const; + friend class StructureArray; + friend class Structure; + friend class PVFieldPvt; + friend class StandardField; + friend class BasePVStructureArray; +}; - class Scalar : public Field{ - public: - Scalar(String fieldName,ScalarType scalarType); - virtual ~Scalar(); - ScalarType getScalarType() const {return scalarType;} - virtual void toString(StringBuilder buf) const{toString(buf,0);} - virtual void toString(StringBuilder buf,int indentLevel) const; - private: - ScalarType scalarType; - }; +class Scalar : public Field{ +public: + Scalar(String fieldName,ScalarType scalarType); + virtual ~Scalar(); + ScalarType getScalarType() const {return scalarType;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; +private: + ScalarType scalarType; +}; - class ScalarArray : public Field{ - public: - ScalarArray(String fieldName,ScalarType scalarType); - virtual ~ScalarArray(); - ScalarType getElementType() const {return elementType;} - virtual void toString(StringBuilder buf) const{toString(buf,0);} - virtual void toString(StringBuilder buf,int indentLevel) const; - private: - ScalarType elementType; - }; +class ScalarArray : public Field{ +public: + ScalarArray(String fieldName,ScalarType scalarType); + virtual ~ScalarArray(); + ScalarType getElementType() const {return elementType;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; +private: + ScalarType elementType; +}; - class StructureArray : public Field{ - public: - StructureArray(String fieldName,StructureConstPtr structure); - virtual ~StructureArray(); - StructureConstPtr getStructure() const {return pstructure;} - virtual void toString(StringBuilder buf) const{toString(buf,0);} - virtual void toString(StringBuilder buf,int indentLevel) const; - private: - StructureConstPtr pstructure; - }; +class StructureArray : public Field{ +public: + StructureArray(String fieldName,StructureConstPtr structure); + virtual ~StructureArray(); + StructureConstPtr getStructure() const {return pstructure;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; +private: + StructureConstPtr pstructure; +}; - class Structure : public Field { - public: - Structure(String fieldName, int numberFields,FieldConstPtrArray fields); - virtual ~Structure(); - int getNumberFields() const {return numberFields;} - FieldConstPtr getField(String fieldName) const; - int getFieldIndex(String fieldName) const; - FieldConstPtrArray getFields() const {return fields;} - virtual void toString(StringBuilder buf) const{toString(buf,0);} - virtual void toString(StringBuilder buf,int indentLevel) const; - private: - int numberFields; - FieldConstPtrArray fields; - }; +class Structure : public Field { +public: + Structure(String fieldName, int numberFields,FieldConstPtrArray fields); + virtual ~Structure(); + int getNumberFields() const {return numberFields;} + FieldConstPtr getField(String fieldName) const; + int getFieldIndex(String fieldName) const; + FieldConstPtrArray getFields() const {return fields;} + virtual void toString(StringBuilder buf) const{toString(buf,0);} + virtual void toString(StringBuilder buf,int indentLevel) const; +private: + int numberFields; + FieldConstPtrArray fields; +}; - class FieldCreate : NoDefaultMethods { - public: - FieldConstPtr create(String fieldName,FieldConstPtr field) const; - ScalarConstPtr createScalar(String fieldName,ScalarType scalarType) const; - ScalarArrayConstPtr createScalarArray(String fieldName, - ScalarType elementType) const; - StructureConstPtr createStructure (String fieldName, - int numberFields,FieldConstPtrArray fields) const; - StructureArrayConstPtr createStructureArray(String fieldName, - StructureConstPtr structure) const; - private: - FieldCreate(); - friend FieldCreate * getFieldCreate(); - }; +class FieldCreate : NoDefaultMethods { +public: + FieldConstPtr create(String fieldName,FieldConstPtr field) const; + ScalarConstPtr createScalar(String fieldName,ScalarType scalarType) const; + ScalarArrayConstPtr createScalarArray(String fieldName, + ScalarType elementType) const; + StructureConstPtr createStructure (String fieldName, + int numberFields,FieldConstPtrArray fields) const; + StructureArrayConstPtr createStructureArray(String fieldName, + StructureConstPtr structure) const; +private: + FieldCreate(); + friend FieldCreate * getFieldCreate(); +}; - extern FieldCreate * getFieldCreate(); +extern FieldCreate * getFieldCreate(); }} #endif /* PVINTROSPECT_H */ diff --git a/pvDataApp/pv/standardField.h b/pvDataApp/pv/standardField.h index fdcc9ce..0c7e709 100644 --- a/pvDataApp/pv/standardField.h +++ b/pvDataApp/pv/standardField.h @@ -12,57 +12,57 @@ namespace epics { namespace pvData { - class StandardField : private NoDefaultMethods { - public: - StandardField(); - ~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, - 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, - StringArray choices); - StructureConstPtr enumerated(String fieldName, - StringArray choices, 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 alarm(); - StructureConstPtr timeStamp(); - StructureConstPtr display(); - StructureConstPtr control(); - StructureConstPtr booleanAlarm(); - StructureConstPtr byteAlarm(); - StructureConstPtr shortAlarm(); - StructureConstPtr intAlarm(); - StructureConstPtr longAlarm(); - StructureConstPtr floatAlarm(); - StructureConstPtr doubleAlarm(); - StructureConstPtr enumeratedAlarm(); - private: - static void init(); - }; +class StandardField : private NoDefaultMethods { +public: + StandardField(); + ~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, + 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, + StringArray choices); + StructureConstPtr enumerated(String fieldName, + StringArray choices, 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 alarm(); + StructureConstPtr timeStamp(); + StructureConstPtr display(); + StructureConstPtr control(); + StructureConstPtr booleanAlarm(); + StructureConstPtr byteAlarm(); + StructureConstPtr shortAlarm(); + StructureConstPtr intAlarm(); + StructureConstPtr longAlarm(); + StructureConstPtr floatAlarm(); + StructureConstPtr doubleAlarm(); + StructureConstPtr enumeratedAlarm(); +private: + static void init(); +}; - extern StandardField * getStandardField(); +extern StandardField * getStandardField(); }} #endif /* STANDARDFIELD_H */ diff --git a/pvDataApp/pv/standardPVField.h b/pvDataApp/pv/standardPVField.h index be1ea74..3600e34 100644 --- a/pvDataApp/pv/standardPVField.h +++ b/pvDataApp/pv/standardPVField.h @@ -13,54 +13,54 @@ namespace epics { namespace pvData { - 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); - PVStructure * enumerated(PVStructure *parent, - String fieldName,StringArray choices, 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 : 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); + PVStructure * enumerated(PVStructure *parent, + String fieldName,StringArray choices, 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); +}; - extern StandardPVField * getStandardPVField(); +extern StandardPVField * getStandardPVField(); }} #endif /* STANDARDPVFIELD_H */ diff --git a/test/testIntrospect b/test/testIntrospect index ae84a81..9de4a2d 100644 --- a/test/testIntrospect +++ b/test/testIntrospect @@ -77,5 +77,7 @@ structure value structure timeStamp long secondsPastEpoch int nanoSeconds +linkedListNode: totalConstruct 5 totalDestruct 0 +linkedList: totalConstruct 1 totalDestruct 0 field: totalConstruct 156 totalDestruct 63 totalReference 93 pvField: totalConstruct 55 totalDestruct 55 diff --git a/test/testIntrospectGold b/test/testIntrospectGold index ae84a81..9de4a2d 100644 --- a/test/testIntrospectGold +++ b/test/testIntrospectGold @@ -77,5 +77,7 @@ structure value structure timeStamp long secondsPastEpoch int nanoSeconds +linkedListNode: totalConstruct 5 totalDestruct 0 +linkedList: totalConstruct 1 totalDestruct 0 field: totalConstruct 156 totalDestruct 63 totalReference 93 pvField: totalConstruct 55 totalDestruct 55 diff --git a/test/testLinkedListAux b/test/testLinkedListAux index 0dbfb83..5b7cd91 100644 --- a/test/testLinkedListAux +++ b/test/testLinkedListAux @@ -1,20 +1,20 @@ Time test -diff 25.093909 milliSeconds -time per iteration 25.093909 microseconds -time per addTail/removeHead 0.012547 microseconds +diff 30.073240 milliSeconds +time per iteration 30.073240 microseconds +time per addTail/removeHead 0.015037 microseconds Time test locked -diff 176.854724 milliSeconds -time per iteration 176.854724 microseconds -time per addTail/removeHead 0.088427 microseconds +diff 188.396252 milliSeconds +time per iteration 188.396252 microseconds +time per addTail/removeHead 0.094198 microseconds -Time ArrayList test -diff 651.776054 milliSeconds -time per iteration 651.776054 microseconds -time per addTail/removeHead 0.325888 microseconds +Time std::list test +diff 656.937507 milliSeconds +time per iteration 656.937507 microseconds +time per addTail/removeHead 0.328469 microseconds -Time ArrayList test locked -diff 808.411295 milliSeconds -time per iteration 808.411295 microseconds -time per addTail/removeHead 0.404206 microseconds +Time std::list test locked +diff 814.306906 milliSeconds +time per iteration 814.306906 microseconds +time per addTail/removeHead 0.407153 microseconds diff --git a/test/testPVAuxInfo b/test/testPVAuxInfo index 533839c..cd08a3d 100644 --- a/test/testPVAuxInfo +++ b/test/testPVAuxInfo @@ -33,6 +33,8 @@ units offset 11 next 12 number 1 limit offset 12 next 15 number 3 low offset 13 next 14 number 1 high offset 14 next 15 number 1 +linkedListNode: totalConstruct 6 totalDestruct 0 +linkedList: totalConstruct 1 totalDestruct 0 field: totalConstruct 111 totalDestruct 18 totalReference 93 pvField: totalConstruct 17 totalDestruct 17 pvAuxInfo: totalConstruct 1 totalDestruct 1 diff --git a/test/testPVAuxInfoGold b/test/testPVAuxInfoGold index 533839c..cd08a3d 100644 --- a/test/testPVAuxInfoGold +++ b/test/testPVAuxInfoGold @@ -33,6 +33,8 @@ units offset 11 next 12 number 1 limit offset 12 next 15 number 3 low offset 13 next 14 number 1 high offset 14 next 15 number 1 +linkedListNode: totalConstruct 6 totalDestruct 0 +linkedList: totalConstruct 1 totalDestruct 0 field: totalConstruct 111 totalDestruct 18 totalReference 93 pvField: totalConstruct 17 totalDestruct 17 pvAuxInfo: totalConstruct 1 totalDestruct 1 diff --git a/test/testPVData b/test/testPVData index ea8eb3d..895db48 100644 --- a/test/testPVData +++ b/test/testPVData @@ -281,5 +281,7 @@ structure string structure timeStamp long secondsPastEpoch 0 int nanoSeconds 0 +linkedListNode: totalConstruct 5 totalDestruct 0 +linkedList: totalConstruct 1 totalDestruct 0 field: totalConstruct 388 totalDestruct 295 totalReference 93 pvField: totalConstruct 279 totalDestruct 279 diff --git a/test/testPVDataGold b/test/testPVDataGold index ea8eb3d..895db48 100644 --- a/test/testPVDataGold +++ b/test/testPVDataGold @@ -281,5 +281,7 @@ structure string structure timeStamp long secondsPastEpoch 0 int nanoSeconds 0 +linkedListNode: totalConstruct 5 totalDestruct 0 +linkedList: totalConstruct 1 totalDestruct 0 field: totalConstruct 388 totalDestruct 295 totalReference 93 pvField: totalConstruct 279 totalDestruct 279 diff --git a/test/testPVStructureArray b/test/testPVStructureArray index 2edafb6..2312d5e 100644 --- a/test/testPVStructureArray +++ b/test/testPVStructureArray @@ -56,5 +56,7 @@ structure powerSupply structure timeStamp long secondsPastEpoch 0 int nanoSeconds 0 +linkedListNode: totalConstruct 5 totalDestruct 0 +linkedList: totalConstruct 1 totalDestruct 0 field: totalConstruct 153 totalDestruct 60 totalReference 93 pvField: totalConstruct 56 totalDestruct 56 diff --git a/test/testPVStructureArrayGold b/test/testPVStructureArrayGold index 2edafb6..2312d5e 100644 --- a/test/testPVStructureArrayGold +++ b/test/testPVStructureArrayGold @@ -56,5 +56,7 @@ structure powerSupply structure timeStamp long secondsPastEpoch 0 int nanoSeconds 0 +linkedListNode: totalConstruct 5 totalDestruct 0 +linkedList: totalConstruct 1 totalDestruct 0 field: totalConstruct 153 totalDestruct 60 totalReference 93 pvField: totalConstruct 56 totalDestruct 56 diff --git a/test/testThreadAux b/test/testThreadAux index cc072cb..a2b64c8 100644 --- a/test/testThreadAux +++ b/test/testThreadAux @@ -1 +1 @@ -time per call 23.580658 microseconds +time per call 33.872702 microseconds diff --git a/test/testTimeStampAux b/test/testTimeStampAux index 1204fc9..f9ffe35 100644 --- a/test/testTimeStampAux +++ b/test/testTimeStampAux @@ -1 +1,5 @@ -current 1290516873 809711508 milliSec 1290516873809 +current 1291321593 147449761 milliSec 1291321593147 +2010.12.02 15:26:33 147449761 nanoSeconds isDst false +fromTime_t +current 1291321593 0 milliSec 1291321593000 +2010.12.02 15:26:33 0 nanoSeconds isDst false diff --git a/test/testTimer b/test/testTimer index 33d35fa..4740546 100644 --- a/test/testTimer +++ b/test/testTimer @@ -1,3 +1,5 @@ +linkedListNode: totalConstruct 20 totalDestruct 12 +linkedList: totalConstruct 5 totalDestruct 3 event: totalConstruct 15 totalDestruct 15 thread: totalConstruct 3 totalDestruct 3 timerNode: totalConstruct 6 totalDestruct 6 diff --git a/test/testTimerAux b/test/testTimerAux index 25b8865..9592f2b 100644 --- a/test/testTimerAux +++ b/test/testTimerAux @@ -1,6 +1,6 @@ -one requested 0.400000 diff 0.400214 seconds -two requested 0.200000 diff 0.200183 seconds -one requested 0.200000 diff 0.200328 seconds -two requested 0.400000 diff 0.400277 seconds -one requested 0.000000 diff 0.000038 seconds -two requested 0.000000 diff 0.000060 seconds +one requested 0.400000 diff 0.400275 seconds +two requested 0.200000 diff 0.200137 seconds +one requested 0.200000 diff 0.200168 seconds +two requested 0.400000 diff 0.400172 seconds +one requested 0.000000 diff 0.000026 seconds +two requested 0.000000 diff 0.000082 seconds diff --git a/test/testTimerGold b/test/testTimerGold index 33d35fa..4740546 100644 --- a/test/testTimerGold +++ b/test/testTimerGold @@ -1,3 +1,5 @@ +linkedListNode: totalConstruct 20 totalDestruct 12 +linkedList: totalConstruct 5 totalDestruct 3 event: totalConstruct 15 totalDestruct 15 thread: totalConstruct 3 totalDestruct 3 timerNode: totalConstruct 6 totalDestruct 6