Difference between revisions of "V4 Design: dbdClass"

From EPICSWIKI
(Still modifying)
 
(22 intermediate revisions by the same user not shown)
Line 1: Line 1:
== EPICS: C++ class definitions for Database Definition ==
This page is obsolete. It is replaced by dbdInterfaces.
 
May 17 2005
 
<center>
 
== Overview ==
 
</center>
 
This document describes the C++ class definitions for code that implements
the semantics for records created from Database Definitions. The definitions
are intended for code that:
* includes header files generated from dbd definitions.  Header files are generated from the following dbd definitions:
** <tt>record</tt> 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.
 
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>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>dbdInterfaces.h</tt> - Type definitions for interfaces related to DBD definitions.
 
----
<center>
 
== epicsTypes ==
 
</center>
=== <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.
 
In addition two extra types are defined:
* epicsUnknownT - Unknown
* epicsOctetT - An 8 bit byte.
 
<tt>epicsTypes.h</tt> 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 <tt>long</tt> rather than a <tt>long long</tt>.
<tt>epicsTypeUnknownT</tt> is reserved for unknown types and will normally be cause by some configuration error.
 
----
<center>
 
== dbdTypes ==
</center>
 
File <tt>dbdTypes.h</tt> describes types and classes related to
dbd <tt>struct</tt> or <tt>record</tt> 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.
 
=== <tt>dbdTypes.h</tt> ===
<tt>dbdTypes.h</tt> 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 ====
<tt>DbfString</tt> is described as:
    class DbfString {
    public:
        dbfInt32  capacity;  /*capacity in bytes*/
        dbfOctet  *pstorage;
    };
If a record definition contains
    field(sfield,string)
Then the generated header file contains
    DbfString sfield;
 
<tt>pstorage</tt> 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.
 
==== DbfStruct ====
 
<tt>DbfStruct></tt> 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;
<tt>pstruct</tt> is the address of storage for the structure and <tt>pstructDef</tt> is the address of a description of the structure. StructDbdDef is described in <tt>dbdStatatements.h</tt>
 
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 ====
<tt>DbfMenu></tt> is described as:
    class DbfMenu{
    public:
        dbfInt16    index;
        MenuDbfDef  *pmenuDef;
    };
 
If a record definition contains
    field(fmenu,menu(name))
Then the generated header file contains
    DbfMenu fmenu;
<tt>DbfMenu</tt> provides the current menu index and also the menu definition.
 
==== DbfEnum ====
<tt>DbfEnum></tt> 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 ====
<tt>DbfLink</tt> 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 <tt>link</tt> definition that matches the <tt>dir</tt> specified in the dbd <tt>field</tt> definition.
 
The fields of <tt>DbfLink</tt> are initialized as follows:
; <tt>dir</tt>
: This is taken from either the <tt>field</tt> definition or from the <tt>LinkDbd</tt> definition and is the most restrictive. For example if one says inout and the other says in then <tt>dir</tt> will be in.
; <tt>choiceName</tt>
: The record instance specifies this and it is used to locate the associated dbd <tt>link</tt> definition.
; <tt>plinkDef</tt>
: This is the address of the <tt>LinkDbd</tt>.
; <tt>dataStruct</tt>
: The describes the data structure specified in the dbd <tt>link</tt> definition. It contains data used by the link support.
 
Note that link support always implements interface <tt>LinkDbdSupport</tt>
==== dbdDevice ====
 
A <tt>dbdDevice</tt> is similar to a <tt>dbdLink</tt> except that the interface implemented by the device support is also specified, i.e. instead of implementing interface <tt>LinkDbdSupport</tt>, the device support implements an interface that both record support and device support understand.
 
 
----
<center>
 
== dbdStatements ==
 
</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> 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 <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:
; <tt>name</tt>
: The name of the struct.
; <tt>plifetime</tt>
: The address of an implementation of interface <tt>StructDbdLifetime</tt>. The implementation is automatically generated from the dbd <tt>struct</tt> statement. See below for a description of the <tt>StructDbdLifetime</tt> methods.
; <tt>nfields</tt>
: The number of fields, e.g. fields in the structure.
; <tt>pfields</tt>
: pointer to an array of pointers to <tt>StructDbdField</tt>. Each StructDbdField contains the name and type of the fields.
 
The fields of <tt>StructDbdField</tt> are:
; <tt>name</tt>
: The name of the field
; <tt>type</tt>
: The dbfType for the field.
; <tt>pattribute</tt>
: The address of a StructFieldAttribute for the field
 
<tt>StructFieldAttribute</tt> has the attribute values for the field.
 
==== Menu ====
 
A dbd <tt>menu</tt> is described by the classes: MenuDbdDef and MenuDbdChoice
 
The fields of MenuDbdDef are:
; <tt>name</tt>
: The menu name.
; <tt>nchoices</tt>
: The number of menu choices.
; <tt>pchoice</tt>
: The address of an array of pointers to choices
 
The fields of MenuDbdChoice described a single choice:
; <tt>choiceName</tt>
: The choice name, i.e. the C++ variable name that appears in the generated enum statement for the menu
; <tt>menuName</tt>
: The menu choice that DCTs and the value returned when the menu choice strings are requested.
 
==== Link and Device ====
 
Each dbd <tt>link</tt> definition has an associated class LinkDbd with fields:
; <tt>dir</tt>
: The link direction
; <tt>choiceName</tt>
: The name that to find a LinkDbd for a DbfLink instance.
; <tt>dataStructName</tt>
: The class name of a DbfStruct for the Interface implementation
; <tt>pinterface</tt>
: The address of the Interface implementation. The interface class is LinkDbdSupport
 
Each dbd <tt>device</tt> definition has an associated class DeviceDbd with fields:
; <tt>dir</tt>
: The link direction
; <tt>interfaceName</tt>
: The name of the interface class implemented by the device support
; <tt>choiceName</tt>
: The name that to find a LinkDbd for a DbfLink instance.
; <tt>dataStructName</tt>
: The class name of a DbfStruct for the Interface implementation
; <tt>pinterface</tt>
: 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>
 
== 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>
 
=== <tt>dbdInterfaces.h</tt> ===
<tt>dbdInterfaces.h</tt> contains the following:
 
// every struct and every record support module implements the following
// The implementation is generated from the dbd definition
class StructDbdLifetime {
public:
    virtual StructDbdPtr create() = 0;
    virtual bool initialize(dbfString *errorMessage,
                              StructDbdPtr ptr) = 0;
    virtual bool finalize(dbfString *errorMessage,
                              StructDbdPtr ptr) = 0;
    virtual void destroy(StructDbdPtr ptr) = 0;
    virtual void *indexToAddr(dbfString *errorMessage,
                              StructDbdPtr ptr, dbfInt16 index) = 0;
    // ???? is anything else needed
};
 
// every link support module implements the following interface
class LinkDbdSupport {
public:
    virtual void report(dbfString *errorMessage,
                      iocRecord *precord, dbfLink *pdbfLink) = 0;
    virtual bool initialize(dbfString *errorMessage,
                      iocRecord *precord, dbfLink *pdbfLink) = 0;
    virtual bool finalize(dbfString *errorMessage,
                      iocRecord *precord, dbfLink *pdbfLink) = 0;
    virtual bool connect(dbfString *errorMessage,
                      iocRecord *precord, dbfLink *pdbfLink) = 0;
    virtual bool disconnect(dbfString *errorMessage,
                      iocRecord *precord, dbfLink *pdbfLink) = 0;
    virtual bool get(dbfString *errorMessage,
                      iocRecord *precord, dbfLink *pdbfLink,
                      dbfType type, FieldDbdPtr pfield) = 0;
    virtual bool put(dbfString *errorMessage,
                      iocRecord *precord, dbfLink *pdbfLink,
                      dbfType type, FieldDbdPtr pfield) = 0;
};
 
/* record support implements the following*/
class RecordDbdSupport {
public:
    virtual iocRecord *create(dbfString *errorMessage) = 0;
    virtual bool destroy(dbfString *errorMessage, iocRecord *precord) = 0;
    virtual bool init(dbfString *errorMessage,
                      iocRecord *precord, bool firstPass) = 0;
    virtual void special(iocRecord *precord, iocRecord *precord,
            bool  after,
            dbfInt16 nlevels, // number of elements in fieldIndex
            dbfInt16 fieldIndex[] // array of field indices
            ) = 0;
};
 
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 ===
==== <tt>StructDbdLifetime</tt> ====
Every dbd <tt>struct</tt> and <tt>record</tt> has an associated <tt>StructDbdLifetime</tt> interface implementation. A tool is provided that automatically generates the implementation form the dbd definition.
<tt>StructDbdLifetime</tt> has the following fields:
; <tt>create</tt>
: Creates storage for the struct or record.
; <tt>initialize</tt>
: initializes the struct or record
; <tt>finalize</tt>
: cleans up but does not free storage
; <tt>destroy</tt>
: frees storage
; <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.
 
==== <tt>LinkDbdSupport</tt> ====
This describes the interface implemented by link support.
==== <tt>RecordDbdSupport</tt> ====
This is the interface implemented by record support.
==== <tt>UserFieldHandler</tt> ====
This is the interface implemented by code for user extensible fields.
 
----
<center>
 
== Example of Generated Header Files ==
 
</center>
 
=== Database Definition Files ===
 
<tt>menuAlarmSevr.dbd</tt> contains:
    menu(menuAlarmSevr) {
          choice(menuAlarmSevrNO_ALARM,"NO_ALARM")
          choice(menuAlarmSevrMINOR,"MINOR")
          choice(menuAlarmSevrMAJOR,"MAJOR")
          choice(menuAlarmSevrINVALID,"INVALID")
    }
 
<tt>displayLimit.dbd</tt> contains:
    struct(displayLimit) {
        field(low,float64)
        field(high,float64)
    }
<tt>exampleRecord.dbd</tt> contains:
    record(example) extends iocRecord {
        field(value,float64)
        field(displayLimit,struct(displayLimit))
    }
<tt>alltypesRecord.dbd</tt> contains:
    record(allTypes) extends iocRecord {
        field(fbool,bool)
        field(foctet,octet)
        field(fint16,int16)
        field(fuint16,uint16)
        field(fint32,int32)
        field(fuint32,uint32)
        field(fint64,int64)
        field(fuint64,uint64)
        field(ffloat32,float32)
        field(ffloat64,float64)
        field(fstring,string)
        field(fmenu,menu(menuName))
        field(fenum,enum)
        field(fstruct,struct(displayLimit))
        field(flink,link(dir))
        field(fdevice,device(dir,interfaceName))
    }
=== Generated Header Files ===
Tools are provided to generate header files from the following dbd definitions:
*menu
*struct
*record
<tt>menuAlarmSevr.h</tt> is generated from <tt>menuAlarmSevr.dbd</tt>
    enum menuAlarmSevr {
            menuAlarmSevrNO_ALARM,
            menuAlarmSevrMINOR,
            menuAlarmSevrMAJOR,
            menuAlarmSevrINVALID
    };
<tt>displayLimit.h</tt> is generated from <tt>displayLimit.dbd</tt>
    class displayLimit {
    public:
        dbfFloat64 low;
        dbfFloat64 high;
    };
    const dbfInt16 displayLimit_firstIndex = 1
    const dbfInt16 displayLimit_low        = 1
    const dbfInt16 displayLimit_high      = 2
    const dbfInt16 displayLimit_lastIndex =displayLimit_high
<tt>exampleRecord.h</tt> is generated from <tt>exampleRecord.dbd</tt>
    class exampleRecord {
    public:
        ...    All the fields from iocRecord.dbd
        dbfFloat64 value;
        dbfStruct  displayLimit;
    };
   
    const dbfInt16 example_firstIndex = 1001001
    const dbfInt16 example_low = 1001001;
    const dbfInt16 example_high = 1001002;
    const dbfInt16 example_lastIndex = example_high;
<tt>alltypesRecord.h</tt> is generated from <tt>alltypesRecord.dbd</tt>
    class allTypesRecord {
    public:
        ...    All the fields from iocRecord.dbd
        iocRecord  common;
        dbfBoolean fbool;
        dbfOctet  foctet;
        dbfInt16  fint16;
        dbfUInt16  fuint16;
        dbfInt32  fint32;
        dbfUInt32  fuint32;
        dbfInt64  fint32;
        dbfUInt64  fuint32;
        dbfFloat32 ffloat32;
        dbfFloat64 ffloat64;
        dbfString  fstring;
        dbfMenu    fmenu;
        dbfEnum    fenum
        dbfStruct  fstruct;
        dbfLink    flink;
        dbfDevice  fdevice;
    };
   
    const dbfInt16 allTypes_firstIndex = 1001001
    const dbfInt16 allTypes_fbool = 1001001;
    const dbfInt16 allTypes_foctet = 1001002;
    const dbfInt16 allTypes_fint16 = 1001003;
    const dbfInt16 allTypes_fuint16 = 1001004;
    const dbfInt16 allTypes_fint32 = 1001005;
    const dbfInt16 allTypes_fuint32 = 1001006;
    const dbfInt16 allTypes_fint64 = 1001007;
    const dbfInt16 allTypes_fuint64 = 1001008;
    const dbfInt16 allTypes_ffloat32 = 1001009;
    const dbfInt16 allTypes_ffloatn64 = 10010010;
    const dbfInt16 allTypes_ffstring = 10010011;
    const dbfInt16 allTypes_fmenu = 10010012;
    const dbfInt16 allTypes_fenum = 10010013;
    const dbfInt16 allTypes_fstruct = 10010014;
    const dbfInt16 allTypes_flink = 10010015
    const dbfInt16 allTypes_fdevice = 10010016
    const dbfInt16 allTypes_lastIndex = allTypes_fdevice;
 
----

Latest revision as of 19:53, 11 August 2005

This page is obsolete. It is replaced by dbdInterfaces.