Difference between revisions of "V4 Design: dbdClass"

From EPICSWIKI
 
Line 1: Line 1:
= EPICS: dbdClasses - IOC Database Description =
This page is obsolete. It is replaced by dbdInterfaces.
July 07 2005
 
----
<center>
 
== Overview ==
 
</center>
 
This document describes the C++ definitions for code that accessses
IOC records, i.e. the 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.
 
This document discusses the following:
* dbfTypes - Type definitions for <tt>field</tt> definitions in <tt>struct</tt> or <tt>record></tt> DBD definitions.
* Database Fields - The C++ types for database fields.
* dbdStatements - Structures that describe the <tt>menu, link, device, struct,</tt> and <tt>record</tt> DBD definitions, and also structures that describe record instances.
* Introspection - Class definitions that provide access to database fields and to dbdStatements.
* Field Access - Classes for accessing the values in database fields.
* Record and Structure Lifetime - Automatically generated files for <tt>struct</tt> and <tt>record</tt> DBD definitions.
* Record Support - The interface that must be implemented by record support
* User Field Support - The classes associated with user defined fields.
* Link and Device Support - The classes implemented by link and device support
* Runtime Database Access - Classes and rules for runtime access of database fields.
 
 
----
<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:
; C++ <tt>struct</tt> vs <tt>class</tt>
: A C++ <tt>class</tt> is used for a class that has methods and <tt>struct</tt> is used for a class that has only data. Most Dbf and Dbd definitions are <tt>struct</tt>. Since records are accessed by many different interfaces, defining these as pure data seems to best. The only exceptions are interface definitions.
; Dbf
: any class starting with Dbf describes a field in a generated header file. For example DbfArray describes a field generated from <tt>field(name,array(float64[])</tt>.
; Dbd
: A class name starting with Dbd describes something related to dbd definitions. For example DbdLinkSupport describes a dbd link definition.
 
=== <tt>dbfTypes.h</tt> ===
Every field in the header files generated from DBD <tt>struct</tt> and
<tt>record</tt> definitions has one on the following types:
 
 
    enum dbfType {
        dbfTypeBoolean,    // epicsBoolean
        dbfTypeOctet,      // epicsOctet
        dbfTypeInt16,      // epicsInt16
        dbfTypeInt32,      // epicsInt32
        dbfTypeInt64,      // epicsInt64
        dbfTypeFloat32,    // epicsFloat32
        dbfTypeFloat64,    // epicsFloat64
        dbfTypeString,      // EpicsString
        dbfTypeArray,      // DbfArray
        dbfTypeMDArray      // DbfMDArray
        dbfTypeMenu,        // DbfMenu
        dbfTypeEnum,        // DbfEnum
        dbfTypeLink,        // DbfLink
        dbfTypeDevice      // DbfDevice
        dbfTypeStruct,      // DbfStruct
    };
 
=== Discussion of dbfTypes ===
 
Question:
* Should dbfTypeString be EpicsString or should a DbfString be defined?
 
DBD type
* bool,...,string all become an epicsType , i.e. epicsBoolean,...EpicsString
* array becomes a DbfArray or DbfMDArray.
* struct becomes a DbfStruct
* menu becomes DbfMenu
* enum becomes DbfEnum
* link becomes DbfLink
* device becomes DbfDevice
 
 
If a record is defined as:
    struct(displayLimits) {
        field(low,double)
        field(high,double)
    }
    record(example) extends iocRecord {
        ...
        field(fbool,bool)
        field(foctet,octet)
        field(fint,int16)
        ...
        field(ffloat,float64)
        field(fstring,string)
        field(farray,array(double[])
        field(fmdarray,array(double[,])
        field(fmenu,menu(name))
        field(fenum,enum)
        field(flink,link(in))
        field(fdevice,link(in,analogIO))
        field(displayLimits,struct(displayLimits))
    }
 
Then the generated header file will be
    class displayLimit {
    public:
        epicsFloat64 low;
        epicsFloat64 high;
    };
    const epicsInt16 displayLimit_firstIndex = 1
    const epicsInt16 displayLimit_low        = 1
    const epicsInt16 displayLimit_high      = 2
    const epicsInt16 displayLimit_lastIndex =displayLimit_high
 
    class exampleRecord : public iocRecord {
    public:
        epicsBoolean fbool;
        epicsOctet  foctet;
        epicsInt16  fint;
        ...
        epicsFloat64 ffloat;
        EpicsString  fstring;
        DbfArray    farray;
        DbfMDArray  fmdarray;
        DbfMenu      fmenu;
        DbfEnum      fenum;
        DbfLink      flink;
        DbfDevice    fdevice;
        DbfStruct    displayLimits;
    };
    const epicsInt16 example_firstIndex = 1001001
    const epicsInt16 example_fbool = 1001001;
    const epicsInt16 example_foctet = 1001002;
    const epicsInt16 example_fint      = 1001003;
      ...
    const epicsInt16 example_lastIndex = example_displayLimits;
 
----
<center>
 
== Database Fields ==
</center>
 
=== Primitive Types ===
 
Fields of  type epicsBoolean, epicsOctet, epicsInt16, epicsInt32, epicsInt64,
epicsFloat32, or epicsFloat64 are all a C++ fundamental type. When a record
instance is created these are all initialized to 0.
 
Record support code can directly access such fields via the generated header
file. Some examples are:
 
    exampleRecord *precord;
    epicsInt16 myint;
    ...
    precord->ffloat = 10.0
    ...
    myint = precord->fint;
 
Code that does not include the generated header file can access these fields
via the introspecion interfaces described later in this document.
For example code that expects a epicsFloat64 field can access it via
 
    EpicsString pvname;
    DbAddr *pDbAddr;
    epicsFloat64 *pfield;
    ...
   
    pDbAddr = pDbdLocate->nameToAddr(pvname);
    if(!pDbAddr || (pDbAddr->getType != dbfTypeFloat64)) // do SOMETHING
    pfield = (epicsFloat64 *)pDbAddr->getAddr();
    *pfield = 10.0;
    // NOTE that all modification of fields must also be posted
   
 
=== EpicsString ===
 
A field of type EpicsString is initialized via the default constructor for
EpicsString, which means that no EpicsBuffer is created. Record support
must call createBuffer.
 
Code that includes the generated header file can call the EpicsString methods.
For an example lets assume that record support creates a contiguous buffer
and the record support wants to print the string value.
 
    exampleRecord *precord;
    const epicsOctet *pdata;
    epicsInt32 len;
    ...
    if(precord->fstring->expose(0,len,pdata)) {// do something}
    ...
    printf("%.*s\n",len,pdata);
 
Code that does not include the header file can use the introspection methods
to locate the field. For example:
 
    EpicsString pvname;
    DbAddr *pDbAddr;
    EpicsString *pfield;
    ...
   
    pDbAddr = pDbdLocate->nameToAddr(pvname);
    if(!pDbAddr || (pDbAddr->getType != dbfTypeString)) // do SOMETHING
    pfield = (EpicsString *)pDbAddr->getAddr();
    ...
   
 
 
=== DbfArray ===
<tt>DbfArray</tt> is:
 
    struct DbfArray {
        dbfType type;
        EpicsArray *parray;
    };
       
Code that includes the header file can directly access the DbfArray.
Code that does not include the header file can use the introspection methods
to get the address of the DbfArray.
 
Wrapper classes, described below, are provided for <tt>OctetArray,
Int16Array,Int32Array, Int64Array, Float32Array,</tt> and <tt>Float64Array</tt>
make it easy to access a DbfArray of the corresponding type.
 
An example of how a wrapper class can be used is:
 
    DbfArray  array;
    ...
    Float64Array floatArray(array);
    epicsFloat64 *pdata = new epicsFloat64[10];
    ...
    floatArray.put(0,10,pdata);
 
 
=== DbfMDArray ===
 
<tt>DbfMDArray</tt> is:
 
Need something like for DbfArray except that convenience classes will be
 
    class BasicTypeMDArray;
    class OctetMDArray ;
    class Int32MDArray ;
    class Int64MDArray ;
    class Float32MDArray ;
    class Float64MDArray ;
   
 
=== <tt>DbfMenu</tt> ===
 
<tt>DbfMenu</tt> is described as:
    struct DbfMenu{
        epicsInt16    index;
        DbdMenu  *pmenuDef;
    };
 
<tt>DbfMenu</tt> provides the current menu index and also the menu definition.
A field of type DbfMenu is automatically initialized by dbLoadRecords.
 
A <tt>DbfMenu</tt> field can be accessed via the generated header file or via
the introspection methods.
 
 
=== DbfEnum ===
 
<tt>DbfEnum</tt> is described as:
    struct DbfEnum{
        epicsInt16  index;
        DbfArray  *pfield; //EpicsArray of epicsTypeString
    };
 
<tt>pfield</tt> is the address of a field in the same record that is a
DbfArray of type EpicsString which contains the choices.
 
A field of type DbfEnum is automatically initialized by dbLoadRecords.
 
=== DbfLink and DbfDevice ===
<tt>DbfLink</tt> is described as
    enum LinkDir {
        LinkDirNone,
        LinkDirForward,
        LinkDirIn,
        LinkDirOut,
        LinkDirInOut
    };
   
    struct DbfLink{
        LinkDir  dir;
        DbdLink  *plinkDef;
        DbfStruct dataStruct;
    };
   
    struct DbfDevice{
        LinkDir  dir;
        DbdDevice *pDbdDevice;
        DbfStruct dataStruct;
    };
 
The fields of <tt>DbfLink</tt> are initialized by dbLoadRecords 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 <tt>inout</tt> and the other says <tt>in</tt> then <tt>dir</tt> will be <tt>in</tt>.
; <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.
 
Link support always implements interface <tt>DbdLinkSupport</tt>
 
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.
 
 
 
=== DbfStruct ===
 
<tt>DbfStruct</tt> is described as
 
    struct DbfStruct {
        DbdStruct *pdescription;
        void      *pstorage;
    };
The fields of <tt>DbfStruct</tt> are initialized by dbLoadRecords as follows:
; <tt>pdescription</tt>
: This is initialized via the structure name specified in field definition.
; <tt>pstorage</tt>
: This is initialized by calling DbdStructLifetime:allocate
 
----
<center>
 
== dbdStatements ==
 
</center>
The definitions in <tt>dbdStatements.h</tt> describe everything defined in
database definition files.
 
In the definitions:
 
* <b>NODE</b> and <b>LIST</b> specify a doubly linked list.  An implementation is not specified.
* <tt>class Interface {};</tt> Represents an unspecified interface.
 
=== <tt>DbdMenu</tt> ===
 
    struct DbdMenu{
        NODE        node; // for DbdBase:menuList
        EpicsString name;
        epicsInt16  nchoices;
        EpicsString **papchoice; // ptr to array of ptr to EpicsString
    };
 
The fields of DbdMenu are:
; <tt>node</tt>
: node for DbdBase:menuList
; <tt>name</tt>
: The menu name.
; <tt>nchoices</tt>
: The number of menu choices.
; <tt>papchoice</tt>
: The address of an array of pointers to EpicsString. Each EpicsString is a choice.
 
=== <tt>DbdLink</tt> and <tt>DbdDevice</tt> ===
    struct DbdLink{ //describes dbd link statement
        NODE            node; // For DbdBase:linkList
        LinkDir        dir;
        EpicsString    choiceName;
        EpicsString    dataStructName;
        DbdLinkSupport  *pinterface;
        };
 
    struct DbdDevice { //describes dbd device statement
        NODE        node; // For DbdBase:deviceList
        LinkDir    dir;
        EpicsString choiceName;
        EpicsString dataStructName;
        EpicsString interfaceName;
        Interface  *pinterface;
    };
 
 
A dbd <tt>link</tt> definition is described by <tt>DbdLink</tt>
; <tt>node</tt>
: This is a node for <tt>DbdLinkList</tt>
; <tt>dir</tt>
: The link direction
; <tt>choiceName</tt>
: The name that connects a DbdLink to a DbfLink instance.
; <tt>dataStructName</tt>
: The class name of an DbdStruct for the Interface implementation
; <tt>pinterface</tt>
: The address of the DbdLinkSupport Interface implementation.
 
Each dbd <tt>device</tt> definition is described by <tt>DbdDevice</tt>
; <tt>node</tt>
: This is a node for <tt>DbdDeviceList</tt>
; <tt>dir</tt>
: The link direction
; <tt>choiceName</tt>
: The name that matches a DbdDevice to a DbfDevice instance.
; <tt>dataStructName</tt>
: The class name of an EpicsStruct for the Interface implementation
; <tt>interfaceName</tt>
: The name of the interface type implemented by the device support
; <tt>pinterface</tt>
: The address of the Interface implementation.
   
=== <tt>DbdStruct</tt> and <tt>DbdRecord</tt> ===
 
    struct DbdAttribute {
        EpicsString  default;
        epicsBoolean readonly;
        epicsBoolean design;
        epicsBoolean special;
        epicsBoolean dynamic;
        epicsInt16  asl;
    };
 
    struct DbdStringDefaults { // defaults for string
        const char *bufferType;
        epicsInt32 capacity;
    };
 
    struct DbdArrayDefaults { // defaults for array
        dbfType    type;
        const char *bufferType;
        epicsInt32 capacity;
        epicsInt32 nelements;
    };
 
    struct DbdMDArrayDefaults { // defaults for mdarray
        dbfType    type;
        epicsInt16 ndim
        const char *bufferType;
        epicsInt32 capacity;
    };
 
    struct DbdStructDefaults { // defaults for struct
        DbdStruct *pdescription;
    };
 
    struct DbdField {
        const char *name;
        dbfType  type;
        union {
            DbdStringDefaults  *pstring;
            DbdArrayDefaults  *parray;
            DbdMDArrayDefaults *pmdarray;
            DbdStructDefaults  *pstruct;
        } defaults;
        DbdAttribute attribute;
    };
 
    struct DbdStruct{ // describes a struct
        NODE            node; // for DbdBase:structList
        const char      *name;
        epicsInt16      nfields;
        DbdField        **papfield;//ptr to array of ptr to DbdField
        DbdStructLifetime *plifetime;
    };
 
 
    struct DbdRecord { // describes a record
        NODE              node; // for DbdBase:recordList
        LIST              instanceList;
        const char        *name;
        epicsInt16        nfields;
        DbdField          **papfield;//ptr to array of ptr to DbdField
        DbdRecordSupport  *psupport;
        DbdRecordLifetime *plifetime;
    };
 
The following describe the fields in a dbd <tt>struct</tt> or <tt>record</tt> definition: <tt>DbdStruct</tt>, <tt>DbdRecord</tt>, <tt>DbdField</tt>,and <tt>DbdAttribute</tt>
 
The fields of <tt>DbdStruct</tt> are:
; <tt>node</tt>
: node for <tt>DbdBase:structList</tt>
; <tt>name</tt>
: The name of the struct.
; <tt>nfields</tt>
: The number of fields, e.g. fields in the structure.
; <tt>papfields</tt>
: pointer to an array of pointers to <tt>DbdField</tt>.
; <tt>plifetime</tt>
: The address of an implementation of interface <tt>DbdStructLifetime</tt>. The implementation is automatically generated from the dbd <tt>struct</tt>. See below for a description of the Lifetime methods.
 
The fields of <tt>DbdRecord</tt> are;
; <tt>node</tt>
: node for <tt>DbdBase:recordList</tt>
; <tt>instanceList</tt>
: list of instances of this record type
; <tt>name</tt>
: The name of the record type.
; <tt>nfields</tt>
: The number of fields, e.g. fields in the record.
; <tt>papfields</tt>
: pointer to an array of pointers to <tt>DbdField</tt>.
; <tt>psupport</tt>
: The address of the <tt>DbdRecordSupport</tt> for this record type.
; <tt>plifetime</tt>
: The address of an implementation of interface <tt>DbdRecordLifetime</tt>. The implementation is automatically generated from the dbd <tt>record</tt> statement. See below for a description of the Lifetime methods.
 
 
The fields of <tt>DbdField</tt> are:
; <tt>name</tt>
: The name of the field
; <tt>type</tt>
: The dbfType of the field.
; <tt>defaults</tt>
: a union of default values. The default values depend on the record type definitions. Most types do not have associated default values. Note that these are defaults for the description of the field NOT for values to put in the field.
; <tt>attribute</tt>
: DbdAttribute for the field
 
Question
# For string and array defaults how is bufferType determined?
 
The fields of <tt>DbdAttribute</tt> are:
; <tt>default</tt>
: An EpicsString providing a default value for the field.
; <tt>readonly</tt>
: Is the field readonly?
; <tt>design</tt>
: Is the field a design fields for DCTs?
; <tt>special</tt>
: Should DbdRecordSupport:special be called if the field is modified.
; <tt>dynamic</tt>
: Can the field change because of record processing?
; <tt>asl</tt>
: The access security level.
   
=== Record Instance ===
 
    struct DbdUserField{ // describes a dbd userField statement
        NODE                node; // For DbdBase:userFieldList
        EpicsString        choiceName;
        epicsType          type;
        EpicsString        dataStructName;
        DbdUserFieldHandler *pinterface;
    };
   
    struct DbdUserFieldInstance {
        NODE        node; // for DbdRecordInstance.userField
        EpicsString  name; // user field name
        dbfType      sourceType;
        void        *psource;
        DbdUserField *pDbdUserField;
        void        *pstorage; // for DbdUserField.type
        DbfStruct    dataStruct;
    };
   
    struct DbdRecordInstance {
        NODE        node; // for DbdRecord.instanceList
        DbdRecord    *pDbdRecord;
        void        *pstorage;
        EpicsString  name;
        LIST        userField; // of DbdUserFieldInstance
    };
 
NOTE: userField has NOT been defined.
 
Each dbd <tt>userField</tt> definition has an associated class <tt>DbdUserField</tt> with fields:
; <tt>node</tt>
: This is a node for <tt>DbdUserFieldList</tt>
; <tt>choiceName</tt>
: The name that matches a DbdUserField to a DbdUserFieldInstance
; <tt>type</tt>
: The epicsType for the user field
; <tt>dataStructName</tt>
: The class name of an EpicsStruct for the DbdUserFieldHandler
; <tt>pinterface</tt>
: The address of the DbdUserFieldHandler implementation.
 
 
A record instance has two associated classes:<tt>DbdUserFieldInstance</tt> and <tt>DbdRecordInstance</tt>.
 
<tt>DbdUserFieldInstance</tt> contains information for a user defined field:
; <tt>node</tt>
: A node for list <tt>DbdRecordInstance.userField</tt>
; <tt>name</tt>
: The name of the user defined field, i.e. the psuedo field name
; <tt>sourceType</tt>
: the type of the field of the record that DbdUserFieldHandler accesses.
; <tt>psource</tt>
: The address of the field that DbdUserFieldHandler accesses.
; <tt>pDbdUserField</tt>
: The DbdUserField that describes the field
; <tt>pstorage</tt>
: Address of storage for the dbfType.
; <tt>dataStruct</tt>
: An DbfStruct that holds the private data for the DbdUserFieldHandler.
 
The fields of <tt>DbdRecordInstance</tt> are:
 
; <tt>node</tt>
: A node for list <tt>DbdRecord.instanceList</tt>
; <tt>pDbdRecord</tt>
: address of the DbdRecord describing the record
; <tt>pstorage</tt>
: address of the storage for the record instance
; <tt>name</tt>
: The name of the record instance
; <tt>userField</tt>
: <tt>DbdUserFieldInstance</tt> list for the record instance.
 
   
=== Base ===
 
    struct DbdBase {
        LIST structList;
        LIST recordList;
        LIST menuList;
        LIST linkList;
        LIST deviceList;
        LIST userFieldList;
    };
 
 
This is only accessable via the introspection interfaces described in the next
section. They are shown here for completeness.
 
The following provide lists of various things:
 
; <tt>structList</tt>
: The list of each struct definition
; <tt>recordList</tt>
: The list of each record type definition
; <tt>menuList</tt>
: The list of each menu definition
; <tt>linkList</tt>
: The list of each link definition
; <tt>deviceList</tt>
: The list of each device definition
; <tt>userFieldList</tt>
: The list of each DbdUserField definition
 
----
<center>
 
== Introspection ==
</center>
 
This section describes interfaces provided by iocCore for locating
information related to <tt>Dbf</tt> and <tt>Dbd</tt> definitions.
 
    class DbdLocate {
    public:
        DbdMenu *menu(EpicsString &menuName);
        DbdLink *link(EpicsString &choiceName);
        DbdDevice *device(EpicsString &choiceName);
        DbdStruct *struct(EpicsString &name);
        DbdRecord *record(EpicsString &name);
        DbdUserField *userField(EpicsString &name);
 
        DbdField *field(DbdRecord *pDbdRecord, EpicsString &fieldName);
        DbdField *field(DbdStruct *pDbdStruct, EpicsString &fieldName);
        void registerRecordSupport(EpicsString &name,
                  DbdRecordSupport &support);
        void registerLinkSupport(EpicsString &choiceName,
                  EpicsString &dataStructName, DbdLinkSupport &support);
        void registerDeviceSupport(EpicsString &choiceName,
                  EpicsString &dataStructName, EpicsString &interfaceName,
                  DbdLinkSupport &support);
    };
    extern DbdLocate *pDbdLocate;
 
 
    class DbAddr {
    public:
        DbAddr(EpicsString &pvname);
        DbAddr(EpicsString &recordName, EpicsString &fieldName);
        virtual ~DbAddr();
        virtual dbfType getType() = 0;
        virtual void    *getAddr() = 0;
        virtual DbdRecordInstance *getDbdRecordInstance() = 0;
        virtual void getIndex(epicsInt16 *nlevels,epicsInt16 *paindex) = 0;
    };
 
    class DbdRecordIntrospect {
    public:
        DbAddr *nameToAddr(EpicsString &pvname);
    };
----
<center>
 
== Field access ==
</center>
 
This section describes interfaces provided by iocCore for
modifying fields in database reords.
 
=== DbfArray access ===
 
Classes are provided for accessing <tt>DbfArray</tt> fields that
are arrays of any of the following primitive types: octet, int, float.
 
    class Int16Array {
    public:
        Int16Array(DbfArray &array);
        Int16Array(DbfArray &array,
                    const char *bufferType, epicsInt32 capacity);
        Int16Array(DbfArray &array,
                    EpicsBufferCreator *creator, epicsInt32 capacity);
        ~Int16Array();
        epicsInt16 *element(epicsInt32 index);
        const epicsInt16 * element(epicsInt32 index) const;
        epicsInt32 get(epicsInt32 offset, epicsInt32 len,
                        epicsInt16 *pto) const;
        epicsInt32 put(epicsInt32 offset, epicsInt32 len,
                        const epicsInt16 *pfrom);
        epicsInt32 getElementSize() const;
        void useBuffer(const char *bufferType, epicsInt32 capacity = 0);
        void useBuffer(EpicsBufferCreator *creator, epicsInt32 capacity = 0);
        void destroy();
        EpicsBufferCreator *creator() const;
        bool mutable() const;
        // These are similar to Buffer, measured in elements not octets
        void reserve(epicsInt32 capacity);
        epicsInt32 capacity() const;
        void resize(epicsInt32 newsize);
        epicsInt32 size() const;
        epicsInt32 maxSize() const;
        void expose(epicsInt32 offset, epicsInt32 &len,
                    epicsInt16 *&pdata);
        void expose(epicsInt32 offset, epicsInt32 &len,
                    const epicsInt16 *&pdata) const;
    private:
        DbfArray &array;
        Int16Array(const EpicsInt16Array &);            // No copy constructor
        Int16Array& operator=(const EpicsInt16Array &); // No assignment operator
    };
 
    // The following are like Int16Array except for type
    class OctetArray ;
    class Int32Array ;
    class Int16Array;
    class Int64Array ;
    class Float32Array ;
    class Float64Array ;
 
 
=== DbdFieldPutString ===
 
Given an EpicsString, these methods put a value in a Dbf field
 
class DbdFieldPutString {
public:
    void primitive(EpicsString *pfrom, dbfType type, void *pstorage);
    void string(EpicsString *pfrom, EpicsString *pEpicsString);
    void array(EpicsString *pfrom, DbfArray *parray);
    void dbfStruct(EpicsString *pfrom, DbfStruct *pstruct);
    void dbfMDArray(EpicsString *pfrom, DbfMDArray *parray);
}
extern DbdFieldPutString *pDbdFieldPutString;
 
<tt>DbdFieldPutString</tt> is an interface,
which has an implementation provided by iocCore,
that convert an <tt>EpicsString</tt> to an dbfType.
 
The methods are:
; <tt>primitive</tt>
: This convert a string to one of the types: <tt>epicsBoolean</tt>, ..., <tt>epicsFloat64</tt>
; <tt>string</tt>
: Copies an EpicsString to an EpicsString
; <tt>array</tt>
: Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either DbdFieldPutString:primitive or DbdFieldPutString:string to convert the value and put it into the correct element of <tt>DbfArray</tt>
; <tt>dbfStruct</tt>
: Accepts a string that has the DBD struct initialialization syntax, locates the string value associated with each field and calls primitive, string, or array to convert the value and put the result of the correct field of <tt>DbfStruct</tt>
; <tt>dbfMDArray</tt>
: Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either DbdFieldPutString:primitive or DbdFieldPutString:string to convert the value and put it into the correct element of <tt>DbfMDArray</tt>
 
----
<center>
== Record and Structure Lifetime ==
</center>
 
The following are automatically generated from the DBD definitions.
 
// For struct definitions
// An DbdStructLifetime interface is automatically generated.
class DbdStructLifetime {
public:
    virtual void allocate(DbfStruct &struct) = 0;
    virtual void destroy(DbfStruct &struct) = 0;
    virtual bool initialize(DbfStruct *pDbfStruct) = 0;
    virtual bool finalize(DbfStruct *pDbfStruct) = 0;
    virtual void *exposeField(DbfStruct &struct, epicsInt16 index) = 0;
};
 
// For record definitions a DbdRecordLifetime is automatically generated.
class DbdRecordLifetime{
public:
    virtual void allocate(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual void destroy(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool initialize(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool finalize(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual void *exposeField(DbdRecordInstance *pDbdRecordInstance,
                            epicsInt16 index) = 0;
};
 
Every dbd <tt>struct</tt> and <tt>record</tt> has an associated Lifetime interface implementation.
A tool is provided that automatically generates the implementation from the dbd definition.
 
<tt>DbdStructLifetime</tt> and <tt>DbdRecordLifetime</tt> each has the following fields:
; <tt>allocate</tt>
: Creates storage for the struct or record.
; <tt>destroy</tt>
: frees storage
; <tt>exposeField</tt>
: Given an index it returns the address of the storage for the field. Note the the generated header files assign an index to each field.
; <tt>initialize</tt>
: initializes the struct or record
; <tt>finalize</tt>
: cleans up but does not free storage
 
----
<center>
== Record Support ==
</center>
 
/* record support implements the following*/
class DbdRecordSupport {
public:
    virtual bool initBuffers(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool initConnections(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool breakConnections(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool process(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual void special(DbdRecordInstance *pDbdRecordInstance,
            bool  after,
            epicsInt16 nlevels, // number of elements in fieldIndex
            epicsInt16 fieldIndex[] // array of field indices
            ) = 0;
};
 
 
This is the interface implemented by each record support module.
<tt>DbdRecordSupport</tt> has the following methods:
 
; <tt>initBuffers</tt>
: This is called during record initialization. It is responsible for creating the buffers associated with each string and array field. It may call associated support to do the initialization.
; <tt>initConnections</tt>
: This is called to connect to external sources.  It may call associated support to make the connections.
; <tt>breakConnections</tt>
: This is called to disconnect to external sources. It may call associated support to break the connections.
; <tt>process</tt>
: Process the record.
; <tt>special</tt>
: This is called whenever an external source modifies a field with attribute special set to true.
 
----
<center>
== User Field Support ==
</center>
 
class DbdUserFieldHandler {
public:
    virtual bool initialize(
                      iocRecord *precord,DbdUserFieldInstance *puserField) = 0;
    virtual bool finalize(
                      iocRecord *precord,DbdUserFieldInstance *puserField) = 0;
    virtual bool process(
                      iocRecord *precord,DbdUserFieldInstance *puserField) = 0;
};
 
This is the interface implemented by code for user extensible fields.
 
<tt>DbdUserFieldHandler</tt> has the following fields:
; <tt>initialize</tt>
: Initialize the user field.
; <tt>finalize</tt>
: undo what was done during initialization
; <tt>process</tt>
: Called near the end of record processing just before monitors are handled.
 
----
<center>
== Link and Device Support ==
</center>
 
// link support modules implement the following interface
class DbdLinkSupport {
public:
    virtual void report(iocRecord *precord, DbfLink *pdbfLink) = 0;
    virtual bool initialize(iocRecord *precord, DbfLink *pdbfLink) = 0;
    virtual bool finalize(iocRecord *precord, DbfLink *pdbfLink) = 0;
    virtual bool connect(iocRecord *precord, DbfLink *pdbfLink) = 0;
    virtual bool disconnect(iocRecord *precord, DbffLink *pdbfLink) = 0;
    virtual bool get(iocRecord *precord, DbffLink *pdbfLink,
                    epicsType type, void *pfield) = 0;
    virtual bool put(iocRecord *precord, DbfLink *pdbfLink,
                      epicsType type, void *pfield) = 0;
};
 
This is the interface implemented by the support associated with each DBD link.
 
<tt>DbdLinkSupport</tt> has the following methods:
; <tt>report</tt>
: generate a report about the link instance
; <tt>initialize</tt>
: perform initialization but do not connect
; <tt>finalize</tt>
: undo initialization. It is assumed that disconnect has already been called.
; <tt>connect</tt>
: connect to external source of data
; <tt>disconnect</tt>
: disconnect from external source of data
; <tt>get</tt>
: get a value from the external source. <tt>type</tt> specified the field type and <tt>pfield</tt> is the address of where to store the data.
; <tt>put</tt>
: put a value from the external source. <tt>type</tt> specified the field type and <tt>pfield</tt> is the address of where to obtain the data.
 
 
Multiple interface definitions for device support will be defined.
Record Support and device support must agree on which interface type
is used for communication.
----
<center>
== Runtime Database Access ==
</center>
 
=== Record Support ===
 
Must allow for
* post any field that is modified either by record support or by associated device support.
 
=== Link Support ===
 
Must allow for
 
* get
* getNotify
* put
* putNotify
* post any field that is modified
 
=== External Access ===
 
Must allow for
 
* permission to get or put
* get
* get after process
* put
* put and process
* put process and notify
* post any field that is modified

Latest revision as of 19:53, 11 August 2005

This page is obsolete. It is replaced by dbdInterfaces.