Difference between revisions of "V4 Design: dbdClass"

From EPICSWIKI
 
(24 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:
 
/* 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 are described  in dbdStatements.h
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:
 
// 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
}
 
=== Discussion of dbdStatements ===
NOT YET DONE
----
<center>
 
== dbdInterfaces.h ==
 
</center>
 
=== <tt>dbdInterfaces.h</tt> ===
<tt>dbdInterfaces.h</tt> contains the following:
 
// 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;
};
 
=== 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;
 
----

Latest revision as of 19:53, 11 August 2005

This page is obsolete. It is replaced by dbdInterfaces.