|
|
(17 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| == EPICS: dbdClasses - IOC records data == May 24 2005
| | This page is obsolete. It is replaced by dbdInterfaces. |
| <center>
| |
| | |
| == Overview ==
| |
| | |
| </center>
| |
| | |
| 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:
| |
| ** <tt>record</tt> - Should only be included by record support.
| |
| ** <tt>struct</tt> - Included by code that understands the struct.
| |
| ** <tt>menu</tt> - Included by code that understands the menu.
| |
| * does not include the header files.
| |
| | |
| The following headers files are described:
| |
| * <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>dbdInterfaces.h</tt> - Type definitions for interfaces related to DBD definitions.
| |
| | |
| ----
| |
| <center>
| |
| | |
| == dbfTypes ==
| |
| </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:
| |
| ; Dbf
| |
| : any class starting with Dbf describes a non epicsType struct or record field as it appears in a generated header file. For example DbfString describes a field generated from <tt>field(name,string)</tt>.
| |
| ; Dbd
| |
| : A class name starting with Dbd describes something directly related to a dbd statement. For example DbdLinkSupport describes a dbd link definition.
| |
| | |
| === <tt>dbdTypes.h</tt> ===
| |
| enum dbfType {
| |
| dbfUnknownT,
| |
| dbfEpicsT, // an epicsType except epicsUnknownT
| |
| dbfArrayT,
| |
| dbfStructT,
| |
| dbfMenuT,
| |
| dbfEnumT,
| |
| dbfLinkT,
| |
| dbfDeviceT
| |
| };
| |
| | |
| class DbdStruct; //describes a dbd struct definition
| |
| class DbdMenu; //describes a dbd menu definition
| |
| class DbdLink; //describes dbd link statement
| |
| class DbdDevice; //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:
| |
| DbdStruct *pDbdStruct;
| |
| void *pstorage;
| |
| };
| |
| | |
| class DbfMenu{
| |
| public:
| |
| epicsInt16 index;
| |
| DbdMenu *pmenuDef; /* address of global menu */
| |
| };
| |
| | |
| class DbfEnum{
| |
| public:
| |
| epicsInt16 index;
| |
| EpicsArray *pchoiceArray; // addr of field that is array of string
| |
| };
| |
|
| |
| enum LinkDir {
| |
| LinkDirNone,
| |
| LinkDirForward,
| |
| LinkDirIn,
| |
| LinkDirOut,
| |
| LinkDirInOut
| |
| };
| |
| | |
| class DbfLink{
| |
| public:
| |
| LinkDir dir;
| |
| DbdLink *plinkDef;
| |
| EpicsStruct dataStruct;
| |
| };
| |
| | |
| class DbfDevice{
| |
| public:
| |
| LinkDir dir;
| |
| DbdDevice *pDbdDevice;
| |
| 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 <tt>struct</tt> and <tt>record</tt> dbd definitions.
| |
| | |
| ==== Epics Types ====
| |
| | |
| DBD types bool,...,string all become an epicsType.
| |
| | |
| DBD type array becomes an EpicsArray if the array type maps to an epicsType
| |
| or to DbfArray if the type is not an epicsType.
| |
| | |
| DBD type struct maps to EpicsStruct if all fields in the struct map to
| |
| an epicsType other than epicsUnknownT or otherwise to DbfStruct.
| |
| | |
| 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 ====
| |
| <tt>DbfMenu></tt> is described as:
| |
| class DbfMenu{
| |
| public:
| |
| epicsInt16 index;
| |
| DbdMenu *pmenuDef;
| |
| };
| |
| | |
| If a record definition contains
| |
| field(fmenu,menu(name))
| |
| Then the generated header file contains
| |
| DbfMenu fmenu;
| |
| <tt>DbfMenu</tt> provides the current menu index and also the menu definition.
| |
| | |
| ==== DbfEnum ====
| |
| <tt>DbfEnum></tt> 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;
| |
| <tt>pchoiceArray</tt> is the address of a field in the same record that is a
| |
| DbfArray of choices.
| |
| ==== DbfLink ====
| |
| <tt>DbfLink</tt> is described as
| |
| class DbfLink{
| |
| public:
| |
| LinkDir dir;
| |
| DbdLink *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 <tt>link</tt> definition that matches the <tt>dir</tt> specified in the dbd <tt>field</tt> definition.
| |
| | |
| The fields of <tt>DbfLink</tt> are initialized as follows:
| |
| ; <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.
| |
| ; <tt>plinkDef</tt>
| |
| : This is the address of the <tt>DbdLink</tt>.
| |
| ; <tt>dataStruct</tt>
| |
| : The describes the data structure specified in the dbd <tt>link</tt> definition. It contains data used by the link support.
| |
| | |
| Note that link support always implements interface <tt>DbdLinkSupport</tt>
| |
| ==== DbfDevice ====
| |
| | |
| A <tt>DbfDevice</tt> is similar to a <tt>DbfLink</tt> except that the interface implemented by the device support is also specified, i.e. instead of implementing interface <tt>DbdLinkSupport</tt>, the device support implements an interface that both record support and device support understand.
| |
| | |
| | |
| ----
| |
| <center>
| |
| | |
| == dbdStatements ==
| |
| | |
| </center>
| |
| The classes in <tt>dbdStatements.h</tt> allow introspection of ioc records. They describe everything defined in DBD definitions.
| |
| | |
| === <tt>dbdStatements.h</tt> ===
| |
| | |
| | |
| // 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 DbdStruct{
| |
| public:
| |
| EpicsString name;
| |
| Interface *plifetime; // references a StructLifetime
| |
| epicsInt16 nfields;
| |
| StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField
| |
| };
| |
| | |
| class DbdMenu{
| |
| public:
| |
| EpicsString name;
| |
| epicsInt16 nchoices;
| |
| EpicsString *pchoice[];
| |
| };
| |
| | |
| class DbdLink{ //describes dbd link statement
| |
| public:
| |
| LinkDir dir;
| |
| EpicsString choiceName;
| |
| EpicsString dataStructName;
| |
| Interface *pinterface;
| |
| };
| |
| | |
| class DbdDevice { //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 <tt>struct</tt> or <tt>record</tt> definition. The classes are : <tt>DbdStruct</tt>, <tt>StructDbdField</tt>,and <tt>StructFieldAttribute</tt>
| |
| | |
| The fields of <tt>DbdStruct</tt> are:
| |
| ; <tt>name</tt>
| |
| : The name of the struct.
| |
| ; <tt>plifetime</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>
| |
| : The number of fields, e.g. fields in the structure.
| |
| ; <tt>pfields</tt>
| |
| : pointer to an array of pointers to <tt>StructDbdField</tt>.
| |
| | |
| The fields of <tt>StructDbdField</tt> are:
| |
| ; <tt>name</tt>
| |
| : 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>
| |
| : The dbfType for the field. Note that unless basic is epicsUnknownT this has the value dbfEpicsT.
| |
| ; <tt>pattribute</tt>
| |
| : The address of a StructFieldAttribute for the field
| |
| | |
| <tt>StructFieldAttribute</tt> has the attribute values for the field.
| |
| | |
| ==== Menu ====
| |
| | |
| A dbd <tt>menu</tt> is described by class DbdMenu
| |
| | |
| The fields of DbdMenu are:
| |
| ; <tt>name</tt>
| |
| : The menu name.
| |
| ; <tt>nchoices</tt>
| |
| : The number of menu choices.
| |
| ; <tt>pchoice</tt>
| |
| : The address of an array of pointers to EpicsString. Each EpicsString is a choice.
| |
| | |
| ==== Link and Device ====
| |
| | |
| Each dbd <tt>link</tt> definition has an associated class <tt>DbdLink</tt> with fields:
| |
| ; <tt>dir</tt>
| |
| : The link direction
| |
| ; <tt>choiceName</tt>
| |
| : The name that matches a DbdLink for a DbfLink instance.
| |
| ; <tt>dataStructName</tt>
| |
| : The class name of a DbfStruct for the Interface implementation
| |
| ; <tt>pinterface</tt>
| |
| : The address of the Interface implementation. The interface class is DbdLinkSupport
| |
| | |
| Each dbd <tt>device</tt> definition has an associated class <tt>DbdDevice</tt> with fields:
| |
| ; <tt>dir</tt>
| |
| : The link direction
| |
| ; <tt>interfaceName</tt>
| |
| : The name of the interface class implemented by the device support
| |
| ; <tt>choiceName</tt>
| |
| : The name that matches a DbdDevice for a DbfDevice instance.
| |
| ; <tt>dataStructName</tt>
| |
| : The class name of a DbfStruct for the Interface implementation
| |
| ; <tt>pinterface</tt>
| |
| : The address of the Interface implementation.
| |
| | |
| ==== Record ====
| |
| A record type has an associated class: <tt>RecordDbd</tt>.
| |
| The fields of <tt>RecordDbd</tt> are the same as fields in <tt>DbdStruct</tt> except that they refer to a record instead of a structure.
| |
| ; <tt>name</tt>
| |
| : The name of the record.
| |
| ; <tt>plifetime</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>
| |
| : The number of fields, e.g. fields in the record.
| |
| ; <tt>pfields</tt>
| |
| : pointer to an array of pointers to <tt>StructDbdField</tt>. Each StructDbdField contains the name and type of the fields.
| |
| ; <tt>puserField</tt>
| |
| : Address of an array of pointers to <tt>UserDbdField</tt>.
| |
| | |
| | |
| ==== Record Instance ====
| |
| | |
| 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>name</tt>
| |
| : The name of the user defined field
| |
| ; <tt>type</tt>
| |
| : The dbfType for the field.
| |
| ; <tt>pfield</tt>
| |
| : Address of storage for field.
| |
| ; <tt>pinterface</tt>
| |
| : The address of an implementation of interface userFieldHandler;
| |
| | |
| The fields of <tt>RecordInstance</tt> are:
| |
| | |
| ; <tt>name</tt>
| |
| : The name of the record instance
| |
| ; <tt>pRecordDbd</tt>
| |
| : The address of the description of the record type
| |
| ; <tt>precord</tt>
| |
| : The address of the record itself.
| |
| ; <tt>puserField</tt>
| |
| : The address of a array of pointers to UserDbdField
| |
| | |
| ----
| |
| <center>
| |
| | |
| == dbdInterfaces ==
| |
| | |
| dbdInterfaces describes standard interfaces implemented by code that | |
| supports runtime database access.
| |
| | |
| </center>
| |
| | |
| === <tt>dbdInterfaces.h</tt> ===
| |
| <tt>dbdInterfaces.h</tt> 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 DbdLinkSupport {
| |
| 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 ===
| |
| ==== <tt>StructLifetime</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>StructLifetime</tt> has the following fields:
| |
| ; <tt>allocate</tt>
| |
| : Creates storage for the struct or record.
| |
| ; <tt>initialize</tt>
| |
| : initializes the struct or record
| |
| ; <tt>finalize</tt>
| |
| : cleans up but does not free storage
| |
| ; <tt>destroy</tt>
| |
| : frees storage
| |
| ; <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.
| |
| | |
| ==== <tt>DbdLinkSupport</tt> ====
| |
| This describes the interface implemented by link support.
| |
| ==== <tt>RecordDbdSupport</tt> ====
| |
| This is the interface implemented by record support.
| |
| ==== <tt>UserFieldHandler</tt> ====
| |
| 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);
| |
| };
| |