Difference between revisions of "V4 Design: dbdClass"

From EPICSWIKI
Line 1: Line 1:
= EPICS: dbdClasses - IOC record =
= EPICS: dbdClasses - IOC record =
June 17 2005  
June 20 2005  


----
----
Line 6: Line 6:


== Overview ==
== Overview ==
UNDER CONSTRUCTION


  </center>
  </center>
Line 136: Line 134:
<tt>DbfArray</tt> is:
<tt>DbfArray</tt> is:


     class DbfArray : protected EpicsArray {
     struct DbfArray {
    public:
        DbfArray(dbfType type = dbfTypeOctet);
        DbfArray(const char *bufferType,
                  dbfType type = dbfTypeOctet, epicsInt32 capacity = 0);
        DbfArray(DbfBufferCreator *creator,
                  dbfType type = dbfTypeOctet, epicsInt32 capacity = 0);
        ~DbfArray();
        void setType(dbfType type);
        dbfType getType() const;
        void createBuffer(const char *bufferType, epicsInt32 capacity = 0);
        void createBuffer(DbfBufferCreator *creator, epicsInt32 capacity = 0);
        DbfBufferCreator *creator() const;
        void destroyBuffer();
        epicsOctet *element(epicsInt32 index);
        const epicsOctet *element(epicsInt32 index) const;
        epicsInt32 get(epicsInt32 offset, epicsInt32 len,
                        epicsOctet *pto) const;
        epicsInt32 put(epicsInt32 offset, epicsInt32 len,
                        const epicsOctet *pfrom);
        bool mutable() const;
        // These are similar to DbfBuffer, 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,
                    epicsOctet *&pdata);
        void expose(epicsInt32 offset, epicsInt32 &len,
                    const epicsOctet *&pdata) const;
    protected:
         dbfType type;
         dbfType type;
    private:
         EpicsArray *parray;
         DbfArray(const DbfArray &);            // No copy constructor
        DbfArray& operator=(const DbfArray &); // No assignment operator
    };
 
 
QUESTIONS:
# should operator = be allowed?
# should EpicsArray provide convience wrappers for basic types
 
In addition convenience classes are available for each dbfType.
They provide a type safe wrapper the has a reference to a DbfArray.
The convience classes are:
 
    class Int16Array {
    public:
        Int16Array(DbfArray &array);
        Int16Array(DbfArray &array,
                    const char *bufferType, epicsInt32 capacity = 0);
        Int16Array(DbfArray &array
                    EpicsBufferCreator *creator, epicsInt32 capacity = 0);
        ~Int16Array();
        void createBuffer(const char *bufferType, epicsInt32 capacity = 0);
        void createBuffer(DbfBufferCreator *creator, epicsInt32 capacity = 0);
        DbfBufferCreator *creator() const;
        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);
        bool mutable() const;
        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(); // No default constructor
        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 Int64Array ;
    class Float32Array ;
    class Float64Array ;
    class StringArray ;
    class StructArray ;
As an example of how the convience classes are used is:
    DbfArray  dbfArray;
    ...
    Float64Array floatArray(dbfArray);
    epicsFloat64 *pdata = new epicsFloat64[10];
    ...
    floatArray.put(0,10,pdata);
          
          
----
----
Line 259: Line 162:
  </center>
  </center>
<tt>DbfMenu</tt> is described as:
<tt>DbfMenu</tt> is described as:
     class DbfMenu{
     struct DbfMenu{
    public:
        DbfMenu(DbdMenu &menu);
        epicsInt16 nChoices();
        EpicsString &choice() const;
        EpicsString &choice(epicsInt16 index) const;
        epicsInt16 getIndex() const;
        void setIndex(epicsInt16 index) const;
        EpicsEnumChoices &choices() const;
        DbdMenu &menu() const;
    private:
         epicsInt16    index;
         epicsInt16    index;
         DbdMenu  &menuDef;
         DbdMenu  *pmenuDef;
        DbfMenu(); // no default constructor
     };
     };


<tt>DbfMenu</tt> provides the current menu index and also a reference to the associated DbDMenu.
<tt>DbfMenu</tt> provides the current menu index and also the menu definition.


Questions
A field of type DbfMenu is automatically initialized by dbLoadRecords.
# Is this how we want to do this?
 
The constructor for the record type must also construct a DbfMenu.


----
----
Line 288: Line 177:
  </center>
  </center>
<tt>DbfEnum</tt> is described as:
<tt>DbfEnum</tt> is described as:
     class DbfEnum{
     struct DbfEnum{
    public:
         epicsInt16 index;
        DbfEnum(DbfArray &field);
         DbfArray  *pfield; //EpicsArray of epicsTypeString
        epicsInt16 nChoices();
         EpicsString &choice() const;
        EpicsString &choice(epicsInt16 index) const;
         epicsInt16 getIndex() const;
        void setIndex(epicsInt16 index) const;
        EpicsEnumChoices &choices() const;
    private:
        epicsInt16    index;
        EpicsEnumChoices *pEpicsEnumChoices;
        DbfEnum(); // no default constructor
     };
     };


The only way to create a DbfEnum is to pass it a reference to a field that is
<tt>pfield</tt> is the address of a field in the same record that is a
a DbfArray with type EpicsString.
DbfArray of type EpicsString. It contains the choices.
 
A field of type DbfEnum is automatically initialized by dbLoadRecords.


----
----
Line 373: Line 254:
  </center>
  </center>
The definitions in <tt>dbdStatements.h</tt> allow introspection of ioc records. They describe everything defined in DBD definitions.
The definitions in <tt>dbdStatements.h</tt> allow introspection of ioc records. They describe everything defined in DBD definitions.
The following contain the following undefined definitions:


<b>NODE</b> and <b>LIST</b> specify a doubly linked list.
<b>NODE</b> and <b>LIST</b> specify a doubly linked list.
An implementation is not specified.
An implementation is not specified.


=== <tt>dbdStatements.h</tt> ===
The following:
    class Interface {}; // Must be an interface, i.e. pure abstract class
Represents an unspecified interface.


    class Interface {}; // Must be an interface, i.e. pure abstract class
=== <tt>DbdMenu</tt> ===


     class DbdMenu{
     struct DbdMenu{
    public:
        DbdMenu(EpicsEnumChoices &choices);
        epicsInt16 nChoices();
        EpicsString &choice(epicsInt16 index);
        EpicsEnumChoices &choices() const { return choices;}
    private:
        ~DbdMenu(); // Who can call this?
         NODE        node; // for DbdBase:menuList
         NODE        node; // for DbdBase:menuList
         EpicsEnumChoices &choices;
         EpicsString name;
         DbdMenu(); // No default constructor
         epicsInt16  nchoices;
        EpicsString *pchoice[];
     };
     };
   
 
    class DbdLink{ //describes dbd link statement
The fields of DbdMenu are:
    public:
; <tt>node</tt>
          DbdLink(LinkDir,EpicsString &choice,EpicsString &dataStruct);
: node for DbdBase:menuList
          static registerInterface(const EpicsString &choice,LinkDir dir,
; <tt>name</tt>
                              DbdLinkSupport &support);
: The menu name.
          LinkDir dir();
; <tt>nchoices</tt>
          EpicsString &choiceName();
: The number of menu choices.
          EpicsString &dataStructName();
; <tt>pchoice</tt>
          DbdLinkSupport *pinterface();
: The address of an array of pointers to EpicsString. Each EpicsString is a choice.
     private:
 
=== <tt>DbdLink</tt> and <tt>DbdDevice</tt> ===
     struct DbdLink{ //describes dbd link statement
         NODE            node; // For DbdBase:linkList
         NODE            node; // For DbdBase:linkList
         LinkDir        dir;
         LinkDir        dir;
Line 409: Line 290:
         EpicsString    dataStructName;
         EpicsString    dataStructName;
         DbdLinkSupport  *pinterface;
         DbdLinkSupport  *pinterface;
    };
        };  
   
 
     struct DbdDevice { //describes dbd device statement
     struct DbdDevice { //describes dbd device statement
         NODE        node; // For DbdBase:deviceList
         NODE        node; // For DbdBase:deviceList
Line 420: Line 301:
     };
     };


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.
      
      
    // Beginning of definitions for DbdStruct
=== <tt>DbdStruct</tt> and <tt>DbdRecord</tt> ===
 
     struct DbdAttribute {
     struct DbdAttribute {
         EpicsString  default;
         EpicsString  default;
Line 484: Line 392:
         DbdRecordLifetime *plifetime;
         DbdRecordLifetime *plifetime;
     };
     };
   
    struct DbdUserField{ // describes a dbd userField statement
        NODE                node; // For DbdBase:userFieldList
        EpicsString        choiceName;
        epicsType          type;
        EpicsString        dataStructName;
        DbdUserFieldHandler *pinterface;
    };
   
    // The following describes a record instance
    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
    };
   
    struct DbdBase {
        LIST structList;
        LIST recordList;
        LIST menuList;
        LIST linkList;
        LIST deviceList;
        LIST userFieldList;
    };
=== Discussion of dbdStatements ===
GENERIC QUESTIONS:
# NODE - how should we handle lists?
==== Menu ====
A dbd <tt>menu</tt> is described by <tt>DbdMenu</tt>
The methods of DbdMenu are:
; <tt>DbdMenu</tt>
: The only way to create a DbdMenu is via a reference to the EpicsEnumChoices for the menu. Thus the choices must be created first.
; <tt>~DbdMenu</tt>
: destructor. Who can call this?
; <tt>nchoices</tt>
: returns the number of choices.
; <tt>choice</tt>
: returns a reference to the choice.
; <tt>choices</tt>
: returns a reference to the EpicsEnumChoices


QUESTIONS about DbdMenu
# The current definition does not allow the choices to be modified. Is it required that we can change them? Can they be changed AFTER a database is loaded and initialized?
# Who can call destructor?
==== Link ====
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.
==== Device ====
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.
==== struct and record ====
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 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>


Line 631: Line 447:
; <tt>asl</tt>
; <tt>asl</tt>
: The access security level.
: The access security level.
==== User Defined Fields ====
   
=== 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:
Each dbd <tt>userField</tt> definition has an associated class <tt>DbdUserField</tt> with fields:
Line 645: Line 490:
: The address of the DbdUserFieldHandler implementation.
: The address of the DbdUserFieldHandler implementation.


==== Record Instance ====


A record instance has two associated classes:<tt>DbdUserFieldInstance</tt> and <tt>DbdRecordInstance</tt>.
A record instance has two associated classes:<tt>DbdUserFieldInstance</tt> and <tt>DbdRecordInstance</tt>.
Line 678: Line 522:
: <tt>DbdUserFieldInstance</tt> list for the record instance.
: <tt>DbdUserFieldInstance</tt> list for the record instance.


==== DbdBase ====
   
=== Base ===
 
    struct DbdBase {
        LIST structList;
        LIST recordList;
        LIST menuList;
        LIST linkList;
        LIST deviceList;
        LIST userFieldList;
    };
 


The following provide lists of various things:
The following provide lists of various things:
Line 698: Line 553:
<center>
<center>


== dbdInterfaces ==
== 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);
        DbdRecordInstance &recordInstance(EpicsString &name);
        void registerRecordSupport(EpicsString &name,
                  DbdRecordSupport &support);
        void registerLinkSupport(EpicsString &choiceName,
                  EpicsString &dataStructName, DbdLinkSupport &support);
        void registerDeviceSupport(EpicsString &choiceName,
                  EpicsString &dataStructName, EpicsString &interfaceName,
                  DbdLinkSupport &support);
    };
    DbdLocate *pDbdLocate;


dbdInterfaces describes standard interfaces implemented by code that
----
supports runtime database access.
<center>


== Field access ==
  </center>
  </center>


=== <tt>dbdInterfaces.h</tt> ===
This section describes interfaces provided by iocCore for
<tt>dbdInterfaces.h</tt> contains the following:
modifying fields in database reords.
 
=== DbfArray access ===
 
Classes are provided for accessing <tt>DbfArray</tt> fields that
are arrays of aany of the following primitive types: octet, int, float.
 
    class BasicTypeArray {
    public:
        BasicTypeArray(DbfArray &array);
        BasicTypeArray(DbfArray &array,
                    const char *bufferType, epicsInt32 capacity);
        BasicTypeArray(DbfArray &array,
                    BufferCreator *creator, epicsInt32 capacity);
        virtual ~BasicTypeArray();
        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;
    protected:
        DbfArray &array;
    private:
        BasicTypeArray(const EpicsBasicTypeArray &);// No copy constructor
        // No assignment operator
        BasicTypeArray& operator=(const EpicsBasicTypeArray &);
    };
 
 
    class Int16Array : public BasicTypeArray{
    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);
 
        // 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:
        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 Int64Array ;
    class Float32Array ;
    class Float64Array ;
 
An example of how the convience classes are used is:
 
    Float64Array  dbfArray;
    ...
    Float64Array floatArray(dbfArray);
    epicsFloat64 *pdata = new epicsFloat64[10];
    ...
    floatArray.put(0,10,pdata);
 
=== DbdFieldPutString ===
 
Given an EpicsString, these methods put a value in a Dbf field


// The following is implemented by database access
  class DbdFieldPutString {
  class DbdFieldPutString {
     virtual void primitive(EpicsString *pfrom, dbfType type,
public:
                              void *pstorage) = 0;
     void primitive(EpicsString *pfrom, dbfType type, void *pstorage);
     virtual void string(EpicsString *pfrom,
     void string(EpicsString *pfrom, EpicsString *pEpicsString);
                              EpicsString *pEpicsString) = 0;
     void array(EpicsString *pfrom, DbfArray *parray);
     virtual void array(EpicsString *pfrom,
     void dbfStruct(EpicsString *pfrom, DbfStruct *pstruct);
                              DbfArray *parray) = 0;
     void dbfMDArray(EpicsString *pfrom, DbfMDArray *parray);
     virtual void dbfStruct(EpicsString *pfrom,
                              DbfStruct *pstruct) = 0;
     virtual void dbfMDArray(EpicsString *pfrom,
                              DbfMDArray *parray) = 0;
  }
  }
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>
== Automatically Generated Interfaces ==
</center>


  // For struct definitions
  // For struct definitions
Line 743: Line 717:
  };
  };


// link support modules implement the following interface
Every dbd <tt>struct</tt> and <tt>record</tt> has an associated Lifetime interface implementation.
class DbdLinkSupport {
A tool is provided that automatically generates the implementation from the dbd definition.
public:
 
    virtual void report(iocRecord *precord, DbfLink *pdbfLink) = 0;
<tt>DbdStructLifetime</tt> and <tt>DbdRecordLifetime</tt> each has the following fields:
    virtual bool initialize(iocRecord *precord, DbfLink *pdbfLink) = 0;
; <tt>allocate</tt>
    virtual bool finalize(iocRecord *precord, DbfLink *pdbfLink) = 0;
: Creates storage for the struct or record.
    virtual bool connect(iocRecord *precord, DbfLink *pdbfLink) = 0;
; <tt>destroy</tt>
    virtual bool disconnect(iocRecord *precord, DbffLink *pdbfLink) = 0;
: frees storage
    virtual bool get(iocRecord *precord, DbffLink *pdbfLink,
; <tt>exposeField</tt>
                    epicsType type, void *pfield) = 0;
: 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.
    virtual bool put(iocRecord *precord, DbfLink *pdbfLink,
; <tt>initialize</tt>
                      epicsType type, void *pfield) = 0;
: initializes the struct or record
  };
; <tt>finalize</tt>
: cleans up but does not free storage
 
----
<center>
== Record Support ==
  </center>


  /* record support implements the following*/
  /* record support implements the following*/
Line 770: Line 750:
             ) = 0;
             ) = 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 {
  class DbdUserFieldHandler {
Line 781: Line 781:
  };
  };


=== Discussion of dbdInterfaces ===
This is the interface implemented by code for user extensible fields.


=== <tt>DbdFieldPutString</tt> ===
<tt>DbdUserFieldHandler</tt> has the following fields:
 
This 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>
=== <tt>DbdStructLifetime</tt> and <tt>DbdRecordLifetime</tt> ===
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>
; <tt>initialize</tt>
: initializes the struct or record
: Initialize the user field.
; <tt>finalize</tt>
; <tt>finalize</tt>
: cleans up but does not free storage
: 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>


=== <tt>DbdLinkSupport</tt> ===
// 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.
This is the interface implemented by the support associated with each DBD link.
Line 833: Line 827:
; <tt>put</tt>
; <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.
: 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.
=== <tt>DbdRecordSupport</tt> ===
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.
=== <tt>DbdUserFieldHandler</tt> ===
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.


=== Device Support Interfaces ===


Multiple interface definitions for device support will be defined.
Multiple interface definitions for device support will be defined.

Revision as of 14:10, 20 June 2005

EPICS: dbdClasses - IOC record

June 20 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:

  • dbfTypes.h - Type definitions for field definitions in struct or record> DBD definitions.
  • dbdStatements.h - Type definitions for DBD statements.
  • dbdInterfaces.h - Type definitions for interfaces related to DBD definitions.

dbfTypes

File dbfTypes.h describes types and classes that are used in header files generated from dbd struct or record field definitions. The following naming conventions are used:

C++ struct vs class
A C++ class is used for a class that has methods and struct is used for a class that has only data.
Dbf
any class starting with Dbf describes a field in a generated header file. For example DbfString describes a field generated from field(name,string).
Dbd
A class name starting with Dbd describes something related to dbd definitions. For example DbdLinkSupport describes a dbd link definition.

dbfTypes.h

Every field in the header files generated from DBD struct and record 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
        dbfMenuT,           // DbfMenu
        dbfEnumT,           // DbfEnum
        dbfLinkT,           // DbfLink
        dbfDeviceT          // DbfDevice
        dbfTypeStruct,      // DbfStruct
    };

Discussion of dbfTypes

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(xxx) extends iocRecord {
        ...
        field(fbool,bool)
        field(foctet,octet)
        field(fint,int16)
        ...
        field(ffloat,float64)
        field(fstring,string)
        field(array,array(double[])
        field(mdarray,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 xxxRecord : public iocRecord {
    public:
        epicsBoolean fbool;
        epicsOctet   foctet;
        epicsInt16   fint;
        ...
        epicsFloat64 ffloat;
        EpicsString  fstring;
        DbfArray     array;
        DbfMDArray   mdarray;
        DbfMenu      fmenu;
        DbfEnum      fenum;
        DbfLink      flink;
        DbfDevice    fdevice;
        DbfStruct    displayLimits;
   };

epicsTypes

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.

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.


DbfArray

DbfArray is:

    struct DbfArray {
        dbfType type;
        EpicsArray *parray;
    };
       

DbfMDArray

DbfMDArray is:

Need something like for DbfArray except that convenience classes will be

    class BasicTypeMDArray;
    class OctetMDArray ;
    class Int32MDArray ;
    class Int64MDArray ;
    class Float32MDArray ;
    class Float64MDArray ;
    

DbfMenu

DbfMenu is described as:

    struct DbfMenu{
        epicsInt16    index;
        DbdMenu  *pmenuDef;
    };

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

A field of type DbfMenu is automatically initialized by dbLoadRecords.


DbfEnum

DbfEnum is described as:

    struct DbfEnum{
        epicsInt16  index;
        DbfArray  *pfield; //EpicsArray of epicsTypeString
    };

pfield is the address of a field in the same record that is a DbfArray of type EpicsString. It contains the choices.

A field of type DbfEnum is automatically initialized by dbLoadRecords.


DbfLink and DbdDevice


DbfLink 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 DbfLink are initialized by dbLoadRecords as follows:

dir
This is taken from either the field definition or from the DbdLink definition and is the most restrictive. For example if one says inout and the other says in then dir will be in.
plinkDef
This is the address of the DbdLink.
dataStruct
The describes the data structure specified in the dbd link definition. It contains data used by the link support.

Link support always implements interface DbdLinkSupport

A DbfDevice is similar to a DbfLink except that the interface implemented by the device support is also specified, i.e. instead of implementing interface DbdLinkSupport, the device support implements an interface that both record support and device support understand.



DbfStruct

DbfStruct is described as

    struct DbfStruct {
        DbdStruct *pdescription;
        void      *pstorage;
    };

The fields of DbfStruct are initialized by dbLoadRecords as follows:

pdescription
This is initialized via the structure name specified in field definition.
pstorage
This is initialized by calling DbdStructLifetime:allocate

dbdStatements

The definitions in dbdStatements.h allow introspection of ioc records. They describe everything defined in DBD definitions.

The following contain the following undefined definitions:

NODE and LIST specify a doubly linked list. An implementation is not specified.

The following:

    class Interface {}; // Must be an interface, i.e. pure abstract class

Represents an unspecified interface.

DbdMenu

    struct DbdMenu{
        NODE        node; // for DbdBase:menuList
        EpicsString name;
        epicsInt16  nchoices;
        EpicsString *pchoice[];
    };

The fields of DbdMenu are:

node
node for DbdBase:menuList
name
The menu name.
nchoices
The number of menu choices.
pchoice
The address of an array of pointers to EpicsString. Each EpicsString is a choice.

DbdLink and DbdDevice

    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 link definition is described by DbdLink

node
This is a node for DbdLinkList
dir
The link direction
choiceName
The name that connects a DbdLink to a DbfLink instance.
dataStructName
The class name of an DbdStruct for the Interface implementation
pinterface
The address of the DbdLinkSupport Interface implementation.

Each dbd device definition is described by DbdDevice

node
This is a node for DbdDeviceList
dir
The link direction
choiceName
The name that matches a DbdDevice to a DbfDevice instance.
dataStructName
The class name of an EpicsStruct for the Interface implementation
interfaceName
The name of the interface type implemented by the device support
pinterface
The address of the Interface implementation.

DbdStruct and DbdRecord

    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         *pafield;//ptr to array of DbdField
        DbdStructLifetime *plifetime;
    };


    struct DbdRecord { // describes a record
        NODE              node; // for DbdBase:recordList
        LIST              instanceList;
        const char        *name;
        epicsInt16        nfields;
        DbdField          *pafield;//ptr to array of DbdField
        DbdRecordSupport  *psupport;
        DbdRecordLifetime *plifetime;
    };

The following describe the fields in a dbd struct or record definition: DbdStruct, DbdRecord, DbdField,and DbdAttribute

The fields of DbdStruct are:

node
node for DbdBase:structList
name
The name of the struct.
nfields
The number of fields, e.g. fields in the structure.
pafields
pointer to an array of DbdField.
plifetime
The address of an implementation of interface DbdStructLifetime. The implementation is automatically generated from the dbd struct. See below for a description of the Lifetime methods.

The fields of DbdRecord are;

node
node for DbdBase:recordList
instanceList
list of instances of this record type
name
The name of the record type.
nfields
The number of fields, e.g. fields in the record.
pafields
pointer to an array of DbdField.
psupport
The address of the DbdRecordSupport for this record type.
plifetime
The address of an implementation of interface DbdRecordLifetime. The implementation is automatically generated from the dbd record statement. See below for a description of the Lifetime methods.


The fields of DbdField are:

name
The name of the field
type
The dbfType of the field.
defaults
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.
attribute
DbdAttribute for the field

The fields of DbdAttribute are:

default
An EpicsString providing a default value for the field.
readonly
Is the field readonly?
design
Is the field a design fields for DCTs?
special
Should DbdRecordSupport:special be called if the field is modified.
dynamic
Can the field change because of record processing?
asl
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 userField definition has an associated class DbdUserField with fields:

node
This is a node for DbdUserFieldList
choiceName
The name that matches a DbdUserField to a DbdUserFieldInstance
type
The epicsType for the user field
dataStructName
The class name of an EpicsStruct for the DbdUserFieldHandler
pinterface
The address of the DbdUserFieldHandler implementation.


A record instance has two associated classes:DbdUserFieldInstance and DbdRecordInstance.

DbdUserFieldInstance contains information for a user defined field:

node
A node for list DbdRecordInstance.userField
name
The name of the user defined field, i.e. the psuedo field name
sourceType
the type of the field of the record that DbdUserFieldHandler accesses.
psource
The address of the field that DbdUserFieldHandler accesses.
pDbdUserField
The DbdUserField that describes the field
pstorage
Address of storage for the dbfType.
dataStruct
An DbfStruct that holds the private data for the DbdUserFieldHandler.

The fields of DbdRecordInstance are:

node
A node for list DbdRecord.instanceList
pDbdRecord
address of the DbdRecord describing the record
pstorage
address of the storage for the record instance
name
The name of the record instance
userField
DbdUserFieldInstance list for the record instance.


Base

    struct DbdBase {
        LIST structList;
        LIST recordList;
        LIST menuList;
        LIST linkList;
        LIST deviceList;
        LIST userFieldList;
   };


The following provide lists of various things:

structList
The list of each struct definition
recordList
The list of each record type definition
menuList
The list of each menu definition
linkList
The list of each link definition
deviceList
The list of each device definition
userFieldList
The list of each DbdUserField definition

Introspection

This section describes interfaces provided by iocCore for locating information related to Dbf and Dbd 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);
        DbdRecordInstance &recordInstance(EpicsString &name);
        void registerRecordSupport(EpicsString &name,
                 DbdRecordSupport &support);
        void registerLinkSupport(EpicsString &choiceName,
                 EpicsString &dataStructName, DbdLinkSupport &support);
        void registerDeviceSupport(EpicsString &choiceName,
                 EpicsString &dataStructName, EpicsString &interfaceName,
                 DbdLinkSupport &support);
    };
    DbdLocate *pDbdLocate;

Field access

This section describes interfaces provided by iocCore for modifying fields in database reords.

DbfArray access

Classes are provided for accessing DbfArray fields that are arrays of aany of the following primitive types: octet, int, float.

    class BasicTypeArray {
    public:
        BasicTypeArray(DbfArray &array);
        BasicTypeArray(DbfArray &array,
                   const char *bufferType, epicsInt32 capacity);
        BasicTypeArray(DbfArray &array,
                   BufferCreator *creator, epicsInt32 capacity);
        virtual ~BasicTypeArray();
        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;
    protected:
        DbfArray &array;
    private:
        BasicTypeArray(const EpicsBasicTypeArray &);// No copy constructor
        // No assignment operator
        BasicTypeArray& operator=(const EpicsBasicTypeArray &);
    };


    class Int16Array : public BasicTypeArray{
    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);
        // 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:
        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 Int64Array ;
    class Float32Array ;
    class Float64Array ;

An example of how the convience classes are used is:

    Float64Array  dbfArray;
    ...
    Float64Array floatArray(dbfArray);
    epicsFloat64 *pdata = new epicsFloat64[10];
    ...
    floatArray.put(0,10,pdata);

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;

DbdFieldPutString is an interface, which has an implementation provided by iocCore, that convert an EpicsString to an dbfType.

The methods are:

primitive
This convert a string to one of the types: epicsBoolean, ..., epicsFloat64
string
Copies an EpicsString to an EpicsString
array
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 DbfArray
dbfStruct
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 DbfStruct
dbfMDArray
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 DbfMDArray

Automatically Generated Interfaces

// 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) = 0;
};

Every dbd struct and record has an associated Lifetime interface implementation. A tool is provided that automatically generates the implementation from the dbd definition.

DbdStructLifetime and DbdRecordLifetime each has the following fields:

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

Record Support

/* 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. DbdRecordSupport has the following methods:

initBuffers
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.
initConnections
This is called to connect to external sources. It may call associated support to make the connections.
breakConnections
This is called to disconnect to external sources. It may call associated support to break the connections.
process
Process the record.
special
This is called whenever an external source modifies a field with attribute special set to true.

User Field Support

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.

DbdUserFieldHandler has the following fields:

initialize
Initialize the user field.
finalize
undo what was done during initialization
process
Called near the end of record processing just before monitors are handled.

Link and Device Support

// 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.

DbdLinkSupport has the following methods:

report
generate a report about the link instance
initialize
perform initialization but do not connect
finalize
undo initialization. It is assumed that disconnect has already been called.
connect
connect to external source of data
disconnect
disconnect from external source of data
get
get a value from the external source. type specified the field type and pfield is the address of where to store the data.
put
put a value from the external source. type specified the field type and pfield 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.