Difference between revisions of "V4 Design: epicsTypes"
MartyKraimer (talk | contribs) |
MartyKraimer (talk | contribs) |
||
Line 1: | Line 1: | ||
== EPICS: epicsTypes - | == EPICS: epicsTypes - Network Accessable Data == | ||
May | May 23 2005 | ||
<center> | <center> | ||
Line 9: | Line 9: | ||
</center> | </center> | ||
This document describes the C++ definitions for storing data that | This document describes the C++ definitions for storing | ||
structured data that can be accessed without pre-complied code. | |||
Some examples are: | Some examples are: | ||
Line 26: | Line 24: | ||
<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 - | * epicsBooleanT,...,epicsFloat64T - C++ primitive types | ||
* epicsStringT - | * epicsStringT - UTF-8 Encoded Character String | ||
* epicsArrayT - | * epicsArrayT - one dim arrays. The array can be any epicsType. | ||
* epicsStructT - Support for a structure. A structure has fields that can be any epicsType. | * epicsStructT - Support for a structure. A structure has fields that can be any epicsType. | ||
* | * epicsMDArrayT - An ndim array of one of the primitive types | ||
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 | ||
fields of type <tt>epicsStructT</tt> and <tt>epicsArrayT</tt> complicated | fields of type <tt>epicsStructT</tt> and <tt>epicsArrayT</tt> complicated | ||
data can be described. | 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. | |||
<center> | <center> | ||
Line 67: | Line 69: | ||
epicsFloat32T, // epicsFloat32 | epicsFloat32T, // epicsFloat32 | ||
epicsFloat64T, // epicsFloat64 | epicsFloat64T, // epicsFloat64 | ||
epicsStringT, // | epicsStringT, // EpicsString | ||
epicsArrayT, // | epicsArrayT, // EpicsArray | ||
epicsStructT, // | epicsStructT, // EpicsStruct | ||
epicsMDArrayT // EpicsMDArray | |||
}; | }; | ||
Line 85: | Line 87: | ||
The types <tt>epicsStringT</tt>, <tt>epicsArrayT</tt>, <tt>epicsStructT</tt>, | The types <tt>epicsStringT</tt>, <tt>epicsArrayT</tt>, <tt>epicsStructT</tt>, | ||
and <tt> | and <tt>epicsMDArrayT</tt> are designed so that any data | ||
can be described, introspected, and passed over a network. | can be described, introspected, and passed over a network. | ||
An epicsStruct can contain epicsArrays and epicsStructs and a epicsArray | An epicsStruct can contain epicsArrays and epicsStructs and a epicsArray | ||
Line 92: | Line 94: | ||
<tt>epicsUnknownT</tt> is provided in case something expected to produce | <tt>epicsUnknownT</tt> is provided in case something expected to produce | ||
an epicsType fails. | an epicsType fails. | ||
== Global Comments and Questions == | |||
=== expose === | |||
The class definitions for non-primitive types all provide | |||
a method <tt>expose</tt> 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 <tt>allocate</tt> 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? | |||
<center> | <center> | ||
Line 106: | Line 136: | ||
}; | }; | ||
class EpicsUTF_8Buffer { | class EpicsUTF_8Buffer { | ||
public: | public: | ||
Line 122: | Line 147: | ||
virtual void epicsInt32 put(const epicsOctet *pfrom, | virtual void 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; | ||
virtual bool isEqual(const epicsOctet *pstring, epicsInt32 len) = 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; | virtual epicsUint32 hash(epicsInt16 nBitsHashIndex) = 0; | ||
}; | }; | ||
Line 181: | Line 206: | ||
; <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 and puts them into the buffer and returns the nimber 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. | ||
; <tt>isEqual(epicsOctet *pstring, epicsInt32 len)</tt> | ; <tt>isEqual(epicsOctet *pstring, epicsInt32 len)</tt> | ||
: 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. | : 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. | ||
; <tt>expose</tt> | |||
: 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. | |||
; <tt>hash</tt> | ; <tt>hash</tt> | ||
: implement a hash on the octets stored in the buffer. | : implement a hash on the octets stored in the buffer. | ||
Line 203: | Line 228: | ||
<tt>epicsArray.h</tt> contains the following: | <tt>epicsArray.h</tt> contains the following: | ||
class | class EpicsArrayBuffer; | ||
class EpicsArray { | |||
public: | |||
epicsType type; | |||
EpicsArrayBuffer *pbuffer; | |||
}; | }; | ||
class EpicsArrayBuffer { | class EpicsArrayBuffer { | ||
public: | public: | ||
Line 219: | Line 247: | ||
virtual epicsUInt32 position() = 0; | virtual epicsUInt32 position() = 0; | ||
virtual void position(epicsUInt32 newPosition) = 0; | virtual void position(epicsUInt32 newPosition) = 0; | ||
virtual | virtual void expose(epicsUInt32 offset, epicsUInt32 limitRequest, | ||
void *pdata, epicsUInt32 *limit); | |||
} | } | ||
Line 247: | Line 268: | ||
<tt>EpicsArrayBuffer</tt> has the following methods: | <tt>EpicsArrayBuffer</tt> has the following methods: | ||
; <tt>allocate</tt> | ; <tt>allocate</tt> | ||
: This allocates space for up to <tt>capacity</tt> | : This allocates space for up to <tt>capacity</tt> 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. | ||
; <tt>release</tt> | ; <tt>release</tt> | ||
Line 258: | Line 279: | ||
: 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>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. | ||
Line 266: | Line 287: | ||
<tt>epicsStruct.h</tt> contains the following: | <tt>epicsStruct.h</tt> contains the following: | ||
class EpicsStructDef; | |||
class StructDbdLifetime; | |||
class EpicsStruct{ | |||
public: | |||
EpicsStructDef *pstructDef; | |||
void *pstorage; | |||
}; | |||
class EpicsStructField { | class EpicsStructField { | ||
Line 276: | Line 306: | ||
public: | public: | ||
EpicsString name; | EpicsString name; | ||
StructDbdLifetime *plifetime; | |||
epicsInt16 nfields; | epicsInt16 nfields; | ||
EpicsStructField *pfield[]; // ptr to array of ptr to EpicsStructField | EpicsStructField *pfield[]; // ptr to array of ptr to EpicsStructField | ||
}; | }; | ||
class EpicsStruct{ | class StructDbdLifetime { | ||
public: | |||
virtual void allocate(EpicsStruct *pstruct) = 0; | |||
virtual void destroy(EpicsStruct *pstruct) = 0; | |||
virtual void *exposeField(EpicsStruct *pstruct epicsInt16 index) = 0; | |||
}; | |||
class EpicsStructFactory { | |||
public: | public: | ||
static StructDbdLifetime *find(const char *structName); | |||
void | static void register(const char *structName, | ||
EpicsStructDef, *pdef); | |||
}; | }; | ||
=== Discussion of epicsStruct === | === Discussion of epicsStruct === | ||
<tt>epicsStruct</pp> contains two fields: | |||
; <tt>pstructDef</tt> | |||
: Address of a class that describes the structure. | |||
; <tt>pstorage</tt> | |||
: Address of storage for the data contained in the structure. | |||
<tt>EpicsStructDef</tt> has the fields: | |||
; <tt>name</tt> | |||
: The structure name. <b>Question</b> What is the namespace? | |||
; <tt>plifetime</tt> | |||
: Address of a <tt>StructDbdLifetime</tt> interface. See below. | |||
; <tt>nfields</tt> | |||
: The number of fields in the structure. | |||
; <tt>pfield</tt> | |||
: An array of pointers to a <tt>EpicsStructField</tt>, one for each field. | |||
<tt>EpicsStructField</tt> has the fields: | |||
; <tt>name</tt> | |||
: The field name. | |||
; <tt>type</tt> | |||
: The field type, which can be any epicsType. | |||
<tt>StructDbdLifetime</tt> is an interface that has three methods: | |||
; <tt>allocate</tt> | |||
: This sets <tt>pstructDef</tt> to the definition for the associated structure | |||
;nd sets pstorage to the address of storage for the data in the structure. | |||
; <tt>exposeField</tt> | |||
: This returns the address of the storage for the data associated with the field. | |||
<tt>EpicsStructFactory</tt> is a factory for registering and finding | |||
<tt>StructDbdLifetime</tt> interfaces. It has the methods: | |||
; <tt>find</tt> | |||
: Given a name find the associated interface. | |||
; <tt>register</tt> | |||
: Register a <tt>EpicsStructDef</tt> for the name. | |||
If register is called with <tt>EpicsStructDef.plifetime</tt> is <tt>null</tt> | |||
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. | |||
<center> | <center> | ||
== | == epicsMDArray == | ||
</center> | </center> | ||
<tt> | <tt>epicsMDArray.h</tt> contains the following: | ||
class | class EpicsMDArrayDescription; | ||
class EpicsMDArrayBuffer; | |||
class EpicsMDArray { | |||
public: | |||
epicsType type; | |||
EpicsMDArrayDescription *pdescription; | |||
EpicsMDArrayBuffer *pbuffer; | |||
}; | }; | ||
class | |||
class EpicsMDArrayBuffer { | |||
public: | public: | ||
virtual epicsUInt32 allocate( | virtual epicsUInt32 allocate( | ||
Line 309: | Line 391: | ||
virtual epicsUInt32 capacity() = 0; | virtual epicsUInt32 capacity() = 0; | ||
virtual epicsUInt32 elementSize() = 0; | virtual epicsUInt32 elementSize() = 0; | ||
virtual epicsUInt32 expose( | virtual epicsUInt32 limit() = 0; | ||
virtual void limit(epicsUInt32 newLimit) = 0; | |||
virtual void expose(epicsUInt32 offset, epicsUInt32 limitRequest, | |||
void *pdata, epicsUInt32 *limit); | |||
}; | }; | ||
class | class EpicsMDArrayBounds { | ||
epicsUInt32 low; | epicsUInt32 low; | ||
epicsUInt32 high; | epicsUInt32 high; | ||
}; | }; | ||
class | class EpicsMDArrayDescription { | ||
public: | public: | ||
epicsUInt32 capacity; //capacity in number of elements | epicsUInt32 capacity; //capacity in number of elements | ||
Line 322: | Line 407: | ||
epicsType type; | epicsType type; | ||
void *pstorage; // storage for capacity elements of type | void *pstorage; // storage for capacity elements of type | ||
EpicsMDArrayBounds bounds[]; // bounds[ndim] | |||
}; | }; | ||
typedef | typedef EpicsMDArrayBuffer *(EpicsMDArrayBufferAllocate)(); | ||
class | class EpicsMDArrayBufferFactory { | ||
public: | public: | ||
static epicsUint16 typeToTypeID(const char *type); | static epicsUint16 typeToTypeID(const char *type); | ||
static | static EpicsMDArrayBuffer *allocate(epicsUint16 typeId); | ||
static void register(const epicsStringBufferType type, | static void register(const epicsStringBufferType type, | ||
EpicsMDArrayBufferAllocate allocater, | |||
const char *type); | const char *type); | ||
}; | }; | ||
Line 344: | Line 422: | ||
=== Discussion of | === Discussion of epicsMDArray === | ||
MARTY DISCUSS | MARTY DISCUSS |
Revision as of 14:39, 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:
- IOC records - Everything accessable from outside record support
- Channel Access Gateway - Everything accessable by channel access clients
- 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 - UTF-8 Encoded Character String
- epicsArrayT - one dim arrays. The array can be any epicsType.
- epicsStructT - Support for a structure. A structure has fields that can be any epicsType.
- epicsMDArrayT - An ndim array of one of the primitive types
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 void 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 epicsStringBufferType type, EpicsUTF_8BufferAllocate allocater, const char *type); }; // 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 classe because multiple implementation of each are allowed.
EpicsUTF_8Buffer
NOTE: EpicsUTF_8Buffer uses ideas from the Java nio Buffer class.
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
- return 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 and puts them into the buffer and returns the nimber 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.
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 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 epicsStringBufferType type, EpicsArrayBufferAllocate allocater, const char *type); }; // type : At least "Contiguous" and "Segmented" are implemented
Discussion of epicsArray
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.
- 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.
epicsStruct
epicsStruct.h contains the following:
class EpicsStructDef; class StructDbdLifetime;
class EpicsStruct{ public: EpicsStructDef *pstructDef; void *pstorage; };
class EpicsStructField { public: EpicsString name; epicsType type; }; class EpicsStructDef{ public: EpicsString name; StructDbdLifetime *plifetime; epicsInt16 nfields; EpicsStructField *pfield[]; // ptr to array of ptr to EpicsStructField };
class StructDbdLifetime { 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 StructDbdLifetime *find(const char *structName); static void register(const char *structName, EpicsStructDef, *pdef); };
Discussion of epicsStruct
epicsStruct</pp> contains two fields:
- pstructDef
- Address of a class that describes the structure.
- pstorage
- Address of storage for the data contained in the structure.
EpicsStructDef has the fields:
- name
- The structure name. Question What is the namespace?
- plifetime
- Address of a StructDbdLifetime interface. See below.
- nfields
- The number of fields in the structure.
- pfield
- An array of pointers to a EpicsStructField, one for each field.
EpicsStructField has the fields:
- name
- The field name.
- type
- The field type, which can be any epicsType.
StructDbdLifetime is an interface that has three methods:
- allocate
- This sets pstructDef to the definition for the associated structure
- nd sets pstorage to the address of storage for the data in the structure.
- exposeField
- This returns the address of the storage for the data associated with the field.
EpicsStructFactory is a factory for registering and finding StructDbdLifetime 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 is 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 epicsStringBufferType type, EpicsMDArrayBufferAllocate allocater, const char *type); }; // type : At least "Contiguous" and "Segmented" are implemented
Discussion of epicsMDArray
MARTY DISCUSS