Difference between revisions of "V4 Design: dbdClass"
MartyKraimer (talk | contribs) |
MartyKraimer (talk | contribs) |
||
Line 31: | Line 31: | ||
files generated from dbd <tt>struct</tt> or <tt>record</tt> field definitions. | files generated from dbd <tt>struct</tt> or <tt>record</tt> field definitions. | ||
The following naming conventions are used: | The following naming conventions are used: | ||
; C++ <tt>struct</tt> vs <tt>class</tt> | |||
: A C++ <tt>class</tt> is used for a class that has methods and <tt>struct</tt> is used for a class that has only data. | |||
; Dbf | ; Dbf | ||
: any class starting with Dbf describes a field in a generated header file. For example DbfString describes a field generated from <tt>field(name,string)</tt>. | : any class starting with Dbf describes a field in a generated header file. For example DbfString describes a field generated from <tt>field(name,string)</tt>. | ||
Line 37: | Line 39: | ||
=== <tt>dbfTypes.h</tt> === | === <tt>dbfTypes.h</tt> === | ||
Every field in the header files generated from DBD <tt>struct</tt> and | |||
<tt>record</tt> definitions has one on the following types: | |||
enum dbfType { | enum dbfType { | ||
dbfTypeBoolean, // epicsBoolean | dbfTypeBoolean, // epicsBoolean | ||
dbfTypeOctet, // epicsOctet | dbfTypeOctet, // epicsOctet | ||
Line 57: | Line 62: | ||
=== Discussion of dbfTypes === | === Discussion of dbfTypes === | ||
DBD type | DBD type | ||
Line 116: | Line 117: | ||
== epicsTypes == | == epicsTypes == | ||
</center> | </center> | ||
Fields of type epicsBoolean, epicsOctet, epicsInt16, epicsInt32, epicsInt64, | |||
epicsFloat32, or epicsFloat64 are all a C++ fundamental type. When a record | |||
instance is created these are all initialized to 0. | |||
A field of type EpicsString is initialized via the default constructor for | |||
EpicsString, which means that no EpicsBuffer is created. Record support | |||
must call createBuffer. | |||
---- | |||
<center> | |||
== DbfArray == | |||
</center> | |||
<tt>DbfArray</tt> is: | |||
struct DbfArray { | |||
dbfType type; | |||
EpicsArray *parray; | |||
}; | |||
In addition the following convenience classes are available . | |||
class BasicTypeArray { | |||
BasicTypeArray(DbfArray *parray); | |||
BasicTypeArray(DbfArray *parray, | |||
const char *bufferType, epicsInt32 capacity); | |||
BasicTypeArray(DbfArray *parray, | |||
BufferCreator *creator, epicsInt32 capacity); | |||
virtual ~BasicTypeArray(); | |||
protected: | |||
DbfArray *parray; | |||
private: | |||
BasicTypeArray(const EpicsBasicTypeArray &);// No copy constructor | |||
// No assignment operator | |||
BasicTypeArray& operator=(const EpicsBasicTypeArray &); | |||
}; | |||
class Int16Array : public BasicTypeArray { | |||
Int16Array(); | |||
Int16Array(const char *bufferType, epicsInt32 capacity); | |||
Int16Array(EpicsBufferCreator *creator, epicsInt32 capacity); | |||
~Int16Array(); | |||
epicsInt16 * element(epicsInt32 index); | |||
const epicsInt16 * element(epicsInt32 index) const; | |||
epicsInt32 get(epicsInt32 offset, epicsInt32 len, | |||
epicsInt16 *pto) const; | |||
epicsInt32 put(epicsInt32 offset, epicsInt32 len, | |||
const epicsInt16 *pfrom); | |||
// These are similar to Buffer, measured in elements not octets | |||
void reserve(epicsInt32 capacity); | |||
epicsInt32 capacity() const; | |||
void resize(epicsInt32 newsize); | |||
epicsInt32 size() const; | |||
epicsInt32 maxSize() const; | |||
void expose(epicsInt32 offset, epicsInt32 &len, | |||
epicsInt16 *&pdata); | |||
void expose(epicsInt32 offset, epicsInt32 &len, | |||
const epicsInt16 *&pdata) const; | |||
private: | |||
Int16Array(const EpicsInt16Array &); // No copy constructor | |||
Int16Array& operator=(const EpicsInt16Array &); // No assignment operator | |||
}; | |||
class OctetArray ; | |||
class Int32Array ; | |||
class Int64Array ; | |||
class Float32Array ; | |||
class Float64Array ; | |||
class StringArray ; | |||
class StructArray ; | |||
---- | |||
<center> | |||
== DbfMDArray == | |||
</center> | |||
<tt>DbfMDArray</tt> is: | |||
struct DbfMDArray { | |||
dbfType type; | |||
EpicsMDArray *parray; | |||
}; | |||
Need something like for DbfArray except that convenience classes will be | |||
class BasicTypeMDArray; | |||
class OctetMDArray ; | |||
class Int32MDArray ; | |||
class Int64MDArray ; | |||
class Float32MDArray ; | |||
class Float64MDArray ; | |||
---- | ---- | ||
<center> | <center> | ||
Line 123: | Line 220: | ||
</center> | </center> | ||
<tt>DbfMenu</tt> is described as: | <tt>DbfMenu</tt> is described as: | ||
struct DbfMenu{ | |||
epicsInt16 index; | epicsInt16 index; | ||
DbdMenu *pmenuDef; | DbdMenu *pmenuDef; | ||
Line 130: | Line 226: | ||
<tt>DbfMenu</tt> provides the current menu index and also the menu definition. | <tt>DbfMenu</tt> provides the current menu index and also the menu definition. | ||
A field of type DbfMenu is automatically initialized by dbLoadRecords. | |||
---- | ---- | ||
Line 137: | Line 235: | ||
</center> | </center> | ||
<tt>DbfEnum</tt> is described as: | <tt>DbfEnum</tt> is described as: | ||
struct DbfEnum{ | |||
epicsInt16 index; | epicsInt16 index; | ||
DbfArray *pfield; //EpicsArray of epicsTypeString | DbfArray *pfield; //EpicsArray of epicsTypeString | ||
Line 145: | Line 242: | ||
<tt>pfield</tt> is the address of a field in the same record that is a | <tt>pfield</tt> is the address of a field in the same record that is a | ||
DbfArray of type EpicsString. It contains the choices. | DbfArray of type EpicsString. It contains the choices. | ||
A field of type DbfEnum is automatically initialized by dbLoadRecords. | |||
---- | ---- | ||
Line 163: | Line 262: | ||
}; | }; | ||
struct DbfLink{ | |||
LinkDir dir; | LinkDir dir; | ||
DbdLink *plinkDef; | DbdLink *plinkDef; | ||
Line 170: | Line 268: | ||
}; | }; | ||
struct DbfDevice{ | |||
LinkDir dir; | LinkDir dir; | ||
DbdDevice *pDbdDevice; | DbdDevice *pDbdDevice; | ||
Line 177: | Line 274: | ||
}; | }; | ||
The fields of <tt>DbfLink</tt> are initialized as follows: | The fields of <tt>DbfLink</tt> are initialized by dbLoadRecords as follows: | ||
; <tt>dir</tt> | ; <tt>dir</tt> | ||
: This is taken from either the <tt>field</tt> definition or from the <tt>DbdLink</tt> definition and is the most restrictive. For example if one says inout and the other says in then <tt>dir</tt> will be in. | : This is taken from either the <tt>field</tt> definition or from the <tt>DbdLink</tt> definition and is the most restrictive. For example if one says inout and the other says in then <tt>dir</tt> will be in. | ||
Line 197: | Line 294: | ||
<tt>DbfStruct</tt> is described as | <tt>DbfStruct</tt> is described as | ||
struct DbfStruct { | |||
DbdStruct *pdescription; | DbdStruct *pdescription; | ||
void *pstorage; | void *pstorage; | ||
}; | }; | ||
The fields of <tt>DbfStruct</tt> are initialized by dbLoadRecords as follows: | |||
; <tt>pdescription</tt> | |||
: This is initialized via the structure name specified in field definition. | |||
; <tt>pstorage | |||
: This is initialized by calling DbdStructLifetime:allocate | |||
---- | ---- | ||
Line 219: | Line 320: | ||
class Interface {}; // Must be an interface, i.e. pure abstract class | class Interface {}; // Must be an interface, i.e. pure abstract class | ||
struct DbdMenu{ | |||
NODE node; // for DbdBase:menuList | |||
NODE node; // for | |||
EpicsString name; | EpicsString name; | ||
epicsInt16 nchoices; | epicsInt16 nchoices; | ||
Line 227: | Line 327: | ||
}; | }; | ||
struct DbdLink{ //describes dbd link statement | |||
public: | public: | ||
NODE node; // For | NODE node; // For DbdBase:linkList | ||
LinkDir dir; | LinkDir dir; | ||
EpicsString choiceName; | EpicsString choiceName; | ||
Line 236: | Line 336: | ||
}; | }; | ||
struct DbdDevice { //describes dbd device statement | |||
NODE node; // For DbdBase:deviceList | |||
NODE node; // For | |||
LinkDir dir; | LinkDir dir; | ||
EpicsString choiceName; | EpicsString choiceName; | ||
Line 248: | Line 347: | ||
// Beginning of definitions for DbdStruct | // Beginning of definitions for DbdStruct | ||
struct DbdAttribute { | |||
EpicsString default; | EpicsString default; | ||
epicsBoolean readonly; | epicsBoolean readonly; | ||
Line 278: | Line 376: | ||
struct DbdStructDefaults { // defaults for struct | struct DbdStructDefaults { // defaults for struct | ||
DbdStruct *pdescription; | |||
}; | }; | ||
struct DbdField { | |||
const char *name; | const char *name; | ||
dbfType type; | |||
union { | union { | ||
DbdStringDefaults *pstring; | DbdStringDefaults *pstring; | ||
Line 291: | Line 388: | ||
DbdStructDefaults *pstruct; | DbdStructDefaults *pstruct; | ||
} defaults; | } defaults; | ||
DbdAttribute attribute; | |||
}; | }; | ||
struct DbdStruct{ // describes a struct | |||
NODE node; // for DbdBase:structList | |||
NODE node; // for | |||
const char *name; | const char *name; | ||
epicsInt16 nfields; | epicsInt16 nfields; | ||
DbdField *pafield;//ptr to array of DbdField | |||
DbdStructLifetime *plifetime; | |||
}; | }; | ||
struct DbdRecord { // describes a record | |||
NODE node; // for DbdBase:recordList | |||
NODE node; // for | |||
LIST instanceList; | LIST instanceList; | ||
const char *name; | |||
epicsInt16 nfields; | |||
DbdField *pafield;//ptr to array of DbdField | |||
DbdRecordSupport *psupport; | DbdRecordSupport *psupport; | ||
DbdRecordLifetime *plifetime; | |||
}; | }; | ||
struct DbdUserField{ // describes a dbd userField statement | |||
NODE node; // For DbdBase:userFieldList | |||
NODE node; // For | |||
EpicsString choiceName; | EpicsString choiceName; | ||
epicsType type; | epicsType type; | ||
Line 322: | Line 419: | ||
// The following describes a record instance | // The following describes a record instance | ||
struct DbdUserFieldInstance { | |||
public: | public: | ||
NODE node; // for DbdRecordInstance.userField | NODE node; // for DbdRecordInstance.userField | ||
Line 328: | Line 425: | ||
DbdUserField *pDbdUserField; | DbdUserField *pDbdUserField; | ||
void *pstorage; // for DbdUserField.type | void *pstorage; // for DbdUserField.type | ||
DbfStruct dataStruct; | |||
}; | }; | ||
struct DbdRecordInstance { | |||
NODE node; // for DbdRecord.instanceList | NODE node; // for DbdRecord.instanceList | ||
DbdRecord *pDbdRecord; | |||
void *pstorage; | void *pstorage; | ||
EpicsString name; | EpicsString name; | ||
Line 340: | Line 436: | ||
}; | }; | ||
struct DbdBase { | |||
LIST structList; | |||
LIST recordList; | |||
LIST | LIST menuList; | ||
LIST linkList; | |||
LIST deviceList; | |||
LIST userFieldList; | |||
}; | |||
LIST | |||
LIST | |||
LIST | |||
LIST | |||
LIST | |||
=== Discussion of dbdStatements === | === Discussion of dbdStatements === | ||
==== Menu ==== | ==== Menu ==== | ||
A dbd <tt>menu</tt> is described by class DbdMenu | A dbd <tt>menu</tt> is described by class <tt>DbdMenu</tt> | ||
The fields of DbdMenu are: | The fields of DbdMenu are: | ||
; <tt>node</tt> | |||
: node for DbdBase:menuList | |||
; <tt>name</tt> | ; <tt>name</tt> | ||
: The menu name. | : The menu name. | ||
Line 445: | Line 464: | ||
==== Link ==== | ==== Link ==== | ||
A dbd <tt>link</tt> definition is described by class <tt>DbdLink</tt> | |||
; <tt>node</tt> | ; <tt>node</tt> | ||
: This is a node for <tt>DbdLinkList</tt> | : This is a node for <tt>DbdLinkList</tt> | ||
Line 453: | Line 472: | ||
: The name that connects a DbdLink to a DbfLink instance. | : The name that connects a DbdLink to a DbfLink instance. | ||
; <tt>dataStructName</tt> | ; <tt>dataStructName</tt> | ||
: The class name of an | : The class name of an DbdStruct for the Interface implementation | ||
; <tt>pinterface</tt> | ; <tt>pinterface</tt> | ||
: The address of the DbdLinkSupport Interface implementation. | : The address of the DbdLinkSupport Interface implementation. | ||
Line 474: | Line 493: | ||
==== struct and record ==== | |||
The following classes describe the fields in a dbd <tt>struct</tt> or <tt>record</tt> definition: <tt>DbdStruct</tt>, <tt>DbdRecord</tt>, <tt>DbdField</tt>,and <tt>DbdAttribute</tt> | |||
The fields of <tt>DbdStruct</tt> are: | |||
; <tt>node</tt> | |||
: node for <tt>DbdBase:structList</tt> | |||
; <tt>name</tt> | |||
: The name of the struct. | |||
; <tt>nfields</tt> | |||
: The number of fields, e.g. fields in the structure. | |||
; <tt>pafields</tt> | |||
: pointer to an array of <tt>DbdField</tt>. | |||
; <tt>plifetime</tt> | |||
: The address of an implementation of interface <tt>DbdStructLifetime</tt>. The implementation is automatically generated from the dbd <tt>struct</tt>. See below for a description of the Lifetime methods. | |||
The fields of <tt>DbdRecord</tt> are; | |||
; <tt>node</tt> | |||
: node for <tt>DbdBase:recordList</tt> | |||
; <tt>instanceList</tt> | |||
: list of instances of this record type | |||
; <tt>name</tt> | |||
: The name of the record type. | |||
; <tt>nfields</tt> | |||
: The number of fields, e.g. fields in the record. | |||
; <tt>pafields</tt> | |||
: pointer to an array of <tt>DbdField</tt>. | |||
; <tt>psupport</tt> | |||
: The address of the <tt>DbdRecordSupport</tt> for this record type. | |||
; <tt>plifetime</tt> | |||
: The address of an implementation of interface <tt>DbdRecordLifetime</tt>. The implementation is automatically generated from the dbd <tt>record</tt> statement. See below for a description of the Lifetime methods. | |||
The fields of <tt>DbdField</tt> are: | |||
; <tt>name</tt> | |||
: The name of the field | |||
; <tt>type</tt> | |||
: The dbfType of the field. | |||
: <tt>defaults</tt> | |||
; a union of default values. The default values depend on the record type definitions. Most types do not have associated default values. Note that these are defaults for the description of the field NOT for values to put in the field. | |||
; <tt>attribute</tt> | |||
: DbdAttribute for the field | |||
The fields of <tt>DbdAttribute</tt> are: | |||
; <tt>default</tt> | |||
: An EpicsString providing a default value for the field. | |||
; <tt>readonly</tt> | |||
: Is the field readonly? | |||
; <tt>design</tt> | |||
: Is the field a design fields for DCTs? | |||
; <tt>special</tt> | |||
: Should DbdRecordSupport:special be called if the field is modified. | |||
; <tt>dynamic</tt> | |||
: Can the field change because of record processing? | |||
; <tt>asl</tt> | |||
: The access security level. | |||
==== User Defined Fields ==== | ==== User Defined Fields ==== | ||
Line 502: | Line 576: | ||
: Address of storage for the dbfType. | : Address of storage for the dbfType. | ||
; <tt>dataStruct</tt> | ; <tt>dataStruct</tt> | ||
: An | : An DbfStruct that holds the private data for the DbdUserFieldHandler. | ||
The fields of <tt>DbdRecordInstance</tt> are: | The fields of <tt>DbdRecordInstance</tt> are: | ||
; <tt> | ; <tt>node</tt> | ||
: A node for list <tt>DbdRecord.instanceList</tt> | |||
; <tt>pDbdRecord</tt> | |||
: address of the DbdRecord describing the record | : address of the DbdRecord describing the record | ||
; <tt>pstorage</tt> | ; <tt>pstorage</tt> | ||
; address of the storage for the record instance | ; address of the storage for the record instance | ||
; <tt>name</tt> | ; <tt>name</tt> | ||
: The name of the record instance | : The name of the record instance | ||
; <tt>userField</tt> | ; <tt>userField</tt> | ||
: | : <tt>DbdUserFieldInstance</tt> list for the record instance. | ||
==== | ==== DbdBase ==== | ||
The following provide lists of various things: | The following provide lists of various things: | ||
; <tt> | ; <tt>structList</tt> | ||
: The list of each struct definition | : The list of each struct definition | ||
; <tt> | ; <tt>recordList</tt> | ||
: The list of each record type definition | : The list of each record type definition | ||
; <tt> | ; <tt>menuList</tt> | ||
: The list of each menu definition | : The list of each menu definition | ||
; <tt> | ; <tt>linkList</tt> | ||
: The list of each link definition | : The list of each link definition | ||
; <tt> | ; <tt>deviceList</tt> | ||
: The list of each device definition | : The list of each device definition | ||
; <tt> | ; <tt>userFieldList</tt> | ||
: The list of each | : The list of each DbdUserField definition | ||
---- | ---- | ||
Line 549: | Line 623: | ||
// The following is implemented by database access | // The following is implemented by database access | ||
class DbdFieldPutString { | class DbdFieldPutString { | ||
virtual void primitive(EpicsString *pfrom, | virtual void primitive(EpicsString *pfrom, dbfType type, | ||
void *pstorage) = 0; | void *pstorage) = 0; | ||
virtual void string(EpicsString *pfrom, | virtual void string(EpicsString *pfrom, | ||
EpicsString *pEpicsString) = 0; | EpicsString *pEpicsString) = 0; | ||
virtual void array(EpicsString *pfrom, | virtual void array(EpicsString *pfrom, | ||
DbfArray *parray) = 0; | |||
virtual void | virtual void dbfStruct(EpicsString *pfrom, | ||
DbfStruct *pstruct) = 0; | |||
virtual void | virtual void dbfMDArray(EpicsString *pfrom, | ||
DbfMDArray *parray) = 0; | |||
} | } | ||
// For struct definitions | // For struct definitions | ||
// An DbdStructLifetime interface is automatically generated. | // An DbdStructLifetime interface is automatically generated. | ||
class DbdStructLifetime | class DbdStructLifetime { | ||
public: | public: | ||
virtual void allocate(DbfStruct &struct) = 0; | |||
virtual void destroy(DbfStruct &struct) = 0; | |||
virtual bool initialize(DbfStruct *pDbfStruct) = 0; | virtual bool initialize(DbfStruct *pDbfStruct) = 0; | ||
virtual bool finalize(DbfStruct *pDbfStruct) = 0; | virtual bool finalize(DbfStruct *pDbfStruct) = 0; | ||
virtual void *exposeField(DbfStruct &struct, epicsInt16 index) = 0; | |||
}; | }; | ||
// For record definitions a DbdRecordLifetime is automatically generated. | // For record definitions a DbdRecordLifetime is automatically generated. | ||
class DbdRecordLifetime | class DbdRecordLifetime{ | ||
public: | public: | ||
virtual void allocate(DbfStruct &struct) = 0; | |||
virtual void destroy(DbfStruct &struct) = 0; | |||
virtual bool initialize(DbdRecordInstance *pDbdRecordInstance) = 0; | virtual bool initialize(DbdRecordInstance *pDbdRecordInstance) = 0; | ||
virtual bool finalize(DbdRecordInstance *pDbdRecordInstance) = 0; | virtual bool finalize(DbdRecordInstance *pDbdRecordInstance) = 0; | ||
virtual void *exposeField(DbfStruct &struct, epicsInt16 index) = 0; | |||
}; | }; | ||
Line 625: | Line 705: | ||
This is an interface, which has an implementation provided by iocCore, | This is an interface, which has an implementation provided by iocCore, | ||
that convert an <tt>EpicsString</tt> to an | that convert an <tt>EpicsString</tt> to an dbfType. | ||
The methods are: | The methods are: | ||
; <tt>primitive</tt> | ; <tt>primitive</tt> | ||
: This convert a string to one of the types: <tt> | : This convert a string to one of the types: <tt>epicsBoolean</tt>, ..., <epicsFloat64</tt> | ||
; <tt>string</tt> | ; <tt>string</tt> | ||
: Copies | : Copies an EpicsString to an EpicsString | ||
; <tt>array</tt> | ; <tt>array</tt> | ||
: Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either | : Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either DbdFieldPutString:primitive or DbdFieldPutString:string to convert the value and put it into the correct element of <tt>DbfArray</tt> | ||
; <tt> | ; <tt>dbfStruct</tt> | ||
: Accepts a string that has the DBD struct initialialization syntax, locates the string value associated with each field and calls primitive, string, or array to convert the value and put the result of the correct field of <tt> | : Accepts a string that has the DBD struct initialialization syntax, locates the string value associated with each field and calls primitive, string, or array to convert the value and put the result of the correct field of <tt>DbfStruct</tt> | ||
; <tt> | ; <tt>dbfMDArray</tt> | ||
: Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either | : Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either DbdFieldPutString:primitive or DbdFieldPutString:string to convert the value and put it into the correct element of <tt>DbfMDArray</tt> | ||
=== <tt>DbdStructLifetime</tt> and <tt>DbdRecordLifetime</tt> === | === <tt>DbdStructLifetime</tt> and <tt>DbdRecordLifetime</tt> === | ||
Every dbd <tt>struct</tt> and <tt>record</tt> has an associated Lifetime interface implementation. | Every dbd <tt>struct</tt> and <tt>record</tt> has an associated Lifetime interface implementation. |
Revision as of 18:48, 9 June 2005
EPICS: dbdClasses - IOC record
June 9 2005
Overview
This document describes the C++ class definitions for code that implements the semantics for records created from Database Definitions. The definitions are intended for code that:
- includes header files generated from dbd definitions. Header files are generated from the following dbd definitions:
- record - Should only be included by record support.
- struct - Included by code that understands the struct.
- menu - Included by code that understands the menu.
- does not include the header files.
The following headers files are described:
- dbfTypes.h - Type definitions for field definitions in struct or record> DBD definitions.
- dbdStatements.h - Type definitions for DBD statements.
- dbdInterfaces.h - Type definitions for interfaces related to DBD definitions.
dbfTypes
File dbfTypes.h describes types and classes that are used in header files generated from dbd struct or record field definitions. The following naming conventions are used:
- C++ struct vs class
- A C++ class is used for a class that has methods and struct is used for a class that has only data.
- Dbf
- any class starting with Dbf describes a field in a generated header file. For example DbfString describes a field generated from field(name,string).
- Dbd
- A class name starting with Dbd describes something related to dbd definitions. For example DbdLinkSupport describes a dbd link definition.
dbfTypes.h
Every field in the header files generated from DBD struct and record definitions has one on the following types:
enum dbfType { dbfTypeBoolean, // epicsBoolean dbfTypeOctet, // epicsOctet dbfTypeInt16, // epicsInt16 dbfTypeInt32, // epicsInt32 dbfTypeInt64, // epicsInt64 dbfTypeFloat32, // epicsFloat32 dbfTypeFloat64, // epicsFloat64 dbfTypeString, // EpicsString dbfTypeArray, // DbfArray dbfTypeMDArray // DbfMDArray dbfMenuT, // DbfMenu dbfEnumT, // DbfEnum dbfLinkT, // DbfLink dbfDeviceT // DbfDevice dbfTypeStruct, // DbfStruct };
Discussion of dbfTypes
DBD type
- bool,...,string all become an epicsType , i.e. epicsBoolean,...EpicsString
- array becomes a DbfArray or DbfMDArray.
- struct becomes a DbfStruct
- menu becomes DbfMenu
- enum becomes DbfEnum
- link becomes DbfLink
- device becomes DbfDevice
If a record is defined as:
struct(displayLimits) { field(low,double) field(high,double) } record(xxx) extends iocRecord { ... field(fbool,bool) field(foctet,octet) field(fint,int16) ... field(ffloat,float64) field(fstring,string) field(array,array(double[]) field(mdarray,array(double[,]) field(fmenu,menu(name)) field(fenum,enum) field(flink,link(in)) field(fdevice,link(in,analogIO)) field(displayLimits,struct(displayLimits)) }
Then the generated header file will be
class xxxRecord : public iocRecord { public: epicsBoolean fbool; epicsOctet foctet; epicsInt16 fint; ... epicsFloat64 ffloat; EpicsString fstring; DbfArray array; DbfMDArray mdarray; DbfMenu fmenu; DbfEnum fenum; DbfLink flink; DbfDevice fdevice; DbfStruct displayLimits; };
epicsTypes
Fields of type epicsBoolean, epicsOctet, epicsInt16, epicsInt32, epicsInt64, epicsFloat32, or epicsFloat64 are all a C++ fundamental type. When a record instance is created these are all initialized to 0.
A field of type EpicsString is initialized via the default constructor for EpicsString, which means that no EpicsBuffer is created. Record support must call createBuffer.
DbfArray
DbfArray is:
struct DbfArray { dbfType type; EpicsArray *parray; };
In addition the following convenience classes are available .
class BasicTypeArray { BasicTypeArray(DbfArray *parray); BasicTypeArray(DbfArray *parray, const char *bufferType, epicsInt32 capacity); BasicTypeArray(DbfArray *parray, BufferCreator *creator, epicsInt32 capacity); virtual ~BasicTypeArray(); protected: DbfArray *parray; private: BasicTypeArray(const EpicsBasicTypeArray &);// No copy constructor // No assignment operator BasicTypeArray& operator=(const EpicsBasicTypeArray &); };
class Int16Array : public BasicTypeArray { Int16Array(); Int16Array(const char *bufferType, epicsInt32 capacity); Int16Array(EpicsBufferCreator *creator, epicsInt32 capacity); ~Int16Array(); epicsInt16 * element(epicsInt32 index); const epicsInt16 * element(epicsInt32 index) const; epicsInt32 get(epicsInt32 offset, epicsInt32 len, epicsInt16 *pto) const; epicsInt32 put(epicsInt32 offset, epicsInt32 len, const epicsInt16 *pfrom);
// These are similar to Buffer, measured in elements not octets void reserve(epicsInt32 capacity); epicsInt32 capacity() const; void resize(epicsInt32 newsize); epicsInt32 size() const; epicsInt32 maxSize() const; void expose(epicsInt32 offset, epicsInt32 &len, epicsInt16 *&pdata); void expose(epicsInt32 offset, epicsInt32 &len, const epicsInt16 *&pdata) const; private: Int16Array(const EpicsInt16Array &); // No copy constructor Int16Array& operator=(const EpicsInt16Array &); // No assignment operator };
class OctetArray ; class Int32Array ; class Int64Array ; class Float32Array ; class Float64Array ; class StringArray ; class StructArray ;
DbfMDArray
DbfMDArray is:
struct DbfMDArray { dbfType type; EpicsMDArray *parray; };
Need something like for DbfArray except that convenience classes will be
class BasicTypeMDArray; class OctetMDArray ; class Int32MDArray ; class Int64MDArray ; class Float32MDArray ; class Float64MDArray ;
DbfMenu
DbfMenu is described as:
struct DbfMenu{ epicsInt16 index; DbdMenu *pmenuDef; };
DbfMenu provides the current menu index and also the menu definition.
A field of type DbfMenu is automatically initialized by dbLoadRecords.
DbfEnum
DbfEnum is described as:
struct DbfEnum{ epicsInt16 index; DbfArray *pfield; //EpicsArray of epicsTypeString };
pfield is the address of a field in the same record that is a DbfArray of type EpicsString. It contains the choices.
A field of type DbfEnum is automatically initialized by dbLoadRecords.
DbfLink and DbdDevice
DbfLink is described as
enum LinkDir { LinkDirNone, LinkDirForward, LinkDirIn, LinkDirOut, LinkDirInOut }; struct DbfLink{ LinkDir dir; DbdLink *plinkDef; DbfStruct dataStruct; }; struct DbfDevice{ LinkDir dir; DbdDevice *pDbdDevice; DbfStruct dataStruct; };
The fields of DbfLink are initialized by dbLoadRecords as follows:
- dir
- This is taken from either the field definition or from the DbdLink definition and is the most restrictive. For example if one says inout and the other says in then dir will be in.
- plinkDef
- This is the address of the DbdLink.
- dataStruct
- The describes the data structure specified in the dbd link definition. It contains data used by the link support.
Link support always implements interface DbdLinkSupport
A DbfDevice is similar to a DbfLink except that the interface implemented by the device support is also specified, i.e. instead of implementing interface DbdLinkSupport, the device support implements an interface that both record support and device support understand.
DbfStruct
DbfStruct is described as
struct DbfStruct { DbdStruct *pdescription; void *pstorage; };
The fields of DbfStruct are initialized by dbLoadRecords as follows:
- pdescription
- This is initialized via the structure name specified in field definition.
- pstorage
- This is initialized by calling DbdStructLifetime:allocate
dbdStatements
The definitions in dbdStatements.h allow introspection of ioc records. They describe everything defined in DBD definitions.
NODE and LIST specify a doubly linked list. An implementation is not specified.
dbdStatements.h
class Interface {}; // Must be an interface, i.e. pure abstract class
struct DbdMenu{ NODE node; // for DbdBase:menuList EpicsString name; epicsInt16 nchoices; EpicsString *pchoice[]; }; struct DbdLink{ //describes dbd link statement public: NODE node; // For DbdBase:linkList LinkDir dir; EpicsString choiceName; EpicsString dataStructName; DbdLinkSupport *pinterface; }; struct DbdDevice { //describes dbd device statement NODE node; // For DbdBase:deviceList LinkDir dir; EpicsString choiceName; EpicsString dataStructName; EpicsString interfaceName; Interface *pinterface; };
// Beginning of definitions for DbdStruct struct DbdAttribute { EpicsString default; epicsBoolean readonly; epicsBoolean design; epicsBoolean special; epicsBoolean dynamic; epicsInt16 asl; };
struct DbdStringDefaults { // defaults for string const char *bufferType; epicsInt32 capacity; };
struct DbdArrayDefaults { // defaults for array dbfType type; const char *bufferType; epicsInt32 capacity; epicsInt32 nelements; };
struct DbdMDArrayDefaults { // defaults for mdarray dbfType type; epicsInt16 ndim const char *bufferType; epicsInt32 capacity; };
struct DbdStructDefaults { // defaults for struct DbdStruct *pdescription; };
struct DbdField { const char *name; dbfType type; union { DbdStringDefaults *pstring; DbdArrayDefaults *parray; DbdMDArrayDefaults *pmdarray; DbdStructDefaults *pstruct; } defaults; DbdAttribute attribute; };
struct DbdStruct{ // describes a struct NODE node; // for DbdBase:structList const char *name; epicsInt16 nfields; DbdField *pafield;//ptr to array of DbdField DbdStructLifetime *plifetime; };
struct DbdRecord { // describes a record NODE node; // for DbdBase:recordList LIST instanceList; const char *name; epicsInt16 nfields; DbdField *pafield;//ptr to array of DbdField DbdRecordSupport *psupport; DbdRecordLifetime *plifetime; }; struct DbdUserField{ // describes a dbd userField statement NODE node; // For DbdBase:userFieldList EpicsString choiceName; epicsType type; EpicsString dataStructName; DbdUserFieldHandler *pinterface; }; // The following describes a record instance struct DbdUserFieldInstance { public: NODE node; // for DbdRecordInstance.userField EpicsString name; // field name DbdUserField *pDbdUserField; void *pstorage; // for DbdUserField.type DbfStruct dataStruct; }; struct DbdRecordInstance { NODE node; // for DbdRecord.instanceList DbdRecord *pDbdRecord; void *pstorage; EpicsString name; LIST userField; // of DbdUserFieldInstance }; struct DbdBase { LIST structList; LIST recordList; LIST menuList; LIST linkList; LIST deviceList; LIST userFieldList; };
Discussion of dbdStatements
Menu
A dbd menu is described by class DbdMenu
The fields of DbdMenu are:
- node
- node for DbdBase:menuList
- name
- The menu name.
- nchoices
- The number of menu choices.
- pchoice
- The address of an array of pointers to EpicsString. Each EpicsString is a choice.
Link
A dbd link definition is described by class DbdLink
- node
- This is a node for DbdLinkList
- dir
- The link direction
- choiceName
- The name that connects a DbdLink to a DbfLink instance.
- dataStructName
- The class name of an DbdStruct for the Interface implementation
- pinterface
- The address of the DbdLinkSupport Interface implementation.
Device
Each dbd device definition has an associated class DbdDevice with fields:
- node
- This is a node for DbdDeviceList
- dir
- The link direction
- choiceName
- The name that matches a DbdDevice to a DbfDevice instance.
- dataStructName
- The class name of an EpicsStruct for the Interface implementation
- interfaceName
- The name of the interface type implemented by the device support
- pinterface
- The address of the Interface implementation.
struct and record
The following classes describe the fields in a dbd struct or record definition: DbdStruct, DbdRecord, DbdField,and DbdAttribute
The fields of DbdStruct are:
- node
- node for DbdBase:structList
- name
- The name of the struct.
- nfields
- The number of fields, e.g. fields in the structure.
- pafields
- pointer to an array of DbdField.
- plifetime
- The address of an implementation of interface DbdStructLifetime. The implementation is automatically generated from the dbd struct. See below for a description of the Lifetime methods.
The fields of DbdRecord are;
- node
- node for DbdBase:recordList
- instanceList
- list of instances of this record type
- name
- The name of the record type.
- nfields
- The number of fields, e.g. fields in the record.
- pafields
- pointer to an array of DbdField.
- psupport
- The address of the DbdRecordSupport for this record type.
- plifetime
- The address of an implementation of interface DbdRecordLifetime. The implementation is automatically generated from the dbd record statement. See below for a description of the Lifetime methods.
The fields of DbdField are:
- name
- The name of the field
- type
- The dbfType of the field.
- defaults
- a union of default values. The default values depend on the record type definitions. Most types do not have associated default values. Note that these are defaults for the description of the field NOT for values to put in the field.
- attribute
- DbdAttribute for the field
The fields of DbdAttribute are:
- default
- An EpicsString providing a default value for the field.
- readonly
- Is the field readonly?
- design
- Is the field a design fields for DCTs?
- special
- Should DbdRecordSupport:special be called if the field is modified.
- dynamic
- Can the field change because of record processing?
- asl
- The access security level.
User Defined Fields
Each dbd userField definition has an associated class DbdUserField with fields:
- node
- This is a node for DbdUserFieldList
- choiceName
- The name that matches a DbdUserField to a DbdUserFieldInstance
- type
- The epicsType for the user field
- dataStructName
- The class name of an EpicsStruct for the DbdUserFieldHandler
- pinterface
- The address of the DbdUserFieldHandler implementation.
Record Instance
A record instance has two associated classes:DbdUserFieldInstance and DbdRecordInstance.
DbdUserFieldInstance contains information for a user defined field:
- node
- A node for list DbdRecordInstance.userField
- name
- The name of the user defined field, i.e. the psuedo field name
- pDbdUserField
- The DbdUserField that describes the field
- pstorage
- Address of storage for the dbfType.
- dataStruct
- An DbfStruct that holds the private data for the DbdUserFieldHandler.
The fields of DbdRecordInstance are:
- node
- A node for list DbdRecord.instanceList
- pDbdRecord
- address of the DbdRecord describing the record
- pstorage
- address of the storage for the record instance
- name
- The name of the record instance
- userField
- DbdUserFieldInstance list for the record instance.
DbdBase
The following provide lists of various things:
- structList
- The list of each struct definition
- recordList
- The list of each record type definition
- menuList
- The list of each menu definition
- linkList
- The list of each link definition
- deviceList
- The list of each device definition
- userFieldList
- The list of each DbdUserField definition
dbdInterfaces
dbdInterfaces describes standard interfaces implemented by code that supports runtime database access.
dbdInterfaces.h
dbdInterfaces.h contains the following:
// The following is implemented by database access class DbdFieldPutString { virtual void primitive(EpicsString *pfrom, dbfType type, void *pstorage) = 0; virtual void string(EpicsString *pfrom, EpicsString *pEpicsString) = 0; virtual void array(EpicsString *pfrom, DbfArray *parray) = 0; virtual void dbfStruct(EpicsString *pfrom, DbfStruct *pstruct) = 0; virtual void dbfMDArray(EpicsString *pfrom, DbfMDArray *parray) = 0; }
// For struct definitions // An DbdStructLifetime interface is automatically generated. class DbdStructLifetime { public: virtual void allocate(DbfStruct &struct) = 0; virtual void destroy(DbfStruct &struct) = 0; virtual bool initialize(DbfStruct *pDbfStruct) = 0; virtual bool finalize(DbfStruct *pDbfStruct) = 0; virtual void *exposeField(DbfStruct &struct, epicsInt16 index) = 0; };
// For record definitions a DbdRecordLifetime is automatically generated. class DbdRecordLifetime{ public: virtual void allocate(DbfStruct &struct) = 0; virtual void destroy(DbfStruct &struct) = 0; virtual bool initialize(DbdRecordInstance *pDbdRecordInstance) = 0; virtual bool finalize(DbdRecordInstance *pDbdRecordInstance) = 0; virtual void *exposeField(DbfStruct &struct, epicsInt16 index) = 0; };
// link support modules implement the following interface class DbdLinkSupport { public: virtual void report(iocRecord *precord, DbfLink *pdbfLink) = 0; virtual bool initialize(EpicsString *errorMessage, iocRecord *precord, DbfLink *pdbfLink) = 0; virtual bool finalize(EpicsString *errorMessage, iocRecord *precord, DbfLink *pdbfLink) = 0; virtual bool connect(EpicsString *errorMessage, iocRecord *precord, DbfLink *pdbfLink) = 0; virtual bool disconnect(EpicsString *errorMessage, iocRecord *precord, DbffLink *pdbfLink) = 0; virtual bool get(EpicsString *errorMessage, iocRecord *precord, DbffLink *pdbfLink, epicsType type, void *pfield) = 0; virtual bool put(EpicsString *errorMessage, iocRecord *precord, DbfLink *pdbfLink, epicsType type, void *pfield) = 0; };
/* record support implements the following*/ class DbdRecordSupport { public: virtual bool initBuffers(DbdRecordInstance *pDbdRecordInstance) = 0; virtual bool initConnections(DbdRecordInstance *pDbdRecordInstance) = 0; virtual bool breakConnections(DbdRecordInstance *pDbdRecordInstance) = 0; virtual bool process(DbdRecordInstance *pDbdRecordInstance) = 0; virtual void special(DbdRecordInstance *pDbdRecordInstance, bool after, epicsInt16 nlevels, // number of elements in fieldIndex epicsInt16 fieldIndex[] // array of field indices ) = 0; };
class DbdUserFieldHandler { public: virtual bool initialize(EpicsString *errorMessage, iocRecord *precord,DbdUserFieldInstance *puserField) = 0; virtual bool finalize(EpicsString *errorMessage, iocRecord *precord,DbdUserFieldInstance *puserField) = 0; virtual bool process(EpicsString *errorMessage, iocRecord *precord,DbdUserFieldInstance *puserField) = 0; };
Discussion of dbdInterfaces
DbdFieldPutString
This is an interface, which has an implementation provided by iocCore, that convert an EpicsString to an dbfType. The methods are:
- primitive
- This convert a string to one of the types: epicsBoolean, ..., <epicsFloat64
- string
- Copies an EpicsString to an EpicsString
- array
- Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either DbdFieldPutString:primitive or DbdFieldPutString:string to convert the value and put it into the correct element of DbfArray
- dbfStruct
- Accepts a string that has the DBD struct initialialization syntax, locates the string value associated with each field and calls primitive, string, or array to convert the value and put the result of the correct field of DbfStruct
- dbfMDArray
- Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either DbdFieldPutString:primitive or DbdFieldPutString:string to convert the value and put it into the correct element of DbfMDArray
DbdStructLifetime and DbdRecordLifetime
Every dbd struct and record has an associated Lifetime interface implementation. A tool is provided that automatically generates the implementation from the dbd definition.
DbdStructLifetime and DbdRecordLifetime each has the following fields:
- allocate
- Creates storage for the struct or record.
- destroy
- frees storage
- exposeField
- Given an index it returns the address of the storage for the field. Note the the generated header files assign an index to each field.
- initialize
- initializes the struct or record
- finalize
- cleans up but does not free storage
DbdLinkSupport
This is the interface implemented by the support associated with each DBD link.
DbdLinkSupport has the following methods:
- report
- generate a report about the link instance
- initialize
- perform initialization but do not connect
- finalize
- undo initialization. It is assumed that disconnect has already been called.
- connect
- connect to external source of data
- disconnect
- disconnect from external source of data
- get
- get a value from the external source. type specified the field type and pfield is the address of where to store the data.
- put
- put a value from the external source. type specified the field type and pfield is the address of where to obtain the data.
DbdRecordSupport
This is the interface implemented by each record support module. DbdRecordSupport has the following methods:
- initBuffers
- This is called during record initialization. It is responsible for creating the buffers associated with each string and array field. It may call associated support to do the initialization.
- initConnections
- This is called to connect to external sources. It may call associated support to make the connections.
- breakConnections
- This is called to disconnect to external sources. It may call associated support to break the connections.
- process
- Process the record.
- special
- This is called whenever an external source modifies a field with attribute special set to true.
DbdUserFieldHandler
This is the interface implemented by code for user extensible fields.
DbdUserFieldHandler has the following fields:
- initialize
- Initialize the user field.
- finalize
- undo what was done during initialization
- process
- Called near the end of record processing just before monitors are handled.
Device Support Interfaces
Multiple interface definitions for device support will be defined. Record Support and device support must agree on which interface type is used for communication.