Difference between revisions of "V4 Design: dbdClass"
MartyKraimer (talk | contribs) |
MartyKraimer (talk | contribs) |
||
Line 1: | Line 1: | ||
May 24 2005 | |||
May | |||
<center> | <center> | ||
Line 19: | Line 17: | ||
The following headers files are described: | The following headers files are described: | ||
* <tt> | * <tt>dbfTypes.h</tt> - Type definitions for <tt>field</tt> definitions in <tt>struct</tt> or <tt>record></tt> DBD definitions. | ||
* <tt>dbdStatements.h</tt> - Type definitions for DBD statements. | * <tt>dbdStatements.h</tt> - Type definitions for DBD statements. | ||
* <tt>dbdInterfaces.h</tt> - Type definitions for interfaces related to DBD definitions. | * <tt>dbdInterfaces.h</tt> - Type definitions for interfaces related to DBD definitions. | ||
Line 27: | Line 24: | ||
<center> | <center> | ||
== | == dbfTypes == | ||
</center> | </center> | ||
File <tt>dbfTypes.h</tt> describes types and classes that are used | |||
in header 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: | ||
; Dbf | ; Dbf | ||
: any class starting with Dbf describes a non-primitive struct or record field. For example | : any class starting with Dbf describes a non-primitive struct or record field. For example EpicsString describes a field(name,string). | ||
; *Dbd* | ; *Dbd* | ||
: A class name that has Dbd imbeded in it describes something directly related to a dbd statement. For example LinkDbdSupport describes a dbd link definition. | : A class name that has Dbd imbeded in it describes something directly related to a dbd statement. For example LinkDbdSupport describes a dbd link definition. | ||
Line 91: | Line 39: | ||
=== <tt>dbdTypes.h</tt> === | === <tt>dbdTypes.h</tt> === | ||
enum dbfType { | enum dbfType { | ||
dbfUnknownT | dbfUnknownT, | ||
dbfEpicsT, // an epicsType except epicsUnknownT | |||
dbfArrayT, | |||
dbfStructT, | dbfStructT, | ||
dbfMenuT, | |||
dbfEnumT, | dbfEnumT, | ||
dbfLinkT, | dbfLinkT, | ||
dbfDeviceT | dbfDeviceT | ||
}; | }; | ||
class ArrayDbdDef; //describes a dbd array definition | |||
class | |||
class StructDbdDef; //describes a dbd struct definition | class StructDbdDef; //describes a dbd struct definition | ||
class MenuDbdDef; //describes a dbd menu definition | class MenuDbdDef; //describes a dbd menu definition | ||
Line 130: | Line 55: | ||
class DeviceDbd; //describes dbd device statement | class DeviceDbd; //describes dbd device statement | ||
/ | // If array type is a known epicsType then EpicsArray | ||
class | class DbfArray : public EpicsArray { | ||
public: | public: | ||
dbfType dbftype; | |||
}; | }; | ||
class | // If every field is a known epicsType then EpicsStruct | ||
class DbfStruct { | |||
public: | public: | ||
StructDbdDef *pStructDbdDef; | |||
void *pstorage; | |||
void | |||
}; | }; | ||
class DbfMenu{ | class DbfMenu{ | ||
public: | public: | ||
epicsInt16 index; | |||
MenuDbdDef *pmenuDef; /* address of global menu */ | MenuDbdDef *pmenuDef; /* address of global menu */ | ||
}; | }; | ||
Line 160: | Line 76: | ||
class DbfEnum{ | class DbfEnum{ | ||
public: | public: | ||
epicsInt16 index; | |||
DbfArray *pchoiceArray; // addr of field that is DbfArray on choices | DbfArray *pchoiceArray; // addr of field that is DbfArray on choices | ||
}; | }; | ||
Line 176: | Line 92: | ||
LinkDir dir; | LinkDir dir; | ||
LinkDbd *plinkDef; | LinkDbd *plinkDef; | ||
EpicsStruct dataStruct; | |||
}; | }; | ||
Line 183: | Line 99: | ||
LinkDir dir; | LinkDir dir; | ||
DeviceDbd *pdeviceDef; | DeviceDbd *pdeviceDef; | ||
EpicsStruct dataStruct; | |||
}; | }; | ||
=== Discussion of | === Discussion of dbfTypes === | ||
==== | The classes defined in dbfTypes together with the definitions from epicsTypes | ||
The | is a complete list of the definitions that appear in header files generated | ||
from <tt>struct</tt> and <tt>record</tt> dbd definitions. | |||
==== Epics Types ==== | |||
The types bool,...,string all map to an epicsType. | |||
The type array maps to EpicsArray if the array type maps to an epicsType. | |||
The type struct maps to EpicsStruct only if all fields in the struct map to | |||
an epicsType other than epicsUnknownT. | |||
If a record is defined as: | If a record is defined as: | ||
struct(displayLimits) { | |||
field(low,double) | |||
field(high,double) | |||
} | |||
record(xxx) extends iocRecord { | record(xxx) extends iocRecord { | ||
... | ... | ||
Line 199: | Line 129: | ||
field(ffloat64,float64) | field(ffloat64,float64) | ||
... | ... | ||
field(fstring,string) | |||
field(darray,array(double[]) | |||
field(displayLimits,struct(displayLimits)) | |||
} | } | ||
Then the generated header file will be | Then the generated header file will be | ||
class xxxRecord : public iocRecord { | class xxxRecord : public iocRecord { | ||
public: | public: | ||
epicsBoolean fbool; | |||
epicsOctet foctet; | |||
... | ... | ||
epicsFloat64 ffloat64; | |||
... | ... | ||
EpicsString fstring; | |||
EpicsArray darray; | |||
EpicsStruct displayLimits; | |||
}; | }; | ||
==== | ==== DbfArray ==== | ||
This is for array fields with a type that is not a standard epicsType, i.e. the epicsType is epicsUnknownT. | |||
If a record definition contains: | |||
: | |||
struct(calcInpLink) { | |||
field(link,link(in)) | |||
field(value,float64) | |||
} | |||
record(calc) extends iocRecord { | |||
... | |||
field(inp,array(struct(calcInpLink)[])) | |||
... | |||
} | |||
Then the generated code contains: | |||
DbfArray inp; | |||
==== DbfStruct ==== | |||
This is for a struct field that itself has fields that are not a standard epicsType, i.e. the epicsType is epicsUnknownT. | |||
If a record definition contains: | |||
struct(calcInpLink) { | |||
field(link,link(in)) // NOT a standard epicsType | |||
field(value,float64) | |||
} | |||
record(calc) extends iocRecord { | |||
... | |||
field(inp,struct(calcInpLink)) | |||
... | |||
} | |||
Then the generated code contains: | |||
DbfArray inp; | |||
==== DbfMenu ==== | ==== DbfMenu ==== | ||
Line 262: | Line 192: | ||
class DbfMenu{ | class DbfMenu{ | ||
public: | public: | ||
epicsInt16 index; | |||
MenuDbdDef *pmenuDef; | |||
}; | }; | ||
Line 276: | Line 206: | ||
class DbfEnum{ | class DbfEnum{ | ||
public: | public: | ||
epicsInt16 index; | |||
DbfArray *pchoiceArray; // addr of field that is DbfArray on choices | DbfArray *pchoiceArray; // addr of field that is DbfArray on choices | ||
}; | }; | ||
Line 292: | Line 222: | ||
LinkDir dir; | LinkDir dir; | ||
LinkDbd *plinkDef; | LinkDbd *plinkDef; | ||
EpicsStruct dataStruct; | |||
}; | }; | ||
If a record definition contains | If a record definition contains | ||
Line 324: | Line 254: | ||
=== <tt>dbdStatements.h</tt> === | === <tt>dbdStatements.h</tt> === | ||
// Interface is base class for an interface | // Interface is base class for an interface | ||
Line 332: | Line 259: | ||
class InterfaceLocator { | class InterfaceLocator { | ||
public: | public: | ||
EpicsString name; | |||
Interface *pinterface; | Interface *pinterface; | ||
}; | }; | ||
class StructFieldAttribute { | class StructFieldAttribute { | ||
EpicsString default; | |||
epicsBoolean readonly; | |||
epicsBoolean design; | |||
epicsBoolean special; | |||
epicsBoolean dynamic; | |||
epicsInt16 asl; | epicsInt16 asl; | ||
}; | }; | ||
Line 347: | Line 274: | ||
class StructDbdField { | class StructDbdField { | ||
public: | public: | ||
EpicsString name; | |||
dbfType | epicsType basic; | ||
dbfType type; | |||
StructFieldAttribute *pattribute; | StructFieldAttribute *pattribute; | ||
}; | }; | ||
Line 354: | Line 282: | ||
class StructDbdDef{ | class StructDbdDef{ | ||
public: | public: | ||
EpicsString name; | |||
Interface *plifetime; // references a | Interface *plifetime; // references a StructLifetime | ||
epicsInt16 nfields; | |||
StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField | StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField | ||
}; | }; | ||
Line 362: | Line 290: | ||
class MenuDbdDef{ | class MenuDbdDef{ | ||
public: | public: | ||
EpicsString name; | |||
epicsInt16 nchoices; | |||
EpicsString *pchoice[]; | |||
}; | }; | ||
Line 370: | Line 298: | ||
public: | public: | ||
LinkDir dir; | LinkDir dir; | ||
EpicsString choiceName; | |||
EpicsString dataStructName; | |||
Interface *pinterface; | Interface *pinterface; | ||
}; | }; | ||
Line 378: | Line 306: | ||
public: | public: | ||
LinkDir dir; | LinkDir dir; | ||
EpicsString interfaceName; | |||
EpicsString choiceName; | |||
EpicsString dataStructName; | |||
Interface *pinterface; | Interface *pinterface; | ||
}; | }; | ||
// The following describes a record type | // The following describes a record type | ||
class | class RecordDbd { // describes a record type | ||
EpicsString name; | |||
Interface *plifetime; // references a | Interface *plifetime; // references a RecordLifetime | ||
epicsInt16 nfields; | |||
StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField | StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField | ||
}; | }; | ||
Line 395: | Line 323: | ||
class UserDbdField { | class UserDbdField { | ||
public: | public: | ||
EpicsString name; | |||
epicsType type; | |||
void *pfield; | |||
InterfacePtr *pinterface; // | InterfacePtr *pinterface; // userFieldHandler | ||
}; | }; | ||
class | class RecordInstance { // describes a record instance | ||
EpicsString name; | |||
RecordDbd *pRecordDbd; | |||
void *precord; // address of record instance | |||
UserDbdField *puserField[]; | UserDbdField *puserField[]; | ||
}; | }; | ||
Line 410: | Line 338: | ||
=== Discussion of dbdStatements === | === Discussion of dbdStatements === | ||
==== | ==== StructXXX ==== | ||
The Struct classes describe the fields in a dbd <tt>struct</tt> or <tt>record</tt> definition. The classes are : <tt>StructDbdDef</tt>, <tt>StructDbdField</tt>,and <tt>StructFieldAttribute</tt> | The Struct classes describe the fields in a dbd <tt>struct</tt> or <tt>record</tt> definition. The classes are : <tt>StructDbdDef</tt>, <tt>StructDbdField</tt>,and <tt>StructFieldAttribute</tt> | ||
Line 417: | Line 345: | ||
: The name of the struct. | : The name of the struct. | ||
; <tt>plifetime</tt> | ; <tt>plifetime</tt> | ||
: The address of an implementation of interface <tt> | : The address of an implementation of interface <tt>StructLifetime</tt>. The implementation is automatically generated from the dbd <tt>struct</tt> statement. See below for a description of the <tt>StructLifetime</tt> methods. | ||
; <tt>nfields</tt> | ; <tt>nfields</tt> | ||
: The number of fields, e.g. fields in the structure. | : The number of fields, e.g. fields in the structure. | ||
; <tt>pfields</tt> | ; <tt>pfields</tt> | ||
: pointer to an array of pointers to <tt>StructDbdField</tt> | : pointer to an array of pointers to <tt>StructDbdField</tt>. | ||
The fields of <tt>StructDbdField</tt> are: | The fields of <tt>StructDbdField</tt> are: | ||
; <tt>name</tt> | ; <tt>name</tt> | ||
: The name of the field | : The name of the field | ||
; <tt>basic</tt> | |||
: The epicsType of the field. Unless this is epicsUnknownT generic code is usually provided for accessing the field. | |||
; <tt>type</tt> | ; <tt>type</tt> | ||
: The dbfType for the field. | : The dbfType for the field. Note that unless basic is epicsUnknownT this has the value dbfEpicsT. | ||
; <tt>pattribute</tt> | ; <tt>pattribute</tt> | ||
: The address of a StructFieldAttribute for the field | : The address of a StructFieldAttribute for the field | ||
Line 443: | Line 373: | ||
: The number of menu choices. | : The number of menu choices. | ||
; <tt>pchoice</tt> | ; <tt>pchoice</tt> | ||
: The address of an array of pointers to | : The address of an array of pointers to EpicsString. Each EpicsString is a choice. | ||
==== Link and Device ==== | ==== Link and Device ==== | ||
Line 470: | Line 400: | ||
==== Record ==== | ==== Record ==== | ||
A record type has an associated class: <tt> | A record type has an associated class: <tt>RecordDbd</tt>. | ||
The fields of <tt> | The fields of <tt>RecordDbd</tt> are the same as fields in <tt>StructDbdDef</tt> except that they refer to a record instead of a structure. | ||
; <tt>name</tt> | ; <tt>name</tt> | ||
: The name of the record. | : The name of the record. | ||
; <tt>plifetime</tt> | ; <tt>plifetime</tt> | ||
: The address of an implementation of interface <tt> | : The address of an implementation of interface <tt>RecordLifetime</tt>. The implementation is automatically generated from the dbd <tt>record</tt> statement. See below for a description of the <tt>RecordLifetime</tt> methods. | ||
; <tt>nfields</tt> | ; <tt>nfields</tt> | ||
: The number of fields, e.g. fields in the record. | : The number of fields, e.g. fields in the record. | ||
Line 483: | Line 413: | ||
: Address of an array of pointers to <tt>UserDbdField</tt>. | : Address of an array of pointers to <tt>UserDbdField</tt>. | ||
==== Record Instance ==== | ==== Record Instance ==== | ||
A record instance has two associated classes:<tt>UserDbdField</tt> and <tt> | A record instance has two associated classes:<tt>UserDbdField</tt> and <tt>RecordInstance</tt>. | ||
<tt>UserDbdField</tt> contains information for a user defined field: | <tt>UserDbdField</tt> contains information for a user defined field: | ||
Line 499: | Line 428: | ||
: The address of an implementation of interface userFieldHandler; | : The address of an implementation of interface userFieldHandler; | ||
The fields of <tt> | The fields of <tt>RecordInstance</tt> are: | ||
; <tt>name</tt> | ; <tt>name</tt> | ||
: The name of the record instance | : The name of the record instance | ||
; <tt> | ; <tt>pRecordDbd</tt> | ||
: The address of the description of the record type | : The address of the description of the record type | ||
; <tt>precord</tt> | ; <tt>precord</tt> | ||
Line 516: | Line 445: | ||
dbdInterfaces describes standard interfaces implemented by code that | dbdInterfaces describes standard interfaces implemented by code that | ||
supports runtime database access | supports runtime database access. | ||
</center> | </center> | ||
Line 523: | Line 452: | ||
<tt>dbdInterfaces.h</tt> contains the following: | <tt>dbdInterfaces.h</tt> contains the following: | ||
// | // For struct definitions that become EpicsStruct fields | ||
// | // An EpicsStructLifetime interface is automatically generated. | ||
class | |||
// For struct definitions that become DbfStruct fields | |||
// An StructLifetime interface is automatically generated. | |||
class StructLifetime { | |||
public: | |||
virtual void allocate(DbfStruct *pDbfStruct) = 0; | |||
virtual bool initialize(DbfStruct *pDbfStruct) = 0; | |||
virtual bool finalize(DbfStruct *pDbfStruct) = 0; | |||
virtual void destroy(DbfStruct *pDbfStruct) = 0; | |||
virtual void *expose(DbfStruct *pDbfStruct, epicsInt16 index) = 0; | |||
}; | |||
// For record definitions an RecordLifetime is automatically generated. | |||
class RecordLifetime { | |||
public: | public: | ||
virtual | virtual void allocate(void *precord) = 0; | ||
virtual bool initialize( | virtual bool initialize(void *precord) = 0; | ||
virtual bool finalize(void *precord) = 0; | |||
virtual bool finalize( | virtual void destroy(void *precord) = 0; | ||
virtual void *expose(void *precord, epicsInt16 index) = 0; | |||
virtual void destroy( | |||
virtual void * | |||
}; | }; | ||
Line 541: | Line 479: | ||
class LinkDbdSupport { | class LinkDbdSupport { | ||
public: | public: | ||
virtual void report( | virtual void report(EpicsString *errorMessage, | ||
iocRecord *precord, | iocRecord *precord, DbfLink *pdbfLink) = 0; | ||
virtual bool initialize( | virtual bool initialize(EpicsString *errorMessage, | ||
iocRecord *precord, | iocRecord *precord, DbfLink *pdbfLink) = 0; | ||
virtual bool finalize( | virtual bool finalize(EpicsString *errorMessage, | ||
iocRecord *precord, | iocRecord *precord, DbfLink *pdbfLink) = 0; | ||
virtual bool connect( | virtual bool connect(EpicsString *errorMessage, | ||
iocRecord *precord, | iocRecord *precord, DbfLink *pdbfLink) = 0; | ||
virtual bool disconnect( | virtual bool disconnect(epicsfString *errorMessage, | ||
iocRecord *precord, | iocRecord *precord, DbffLink *pdbfLink) = 0; | ||
virtual bool get( | virtual bool get(EpicsString *errorMessage, | ||
iocRecord *precord, | iocRecord *precord, DbffLink *pdbfLink, | ||
dbfType type, | dbfType type, void *pfield) = 0; | ||
virtual bool put( | virtual bool put(EpicsString *errorMessage, | ||
iocRecord *precord, | iocRecord *precord, DbfLink *pdbfLink, | ||
dbfType type, | dbfType type, void *pfield) = 0; | ||
}; | }; | ||
Line 562: | Line 500: | ||
class RecordDbdSupport { | class RecordDbdSupport { | ||
public: | public: | ||
virtual iocRecord * | virtual iocRecord *allocate(EpicsString *errorMessage) = 0; | ||
virtual bool destroy( | virtual bool destroy(EpicsString *errorMessage, iocRecord *precord) = 0; | ||
virtual bool init( | virtual bool init(EpicsString *errorMessage, | ||
iocRecord *precord, bool firstPass) = 0; | iocRecord *precord, bool firstPass) = 0; | ||
virtual void special(iocRecord *precord, iocRecord *precord, | virtual void special(iocRecord *precord, iocRecord *precord, | ||
bool after, | bool after, | ||
epicsInt16 nlevels, // number of elements in fieldIndex | |||
epicsInt16 fieldIndex[] // array of field indices | |||
) = 0; | ) = 0; | ||
}; | }; | ||
Line 575: | Line 513: | ||
class UserFieldHandler { | class UserFieldHandler { | ||
public: | public: | ||
virtual bool initialize( | virtual bool initialize(EpicsString *errorMessage, | ||
iocRecord *precord,UserDbdField *puserField) = 0; | iocRecord *precord,UserDbdField *puserField) = 0; | ||
virtual bool finalize( | virtual bool finalize(EpicsString *errorMessage, | ||
iocRecord *precord,UserDbdField *puserField) = 0; | iocRecord *precord,UserDbdField *puserField) = 0; | ||
virtual bool process( | virtual bool process(EpicsString *errorMessage, | ||
iocRecord *precord,UserDbdField *puserField) = 0; | iocRecord *precord,UserDbdField *puserField) = 0; | ||
}; | }; | ||
=== Discussion of dbdInterfaces === | === Discussion of dbdInterfaces === | ||
==== <tt> | ==== <tt>StructLifetime</tt> ==== | ||
Every dbd <tt>struct</tt> and <tt>record</tt> has an associated <tt> | Every dbd <tt>struct</tt> and <tt>record</tt> has an associated <tt>StructLifetime</tt> interface implementation. A tool is provided that automatically generates the implementation form the dbd definition. | ||
<tt> | <tt>StructLifetime</tt> has the following fields: | ||
; <tt> | ; <tt>allocate</tt> | ||
: Creates storage for the struct or record. | : Creates storage for the struct or record. | ||
; <tt>initialize</tt> | ; <tt>initialize</tt> | ||
Line 595: | Line 533: | ||
; <tt>destroy</tt> | ; <tt>destroy</tt> | ||
: frees storage | : frees storage | ||
; <tt> | ; <tt>expose</tt> | ||
: Given an index it returns the address of the storage. Note the the generated header files assign an index to each field. | : Given an index it returns the address of the storage. Note the the generated header files assign an index to each field. | ||
Line 608: | Line 546: | ||
== Class Factories == | |||
class DbfStructFactory { | |||
class | |||
public: | public: | ||
static DbfStructLifetime *find(const char *structName); | |||
static void register(const char *structName, | |||
DbfStructDef, *pdef); | |||
}; | }; | ||
Revision as of 19:38, 24 May 2005
May 24 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:
- Dbf
- any class starting with Dbf describes a non-primitive struct or record field. For example EpicsString describes a field(name,string).
- *Dbd*
- A class name that has Dbd imbeded in it describes something directly related to a dbd statement. For example LinkDbdSupport describes a dbd link definition.
dbdTypes.h
enum dbfType { dbfUnknownT, dbfEpicsT, // an epicsType except epicsUnknownT dbfArrayT, dbfStructT, dbfMenuT, dbfEnumT, dbfLinkT, dbfDeviceT };
class ArrayDbdDef; //describes a dbd array definition class StructDbdDef; //describes a dbd struct definition class MenuDbdDef; //describes a dbd menu definition class LinkDbd; //describes dbd link statement class DeviceDbd; //describes dbd device statement
// If array type is a known epicsType then EpicsArray class DbfArray : public EpicsArray { public: dbfType dbftype; };
// If every field is a known epicsType then EpicsStruct class DbfStruct { public: StructDbdDef *pStructDbdDef; void *pstorage; };
class DbfMenu{ public: epicsInt16 index; MenuDbdDef *pmenuDef; /* address of global menu */ };
class DbfEnum{ public: epicsInt16 index; DbfArray *pchoiceArray; // addr of field that is DbfArray on choices }; enum LinkDir { LinkDirNone, LinkDirForward, LinkDirIn, LinkDirOut, LinkDirInOut };
class DbfLink{ public: LinkDir dir; LinkDbd *plinkDef; EpicsStruct dataStruct; };
class DbfDevice{ public: LinkDir dir; DeviceDbd *pdeviceDef; EpicsStruct dataStruct; };
Discussion of dbfTypes
The classes defined in dbfTypes together with the definitions from epicsTypes is a complete list of the definitions that appear in header files generated from struct and record dbd definitions.
Epics Types
The types bool,...,string all map to an epicsType.
The type array maps to EpicsArray if the array type maps to an epicsType.
The type struct maps to EpicsStruct only if all fields in the struct map to an epicsType other than epicsUnknownT.
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(ffloat64,float64) ... field(fstring,string) field(darray,array(double[]) field(displayLimits,struct(displayLimits)) }
Then the generated header file will be
class xxxRecord : public iocRecord { public: epicsBoolean fbool; epicsOctet foctet; ... epicsFloat64 ffloat64; ... EpicsString fstring; EpicsArray darray; EpicsStruct displayLimits; };
DbfArray
This is for array fields with a type that is not a standard epicsType, i.e. the epicsType is epicsUnknownT.
If a record definition contains:
struct(calcInpLink) { field(link,link(in)) field(value,float64) } record(calc) extends iocRecord { ... field(inp,array(struct(calcInpLink)[])) ... }
Then the generated code contains:
DbfArray inp;
DbfStruct
This is for a struct field that itself has fields that are not a standard epicsType, i.e. the epicsType is epicsUnknownT.
If a record definition contains:
struct(calcInpLink) { field(link,link(in)) // NOT a standard epicsType field(value,float64) } record(calc) extends iocRecord { ... field(inp,struct(calcInpLink)) ... }
Then the generated code contains:
DbfArray inp;
DbfMenu
DbfMenu> is described as:
class DbfMenu{ public: epicsInt16 index; MenuDbdDef *pmenuDef; };
If a record definition contains
field(fmenu,menu(name))
Then the generated header file contains
DbfMenu fmenu;
DbfMenu provides the current menu index and also the menu definition.
DbfEnum
DbfEnum> is described as:
class DbfEnum{ public: epicsInt16 index; DbfArray *pchoiceArray; // addr of field that is DbfArray on choices };
If a record definition contains
field(fenum,enum)
Then the generated header file contains
DbfEnum fenum;
pchoiceArray is the address of a field in the same record that is a DbfArray of choices.
DbfLink
DbfLink is described as
class DbfLink{ public: LinkDir dir; LinkDbd *plinkDef; EpicsStruct dataStruct; };
If a record definition contains
field(flink,link(in))
Then the generated header file contains
DbfLink flink;
The fields of DbfLink are initialized by locating a dbd link definition that matches the dir specified in the dbd field definition.
The fields of DbfLink are initialized as follows:
- dir
- This is taken from either the field definition or from the LinkDbd 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 LinkDbd.
- dataStruct
- The describes the data structure specified in the dbd link definition. It contains data used by the link support.
Note that link support always implements interface LinkDbdSupport
DbfDevice
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 LinkDbdSupport, the device support implements an interface that both record support and device support understand.
dbdStatements
The classes in dbdStatements.h allow introspection of ioc records. They describe everything defined in DBD definitions.
dbdStatements.h
// Interface is base class for an interface class Interface {}; class InterfaceLocator { public: EpicsString name; Interface *pinterface; };
class StructFieldAttribute { EpicsString default; epicsBoolean readonly; epicsBoolean design; epicsBoolean special; epicsBoolean dynamic; epicsInt16 asl; };
class StructDbdField { public: EpicsString name; epicsType basic; dbfType type; StructFieldAttribute *pattribute; };
class StructDbdDef{ public: EpicsString name; Interface *plifetime; // references a StructLifetime epicsInt16 nfields; StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField };
class MenuDbdDef{ public: EpicsString name; epicsInt16 nchoices; EpicsString *pchoice[]; };
class LinkDbd{ //describes dbd link statement public: LinkDir dir; EpicsString choiceName; EpicsString dataStructName; Interface *pinterface; };
class DeviceDbd { //describes dbd device statement public: LinkDir dir; EpicsString interfaceName; EpicsString choiceName; EpicsString dataStructName; Interface *pinterface; };
// The following describes a record type class RecordDbd { // describes a record type EpicsString name; Interface *plifetime; // references a RecordLifetime epicsInt16 nfields; StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField };
// The following describes a record instance class UserDbdField { public: EpicsString name; epicsType type; void *pfield; InterfacePtr *pinterface; // userFieldHandler };
class RecordInstance { // describes a record instance EpicsString name; RecordDbd *pRecordDbd; void *precord; // address of record instance UserDbdField *puserField[]; };
Discussion of dbdStatements
StructXXX
The Struct classes describe the fields in a dbd struct or record definition. The classes are : StructDbdDef, StructDbdField,and StructFieldAttribute
The fields of StructDbdDef are:
- name
- The name of the struct.
- plifetime
- The address of an implementation of interface StructLifetime. The implementation is automatically generated from the dbd struct statement. See below for a description of the StructLifetime methods.
- nfields
- The number of fields, e.g. fields in the structure.
- pfields
- pointer to an array of pointers to StructDbdField.
The fields of StructDbdField are:
- name
- The name of the field
- basic
- The epicsType of the field. Unless this is epicsUnknownT generic code is usually provided for accessing the field.
- type
- The dbfType for the field. Note that unless basic is epicsUnknownT this has the value dbfEpicsT.
- pattribute
- The address of a StructFieldAttribute for the field
StructFieldAttribute has the attribute values for the field.
Menu
A dbd menu is described by class MenuDbdDef
The fields of MenuDbdDef are:
- 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 and Device
Each dbd link definition has an associated class LinkDbd with fields:
- dir
- The link direction
- choiceName
- The name that matches a LinkDbd for a DbfLink instance.
- dataStructName
- The class name of a DbfStruct for the Interface implementation
- pinterface
- The address of the Interface implementation. The interface class is LinkDbdSupport
Each dbd device definition has an associated class DeviceDbd with fields:
- dir
- The link direction
- interfaceName
- The name of the interface class implemented by the device support
- choiceName
- The name that matches a DeviceDbd for a DbfDevice instance.
- dataStructName
- The class name of a DbfStruct for the Interface implementation
- pinterface
- The address of the Interface implementation.
Record
A record type has an associated class: RecordDbd. The fields of RecordDbd are the same as fields in StructDbdDef except that they refer to a record instead of a structure.
- name
- The name of the record.
- plifetime
- The address of an implementation of interface RecordLifetime. The implementation is automatically generated from the dbd record statement. See below for a description of the RecordLifetime methods.
- nfields
- The number of fields, e.g. fields in the record.
- pfields
- pointer to an array of pointers to StructDbdField. Each StructDbdField contains the name and type of the fields.
- puserField
- Address of an array of pointers to UserDbdField.
Record Instance
A record instance has two associated classes:UserDbdField and RecordInstance.
UserDbdField contains information for a user defined field:
- name
- The name of the user defined field
- type
- The dbfType for the field.
- pfield
- Address of storage for field.
- pinterface
- The address of an implementation of interface userFieldHandler;
The fields of RecordInstance are:
- name
- The name of the record instance
- pRecordDbd
- The address of the description of the record type
- precord
- The address of the record itself.
- puserField
- The address of a array of pointers to UserDbdField
dbdInterfaces
dbdInterfaces describes standard interfaces implemented by code that supports runtime database access.
dbdInterfaces.h
dbdInterfaces.h contains the following:
// For struct definitions that become EpicsStruct fields // An EpicsStructLifetime interface is automatically generated.
// For struct definitions that become DbfStruct fields // An StructLifetime interface is automatically generated. class StructLifetime { public: virtual void allocate(DbfStruct *pDbfStruct) = 0; virtual bool initialize(DbfStruct *pDbfStruct) = 0; virtual bool finalize(DbfStruct *pDbfStruct) = 0; virtual void destroy(DbfStruct *pDbfStruct) = 0; virtual void *expose(DbfStruct *pDbfStruct, epicsInt16 index) = 0; };
// For record definitions an RecordLifetime is automatically generated. class RecordLifetime { public: virtual void allocate(void *precord) = 0; virtual bool initialize(void *precord) = 0; virtual bool finalize(void *precord) = 0; virtual void destroy(void *precord) = 0; virtual void *expose(void *precord, epicsInt16 index) = 0; };
// every link support module implements the following interface class LinkDbdSupport { public: virtual void report(EpicsString *errorMessage, 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(epicsfString *errorMessage, iocRecord *precord, DbffLink *pdbfLink) = 0; virtual bool get(EpicsString *errorMessage, iocRecord *precord, DbffLink *pdbfLink, dbfType type, void *pfield) = 0; virtual bool put(EpicsString *errorMessage, iocRecord *precord, DbfLink *pdbfLink, dbfType type, void *pfield) = 0; };
/* record support implements the following*/ class RecordDbdSupport { public: virtual iocRecord *allocate(EpicsString *errorMessage) = 0; virtual bool destroy(EpicsString *errorMessage, iocRecord *precord) = 0; virtual bool init(EpicsString *errorMessage, iocRecord *precord, bool firstPass) = 0; virtual void special(iocRecord *precord, iocRecord *precord, bool after, epicsInt16 nlevels, // number of elements in fieldIndex epicsInt16 fieldIndex[] // array of field indices ) = 0; };
class UserFieldHandler { public: virtual bool initialize(EpicsString *errorMessage, iocRecord *precord,UserDbdField *puserField) = 0; virtual bool finalize(EpicsString *errorMessage, iocRecord *precord,UserDbdField *puserField) = 0; virtual bool process(EpicsString *errorMessage, iocRecord *precord,UserDbdField *puserField) = 0; };
Discussion of dbdInterfaces
StructLifetime
Every dbd struct and record has an associated StructLifetime interface implementation. A tool is provided that automatically generates the implementation form the dbd definition. StructLifetime has the following fields:
- allocate
- Creates storage for the struct or record.
- initialize
- initializes the struct or record
- finalize
- cleans up but does not free storage
- destroy
- frees storage
- expose
- Given an index it returns the address of the storage. Note the the generated header files assign an index to each field.
LinkDbdSupport
This describes the interface implemented by link support.
RecordDbdSupport
This is the interface implemented by record support.
UserFieldHandler
This is the interface implemented by code for user extensible fields.
Class Factories
class DbfStructFactory { public: static DbfStructLifetime *find(const char *structName); static void register(const char *structName, DbfStructDef, *pdef); };