Difference between revisions of "V4 Design: epicsTypes"

From EPICSWIKI
Line 25: Line 25:
<tt>epicsType</tt> is an <tt>enum</tt> that lists the following:
<tt>epicsType</tt> is an <tt>enum</tt> that lists the following:
* epicsBooleanT,...,epicsFloat64T - C++ primitive types
* epicsBooleanT,...,epicsFloat64T - C++ primitive types
* epicsStringT - UTF-8 Encoded Character String
* epicsStringT - EpicsString which contains a UTF-8 Encoded Character String
* epicsArrayT - one dim arrays. The array can be any epicsType.
* epicsArrayT - EpicsArray which describes type and storage for a one dim array. The array can be any epicsType.
* epicsStructT - Support for a structure. A structure has fields that can be any epicsType.
* epicsStructT - EpicsStruct which describes and provides storage for a set of fields each of some epicsType
* epicsMDArrayT - An ndim array of one of the primitive types
* epicsMDArrayT - EpicsMDArray which describes type and storage for a multidimensional array.
 
The actual types associated with the <tt>epicsType</tt>s are:
   
    typedef bool              epicsBoolean;
    typedef char              epicsOctet;
    typedef short              epicsInt16;
    typedef unsigned short    epicsUInt16;
    typedef int                epicsInt32;
    typedef unsigned int      epicsUInt32;
    typedef long long          epicsInt64;
    typedef unsigned long long epicsUInt64;
    typedef float              epicsFloat32;
    typedef double            epicsFloat64;
 
    /*EpicsString holds UTF-8 characters*/
    class EpicsString  {
    public:
        EpicsUTF_8Buffer    *pbuffer;
    };
    class EpicsArray {
    public:
        epicsType        type;
        EpicsArrayBuffer *pbuffer;
    };
    class EpicsStruct{
    public:
        EpicsStructDef *pstructDef;
        void    *pstorage;
    };
    class EpicsMDArray {
    public:
        epicsType type;
        EpicsMDArrayDescription *pdescription;
        EpicsMDArrayBuffer *pbuffer;
    };
 
An instance of a primitive type has only storage associated with it.
An <tt>EpicsString</tt> is instance of an <tt>epicsStringT</tt>.
It has an associated buffer that holds the storage for a UTF-8 encoded string.
An <tt>EpicsArray</tt> is instance of an <tt>EpicsArrayT</tt>.
It specifies the element type and has an associated buffer
that holds the storage for the array.
An <tt>EpicsStruct</tt> is an instance of an <tt>epicsStructT</tt>
It has the address of the structure description and the address of storage
for the fields of the structure.
An <tt>EpicsMDArray</tt> is an instance of an <tt>epicsMDArrayT</tt>
It specifies the element type, has the address of the array description,
type and has an associated buffer
that holds the storage for the array.


Since an array can have type <tt>epicsStructT</tt> and a structure can have
Since an array can have type <tt>epicsStructT</tt> and a structure can have
Line 145: Line 194:
         virtual epicsInt32 get(epicsOctet *pto,
         virtual epicsInt32 get(epicsOctet *pto,
                                 epicsInt32 offset, epicsInt32 limit) = 0;
                                 epicsInt32 offset, epicsInt32 limit) = 0;
         virtual void epicsInt32 put(const epicsOctet *pfrom,
         virtual epicsInt32 put(const epicsOctet *pfrom,
                                 epicsInt32 offset, epicsInt32 limit) = 0;
                                 epicsInt32 offset, epicsInt32 limit) = 0;
         virtual bool isEqual(const EpicsUTF_8Buffer *pbuffer) = 0;
         virtual bool isEqual(const EpicsUTF_8Buffer *pbuffer) = 0;
Line 160: Line 209:
         static epicsUint16 typeToTypeID(const char *type);
         static epicsUint16 typeToTypeID(const char *type);
         static EpicsUTF_8Buffer *allocate(epicsUint16 typeId);
         static EpicsUTF_8Buffer *allocate(epicsUint16 typeId);
         static void register(const epicsStringBufferType type,
         static void register(const char *type,
                           EpicsUTF_8BufferAllocate allocater,
                           EpicsUTF_8BufferAllocate allocater);
                          const char *type);
     };
     };
     // type : At least "Contiguous" and "Segmented" are implemented
     // type : At least "Contiguous" and "Segmented" are implemented
Line 175: Line 223:


<tt>EpicsUTF_8Buffer</tt> is a pure
<tt>EpicsUTF_8Buffer</tt> is a pure
abstract base classe because multiple implementation of each are allowed.
abstract base class because multiple implementations are provided.


==== EpicsUTF_8Buffer ====
==== EpicsUTF_8Buffer ====
NOTE: EpicsUTF_8Buffer uses ideas from the Java nio Buffer class.


An <tt>EpicsUTF_8Buffer</tt> contains storage for a UTF-8 encoded string.
An <tt>EpicsUTF_8Buffer</tt> contains storage for a UTF-8 encoded string.
Line 198: Line 243:
: Releases storage. If <tt>onlyStorage</tt> is <tt>true</tt> then the storage for the string is freed and capacity is set to zero; otherwise the string storage and the storage for EpicsUTF_8Buffer itself is freed.
: Releases storage. If <tt>onlyStorage</tt> is <tt>true</tt> then the storage for the string is freed and capacity is set to zero; otherwise the string storage and the storage for EpicsUTF_8Buffer itself is freed.
; <tt>capacity</tt>
; <tt>capacity</tt>
: return the capacity
: returns the capacity
; <tt>limit</tt>
; <tt>limit</tt>
: Two methods are available, one to get the current limit and one to set the limit.
: Two methods are available, one to get the current limit and one to set the limit.
Line 205: Line 250:


; <tt>put</tt>
; <tt>put</tt>
: copies characters from pfrom and puts them into the buffer and returns the nimber of octets transfered.
: copies characters from pfrom, puts them into the buffer, and returns the number of octets transfered.
; <tt>isEqual(EpicsUTF_8Buffer *)</tt>
; <tt>isEqual(EpicsUTF_8Buffer *)</tt>
: Compares the string stored in the buffer with a string stored in a different buffer. This is normally called by code that uses an EpicsUTF_8Buffer.
: Compares the string stored in the buffer with a string stored in a different buffer. This is normally called by code that uses an EpicsUTF_8Buffer.
Line 220: Line 265:
This is a class for allocating an EpicsUTF_8Buffer
This is a class for allocating an EpicsUTF_8Buffer
and also for registering EpicsUTF_8Buffer implementations.
and also for registering EpicsUTF_8Buffer implementations.
At least two implementations will be provided: contiguous and segmented.
The contiguous implementation is appropriate for a string that is allocated
at initialization and is only rarely modified.
The segmented implementation is appropriate for strings that are frequently
modified or are transient, e.g. strings being transfered over the network.




Line 247: Line 298:
         virtual epicsUInt32 position() = 0;
         virtual epicsUInt32 position() = 0;
         virtual void position(epicsUInt32 newPosition) = 0;
         virtual void position(epicsUInt32 newPosition) = 0;
        virtual epicsInt32 get(void *pto,
                                epicsInt32 offset, epicsInt32 limit) = 0;
        virtual epicsInt32 put(const void *pfrom,
                                epicsInt32 offset, epicsInt32 limit) = 0;
         virtual void expose(epicsUInt32 offset, epicsUInt32 limitRequest,
         virtual void expose(epicsUInt32 offset, epicsUInt32 limitRequest,
                                     void *pdata, epicsUInt32 *limit);
                                     void *pdata, epicsUInt32 *limit);
Line 257: Line 312:
         static epicsUint16 typeToTypeID(const char *type);
         static epicsUint16 typeToTypeID(const char *type);
         static EpicsArrayBuffer *allocate(epicsUint16 typeId);
         static EpicsArrayBuffer *allocate(epicsUint16 typeId);
         static void register(const epicsStringBufferType type,
         static void register(const char *type,
                           EpicsArrayBufferAllocate allocater,
                           EpicsArrayBufferAllocate allocater);
                          const char *type);
     };
     };
     // type : At least "Contiguous" and "Segmented" are implemented
     // type : At least "Contiguous" and "Segmented" are implemented
Line 265: Line 319:


=== Discussion of epicsArray ===
=== Discussion of epicsArray ===
An <tt>EpicsArray</tt> describes and array with elements of any epicsType.
It has the following fields:
; <type>
: Any epicsType
; <tt>pbuffer</tt>
: The address of an <tt>EpicsArrayBuffer</tt> that provides access to the array.
==== EpicsArrayBuffer  ====


<tt>EpicsArrayBuffer</tt> has the following methods:
<tt>EpicsArrayBuffer</tt> has the following methods:
Line 278: Line 341:
; <tt>position</tt>
; <tt>position</tt>
: Two methods are available, one to get the current position and one to set the position.
: Two methods are available, one to get the current position and one to set the position.
; <tt>get</tt>
: copies characters to pto and returns the number of octets transfered.
; <tt>put</tt>
: copies characters from pfrom, puts them into the buffer, and returns the number of octets transfered. 
; <tt>expose</tt>
; <tt>expose</tt>
: A request to return the address of actual storage. Since a buffer implementation may used segmented memory the amount of storage exposed may be less than the amount requested.
: A request to return the address of actual storage. Since a buffer implementation may used segmented memory the amount of storage exposed may be less than the amount requested.
==== EpicsArrayBufferFactory ====
This is a class for allocating an EpicsArrayBuffer
and also for registering EpicsArrayBuffer implementations.
At least two implementations will be provided: contiguous and segmented.
The contiguous implementation is appropriate for a string that is allocated
at initialization and is only rarely modified.
The segmented implementation is appropriate for strings that are frequently
modified or are transient, e.g. strings being transfered over the network.




Line 289: Line 367:


     class EpicsStructDef;
     class EpicsStructDef;
     class StructDbdLifetime;
     class EpicsStructLifetime;


     class EpicsStruct{
     class EpicsStruct{
Line 306: Line 384:
     public:
     public:
         EpicsString  name;
         EpicsString  name;
         StructDbdLifetime *plifetime;
         EpicsStructLifetime *plifetime;
         epicsInt16    nfields;
         epicsInt16    nfields;
         EpicsStructField *pfield[]; // ptr to array of ptr to EpicsStructField
         EpicsStructField *pfield[]; // ptr to array of ptr to EpicsStructField
     };
     };


     class StructDbdLifetime {
     class EpicsStructLifetime {
     public:
     public:
         virtual void allocate(EpicsStruct *pstruct) = 0;
         virtual void allocate(EpicsStruct *pstruct) = 0;
Line 320: Line 398:
     class EpicsStructFactory {
     class EpicsStructFactory {
     public:
     public:
         static StructDbdLifetime *find(const char *structName);
         static EpicsStructLifetime *find(const char *structName);
         static void register(const char *structName,
         static void register(const char *structName,
                               EpicsStructDef, *pdef);
                               EpicsStructDef, *pdef);
Line 330: Line 408:
<tt>epicsStruct</pp> contains two fields:
<tt>epicsStruct</pp> contains two fields:
; <tt>pstructDef</tt>
; <tt>pstructDef</tt>
: Address of a class that describes the structure.
: Address of a <tt>EpicsStructDef</tt> that describes the structure.
; <tt>pstorage</tt>
; <tt>pstorage</tt>
: Address of storage for the data contained in the structure.
: Address of storage for the data contained in the structure.
==== EpicsStructDef ====


<tt>EpicsStructDef</tt> has the fields:
<tt>EpicsStructDef</tt> has the fields:
; <tt>name</tt>
; <tt>name</tt>
: The structure name. <b>Question</b> What is the namespace?
: The structure name.
; <tt>plifetime</tt>
; <tt>plifetime</tt>
: Address of a <tt>StructDbdLifetime</tt> interface. See below.
: Address of a <tt>EpicsStructLifetime</tt> interface. See below.
; <tt>nfields</tt>
; <tt>nfields</tt>
: The number of fields in the structure.
: The number of fields in the structure.
; <tt>pfield</tt>
; <tt>pfield</tt>
: An array of pointers to a <tt>EpicsStructField</tt>, one for each field.
: An array of pointers to <tt>EpicsStructField</tt>, one for each field.
 
==== EpicsStructField ====


<tt>EpicsStructField</tt> has the fields:
<tt>EpicsStructField</tt> has the fields:
Line 350: Line 432:
: The field type, which can be any epicsType.
: The field type, which can be any epicsType.


<tt>StructDbdLifetime</tt> is an interface that has three methods:
==== EpicsStructLifetime ====
<tt>EpicsStructLifetime</tt> is an interface that has three methods:
; <tt>allocate</tt>
; <tt>allocate</tt>
: This sets <tt>pstructDef</tt> to the definition for the associated structure
: This sets <tt>pstructDef</tt> to the definition for the associated structure and sets pstorage to the address of storage for the fields in the structure.
;nd sets pstorage to the address of storage for the data in the structure.
; <tt>exposeField</tt>
; <tt>exposeField</tt>
: This returns the address of the storage for the data associated with the field.
: This returns the address of the storage for the data associated with the field.
==== EpicsStructFactory ====


<tt>EpicsStructFactory</tt> is a factory for registering and finding
<tt>EpicsStructFactory</tt> is a factory for registering and finding
<tt>StructDbdLifetime</tt> interfaces. It has the methods:
<tt>EpicsStructLifetime</tt> interfaces. It has the methods:
; <tt>find</tt>
; <tt>find</tt>
: Given a name find the associated interface.
: Given a name find the associated interface.
Line 364: Line 448:
: Register a <tt>EpicsStructDef</tt> for the name.
: Register a <tt>EpicsStructDef</tt> for the name.


If register is called with <tt>EpicsStructDef.plifetime</tt> is <tt>null</tt>
If register is called with <tt>EpicsStructDef.plifetime = null</tt>
then the factory will provide a default implementation.
then the factory will provide a default implementation.
The default implementation will be an array of pointers for each field.
The default implementation will be an array of pointers for each field.
Line 415: Line 499:
         static epicsUint16 typeToTypeID(const char *type);
         static epicsUint16 typeToTypeID(const char *type);
         static EpicsMDArrayBuffer *allocate(epicsUint16 typeId);
         static EpicsMDArrayBuffer *allocate(epicsUint16 typeId);
         static void register(const epicsStringBufferType type,
         static void register(const char *type,
                           EpicsMDArrayBufferAllocate allocater,
                           EpicsMDArrayBufferAllocate allocater);
                          const char *type);
     };
     };
     // type : At least "Contiguous" and "Segmented" are implemented
     // type : At least "Contiguous" and "Segmented" are implemented

Revision as of 15:50, 23 May 2005

EPICS: epicsTypes - Network Accessable Data

May 23 2005

Overview

This document describes the C++ definitions for storing structured data that can be accessed without pre-complied code.

Some examples are:

  1. IOC records - Everything accessable from outside record support
  2. Channel Access Gateway - Everything accessable by channel access clients
  3. Channel Access Clients - Everything a client sends or receives

NOTE: This is NOT a replacement for dataAccess

Standard support can be provided to access, via dataAccess, epicsType data. For example standard support can be provided to move IOC record data between record instances and a Channel Access server.

epicsType is an enum that lists the following:

  • epicsBooleanT,...,epicsFloat64T - C++ primitive types
  • epicsStringT - EpicsString which contains a UTF-8 Encoded Character String
  • epicsArrayT - EpicsArray which describes type and storage for a one dim array. The array can be any epicsType.
  • epicsStructT - EpicsStruct which describes and provides storage for a set of fields each of some epicsType
  • epicsMDArrayT - EpicsMDArray which describes type and storage for a multidimensional array.

The actual types associated with the epicsTypes are:

    typedef bool               epicsBoolean;
    typedef char               epicsOctet;
    typedef short              epicsInt16;
    typedef unsigned short     epicsUInt16;
    typedef int                epicsInt32;
    typedef unsigned int       epicsUInt32;
    typedef long long          epicsInt64;
    typedef unsigned long long epicsUInt64;
    typedef float              epicsFloat32;
    typedef double             epicsFloat64;
    /*EpicsString holds UTF-8 characters*/
    class EpicsString  {
    public:
        EpicsUTF_8Buffer    *pbuffer;
    };
    class EpicsArray {
    public:
        epicsType        type;
        EpicsArrayBuffer *pbuffer;
    };
    class EpicsStruct{
    public:
        EpicsStructDef *pstructDef;
        void    *pstorage;
    };
    class EpicsMDArray {
    public:
       epicsType type;
       EpicsMDArrayDescription *pdescription;
       EpicsMDArrayBuffer *pbuffer;
    };

An instance of a primitive type has only storage associated with it. An EpicsString is instance of an epicsStringT. It has an associated buffer that holds the storage for a UTF-8 encoded string. An EpicsArray is instance of an EpicsArrayT. It specifies the element type and has an associated buffer that holds the storage for the array. An EpicsStruct is an instance of an epicsStructT It has the address of the structure description and the address of storage for the fields of the structure. An EpicsMDArray is an instance of an epicsMDArrayT It specifies the element type, has the address of the array description, type and has an associated buffer that holds the storage for the array.

Since an array can have type epicsStructT and a structure can have fields of type epicsStructT and epicsArrayT complicated data can be described. Arrays are used both for data and to describe structures.

epicsMDArrayT, i.e. multidimensional array data, is a supported type, because collection and display of two and three dimensional images is a common requirement.

epicsTypes

epicsTypes.h contains the following:

    /* The following may require OSD definitions*/
    typedef bool               epicsBoolean;
    typedef char               epicsOctet;
    typedef short              epicsInt16;
    typedef unsigned short     epicsUInt16;
    typedef int                epicsInt32;
    typedef unsigned int       epicsUInt32;
    typedef long long          epicsInt64;
    typedef unsigned long long epicsUInt64;
    typedef float              epicsFloat32;
    typedef double             epicsFloat64;
   
    enum epicsType {
        epicsUnknownT,
        epicsBooleanT,     // epicsBoolean
        epicsOctetT,       // epicsOctet
        epicsInt16T,       // epicsInt16
        epicsUInt16T,      // epicsUInt16
        epicsInt32T,       // epicsInt32
        epicsUInt32T,      // epicsUInt32
        epicsInt64T,       // epicsInt64
        epicsUInt64T,      // epicsUInt64
        epicsFloat32T,     // epicsFloat32
        epicsFloat64T,     // epicsFloat64
        epicsStringT,      // EpicsString
        epicsArrayT,       // EpicsArray
        epicsStructT,      // EpicsStruct
        epicsMDArrayT      // EpicsMDArray
    };

Discussion of epicsTypes

epicsTypes provides classes for describing data that can be introspected and can be passed between different platforms. All data that is sent to or received from EPICS records will be composed of epicsTypes.

The types epicsBooleanT, ..., epicsFloat64T all map to a C++ standard type. It may be necessary to provide operating system dependent definitions for some of the types. For example on some architectures a epicsInt64 may have to be defined as a long rather than a long long.

The types epicsStringT, epicsArrayT, epicsStructT, and epicsMDArrayT are designed so that any data can be described, introspected, and passed over a network. An epicsStruct can contain epicsArrays and epicsStructs and a epicsArray can be an array of any epicsType except epicsUnknownT.

epicsUnknownT is provided in case something expected to produce an epicsType fails.

Global Comments and Questions

expose

The class definitions for non-primitive types all provide a method expose which returns the address of data. This is done for efficiency and convenience.

In order to make expose safe, some rules must be established. One possibility is that a lock is associated with each object that supports expose. Code can only call expose and can only access the data returned by expose of it holds the lock.

lock???

Should each buffer have an associated lock? For example should EpicsUTF_8Buffer have methods:

        virtual void lock() = 0;
        virtual void unlock() = 0;

If so should the allocate method of the buffer factory accept an epicsMutex argument or should the buffer factory just provide a mutex?

struct names

What is the namespace for structure names? That is how do we prevent struct names from becoming global?

epicsString

epicsString.h contains the following:

    class EpicsUTF_8Buffer;
    
    /*EpicsString holds UTF-8 characters*/
    class EpicsString  {
    public:
        EpicsUTF_8Buffer    *pbuffer;
    };
    class EpicsUTF_8Buffer {
    public:
        virtual epicsInt32 allocate(epicsInt32 capacity) = 0;
        virtual void release(bool onlyStorage) = 0;
        virtual epicsInt32 capacity() = 0;
        virtual epicsInt32 limit() = 0;
        virtual void limit(epicsInt32 newLimit) = 0;
        virtual epicsInt32 get(epicsOctet *pto,
                               epicsInt32 offset, epicsInt32 limit) = 0;
        virtual epicsInt32 put(const epicsOctet *pfrom,
                               epicsInt32 offset, epicsInt32 limit) = 0;
        virtual bool isEqual(const EpicsUTF_8Buffer *pbuffer) = 0;
        virtual bool isEqual(const epicsOctet *pstring, epicsInt32 len) = 0;
        virtual void expose(epicsInt32 offset, epicsInt32 limitRequest,
                            epicsOctet *pdata, epicsInt32 *limit);
        virtual epicsUint32 hash(epicsInt16 nBitsHashIndex) = 0;
    };


    typedef EpicsUTF_8Buffer *(EpicsUTF_8BufferAllocate)();
    class EpicsUTF_8BufferFactory {
    public:
        static epicsUint16 typeToTypeID(const char *type);
        static EpicsUTF_8Buffer *allocate(epicsUint16 typeId);
        static void register(const char *type,
                         EpicsUTF_8BufferAllocate allocater);
    };
    // type : At least "Contiguous" and "Segmented" are implemented


Discussion of epicsString

An EpicsString contains UTF-8 encoded character strings. It has the following fields:

pbuffer
The address of a EpicsUTF_8Buffer, which is a class that manages the string storage.

EpicsUTF_8Buffer is a pure abstract base class because multiple implementations are provided.

EpicsUTF_8Buffer

An EpicsUTF_8Buffer contains storage for a UTF-8 encoded string. In addition to holding storage for a string, a string buffer keeps the following information.

capacity
The number of octets allocated, i.e. the number of UTF-8 characters the buffer can hold.
limit
The current size, i.e. the index of the first octet that can not hold data. Data can not be read from or written into a buffer beyond limit. When data is being written to a buffer limit is normally equal to capacity. When data is being read from a buffer limit is normally less than capacity and indicates the end of valid data.


EpicsUTF_8Buffer has the following methods:

allocate
This allocates space for up to capacity octets. The number of octets allocated is returned. An implementation attempts to allocate the requested capacity but some implemenations, e.g. network buffers, may impose a maximum size. If capacity is not zero when this is called and new storage is allocated then the old storage is freed or reused and the octets spanned by position, limit appear in the newly allocated storage.
release
Releases storage. If onlyStorage is true then the storage for the string is freed and capacity is set to zero; otherwise the string storage and the storage for EpicsUTF_8Buffer itself is freed.
capacity
returns the capacity
limit
Two methods are available, one to get the current limit and one to set the limit.
get
copies characters to pto and returns the number of octets transfered.
put
copies characters from pfrom, puts them into the buffer, and returns the number of octets transfered.
isEqual(EpicsUTF_8Buffer *)
Compares the string stored in the buffer with a string stored in a different buffer. This is normally called by code that uses an EpicsUTF_8Buffer.
isEqual(epicsOctet *pstring, epicsInt32 len)
Compares the string stored in the buffer with a string supplied by the caller. This is normally called by EpicsUTF_8Buffer itself to compare it's string with the string stored in another buffer.
expose
A request to return the address of actual bytes of storage. Since a buffer implementation may used segmented memory the number of bytes exposed may be less than the amount requested.
hash
implement a hash on the octets stored in the buffer.


EpicsUTF_8BufferFactory

This is a class for allocating an EpicsUTF_8Buffer and also for registering EpicsUTF_8Buffer implementations.

At least two implementations will be provided: contiguous and segmented. The contiguous implementation is appropriate for a string that is allocated at initialization and is only rarely modified. The segmented implementation is appropriate for strings that are frequently modified or are transient, e.g. strings being transfered over the network.


epicsArray

epicsArray.h contains the following:

    class EpicsArrayBuffer;
    class EpicsArray {
    public:
        epicsType        type; 
        EpicsArrayBuffer *pbuffer;
    };
    class EpicsArrayBuffer {
    public:
        virtual epicsUInt32 allocate(
                    epicsUInt32 capacity,epicsUint16 elementSize) = 0;
        virtual void release(bool onlyStorage) = 0;
        virtual epicsUInt32 capacity() = 0;
        virtual epicsUInt32 elementSize() = 0;
        virtual epicsUInt32 limit() = 0;
        virtual void limit(epicsUInt32 newLimit) = 0;
        virtual epicsUInt32 position() = 0;
        virtual void position(epicsUInt32 newPosition) = 0;
        virtual epicsInt32 get(void *pto,
                               epicsInt32 offset, epicsInt32 limit) = 0;
        virtual epicsInt32 put(const void *pfrom,
                               epicsInt32 offset, epicsInt32 limit) = 0;
        virtual void expose(epicsUInt32 offset, epicsUInt32 limitRequest,
                                   void *pdata, epicsUInt32 *limit);
    }


    typedef EpicsArrayBuffer *(EpicsArrayBufferAllocate)();
    class EpicsArrayBufferFactory {
    public:
        static epicsUint16 typeToTypeID(const char *type);
        static EpicsArrayBuffer *allocate(epicsUint16 typeId);
        static void register(const char *type,
                         EpicsArrayBufferAllocate allocater);
    };
    // type : At least "Contiguous" and "Segmented" are implemented


Discussion of epicsArray

An EpicsArray describes and array with elements of any epicsType. It has the following fields:

<type>
Any epicsType
pbuffer
The address of an EpicsArrayBuffer that provides access to the array.

EpicsArrayBuffer

EpicsArrayBuffer has the following methods:

allocate
This allocates space for up to capacity elements. The number of elements allocated is returned. An implementation attempts to allocate the requested capacity but some implemenations, e.g. network buffers, may impose a maximum size. If capacity is not zero when this is called and new storage is allocated then the old storage is freed or reused and the elements spanned by position, limit appear in the newly allocated storage.
release
Releases storage. If onlyStorage is true then the storage for the string is freed and capacity is set to zero; otherwise the string storage and the storage for EpicsUTF_8Buffer itself is freed.
capacity
return the capacity
limit
Two methods are available, one to get the current limit and one to set the limit.
position
Two methods are available, one to get the current position and one to set the position.
get
copies characters to pto and returns the number of octets transfered.
put
copies characters from pfrom, puts them into the buffer, and returns the number of octets transfered.
expose
A request to return the address of actual storage. Since a buffer implementation may used segmented memory the amount of storage exposed may be less than the amount requested.

EpicsArrayBufferFactory

This is a class for allocating an EpicsArrayBuffer and also for registering EpicsArrayBuffer implementations.

At least two implementations will be provided: contiguous and segmented. The contiguous implementation is appropriate for a string that is allocated at initialization and is only rarely modified. The segmented implementation is appropriate for strings that are frequently modified or are transient, e.g. strings being transfered over the network.


epicsStruct

epicsStruct.h contains the following:

    class EpicsStructDef;
    class EpicsStructLifetime;
    class EpicsStruct{
    public:
        EpicsStructDef *pstructDef;
        void    *pstorage;
    };
    class EpicsStructField {
    public:
        EpicsString name;
        epicsType   type;
    };
   
    class EpicsStructDef{
    public:
        EpicsString  name;
        EpicsStructLifetime *plifetime;
        epicsInt16     nfields;
        EpicsStructField *pfield[]; // ptr to array of ptr to EpicsStructField
    };
    class EpicsStructLifetime {
    public:
        virtual void allocate(EpicsStruct *pstruct) = 0;
        virtual void destroy(EpicsStruct *pstruct) = 0;
        virtual void *exposeField(EpicsStruct *pstruct epicsInt16 index) = 0;
    };
    class EpicsStructFactory {
    public:
        static EpicsStructLifetime *find(const char *structName);
        static void register(const char *structName,
                             EpicsStructDef, *pdef);
    };
                           

Discussion of epicsStruct

epicsStruct</pp> contains two fields:

pstructDef
Address of a EpicsStructDef that describes the structure.
pstorage
Address of storage for the data contained in the structure.

EpicsStructDef

EpicsStructDef has the fields:

name
The structure name.
plifetime
Address of a EpicsStructLifetime interface. See below.
nfields
The number of fields in the structure.
pfield
An array of pointers to EpicsStructField, one for each field.

EpicsStructField

EpicsStructField has the fields:

name
The field name.
type
The field type, which can be any epicsType.

EpicsStructLifetime

EpicsStructLifetime is an interface that has three methods:

allocate
This sets pstructDef to the definition for the associated structure and sets pstorage to the address of storage for the fields in the structure.
exposeField
This returns the address of the storage for the data associated with the field.

EpicsStructFactory

EpicsStructFactory is a factory for registering and finding EpicsStructLifetime interfaces. It has the methods:

find
Given a name find the associated interface.
register
Register a EpicsStructDef for the name.

If register is called with EpicsStructDef.plifetime = null then the factory will provide a default implementation. The default implementation will be an array of pointers for each field. Each pointer will have the address of storage for the corresponding field type.

epicsMDArray

epicsMDArray.h contains the following:

    class EpicsMDArrayDescription;
    class EpicsMDArrayBuffer;
    class EpicsMDArray {
    public:
       epicsType type;
       EpicsMDArrayDescription *pdescription;
       EpicsMDArrayBuffer *pbuffer;
    };
    class EpicsMDArrayBuffer {
    public:
        virtual epicsUInt32 allocate(
                    epicsUInt32 capacity,epicsUint16 elementSize) = 0;
        virtual void release(bool onlyStorage) = 0;
        virtual epicsUInt32 capacity() = 0;
        virtual epicsUInt32 elementSize() = 0;
        virtual epicsUInt32 limit() = 0;
        virtual void limit(epicsUInt32 newLimit) = 0;
        virtual void expose(epicsUInt32 offset, epicsUInt32 limitRequest,
                                   void *pdata, epicsUInt32 *limit);
    };
    class EpicsMDArrayBounds {
        epicsUInt32 low;
        epicsUInt32 high;
    };
    class EpicsMDArrayDescription {
    public:
        epicsUInt32  capacity;  //capacity in number of elements 
        epicsInt16  ndim;      // number of dimensions
        epicsType   type; 
        void      *pstorage; // storage for capacity elements of type
        EpicsMDArrayBounds bounds[]; // bounds[ndim]
    };
    typedef EpicsMDArrayBuffer *(EpicsMDArrayBufferAllocate)();
    class EpicsMDArrayBufferFactory {
    public:
        static epicsUint16 typeToTypeID(const char *type);
        static EpicsMDArrayBuffer *allocate(epicsUint16 typeId);
        static void register(const char *type,
                         EpicsMDArrayBufferAllocate allocater);
    };
    // type : At least "Contiguous" and "Segmented" are implemented


Discussion of epicsMDArray

MARTY DISCUSS