|
|
(25 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| == EPICS: C++ class definitions for Database Definition ==
| | This page is obsolete. It is replaced by dbdInterfaces. |
| | |
| May 12 2005
| |
| | |
| <b>UNDER CONSTRUCTION - DO NOT COMMENT</b>
| |
| <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>
| |
| ** <tt>struct</tt>
| |
| ** <tt>menu</tt>
| |
| * does not include the header files.
| |
| | |
| The following headers files are described:
| |
| * <tt>dbftypes.h</tt> - Type definitions for <field> definitions in <struct> or <record> DBD definitions.
| |
| * <tt>dbdStatements.h</tt> - Type definitions for DBD statements.
| |
| * <tt>dbdInterfaces.h</tt> - Type definitions for interfaces related to DBD definitions.
| |
| | |
| | |
| ----
| |
| <center>
| |
| | |
| == dbfFields ==
| |
| | |
| </center>
| |
| === <tt>dbfFields.h</tt> ===
| |
| File dbdTypes.h describes the datatypes used by V4 databases:
| |
| The following naming conventions are used:
| |
| ; dbf
| |
| : and name starting with dbf describes a struct or record field. For example dbfString describes a field(name,string).
| |
| ; *Dbf*
| |
| : 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.
| |
| | |
| <tt>dbdTypes.h</tt> contains the following:
| |
| | |
| namespace Dbd {
| |
| /* TBD dbdNdimArrayT*/
| |
| enum dbfType {
| |
| dbfUnknownT,dbfBooleanT,dbfOctetT,
| |
| dbfInt16T,dbfUInt16T,dbfInt32T,dbfUInt32T,dbfInt64T,dbfUInt64T,
| |
| dbfFloat32T,dbfFloat64T,
| |
| dbfStringT,
| |
| dbfStructT,
| |
| dbfMenuT,dbfEnumT,
| |
| dbfLinkT,dbfDeviceT,
| |
| dbfArrayT
| |
| };
| |
| | |
| /* some of the following may require OSD definitions*/
| |
| typedef bool dbfBoolean;
| |
| typedef char dbfOctet;
| |
| typedef short dbfInt16;
| |
| typedef unsigned short dbfUInt16;
| |
| typedef int dbfInt32;
| |
| typedef unsigned int dbfUInt32;
| |
| typedef long long dbfInt64;
| |
| typedef unsigned long long dbfUInt64;
| |
| typedef float dbfFloat32;
| |
| typedef double dbfFloat64;
| |
| | |
| /*dbfString holds UTF-8 characters*/
| |
| class dbfString {
| |
| public:
| |
| dbfInt32 capacity; /*capacity in bytes*/
| |
| dbfOctet *pstorage;
| |
| };
| |
| | |
| // FieldDbdPtr is the address of a dbfType
| |
| typedef void *FieldDbdPtr;
| |
| // StructDbdPtr references a class generated from a struct dbd
| |
| typedef void * StructDbdPtr;
| |
| | |
| // InterfacePtr references a class that contains only methods
| |
| typedef void *InterfacePtr;
| |
| class Interface {
| |
| public:
| |
| dbfString name;
| |
| InterfacePtr interface;
| |
| };
| |
| | |
| // The following Interfaces are described below
| |
| class StructDbdLifetime;
| |
| class LinkDbdSupport;
| |
| | |
| class StructDbdMember {
| |
| public:
| |
| dbfString name;
| |
| dbfType type;
| |
| };
| |
| | |
| class StructDbd{
| |
| public:
| |
| dbfString name;
| |
| dbfInt16 nmembers;
| |
| Interface *plifetime; // references a StructDbdLifetime
| |
| StructDbdMember *pmember[]; // ptr to array of ptr to StructDbdMember
| |
| };
| |
| | |
| class dbfStruct{
| |
| public:
| |
| StructDbd *pstructDef;
| |
| StructDbdPtr ptr;
| |
| };
| |
| | |
| class MenuDbfDef{
| |
| public:
| |
| dbfString name;
| |
| dbfInt16 nchoices;
| |
| dbfString *pchoice[];
| |
| };
| |
| | |
| class dbfMenu{
| |
| public:
| |
| dbfInt16 index;
| |
| MenuDbfDef *pmenuDef;
| |
| };
| |
| | |
| class dbfEnum{
| |
| public:
| |
| dbfInt16 index;
| |
| dbfInt16 nchoices;
| |
| dbfString *pchoice[];
| |
| };
| |
|
| |
| enum LinkDir {
| |
| LinkDirNone,
| |
| LinkDirForward,
| |
| LinkDirIn,
| |
| LinkDirOut,
| |
| LinkDirInOut
| |
| };
| |
| class LinkDbd{ //describes dbd link statement
| |
| public:
| |
| LinkDir dir;
| |
| dbfString choiceName;
| |
| dbfString dataStructName;
| |
| InterfacePtr *pinterface;
| |
| };
| |
| | |
| class dbfLink{
| |
| public:
| |
| LinkDir dir;
| |
| dbfString choiceName;
| |
| LinkDbd *plinkDef; //LinkDbd will reference a LinkDbdSupport
| |
| dbfStruct dataStruct;
| |
| };
| |
| | |
| class DeviceDbd { //describes dbd device statement
| |
| public:
| |
| LinkDir dir;
| |
| dbfString interfaceName;
| |
| dbfString choiceName;
| |
| dbfString dataStructName;
| |
| InterfacePtr *pinterface;
| |
| };
| |
| | |
| class dbfDevice{
| |
| public:
| |
| LinkDir dir;
| |
| dbfString choiceName;
| |
| DeviceDbd *pdeviceDef;
| |
| dbfStruct dataStruct;
| |
| };
| |
| | |
| template< class ARR_T > class dbfArray {
| |
| public:
| |
| dbfInt32 capacity; /*capacity in number of elements*/
| |
| dbfInt32 size; /*current number of elements*/
| |
| dbfType type;
| |
| ARR_T *pstorage;
| |
| };
| |
| | |
| /* The following array types are supported by dbdCore
| |
| * dbfArray<void>;
| |
| * dbfArray<dbfOctet>;
| |
| * dbfArray<dbfInt16>;
| |
| * dbfArray<dbfUInt16>;
| |
| * dbfArray<dbfInt32>;
| |
| * dbfArray<dbfUInt32>;
| |
| * dbfArray<dbfInt64>;
| |
| * dbfArray<dbfUInt64>;
| |
| * dbfArray<dbfFloat32>;
| |
| * dbfArray<dbfFloat64>;
| |
| * dbfArray<dbfString>;
| |
| * dbfArray<dbfLinkField>;
| |
| **/
| |
| | |
| === Discussion of dbfTypes ===
| |
| | |
| ==== Primitive Types ====
| |
| The types dbfBoolean, dbfOctet, dbfInt16, dbfUInt16, dbfInt32, dbfUInt32, dbfInt64, dbfUInt64, dbfFloat32, dbfFloat64 all map to a C primitive type. Currently the C type is defined in <tt>iocTypes.h</tt>. It may be necessary to provide operating system dependent definitions for some of the types. For example on some architectures a dbfInt64 may have to be defined as a C <tt>long</tt> rather than a <tt>long long</tt>.
| |
| | |
| If a record is defined as:
| |
| record(xxx) extends iocRecord {
| |
| ...
| |
| field(fbool,bool)
| |
| field(foctet,octet)
| |
| ...
| |
| field(ffloat64,float64)
| |
| ...
| |
| }
| |
| Then the generated header file will be
| |
| class xxxRecord : iocRecord {
| |
| public:
| |
| dbfBoolean fbool;
| |
| dbfOctet foctet;
| |
| ...
| |
| dbfFloat64 ffloat64;
| |
| ...
| |
| };
| |
| | |
| <tt>dbfType dbfTypeUnknownT</tt> is reserved for unknown types and will normally be cause by some configuration error.
| |
| ==== dbfString ====
| |
| <tt>dbfString</tt> is described as:
| |
| class dbfString {
| |
| public:
| |
| dbfInt32 capacity; /*capacity in bytes*/
| |
| dbfOctet *pstorage;
| |
| };
| |
| If a record definition contains
| |
| field(sfield,string)
| |
| Then the generated header file contains
| |
| dbfString sfield;
| |
| | |
| <tt>pstorage</tt>will always be the address of a UTF-8 null terminated character string. The <tt>capacity</tt> is the the number of bytes referenced by <tt>pstorage</tt> <bold>NOT</bold> the number of characters.
| |
| | |
| ==== dbfStruct ====
| |
| | |
| <dbfStruct></tt> is described as:
| |
| class dbfStruct{
| |
| public:
| |
| StructDbd *pstructDef;
| |
| StructDbdPtr ptr;
| |
| };
| |
| | |
| If a record definition contains
| |
| field(sstruct,struct(name))
| |
| Then the generated header file contains
| |
| dbfStruct sfield;
| |
| <tt>dbfStruct:ptr</tt> is the address of storage for the structure and <tt>pstructDef</tt> is the address of a description of the structure. The members of <tt>StructDbd</tt> are:
| |
| ; <tt>name</tt>
| |
| : The name of the struct.
| |
| ; <tt>nmembers</tt>
| |
| : The number of members, e.g. fields in the structure.
| |
| ; <tt>plifetime</tt>
| |
| : The address of an implementation of interface <tt>StructDbdLifetime</tt>. The implementation is automatically generated from the dbd <tt>struct</tt> statement. See below for a description of the <tt>StructDbdLifetime</tt> methods.
| |
| ; <tt>pmember</tt>
| |
| : pointer to an array of pointers to <tt>StructDbdMember</tt>. Each StructDbdMember contains the name and type of the member.
| |
| | |
| Note that given a dbfStruct it is possible to locate both the address and description of the associated structure.
| |
| | |
| ==== dbfMenu ====
| |
| <dbfMenu></tt> is described as:
| |
| class dbfMenu{
| |
| public:
| |
| dbfInt16 index;
| |
| MenuDbfDef *pmenuDef;
| |
| };
| |
| | |
| If a record definition contains
| |
| field(fmenu,menu(name))
| |
| Then the generated header file contains
| |
| dbfMenu fmenu;
| |
| The definition of dbfMenu provides the current menu index and also the menu definition.
| |
| | |
| ==== dbfEnum ====
| |
| <dbfEnum></tt> is described as:
| |
| class dbfEnum{
| |
| public:
| |
| dbfInt16 index;
| |
| dbfInt16 nchoices;
| |
| dbfString *pchoice[];
| |
| };
| |
| | |
| If a record definition contains
| |
| field(fenum,enum)
| |
| Then the generated header file contains
| |
| dbfEnum fenum;
| |
| The definition of dbfEnum provides the current enum index as well as a description on all the choices associated with the enum.
| |
| | |
| ==== dbfLink ====
| |
| <tt>dbfLink</tt> is described as
| |
| class dbfLink{
| |
| public:
| |
| LinkDir dir;
| |
| dbfString choiceName;
| |
| LinkDbd *plinkDef; //LinkDbd will reference a LinkDbdSupport
| |
| dbfStruct dataStruct;
| |
| };
| |
| If a record definition contains
| |
| field(flink,link(in))
| |
| Then the generated header file contains
| |
| dbfLink flink;
| |
| The members 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.
| |
| | |
| Each dbd <tt>link</tt> definition has an asociated C description:
| |
| class LinkDbd{ //describes dbd link statement
| |
| public:
| |
| LinkDir dir;
| |
| dbfString choiceName;
| |
| dbfString dataStructName;
| |
| InterfacePtr *pinterface;
| |
| };
| |
| | |
| The members 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>LinkDbd</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>choiceName</tt>
| |
| : The record instance specifies this and it is used to locate the associated dbd <tt>link</tt> definition.
| |
| ; <tt>plinkDef</tt>
| |
| : This is the address of the <tt>LinkDbd</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>LinkDbdSupport</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>LinkDbdSupport</tt>, the device support implements an interface that both record support and device support understand.
| |
| | |
| | |
| ==== dbfArray ====
| |
| | |
| Discussion needed. Note that multi-dimensional arrays must also be described.
| |
|
| |
| | |
| ----
| |
| <center>
| |
| | |
| == dbdStatements ==
| |
| | |
| </center>
| |
| | |
| === <tt>dbdStatements.h</tt> ===
| |
| | |
| <tt>dbdStatements.h</tt> contains the following:
| |
| | |
| namespace Dbd {
| |
| // The following describes record types and record instances
| |
| class UserDbdField;
| |
| class userFieldHandler {
| |
| public:
| |
| virtual bool initialize(dbfString *errorMessage,
| |
| iocRecord *precord,UserDbdField *puserField) = 0;
| |
| virtual bool finalize(dbfString *errorMessage,
| |
| iocRecord *precord,UserDbdField *puserField) = 0;
| |
| virtual bool process(dbfString *errorMessage,
| |
| iocRecord *precord,UserDbdField *puserField) = 0;
| |
| };
| |
| | |
| class UserDbdField {
| |
| public:
| |
| dbfString name;
| |
| dbfType type;
| |
| FieldDbdPtr pfield;
| |
| InterfacePtr *pinterface; // references userFieldHandler
| |
| }
| |
| | |
| class RecordDbdField {
| |
| public:
| |
| dbfString name;
| |
| dbfType type;
| |
| };
| |
| | |
| class RecordDbd { // describes a record type
| |
| dbfArray< UserDbdField > userField;
| |
| dbfArray< RecordDbdField > recField;
| |
| Interface *plifetime; // references a StructDbdLifetime
| |
| }
| |
| } // namespace Dbd
| |
| | |
| === Discussion of dbdStatements ===
| |
| NOT YET DONE
| |
| ----
| |
| <center>
| |
| | |
| == dbdInterfaces.h ==
| |
| | |
| </center>
| |
| | |
| === <tt>dbdInterfaces.h</tt> ===
| |
| <tt>dbdInterfaces.h</tt> contains the following:
| |
| | |
| namespace Dbd {
| |
| // every struct and every record support module implements the following
| |
| // The implementation is generated from the dbd definition
| |
| class StructDbdLifetime {
| |
| public:
| |
| virtual StructDbdPtr create() = 0;
| |
| virtual bool initialize(dbfString *errorMessage,
| |
| StructDbdPtr ptr) = 0;
| |
| virtual bool finalize(dbfString *errorMessage,
| |
| StructDbdPtr ptr) = 0;
| |
| virtual void destroy(StructDbdPtr ptr) = 0;
| |
| virtual void *indexToAddr(dbfString *errorMessage,
| |
| StructDbdPtr ptr, dbfInt16 index) = 0;
| |
| // ???? is anything else needed
| |
| };
| |
| | |
| // every link support module implements the following interface
| |
| class LinkDbdSupport {
| |
| public:
| |
| virtual void report(dbfString *errorMessage,
| |
| iocRecord *precord, dbfLink *pdbfLink) = 0;
| |
| virtual bool initialize(dbfString *errorMessage,
| |
| iocRecord *precord, dbfLink *pdbfLink) = 0;
| |
| virtual bool finalize(dbfString *errorMessage,
| |
| iocRecord *precord, dbfLink *pdbfLink) = 0;
| |
| virtual bool connect(dbfString *errorMessage,
| |
| iocRecord *precord, dbfLink *pdbfLink) = 0;
| |
| virtual bool disconnect(dbfString *errorMessage,
| |
| iocRecord *precord, dbfLink *pdbfLink) = 0;
| |
| virtual bool get(dbfString *errorMessage,
| |
| iocRecord *precord, dbfLink *pdbfLink,
| |
| dbfType type, FieldDbdPtr pfield) = 0;
| |
| virtual bool put(dbfString *errorMessage,
| |
| iocRecord *precord, dbfLink *pdbfLink,
| |
| dbfType type, FieldDbdPtr pfield) = 0;
| |
| };
| |
| | |
| /* record support implements the following*/
| |
| class RecordDbdSupport {
| |
| public:
| |
| virtual iocRecord *create(dbfString *errorMessage) = 0;
| |
| virtual bool destroy(dbfString *errorMessage, iocRecord *precord) = 0;
| |
| virtual bool init(dbfString *errorMessage,
| |
| iocRecord *precord, bool firstPass) = 0;
| |
| virtual void special(iocRecord *precord, iocRecord *precord,
| |
| bool after,
| |
| dbfInt16 nlevels, // number of elements in fieldIndex
| |
| dbfInt16 fieldIndex[] // array of field indices
| |
| ) = 0;
| |
| };
| |
| } // namespace Dbd
| |
| | |
| === Discussion of dbdInterfaces ===
| |
| ==== <tt>StructDbdLifetime</tt> ====
| |
| Every dbd <tt>struct</tt> and <tt>record</tt> has an associated <tt>StructDbdLifetime</tt> interface implementation. A tool is provided that automatically generates the implementation form the dbd definition.
| |
| <tt>StructDbdLifetime</tt> is described as:
| |
| class StructDbdLifetime {
| |
| public:
| |
| virtual StructDbdPtr create() = 0;
| |
| virtual bool initialize(dbfString *errorMessage,
| |
| StructDbdPtr ptr) = 0;
| |
| virtual bool finalize(dbfString *errorMessage,
| |
| StructDbdPtr ptr) = 0;
| |
| virtual void destroy(StructDbdPtr ptr) = 0;
| |
| virtual void *indexToAddr(dbfString *errorMessage,
| |
| StructDbdPtr ptr, dbfInt16 index) = 0;
| |
| // ???? is anything else needed
| |
| };
| |
| where:
| |
| ; <tt>create</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
| |
| ; indexToAddr
| |
| : Given an index it returns the address of the storage. Note the the generated header files assign an index to each field.
| |
| | |
| ==== <tt>LinkDbdSupport</tt> ====
| |
| Not yet described
| |
| | |
| ==== <tt>RecordDbdSupport</tt> ====
| |
| Not yet described
| |
| | |
| ----
| |
| <center>
| |
| | |
| == Example of Generated Header Files ==
| |
| | |
| </center>
| |
| | |
| === Database Definition Files ===
| |
| | |
| <tt>menuAlarmSevr.dbd</tt> contains:
| |
| menu(menuAlarmSevr) {
| |
| choice(menuAlarmSevrNO_ALARM,"NO_ALARM")
| |
| choice(menuAlarmSevrMINOR,"MINOR")
| |
| choice(menuAlarmSevrMAJOR,"MAJOR")
| |
| choice(menuAlarmSevrINVALID,"INVALID")
| |
| }
| |
| | |
| <tt>displayLimit.dbd</tt> contains:
| |
| struct(displayLimit) {
| |
| field(low,float64)
| |
| field(high,float64)
| |
| }
| |
| <tt>exampleRecord.dbd</tt> contains:
| |
| record(example) extends iocRecord {
| |
| field(value,float64)
| |
| field(displayLimit,struct(displayLimit))
| |
| }
| |
| <tt>alltypesRecord.dbd</tt> contains:
| |
| record(allTypes) extends iocRecord {
| |
| field(fbool,bool)
| |
| field(foctet,octet)
| |
| field(fint16,int16)
| |
| field(fuint16,uint16)
| |
| field(fint32,int32)
| |
| field(fuint32,uint32)
| |
| field(fint64,int64)
| |
| field(fuint64,uint64)
| |
| field(ffloat32,float32)
| |
| field(ffloat64,float64)
| |
| field(fstring,string)
| |
| field(fmenu,menu(menuName))
| |
| field(fenum,enum)
| |
| field(fstruct,struct(displayLimit))
| |
| field(flink,link(dir))
| |
| field(fdevice,device(dir,interfaceName))
| |
| }
| |
| === Generated Header Files ===
| |
| Tools are provided to generate header files from the following dbd definitions:
| |
| *menu
| |
| *struct
| |
| *record
| |
| <tt>menuAlarmSevr.h</tt> is generated from <tt>menuAlarmSevr.dbd</tt>
| |
| enum menuAlarmSevr {
| |
| menuAlarmSevrNO_ALARM,
| |
| menuAlarmSevrMINOR,
| |
| menuAlarmSevrMAJOR,
| |
| menuAlarmSevrINVALID
| |
| };
| |
| <tt>displayLimit.h</tt> is generated from <tt>displayLimit.dbd</tt>
| |
| class displayLimit {
| |
| public:
| |
| dbfFloat64 low;
| |
| dbfFloat64 high;
| |
| };
| |
| const dbfInt16 displayLimit_firstIndex = 1
| |
| const dbfInt16 displayLimit_low = 1
| |
| const dbfInt16 displayLimit_high = 2
| |
| const dbfInt16 displayLimit_lastIndex =displayLimit_high
| |
| <tt>exampleRecord.h</tt> is generated from <tt>exampleRecord.dbd</tt>
| |
| class exampleRecord {
| |
| public:
| |
| ... All the fields from iocRecord.dbd
| |
| dbfFloat64 value;
| |
| dbfStruct displayLimit;
| |
| };
| |
|
| |
| const dbfInt16 example_firstIndex = 1001001
| |
| const dbfInt16 example_low = 1001001;
| |
| const dbfInt16 example_high = 1001002;
| |
| const dbfInt16 example_lastIndex = example_high;
| |
| <tt>alltypesRecord.h</tt> is generated from <tt>alltypesRecord.dbd</tt>
| |
| class allTypesRecord {
| |
| public:
| |
| ... All the fields from iocRecord.dbd
| |
| iocRecord common;
| |
| dbfBoolean fbool;
| |
| dbfOctet foctet;
| |
| dbfInt16 fint16;
| |
| dbfUInt16 fuint16;
| |
| dbfInt32 fint32;
| |
| dbfUInt32 fuint32;
| |
| dbfInt64 fint32;
| |
| dbfUInt64 fuint32;
| |
| dbfFloat32 ffloat32;
| |
| dbfFloat64 ffloat64;
| |
| dbfString fstring;
| |
| dbfMenu fmenu;
| |
| dbfEnum fenum
| |
| dbfStruct fstruct;
| |
| dbfLink flink;
| |
| dbfDevice fdevice;
| |
| };
| |
|
| |
| const dbfInt16 allTypes_firstIndex = 1001001
| |
| const dbfInt16 allTypes_fbool = 1001001;
| |
| const dbfInt16 allTypes_foctet = 1001002;
| |
| const dbfInt16 allTypes_fint16 = 1001003;
| |
| const dbfInt16 allTypes_fuint16 = 1001004;
| |
| const dbfInt16 allTypes_fint32 = 1001005;
| |
| const dbfInt16 allTypes_fuint32 = 1001006;
| |
| const dbfInt16 allTypes_fint64 = 1001007;
| |
| const dbfInt16 allTypes_fuint64 = 1001008;
| |
| const dbfInt16 allTypes_ffloat32 = 1001009;
| |
| const dbfInt16 allTypes_ffloatn64 = 10010010;
| |
| const dbfInt16 allTypes_ffstring = 10010011;
| |
| const dbfInt16 allTypes_fmenu = 10010012;
| |
| const dbfInt16 allTypes_fenum = 10010013;
| |
| const dbfInt16 allTypes_fstruct = 10010014;
| |
| const dbfInt16 allTypes_flink = 10010015
| |
| const dbfInt16 allTypes_fdevice = 10010016
| |
| const dbfInt16 allTypes_lastIndex = allTypes_fdevice;
| |
| | |
| ----
| |