Difference between revisions of "V4 Design: dbdClass"

From EPICSWIKI
(Still making changes)
(Still modifying)
Line 13: Line 13:
are intended for code that:
are intended for code that:
* includes header files generated from dbd definitions.  Header files are generated from the following dbd definitions:
* includes header files generated from dbd definitions.  Header files are generated from the following dbd definitions:
** <tt>record</tt>
** <tt>record</tt> Should only be included by record support.
** <tt>struct</tt>
** <tt>struct</tt> Included by code that understands the struct.
** <tt>menu</tt>
** <tt>menu</tt> Included by code that understands the menu.
*  does not include the header files.
*  does not include the header files.


The following headers files are described:
The following headers files are described:
* <tt>epicsTypes.h</tt> - A set of primitive types that are part of <tt>base/src/libCom</tt>
* <tt>epicsTypes.h</tt> - A set of primitive types that are part of <tt>base/src/libCom</tt>
* <tt>dbdTypes.h</tt> - Type definitions for non-primitive <field> definitions in <struct> or <record> DBD definitions.
* <tt>dbdTypes.h</tt> - Type definitions for non-primitive <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 31: Line 31:
  </center>
  </center>
=== <tt>epicsTypes.h</tt> ===
=== <tt>epicsTypes.h</tt> ===
<tt>epicsTypes.h</tt> defines a set of primitive tupes. It is used because the <tt>C99<tt> standard does not define the exact number of bits for the primitive data types. It only defines the minimum number of bits.
<tt>epicsTypes.h</tt> defines a set of primitive tupes. It is used because the <tt>C99</tt> standard does not define the exact number of bits for the primitive data types. It only defines the minimum number of bits.


In addition two extra types are defined:
In addition two extra types are defined:
Line 68: Line 68:




The types epicsBoolean, epicsOctet, epicsInt16, epicsUInt16, epicsInt32, epicsUInt32, epicsInt64,  epicsUInt64, epicsFloat32, epicsFloat64 all map to a C  or C++ primitive type. It may be necessary to provide operating system dependent definitions for some of the types. For example on some architectures a epicsInt64 may have to be defined as a <tt>long</tt> rather than a <tt>long long</tt>.
Each epicsType mapps to a C++ primitive type.
 
It may be necessary to provide operating system dependent definitions for some of the types. For example on some architectures a epicsInt64 may have to be defined as a <tt>long</tt> rather than a <tt>long long</tt>.
If a record is defined as:
<tt>epicsTypeUnknownT</tt> is reserved for unknown types and will normally be cause by some configuration error.
    record(xxx) extends iocRecord {
        ...
        field(fbool,bool)
        field(foctet,octet)
        ...
        field(ffloat64,float64)
        ...
    }
Then the generated header file will be
    class xxxRecord : iocRecord {
    public:
        epicsBoolean fbool;
        epicsOctet  foctet;
        ...
        epicsFloat64 ffloat64;
        ...
    };
 
<tt>epicsType epicsTypeUnknownT</tt> is reserved for unknown types and will normally be cause by some configuration error.


----
----
Line 95: Line 76:


== dbdTypes ==
== dbdTypes ==
</center>


</center>
File <tt>dbdTypes.h</tt> describes types and classes related to
=== <tt>dbdTypes.h</tt> ===
dbd <tt>struct</tt> or <tt>record</tt> field definitions.
File dbdTypes.h describes the non-primitive types used by V4 databases:
The following naming conventions are used:
The following naming conventions are used:
; dbf
: A primitive field type
; Dbf
; Dbf
: any class starting with Dbf describes a struct or record field. For example DbfString describes a field(name,string).
: any class starting with Dbf describes a non-primitive struct or record field. For example DbfString 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.


=== <tt>dbdTypes.h</tt> ===
<tt>dbdTypes.h</tt> contains the following:
<tt>dbdTypes.h</tt> contains the following:
#include <epicsTypes.h>
  enum dbfType {
  enum dbdType {
     dbfUnknownT = epicsUnknownT,
     dbdUnknownT = epicsUnknownT,
     dbfBooleanT = epicsBooleanT,
     dbdBooleanT = epicsBooleanT,
     dbfOctetT = epicsOctetT,
     dbdOctetT = epicsOctetT,
     dbfInt16T = epicsInt16T,
     dbdInt16T = epicsInt16T,
     dbfUInt16T = epicsUInt16T,
     dbdUInt16T = epicsUInt16T,
     dbfInt32T = epicsInt32T,
     dbdInt32T = epicsInt32T,
     dbfUInt32T = epicsUInt32T,
     dbdUInt32T = epicsUInt32T,
     dbfInt64T = epicsInt64T,
     dbdInt64T = epicsInt64T,
     dbfUInt64T = epicsUInt64T,
     dbdUInt64T = epicsUInt64T,
     dbfFloat32T = epicsFloat32T,
     dbdFloat32T = epicsFloat32T,
     dbfFloat64T = epicsFloat64T,
     dbdFloat64T = epicsFloat64T,
     DbfStringT,
     DbfStringT,
     dbdStructT,
     DbfStructT,
     DbfArrayT,
     DbfArrayT,
     // dbdNdimArrayT not yet defined
     // dbfNdimArrayT not yet defined
     dbdEnumT,
     DbfEnumT,
     dbdMenuT,
     DbfMenuT,
     dbdLinkT,
     DbfLinkT,
     dbdDeviceT
     DbfDeviceT
  };
  };
typedef epicsBoolean  dbfBoolean;
typedef epicsOctet    dbfOctet;
typedef epicsInt16    dbfInt16;
typedef epicsUInt16  dbfUInt16;
typedef epicsInt32    dbfInt32;
typedef epicsUInt32  dbfUInt32;
typedef epicsInt64    dbfInt64;
typedef epicsUInt64  dbfUInt64;
typedef epicsFloat32  dbfFloat32;
typedef epicsFloat64  dbfFloat64;
// The following are described  in dbdStatements.h
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


  /*DbfString holds UTF-8 characters*/
  /*DbfString holds UTF-8 characters*/
  class DbfString {
  class DbfString {
  public:
  public:
     dbdInt32 capacity;  /*capacity in bytes*/
     dbfInt32 capacity;  /*capacity in bytes*/
     dbdOctet *pstorage;
     dbfOctet *pstorage;
  };
  };


Line 148: Line 148:
     Interface *pinterface;
     Interface *pinterface;
  };
  };
// The following are described  in dbdStatements.h
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


  class DbfStruct{
  class DbfStruct{
Line 163: Line 157:
  template< class ARR_T > class DbfArray {
  template< class ARR_T > class DbfArray {
  public:
  public:
     dbdInt32 capacity;  /*capacity in number of elements*/
     dbfInt32 capacity;  /*capacity in number of elements*/
     dbdInt32 size;      /*current number of elements*/
     dbfInt32 size;      /*current number of elements*/
     dbdType  type;
     dbdType  type;
     ARR_T    *pstorage;
     ARR_T    *pstorage;
Line 171: Line 165:
  /*  The following array types are supported by dbdCore
  /*  The following array types are supported by dbdCore
   *  DbfArray<void>;
   *  DbfArray<void>;
   *  DbfArray<dbdOctet>;
   *  DbfArray<dbfOctet>;
   *  DbfArray<dbdInt16>;
   *  DbfArray<dbfInt16>;
   *  DbfArray<dbdUInt16>;
   *  DbfArray<dbfUInt16>;
   *  DbfArray<dbdInt32>;
   *  DbfArray<dbfInt32>;
   *  DbfArray<dbdUInt32>;
   *  DbfArray<dbfUInt32>;
   *  DbfArray<dbdInt64>;
   *  DbfArray<dbfInt64>;
   *  DbfArray<dbdUInt64>;
   *  DbfArray<dbfUInt64>;
   *  DbfArray<dbdFloat32>;
   *  DbfArray<dbfFloat32>;
   *  DbfArray<dbdFloat64>;
   *  DbfArray<dbfFloat64>;
   *  DbfArray<DbfString>;
   *  DbfArray<DbfString>;
   *  DbfArray<dbdLinkField>;
   *  DbfArray<dbdLinkField>;
Line 186: Line 180:
  class DbfMenu{
  class DbfMenu{
  public:
  public:
     dbdInt16   index;
     dbfInt16   index;
     MenuDbdDef  *pmenuDef; /* address of global menu */
     MenuDbdDef  *pmenuDef; /* address of global menu */
  };
  };
Line 192: Line 186:
  class DbfEnum{
  class DbfEnum{
  public:
  public:
     dbdInt16 index;
     dbfInt16 index;
     MenuDbdDef *pmenuDef; /* address of record instance menu */
     MenuDbdDef *pmenuDef; /* address of record instance menu */
  };
  };
Line 221: Line 215:


==== Primitive Types ====
==== Primitive Types ====
The types dbdBoolean, dbdOctet, dbdInt16, dbdUInt16, dbdInt32, dbdUInt32, dbdInt64,  dbdUInt64, dbdFloat32, dbdFloat64 all map to an epicsType.  
The types dbf* types, i.e. the primitive types, all map directly to an epicsType.
 
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;
        ...
    };
 
==== DbfString ====
==== DbfString ====
<tt>DbfString</tt> is described as:
<tt>DbfString</tt> is described as:
     class DbfString {
     class DbfString {
     public:
     public:
         dbdInt32 capacity;  /*capacity in bytes*/
         dbfInt32 capacity;  /*capacity in bytes*/
         dbdOctet *pstorage;
         dbfOctet *pstorage;
     };
     };
If a record definition contains
If a record definition contains
Line 234: Line 248:
     DbfString sfield;
     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> NOT the number of characters.  
<tt>pstorage</tt> is 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> NOT the number of characters.  


A support library and rules must be created for managing DbfStrings.
A support library and rules must be created for managing DbfStrings.
Line 261: Line 275:


==== DbfMenu ====
==== DbfMenu ====
<tt>dbdMenu></tt> is described as:
<tt>DbfMenu></tt> is described as:
     class DbfMenu{
     class DbfMenu{
     public:
     public:
         dbdInt16   index;
         dbfInt16   index;
         MenuDbfDef  *pmenuDef;
         MenuDbfDef  *pmenuDef;
     };
     };
Line 272: Line 286:
Then the generated header file contains
Then the generated header file contains
     DbfMenu fmenu;
     DbfMenu fmenu;
The definition of dbdMenu provides the current menu index and also the menu definition.
<tt>DbfMenu</tt> provides the current menu index and also the menu definition.


==== DbfEnum ====
==== DbfEnum ====
Line 278: Line 292:
     class DbfEnum{
     class DbfEnum{
     public:
     public:
         dbdInt16 index;
         dbfInt16 index;
         MenuDbdDef *pmenuDef; /* address of record instance menu */
         MenuDbdDef *pmenuDef; /* address of record instance menu */
     };
     };
Line 324: Line 338:


  </center>
  </center>
The classes in <tt>dbdStatements.h</tt> allow introspection of ioc records. They describe everything defined in DBD definitions.


=== <tt>dbdStatements.h</tt> ===
=== <tt>dbdStatements.h</tt> ===
Line 331: Line 346:
  class StructFieldAttribute {
  class StructFieldAttribute {
     DbfString  default;
     DbfString  default;
     dbdBoolean readonly;
     dbfBoolean readonly;
     dbdBoolean design;
     dbfBoolean design;
     dbdBoolean special;
     dbfBoolean special;
     dbdBoolean dynamic;
     dbfBoolean dynamic;
     epicsInt16 asl;
     epicsInt16 asl;
  };
  };
Line 349: Line 364:
     DbfString    name;
     DbfString    name;
     Interface    *plifetime; // references a StructDbdLifetime
     Interface    *plifetime; // references a StructDbdLifetime
     dbdInt16     nfields;
     dbfInt16     nfields;
     StructDbdField *pfields[]; // ptr to array of ptr to StructDbdField
     StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField
  };
  };


Line 361: Line 376:
  public:
  public:
     DbfString name;
     DbfString name;
     dbdInt16 nchoices;
     dbfInt16 nchoices;
     MenuDbdChoice *pchoice[];
     MenuDbdChoice *pchoice[];
  };
  };
Line 382: Line 397:
  };
  };


  // The following describes record types and record instances
  // The following describes a record type
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 {
  class UserDbdField {
  public:
  public:
Line 402: Line 406:
  }
  }


  class RecordDbdField {
  class RecordDbdDef { // describes a record type
public:
     DbfString    name;
    dbfString name;
    dbfType  type;
};
 
class RecordDbd { // describes a record type
     dbfArray< UserDbdField > userField;
    dbfArray< RecordDbdField > recField;
     Interface    *plifetime; // references a StructDbdLifetime
     Interface    *plifetime; // references a StructDbdLifetime
    dbfInt16    nfields;
    StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField
    UserDbdField *puserField[];
  }
  }


=== Discussion of dbdStatements ===
=== Discussion of dbdStatements ===
The classes in <tt>dbdStatements.h</tt> allow introspection of ioc records. They describe everything defined in DBD definitions.
==== Struct ====
==== Struct ===
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>
The fields of <tt>StructDbdDef</tt> are:
The fields of <tt>StructDbdDef</tt> are:
Line 436: Line 435:
: The address of a StructFieldAttribute for the field
: The address of a StructFieldAttribute for the field


The fields of <tt>StructFieldAttribute</tt> show the falue of the attributes for the field.
<tt>StructFieldAttribute</tt> has the attribute values for the field.


==== Menu ===
==== Menu ====


A dbd <tt>menu</tt> is described by the classes: MenuDbdDef and MenuDbdChoice
A dbd <tt>menu</tt> is described by the classes: MenuDbdDef and MenuDbdChoice
Line 456: Line 455:
: The menu choice that DCTs and the value returned when the menu choice strings are requested.
: The menu choice that DCTs and the value returned when the menu choice strings are requested.


=== Link and Device ===
==== Link and Device ====


Each dbd <tt>link</tt> definition has an associated class LinkDbd with fields:
Each dbd <tt>link</tt> definition has an associated class LinkDbd with fields:
Line 479: Line 478:
; <tt>pinterface</tt>
; <tt>pinterface</tt>
: The address of the Interface implementation. The interface class is LinkDbdSupport
: The address of the Interface implementation. The interface class is LinkDbdSupport
==== Record ====
A record type has two associated classes: <tt>UserDbdField</tt> and <tt>RecordDbdDef</tt>.
The fields of <tt>StructDbdDef</tt> are similar to the fields in <tt>StructDbdDef</tt> except that they refer to a record instead of a structure. An additional field <tt>puserField</tt> is also present.
; <tt>name</tt>
: The name of the record.
; <tt>plifetime</tt>
: The address of an implementation of interface <tt>StructDbdLifetime</tt>. The implementation is automatically generated from the dbd <tt>record</tt> statement. See below for a description of the <tt>StructDbdLifetime</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>.
The fields of <tt>UserDbdField</tt> are:
; <tt>name</tt>
: The name of the user extended field
; <tt>type</tt>
: The dbfType for the field.
; <tt>pfield</tt>
: ?????????? This does not work
; <tt>pinterface</tt>
: The address of an implementation of interface userFieldHandler;
----
----
<center>
<center>


== dbdInterfaces.h ==
== dbdInterfaces ==
 
dbdInterfaces describes standard interfaces implemented by code that
supports runtime database access. For some the code is automatically generated from the dbd definitions.


  </center>
  </center>
Line 537: Line 566:
             dbfInt16 fieldIndex[] // array of field indices
             dbfInt16 fieldIndex[] // array of field indices
             ) = 0;
             ) = 0;
};
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;
  };
  };


Line 542: Line 581:
==== <tt>StructDbdLifetime</tt> ====
==== <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.
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:
<tt>StructDbdLifetime</tt> has the following fields:
    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>
; <tt>create</tt>
: Creates storage for the struct or record.
: Creates storage for the struct or record.
; <tt>initialize</tt>
; <tt>initialize</tt>
: initializes the struct or record
: initializes the struct or record
; <tt>finalize<tt>
; <tt>finalize</tt>
: cleans up but does not free storage
: cleans up but does not free storage
; <tt>destroy</tt>
; <tt>destroy</tt>
: frees storage
: frees storage
; indexToAddr
; <tt>indexToAddr</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.


==== <tt>LinkDbdSupport</tt> ====
==== <tt>LinkDbdSupport</tt> ====
Not yet described
This describes the interface implemented by link support.
 
==== <tt>RecordDbdSupport</tt> ====
==== <tt>RecordDbdSupport</tt> ====
Not yet described
This is the interface implemented by record support.
==== <tt>UserFieldHandler</tt> ====
This is the interface implemented by code for user extensible fields.


----
----

Revision as of 16:09, 17 May 2005

EPICS: C++ class definitions for Database Definition

May 17 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:

  • epicsTypes.h - A set of primitive types that are part of base/src/libCom
  • dbdTypes.h - Type definitions for non-primitive field definitions in struct or record></tt DBD definitions.
  • dbdStatements.h - Type definitions for DBD statements.
  • dbdInterfaces.h - Type definitions for interfaces related to DBD definitions.

epicsTypes

epicsTypes.h

epicsTypes.h defines a set of primitive tupes. It is used because the C99 standard does not define the exact number of bits for the primitive data types. It only defines the minimum number of bits.

In addition two extra types are defined:

  • epicsUnknownT - Unknown
  • epicsOctetT - An 8 bit byte.

epicsTypes.h contains the following:

enum epicsType {
    epicsUnknownT,
    epicsBooleanT,
    epicsOctetT,
    epicsInt16T,
    epicsUInt16T,
    epicsInt32T,
    epicsUInt32T,
    epicsInt64T,
    epicsUInt64T,
    epicsFloat32T,
    epicsFloat64T,
};
/* some of the following may require OSD definitions*/
typedef bool               epicsBoolean;
typedef char               epicsOctet;
typedef short              epicsInt16;
typedef unsigned short     epicsUInt16;
typedef int                epicsInt32;
typedef unsigned int       epicsUInt32;
typedef long long          epicsInt64;
typedef unsigned long long epicsUInt64;
typedef float              epicsFloat32;
typedef double             epicsFloat64;

Discussion of epicsTypes

Each epicsType mapps to a C++ primitive type. It may be necessary to provide operating system dependent definitions for some of the types. For example on some architectures a epicsInt64 may have to be defined as a long rather than a long long. epicsTypeUnknownT is reserved for unknown types and will normally be cause by some configuration error.


dbdTypes

File dbdTypes.h describes types and classes related to dbd struct or record field definitions. The following naming conventions are used:

dbf
A primitive field type
Dbf
any class starting with Dbf describes a non-primitive struct or record field. For example DbfString 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

dbdTypes.h contains the following:

enum dbfType {
    dbfUnknownT = epicsUnknownT,
    dbfBooleanT = epicsBooleanT,
    dbfOctetT = epicsOctetT,
    dbfInt16T = epicsInt16T,
    dbfUInt16T = epicsUInt16T,
    dbfInt32T = epicsInt32T,
    dbfUInt32T = epicsUInt32T,
    dbfInt64T = epicsInt64T,
    dbfUInt64T = epicsUInt64T,
    dbfFloat32T = epicsFloat32T,
    dbfFloat64T = epicsFloat64T,
    DbfStringT,
    DbfStructT,
    DbfArrayT,
    // dbfNdimArrayT not yet defined
    DbfEnumT,
    DbfMenuT,
    DbfLinkT,
    DbfDeviceT
};
typedef epicsBoolean  dbfBoolean;
typedef epicsOctet    dbfOctet;
typedef epicsInt16    dbfInt16;
typedef epicsUInt16   dbfUInt16;
typedef epicsInt32    dbfInt32;
typedef epicsUInt32   dbfUInt32;
typedef epicsInt64    dbfInt64;
typedef epicsUInt64   dbfUInt64;
typedef epicsFloat32  dbfFloat32;
typedef epicsFloat64  dbfFloat64;
// The following are described  in dbdStatements.h
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
/*DbfString holds UTF-8 characters*/
class DbfString {
public:
    dbfInt32  capacity;  /*capacity in bytes*/
    dbfOctet  *pstorage;
};
// FieldDbdPtr is the address of a dbdType
typedef void *FieldDbdPtr;
// StructDbd is base class for classes implementing struct
class StructDbd {};
// Interface is base class for an interface
class Interface {};
class InterfaceLocator {
public:
    DbfString name;
    Interface *pinterface;
};
class DbfStruct{
public:
    StructDbdDef *pstructDef;
    StructDbd    *pstruct; // address of storage
};
template< class ARR_T > class DbfArray {
public:
    dbfInt32  capacity;  /*capacity in number of elements*/
    dbfInt32  size;      /*current number of elements*/
    dbdType   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<dbdLinkField>;
**/
class DbfMenu{
public:
    dbfInt16    index;
    MenuDbdDef  *pmenuDef; /* address of global menu */
};
class DbfEnum{
public:
    dbfInt16  index;
    MenuDbdDef *pmenuDef; /* address of record instance menu */
};

enum LinkDir {
    LinkDirNone,
    LinkDirForward,
    LinkDirIn,
    LinkDirOut,
    LinkDirInOut
};
class DbfLink{ 
public:
    LinkDir   dir;
    LinkDbd   *plinkDef;
    DbfStruct dataStruct;
};
class DbfDevice{
public:
    LinkDir   dir;
    DeviceDbd *pdeviceDef;
    DbfStruct dataStruct;
};

Discussion of dbdTypes

Primitive Types

The types dbf* types, i.e. the primitive types, all map directly to an epicsType.

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;
        ...
   };

DbfString

DbfString 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;

pstorage is the address of a UTF-8 null terminated character string. The capacity is the the number of bytes referenced by pstorage NOT the number of characters.

A support library and rules must be created for managing DbfStrings.

DbfStruct

DbfStruct> is described as:

    class DbfStruct{
    public:
        StructDbdDef *pstructDef;
        StructDbd    *pstruct; // address of storage
    };

If a record definition contains

    field(sstruct,struct(name))

Then the generated header file contains

    DbfStruct sfield;

pstruct is the address of storage for the structure and pstructDef is the address of a description of the structure. StructDbdDef is described in dbdStatatements.h

Note that given a dbdStruct it is possible to locate both the address and description of the associated structure.

DbfArray

Discussion needed. Note that multi-dimensional arrays must also be described.


DbfMenu

DbfMenu> 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;

DbfMenu provides the current menu index and also the menu definition.

DbfEnum

DbfEnum> is described as:

    class DbfEnum{
    public:
        dbfInt16  index;
        MenuDbdDef *pmenuDef; /* address of record instance menu */
    };

If a record definition contains

    field(fenum,enum)

Then the generated header file contains

    DbfEnum fenum;

Note that the definition of DbfEnum looks identical to DbfMenu. The difference is that DbfMenu has the address of a global MenuDbfDef but DbfEnum has the addrsss of a MenuDbfDef that belongs to the record instance.

DbfLink

DbfLink is described as

    class DbfLink{ 
    public:
        LinkDir   dir;
        LinkDbd   *plinkDef;
        DbfStruct 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.
choiceName
The record instance specifies this and it is used to locate the associated dbd link definition.
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

dbdDevice

A dbdDevice is similar to a dbdLink 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

dbdStatements.h contains the following:

class StructFieldAttribute {
    DbfString  default;
    dbfBoolean readonly;
    dbfBoolean design;
    dbfBoolean special;
    dbfBoolean dynamic;
    epicsInt16 asl;
};
class StructDbdField {
public:
    DbfString name;
    dbdType   type;
    StructFieldAttribute *pattribute;
};
class StructDbdDef{
public:
    DbfString    name;
    Interface    *plifetime; // references a StructDbdLifetime
    dbfInt16     nfields;
    StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField
};
class MenuDbdChoice {
    DbfString choiceName;
    DbfString menuName;
}
class MenuDbdDef{
public:
    DbfString name;
    dbfInt16  nchoices;
    MenuDbdChoice *pchoice[];
};
class LinkDbd{ //describes dbd link statement
public:
    LinkDir    dir;
    DbfString  choiceName;
    DbfString  dataStructName;
    Interface  *pinterface;
};
class DeviceDbd { //describes dbd device statement
public:
    LinkDir   dir;
    DbfString interfaceName;
    DbfString choiceName;
    DbfString dataStructName;
    Interface *pinterface;
};
// The following describes a record type
class UserDbdField {
public:
    dbfString   name;
    dbfType     type;
    FieldDbdPtr pfield;
    InterfacePtr *pinterface; // references userFieldHandler
}
class RecordDbdDef { // describes a record type
    DbfString    name;
    Interface    *plifetime; // references a StructDbdLifetime
    dbfInt16     nfields;
    StructDbdField *pfield[]; // ptr to array of ptr to StructDbdField
    UserDbdField *puserField[];
}

Discussion of dbdStatements

Struct

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 StructDbdLifetime. The implementation is automatically generated from the dbd struct statement. See below for a description of the StructDbdLifetime methods.
nfields
The number of fields, e.g. fields in the structure.
pfields
pointer to an array of pointers to StructDbdField. Each StructDbdField contains the name and type of the fields.

The fields of StructDbdField are:

name
The name of the field
type
The dbfType for the field.
pattribute
The address of a StructFieldAttribute for the field

StructFieldAttribute has the attribute values for the field.

Menu

A dbd menu is described by the classes: MenuDbdDef and MenuDbdChoice

The fields of MenuDbdDef are:

name
The menu name.
nchoices
The number of menu choices.
pchoice
The address of an array of pointers to choices

The fields of MenuDbdChoice described a single choice:

choiceName
The choice name, i.e. the C++ variable name that appears in the generated enum statement for the menu
menuName
The menu choice that DCTs and the value returned when the menu choice strings are requested.

Link and Device

Each dbd link definition has an associated class LinkDbd with fields:

dir
The link direction
choiceName
The name that to find 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 to find 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

Record

A record type has two associated classes: UserDbdField and RecordDbdDef. The fields of StructDbdDef are similar to the fields in StructDbdDef except that they refer to a record instead of a structure. An additional field puserField is also present.

name
The name of the record.
plifetime
The address of an implementation of interface StructDbdLifetime. The implementation is automatically generated from the dbd record statement. See below for a description of the StructDbdLifetime 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.


The fields of UserDbdField are:

name
The name of the user extended field
type
The dbfType for the field.
pfield
?????????? This does not work
pinterface
The address of an implementation of interface userFieldHandler;



dbdInterfaces

dbdInterfaces describes standard interfaces implemented by code that supports runtime database access. For some the code is automatically generated from the dbd definitions.

dbdInterfaces.h

dbdInterfaces.h 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;
};
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;
};

Discussion of dbdInterfaces

StructDbdLifetime

Every dbd struct and record has an associated StructDbdLifetime interface implementation. A tool is provided that automatically generates the implementation form the dbd definition. StructDbdLifetime has the following fields:

create
Creates storage for the struct or record.
initialize
initializes the struct or record
finalize
cleans up but does not free storage
destroy
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.

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.


Example of Generated Header Files

Database Definition Files

menuAlarmSevr.dbd contains:

    menu(menuAlarmSevr) { 
         choice(menuAlarmSevrNO_ALARM,"NO_ALARM") 
         choice(menuAlarmSevrMINOR,"MINOR")
         choice(menuAlarmSevrMAJOR,"MAJOR")
         choice(menuAlarmSevrINVALID,"INVALID")
    }

displayLimit.dbd contains:

    struct(displayLimit) {
        field(low,float64)
        field(high,float64)
    }

exampleRecord.dbd contains:

    record(example) extends iocRecord {
        field(value,float64)
        field(displayLimit,struct(displayLimit))
    }

alltypesRecord.dbd 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

menuAlarmSevr.h is generated from menuAlarmSevr.dbd

    enum menuAlarmSevr {
           menuAlarmSevrNO_ALARM,
           menuAlarmSevrMINOR,
           menuAlarmSevrMAJOR,
           menuAlarmSevrINVALID
    };

displayLimit.h is generated from displayLimit.dbd

    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

exampleRecord.h is generated from exampleRecord.dbd

    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;

alltypesRecord.h is generated from alltypesRecord.dbd

    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;