From: thor@arrakis.denver.co.us (Robert B. Hood)
Subject: cBASE - Part 2 of 4
Summary: A dBASE III+ Class in C++
Reply-To: thor@arrakis.denver.co.us
Organization: Bob's Programming Paradise, Lakewood, CO, USA
Date: Thu, 10 Sep 1992 13:43:13 GMT

------------------------ CBASE.HPP ----------------------------------
// cBASE - A dBASE III+ class for accessing and manipulating .DBF files.
//                Copyright (C) 1992 Bob Hood
//
// Author      : Bob Hood (thor@arrakis.denver.co.us)
// Last Update : 08.01.92
// Header Files: cBASE.HPP
// Comments    : Class is still under construction, so use at your own risk.
//
//               You are free to copy and distribute this code as long as
//               you do not charge a fee for it, and the Copyright notice
//               above remains intact.

#ifndef TRUE
    #define TRUE    1
    #define FALSE   0
#endif

#define NO_PROBLEM                  0
#define DOS_OPEN_ERROR              -1
#define DOS_WRITE_ERROR             -2
#define DOS_READ_ERROR              -3
#define ALREADY_OPEN_ERROR          -4
#define NO_DB_OPEN_ERROR            -5
#define INVALID_RECORD_ERROR        -6
#define INVALID_FIELD_NAME_ERROR    -7
#define INVALID_FIELD_NUM_ERROR     -8
#define FILE_LOCK_FAILED_ERROR      -9
#define FILE_UNLOCK_FAILED_ERROR    -10
#define RECORD_LOCK_FAILED_ERROR    -11
#define RECORD_UNLOCK_FAILED_ERROR  -12
#define RECORD_NOT_LOCKED_ERROR     -13

typedef unsigned int  INT;
typedef unsigned long LONG;
typedef unsigned char BYTE;

typedef struct field_rec
    {
        char        field_name[11];
        char        field_type;
        char        dummy[4];

        union
        {
            INT         char_len;
            struct
            {
                char    len;
                char    dec;
            } num_size;
        } len_info;

        char        filler[14];
    } FIELD_REC;

typedef struct dbf_head
    {
        char        dbf_id;
        char        last_update[3];
        LONG        last_rec;
        INT         data_offset;
        INT         rec_size;
        char        filler[20];
    } DBF_HEAD;

typedef struct index_chain
    {
        struct  index_chain *prev;
        LONG    record;
        union
        {
            char    textKey[100];
            long    longKey;
            float   floatKey;
            int     logicalKey;
        } key;
        struct  index_chain *next;
    } INDEX_CHAIN;

typedef struct index_header
    {
        int         index_field;
        INDEX_CHAIN *current_record;
        INDEX_CHAIN *index_chain;
    } INDEX_HEADER;

typedef struct relation
    {
        struct  relation *next;
        int     field_num;
        int     into_area;
    } RELATION;

typedef struct field_data
    {
        struct  field_data *next;
        int     field_type;

        union
        {
            char    boolean;
            char    text[256];
            long    long_number;
            struct
            {
                int     month;
                int     day;
                int     year;
            } date;
            struct
            {
                float   number;
                char    format[10];
            } float_number;
        } data;
    } FIELD_DATA;

typedef struct area
    {
        char        db_name[80];
        char        alias[40];
        int         database;
        LONG        current_record;
        int         num_fields;
        LONG        field_list_offset;
        LONG        data_records_offset;
        DBF_HEAD    dbf_head;
        FIELD_REC   *field_rec;
        RELATION    *relation_list;
        INDEX_HEADER index;
        void        *record_hold;
        FIELD_DATA  *field_data;
        int         deleted;
    } AREA;

class dBASE
    {
        AREA        data;
        int         eof_met;            // boolean
        int         bof_met;            // boolean
        int         file_locked;        // boolean
        int         record_locked;      // boolean
        long        dbSize;
        int         db_err;     // this is used by routines that don't return `int'
        int         net_err;    // hold any network errors there may be...

        int         getStructure(void);
        FIELD_DATA  *newDBField(void);
        void        clearDBFields(void);
        int         writeRecord(void);
        int         b2f(void);
        void        *getRecord(void);
        int         f2b(void);
        void        grab(char *from, char *to, char *dest);
        int         lock(int file,long offset,long length,int function);

public:
        int         update;
        FIELD_DATA  *field_list;

        // constructor/destructor cannot have return types (not even `void')

                    dBASE();
                    ~dBASE() { deactivate(); }  // use public function...

        int         activate(char *db_name,char *alias);
        int         deactivate(void);
        int         gotoRecord(LONG rec_number,int = FALSE);
        int         goTop(void);
        int         goBottom(void);
        int         getRecordLen(void);
        LONG        currRecord(void);
        LONG        lastRecord(void);
        int         deleteRecord(void);
        int         recallRecord(void);
        void        listInfo(void);
        char        *alias(void);
        int         newRecord(int = FALSE);
        void        printDBFields(void);
        void        skip(LONG = 1L);    // default to one record forward
        int         eof(void);
        int         bof(void);
        int         indexOn(int);
        int         indexOn(char *);
        void        killIndex(void);
        int         fLock(void);
        int         fUnLock(void);
        int         rLock(void);
        int         rUnLock(void);
        int         getDBErr(void);
        int         getNetErr(void);
        FIELD_DATA  *getField(char *);
        FIELD_DATA  *getField(int);
    };


-------------------------- end CBASE.HPP ------------------------
-- 
Bob Hood    thor@arrakis.denver.co.us     H: 303-980-8392  W: 303-632-2180
---------------------------------------------------------------------------
When people are free to do as they please, they usually imitate each other.