home *** CD-ROM | disk | FTP | other *** search
- /* ==( io/src/icodebse.c )== */
-
- /* ----------------------------------------------- */
- /* Pro-C Copyright (C) 1988 - 1990 Vestronix Inc. */
- /* Modification to this source is not supported */
- /* by Vestronix Inc. */
- /* All Rights Reserved */
- /* ----------------------------------------------- */
- /* Written NA 24-Feb-88 */
- /* Modified VV 12-Apr-90 See comments below */
- /* ----------------------------------------------- */
- /* %W% (%H% %T%) */
-
- /*
- * Modifications
- *
- * 12-Apr-90 VvA - correction to next/prev fns at EOF/TOF
- * 28-Mar-90 VvA - adjustments for locking modes, transactions
- * 12-Feb-90 VvA - adjustment to PACK request
- * 01-Feb-90 VvA - fld_cnt now in iogen.c, fd[] struct
- * 01-Feb-90 VvA - Enabled openmode in open_file()
- * 26-Jan-90 VvA - CLIPPER support thru assign_IO_CL
- * 15-Dec-89 VvA - V.2 modifications
- * 01-Sep-89 VvA - Added date, memo, logical dBASE fields
- * 01-Sep-89 VvA - Modified for generic I/O interface
- * 01-Apr-89 VvA - Adapted for CodeBase4 from dBC III+
- * 01-Sep-88 VvA - Adapted for dBASE/dBC III+
- */
-
- /* CodeBase 4 I/O calls via general IOGEN.C interface */
-
-
- # include <stdio.h>
- # include <d4base.h>
- # include <iodef.h>
- # include <iomsg.h>
- # include <proc.io>
- # include <bench.h>
- # include <iosup.h>
-
-
- #define TIMEOUTMAX 500 /* lock attempts before giving up */
- #define CBERROR -1 /* signals CodeBase error */
- #define DBFINACT '*' /* dBASE deletion flag */
- #define DBFNULL (BASE *)0 /* null database ptr for CodeBase */
-
-
- /* Function prototypes */
- # ifdef ANSI
- static int i_addrec(int, char *);
- static int i_close_file(int, char *);
- static int i_commit(int, char *);
- static int i_delrec(int, char *);
- static int i_filename(int, char *);
- static int i_findkey(int, char *);
- static int i_firstkey(int, char *);
- static int i_init_file(int, char *);
- static int i_lastkey(int, char *);
- static int i_lockrec(int, char *);
- static int i_login(int, char *);
- static int i_logoff(int, char *);
- static int i_nextrec(int, char *);
- static int i_open_file(int, char *);
- static int i_prevrec(int, char *);
- static int i_rereadrec(int, char *);
- static int i_rollback(int, char *);
- static int i_selectinx(int, char *);
- static int i_transact(int, char *);
- static int i_unlock_rec(int, char *);
- static int i_updrec(int, char *);
- static int create_file(int, char *, int);
- static int load_keys(int, int);
- static int create_index(int, int, char *);
- static int length_check(int);
- static int setupkey(int, char *, char *);
- static int get_record(int, char *, int);
- static int put_record(int, char *);
- static int io_xlate(int, int, char *);
- # else
- static int i_addrec();
- static int i_close_file();
- static int i_commit();
- static int i_delrec();
- static int i_filename();
- static int i_findkey();
- static int i_firstkey();
- static int i_init_file();
- static int i_lastkey();
- static int i_lockrec();
- static int i_login();
- static int i_logoff();
- static int i_nextrec();
- static int i_open_file();
- static int i_prevrec();
- static int i_rereadrec();
- static int i_rollback();
- static int i_selectinx();
- static int i_transact();
- static int i_unlock_rec();
- static int i_updrec();
- static int create_file();
- static int load_keys();
- static int create_index();
- static int length_check();
- static int setupkey();
- static int get_record();
- static int put_record();
- static int io_xlate();
- # endif
-
-
- extern int v4error; /* CodeBase error code */
-
- #ifdef TC
- extern unsigned _stklen = 10000; /* default stack size for Turbo C */
- #endif
-
-
- /*
- * structure for CodeBase-specific values
- */
- struct dbf_def
- {
- long recnum; /* current CodeBase record for this file */
- int dbrec_len; /* record length of dBASE type record */
- long fld_ref[MAX_FLDS];
- int ndx_num[MAX_KEYS];
- };
-
-
- static struct dbf_def fdbf[MAX_FILES];
- static int enable_clipper;
-
-
- /*
- *
- * Interface Functions
- *
- */
-
-
- /*
- * Sets up File Name extension.
- */
- static int i_filename(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- for ( ; (*buffer != '.') && (*buffer != NULL); buffer++)
- ;
- *buffer = NULL;
-
- return(IOGOOD);
- }
-
- /*
- * File initialization
- */
- static int i_init_file(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(IOGOOD);
- }
-
- /*
- * File open function
- */
- static int i_open_file(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int stat;
- char dbfname[FILENAME_LEN];
- struct fd_def *fptr = &fd[fd_sys];
- struct dbf_def *dptr = &fdbf[fd_sys];
-
- strcpy(dbfname, fptr->filname);
- strcat(dbfname, ".DBF"); /* dBASE III type filename from filname */
-
- if (fptr->openmode & OUTPUT_FLAG)
- create_file(fd_sys, dbfname, 0); /* if OUTPUT, delete existing files */
-
- if (access(dbfname, 0) == IOGOOD) /* if the file exists... */
- {
- if ((stat = d4use(dbfname)) == CBERROR)
- return(io_xlate(fd_sys, v4error, "CB4 OPEN1"));
-
- fptr->fd_num = stat; /* file has opened successfully */
- }
- else if (!(fptr->openmode & INPUT_FLAG))
- {
- if (create_file(fd_sys, dbfname, 1) != IOGOOD)
- return(IOERROR);
- }
- else
- return(io_xlate(fd_sys, v4error, "CB4 OPEN2"));
-
- if (length_check(fd_sys) != IOGOOD)
- {
- i_close_file(fd_sys, buffer);
- return(IOERROR);
- }
-
- return(IOGOOD);
- }
-
- /*
- * CodeBase create file function
- * - file will be opened by the create call, stat is the file descriptor
- */
- static int create_file(fd_sys, dfname, saf)
- int fd_sys; /* index into fd table */
- char *dfname;
- int saf; /* 0 to destroy old file, 1 to retain it */
- {
- int stat, j, foffset = 1;
- FIELD *fldtmp;
- struct fd_def *fptr = &fd[fd_sys];
- struct dbf_def *dptr = &fdbf[fd_sys];
-
- fldtmp = (FIELD *)alloc(sizeof(FIELD) * fptr->fld_cnt);
-
- for (j = 0; j < fptr->fld_cnt; j++) /* load field descriptions */
- {
- strcpy(fldtmp[j].name, cvt_upper(fptr->flds[j].fldname));
- fldtmp[j].offset = foffset;
- fldtmp[j].decimals = (char)0;
- switch(fptr->flds[j].fldtype)
- {
- case CHRTYP :
- fldtmp[j].type = (int)'C';
- fldtmp[j].width = (char)fptr->flds[j].fldlen;
- break;
- case INTTYP :
- case LNGTYP :
- case FLTTYP :
- case DBLTYP :
- fldtmp[j].type = (int)'N';
- fldtmp[j].width = (char)nummasklen(fptr->flds[j].fldmask);
- fldtmp[j].decimals = (char)decmasklen(fptr->flds[j].fldmask);
- break;
- case DATTYP :
- if (fptr->flds[j].fldlen == 6)
- {
- fldtmp[j].type = (int)'D';
- fldtmp[j].width = (char)8;
- }
- else
- {
- fldtmp[j].type = (int)'N';
- fldtmp[j].width = (char)10;
- fldtmp[j].decimals = (char)0;
- }
- break;
- case LOGTYP :
- fldtmp[j].type = (int)'L';
- fldtmp[j].width = (char)1;
- break;
- case MEMTYP :
- fldtmp[j].type = (int)'M';
- fldtmp[j].width = (char)10;
- break;
- }
- foffset += fldtmp[j].width;
- }
-
- if ((stat = d4create(dfname, fptr->fld_cnt, fldtmp, saf)) == CBERROR)
- {
- free(fldtmp);
- return(io_xlate(fd_sys, v4error, "CB4 CRT1"));
- }
- free(fldtmp);
-
- fptr->fd_num = stat; /* created file is also opened now */
-
- return((load_keys(fd_sys, TRUE) > 0) ? IOGOOD : IOERROR);
- }
-
- /*
- * Key load function - creates or opens indexes for new files
- * - if creatndx is TRUE, index will be created, otherwise it is opened
- */
- static int load_keys(fd_sys, creatndx)
- int fd_sys, creatndx;
- {
- int stat, ndxid, n;
- char ndxname[FILENAME_LEN];
- struct fd_def *fptr = &fd[fd_sys];
-
- strcpy(ndxname, fptr->filname); /* index names match their file names */
- if ((ndxid = strlen(ndxname)) > 7) /* ndxid is index id offset */
- ndxid = 7;
- ndxname[ndxid] = '\0';
-
- if (enable_clipper) /* if assign_IO_CL() called from applicn */
- strcat(ndxname, "0.NTX");
- else
- strcat(ndxname, "0.NDX");
-
- n = 0;
- while (fptr->keys[n].segcount != -1)
- {
- ndxname[ndxid] = (char)(n + 49); /* sequential index name suffix */
-
- if (creatndx) /* create the indexes */
- {
- if ((stat = create_index(fd_sys, n, ndxname)) < 0)
- return(stat); /* if negative return, no index created */
- }
- else if ((stat = i4open(ndxname)) == CBERROR) /* open indexes */
- return(io_xlate(fd_sys, v4error, "CB4 IXOPEN")); /* returns neg */
-
- fdbf[fd_sys].ndx_num[n] = stat;
- n++; /* & increment key number */
- }
-
- return(n); /* value returned is the number of keys */
- }
-
- /*
- * Index create function
- */
- static int create_index(fd_sys, n, ndxname)
- int fd_sys, n;
- char *ndxname;
- {
- int stat, m, fx;
- char keyname[FLDNAME_LEN * MAX_SEGS * 3], fmtstr[12];
- struct fd_def *fptr = &fd[fd_sys];
-
- keyname[0] = '\0';
- for (m = 0; m < fptr->keys[n].segcount; m++)
- {
- fx = fptr->keys[n].fldindex[m];
-
- if (m > 0)
- strcat(keyname, "+");
- if (fptr->keys[n].segcount == 1) /* no conversion for simple key */
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- else
- { /* for compound key all types are strings */
- switch(fptr->flds[fx].fldtype)
- {
- case CHRTYP :
- if (fptr->flds[fx].fldlen == fptr->keys[n].seglen[m])
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- else
- {
- strcat(keyname, "SUBSTR(");
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- zerorec(fmtstr, 12);
- sprintf(fmtstr, ",%d,%d)",
- (fptr->keys[n].segstart[m]+1 - fptr->flds[fx].fldstart),
- fptr->keys[n].seglen[m]);
- strcat(keyname, fmtstr);
- }
- break;
- case DATTYP :
- if (fptr->flds[fx].fldlen == 6)
- {
- strcat(keyname, "DTOC(");
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- strcat(keyname, ")");
- }
- else /* long int dates treated like numbers */
- {
- strcat(keyname, "STR(");
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- strcat(keyname, ",10,0)");
- }
- break;
- case INTTYP :
- case LNGTYP :
- case FLTTYP :
- case DBLTYP :
- zerorec(fmtstr, 12);
- sprintf(fmtstr, ",%d,%d)", nummasklen(fptr->flds[fx].fldmask), decmasklen(fptr->flds[fx].fldmask));
- strcat(keyname, "STR(");
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- strcat(keyname, fmtstr);
- break;
- }
- }
- }
-
- if ((stat = i4index(ndxname, keyname, 0, 0)) == CBERROR)
- return(io_xlate(fd_sys, v4error, "CB4 IXCRTE")); /* retn negative */
- return(stat);
- }
-
- /*
- * Length check - checks record length against that expected by PRO-C
- */
- static int length_check(fd_sys)
- int fd_sys;
- {
- int i;
- struct fd_def *fptr = &fd[fd_sys];
- struct dbf_def *dptr = &fdbf[fd_sys];
- BASE *infoptr;
-
- dptr->dbrec_len = 1; /* starts off allowing for deletion byte */
-
- for (i = 0; i < fptr->fld_cnt; i++) /* record length check */
- {
- switch (fptr->flds[i].fldtype)
- {
- case DATTYP :
- if (fptr->flds[i].fldlen == 6)
- dptr->dbrec_len += 8; /* dBASE format date storage */
- else
- dptr->dbrec_len += 10; /* PRO-C long int date type */
- break;
- case CHRTYP :
- dptr->dbrec_len += fptr->flds[i].fldlen;
- break;
- case INTTYP :
- case LNGTYP :
- case FLTTYP :
- case DBLTYP :
- dptr->dbrec_len += nummasklen(fptr->flds[i].fldmask);
- break;
- case LOGTYP :
- dptr->dbrec_len += 1;
- break;
- case MEMTYP :
- dptr->dbrec_len += 10;
- break;
- }
- } /* dbrec_len is PRO-C field length adjusted to .DBF format */
-
- if ((infoptr = d4ptr()) == DBFNULL)
- return(io_xlate(fd_sys, v4error, "CB4 LCHK"));
-
- if (dptr->dbrec_len != infoptr->buffer_len)
- { /* if file length has been changed... */
- errmsg(FileRecLenChg_s, fptr->filname);
- return(IOERROR);
- }
-
- for (i = 0; i < fptr->fld_cnt; i++) /* assign field ref numbers */
- {
- dptr->fld_ref[i] = f4j_ref(i+1);
- if (dptr->fld_ref[i] == (long)CBERROR)
- {
- errmsg(FileFldRef_s, cvt_upper(fptr->flds[i].fldname));
- return(IOERROR);
- }
- }
-
- return((load_keys(fd_sys, FALSE) > 0) ? IOGOOD : IOERROR);
- }
-
- /*
- * File close function
- */
- static int i_close_file(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- if (d4close() == CBERROR)
- return(io_xlate(fd_sys, v4error, "CB4 CLOSE"));
-
- fd[fd_sys].active = NO;
- return(IOGOOD);
- }
-
-
- /*
- * Select an index to perform processing on
- * - uses calls analogous to dBASE "SELECT <dbf file alias>" and
- * "SET INDEX TO <ndx file>"
- */
- static int i_selectinx(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- if (d4select(fd[fd_sys].fd_num) == CBERROR)
- return(io_xlate(fd_sys, v4error, "CB4 SELIX1"));
-
- if (i4select(fdbf[fd_sys].ndx_num[fd[fd_sys].cur_key]) == CBERROR)
- return(io_xlate(fd_sys, v4error, "CB4 SELIX2"));
-
- return(IOGOOD);
- }
-
- /*
- * Find a record by key value
- */
- static int i_findkey(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int errcode, len, fx;
- double dtmp;
- char keybuff[MAX_FLDLEN * MAX_SEGS + MAX_SEGS];
- struct fd_def *fptr = &fd[fd_sys];
- struct keyinfo *kptr = &fd[fd_sys].keys[fd[fd_sys].cur_key];
-
- i_selectinx(fd_sys, buffer); /* ensure required file & index selected */
- len = setupkey(fd_sys, buffer, keybuff);
- fx = kptr->fldindex[0];
-
- if ((fptr->flds[fx].fldtype == CHRTYP)
- || ((fptr->flds[fx].fldtype == DATTYP) && (fptr->flds[fx].fldlen == 6))
- || (kptr->segcount > 1))
- errcode = d4seek(keybuff);
- else /* non-compound numerical keys */
- {
- dtmp = c4atod(keybuff, len);
- errcode = d4seek((char *) &dtmp);
- }
-
- if (errcode == -1)
- return(io_xlate(fd_sys, v4error, "CB4 FIND"));
- else if (errcode != 0) /* exact value not found */
- if ((fptr->exact && (errcode > 0)) || (errcode == 3))
- return(IONOKEY);
- /* otherwise partial match has succeeded */
-
- errcode = get_record(fd_sys, buffer, NEXT);
- return((fptr->exact && (errcode == IOEOF)) ? IONOKEY : errcode);
- }
-
- /*
- * Set up target key
- * - sets up a key string for record retrieval on current index
- * - simple keys will use native type in key searches, compound keys are
- * treated as though all fields converted to string type
- */
- static int setupkey(fd_sys, recbuf, keybuf)
- int fd_sys;
- char *recbuf, *keybuf;
- {
- int i, j, ofs, len, fx, so = 0, nnum, ndec;
- int itmp;
- long ltmp;
- float ftmp;
- double dtmp;
- char *tptr, stmp[20];
- struct fd_def *fptr = &fd[fd_sys];
- struct dbf_def *dptr = &fdbf[fd_sys];
- struct keyinfo *kptr = &fd[fd_sys].keys[fd[fd_sys].cur_key];
-
- memset(keybuf, (int)' ', MAX_FLDLEN * MAX_SEGS);
-
- for (i = 0; i < kptr->segcount; i++)
- {
- ofs = kptr->segstart[i];
- len = kptr->seglen[i];
- fx = kptr->fldindex[i];
-
- switch(fptr->flds[fx].fldtype) /* data type of key field */
- {
- case DATTYP :
- if (len == 6) /* date seen by PRO-C as ASCII string */
- {
- strncpy(&keybuf[so], "19", 2);
- if (!recbuf[ofs])
- strcpy(stmp, "000101");
- else
- strncpy(stmp, &recbuf[ofs], len);
- strncpy(&keybuf[so+2], stmp, 6);
- so += 8;
- break;
- } /* for long int date type fall thru to LNGTYP */
- case LNGTYP : /* don't move this !!! */
- bytecpy(<mp, &recbuf[ofs], len);
- dtmp = (double)ltmp;
- break;
- case CHRTYP :
- strncpy(&keybuf[so], &recbuf[ofs], len);
- for (j = strlen(&recbuf[ofs]); j < len; j++)
- keybuf[so+j] = ' '; /* pad with spaces */
- so += len;
- break;
- case INTTYP :
- bytecpy(&itmp, &recbuf[ofs], len);
- dtmp = (double)itmp;
- break;
- case FLTTYP :
- bytecpy(&ftmp, &recbuf[ofs], len);
- dtmp = (double)ftmp;
- break;
- case DBLTYP :
- bytecpy(&dtmp, &recbuf[ofs], len);
- break;
- }
-
- if ((fptr->flds[fx].fldtype != CHRTYP) || ((fptr->flds[fx].fldtype == DATTYP) && (fptr->flds[fx].fldlen == 4)))
- {
- nnum = nummasklen(fptr->flds[fx].fldmask);
- ndec = decmasklen(fptr->flds[fx].fldmask);
- tptr = c4dtoa(dtmp, nnum, ndec);
- bytecpy(&keybuf[so], tptr, nnum);
- keybuf[so+nnum] = '\0';
- so += nnum;
- }
- }
- return(so); /* length of key string */
- }
-
- /*
- * Find first record in the file
- */
- static int i_firstkey(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int errcode;
-
- i_selectinx(fd_sys, buffer); /* ensure required file & index selected */
-
- if ((errcode = d4top()) != IOGOOD)
- return((errcode == 3) ? IONOKEY : io_xlate(fd_sys, v4error, "CB4 FRST"));
-
- return(get_record(fd_sys, buffer, NEXT));
- }
-
- /*
- * Find last physical record in the file
- */
- static int i_lastkey(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int errcode;
-
- i_selectinx(fd_sys, buffer); /* ensure required file & index selected */
-
- if (d4reccount() == 0L) /* empty file returns EOF for auto numbering */
- return(IOEOF);
-
- if ((errcode = d4bottom()) != IOGOOD)
- return((errcode == 3) ? IONOKEY : io_xlate(fd_sys, v4error, "CB4 LAST"));
-
- return(get_record(fd_sys, buffer, PREV));
- }
-
- /*
- * Find next record in the file
- */
- static int i_nextrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int errcode;
-
- i_selectinx(fd_sys, buffer); /* ensure required file & index selected */
- i_unlock_rec(fd_sys, buffer); /* unlock current rec before proceeding */
-
- if ((errcode = d4skip(1L)) != IOGOOD)
- return((errcode == 3) ? IOEOF : io_xlate(fd_sys, v4error, "CB4 NEXT"));
-
- return(get_record(fd_sys, buffer, NEXT));
- }
-
- /*
- * Find previous record in the file
- */
- static int i_prevrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int errcode;
-
- i_selectinx(fd_sys, buffer); /* ensure required file & index selected */
- i_unlock_rec(fd_sys, buffer); /* unlock current rec before proceeding */
-
- if ((errcode = d4skip(-1L)) != IOGOOD)
- return((errcode == 1) ? IOTOF : io_xlate(fd_sys, v4error, "CB4 PREV"));
-
- return(get_record(fd_sys, buffer, PREV));
- }
-
- /*
- * Retrieve a record, converting from CodeBase to PRO-C buffer format
- * - record locking is taken care of here
- * - if nextone is TRUE, will try next record when passing over a deleted
- * record; otherwise will try previous record
- */
- static int get_record(fd_sys, P_buff, nextone)
- int fd_sys, nextone;
- char *P_buff;
- {
- int ofst, flen, lnum, i, so = 1;
- int itmp;
- long ltmp;
- float ftmp;
- double dtmp;
- char stmp[20];
- char *CB_buff, memobuff[MAX_FLDLEN + 1];
- struct fd_def *fptr = &fd[fd_sys];
- struct dbf_def *dptr = &fdbf[fd_sys];
-
- if (i_lockrec(fd_sys, P_buff) != IOGOOD)
- return(IOERROR);
-
- CB_buff = (char *)f4record(); /* ptr to CodeBase record buffer */
-
- if (!*CB_buff)
- return(io_xlate(fd_sys, v4error, "CB4 GETREC"));
-
- if (CB_buff[0] == DBFINACT) /* if a deleted file, go to next record */
- return(nextone ? i_nextrec(fd_sys, P_buff) : i_prevrec(fd_sys, P_buff));
-
- dptr->recnum = d4recno();
-
- zerorec(P_buff, fptr->rec_len);
-
- for (i = 0; i < fptr->fld_cnt; i++)
- {
- ofst = fptr->flds[i].fldstart;
- flen = fptr->flds[i].fldlen;
- lnum = nummasklen(fptr->flds[i].fldmask);
-
- switch(fptr->flds[i].fldtype)
- {
- case DATTYP :
- if (flen == 6)
- {
- so += 2; /* ignore the "19" in the date */
- strncpy(&P_buff[ofst], &CB_buff[so], flen);
- stripright(&P_buff[ofst], flen);
- so += flen; /* offset for next field */
- break;
- }
- else /* for long int date type fall thru to LNGTYP */
- lnum = 10;
- case LNGTYP : /* don't move this !!! */
- ltmp = c4atol(&CB_buff[so], lnum);
- bytecpy(&P_buff[ofst], <mp, flen);
- so += lnum;
- break;
- case CHRTYP :
- strncpy(&P_buff[ofst], &CB_buff[so], flen);
- stripright(&P_buff[ofst], flen);
- so += flen; /* offset for next field */
- break;
- case INTTYP :
- itmp = c4atoi(&CB_buff[so], lnum);
- bytecpy(&P_buff[ofst], &itmp, flen);
- so += lnum;
- break;
- case FLTTYP :
- dtmp = c4atod(&CB_buff[so], lnum);
- ftmp = (float)dtmp;
- bytecpy(&P_buff[ofst], &ftmp, flen);
- so += lnum;
- break;
- case DBLTYP :
- dtmp = c4atod(&CB_buff[so], lnum);
- bytecpy(&P_buff[ofst], &dtmp, flen);
- so += lnum;
- break;
- case LOGTYP :
- P_buff[ofst] = CB_buff[so];
- so += 1;
- break;
- case MEMTYP :
- so += 10; /* placepointer in CB_buff only */
- if (m3exist(dptr->fld_ref[i]))
- {
- if (m3read(dptr->fld_ref[i], dptr->recnum, memobuff, flen) == -1)
- errmsg(FileMemoNoRead_ss, fptr->flds[i].fldname, fptr->filname);
- strcpy(&P_buff[ofst], memobuff);
- }
- break;
- }
- }
- return(IOGOOD);
- }
-
- /*
- * Re-read/reposition record pointer function - if required
- */
- static int i_rereadrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(i_findkey(fd_sys, buffer));
- }
-
-
- /*
- * Add a new record.
- * - uses put_record() with record number = 0 to enable appending
- */
- static int i_addrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- fdbf[fd_sys].recnum = 0L;
- return(put_record(fd_sys, buffer));
- }
-
- /*
- * Update the current record.
- */
- static int i_updrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(put_record(fd_sys, buffer));
- }
-
- /*
- * Write a record, converting from PRO-C buffer format to CodeBase
- * - this function appends a blank record if called from addrec
- * - memo fields are written as they occur
- * - locking and updating of index files is automatic with d4write
- */
- static int put_record(fd_sys, P_buff)
- int fd_sys;
- char *P_buff;
- {
- int errcode, ofst, flen, lnum, ldec, i, j, so = 1;
- char *ptr;
- int itmp;
- long ltmp;
- float ftmp;
- double dtmp;
- char *CB_buff, tbuff[MAX_RECLEN], memobuff[MAX_FLDLEN + 1];
- struct fd_def *fptr = &fd[fd_sys];
- struct dbf_def *dptr = &fdbf[fd_sys];
-
- i_selectinx(fd_sys, P_buff); /* ensure required file is selected */
- d4go(0L); /* blank the CodeBase record buffer */
- CB_buff = (char *)f4record();
-
- if (dptr->recnum == 0L) /* if a new record, append a blank */
- {
- if ((errcode = d4write(0L)) != IOGOOD)
- return((errcode == -2) ? IODUP : io_xlate(fd_sys, v4error, "CB4 ADD"));
- dptr->recnum = d4recno();
- }
-
- for (i = 0; i < fptr->fld_cnt; i++)
- {
- ofst = fptr->flds[i].fldstart;
- flen = fptr->flds[i].fldlen;
- lnum = nummasklen(fptr->flds[i].fldmask);
- ldec = decmasklen(fptr->flds[i].fldmask);
-
- switch(fptr->flds[i].fldtype)
- {
- case DATTYP :
- if (flen == 6)
- {
- if (!P_buff[ofst])
- strcpy(tbuff, "19000101");
- else
- {
- strcpy(tbuff, "19"); /* dBASE date format */
- strncat(tbuff, &P_buff[ofst], flen);
- }
- strncpy(&CB_buff[so], tbuff, 8);
- so += 8;
- break;
- }
- else /* for long int date type fall thru to LNGTYP */
- lnum = 10;
- case LNGTYP : /* don't move this !!! */
- bytecpy(<mp, &P_buff[ofst], flen);
- c4ltoa(ltmp, &CB_buff[so], lnum);
- so += lnum;
- break;
- case CHRTYP :
- strncpy(&CB_buff[so], &P_buff[ofst], flen);
- for (j = strlen(&P_buff[ofst]); j < flen; j++)
- CB_buff[j+so] = ' '; /* pad with spaces */
- so += flen; /* offset for next field */
- break;
- case INTTYP :
- bytecpy(&itmp, &P_buff[ofst], flen);
- c4ltoa((long)itmp, &CB_buff[so], lnum);
- so += lnum;
- break;
- case FLTTYP :
- bytecpy(&ftmp, &P_buff[ofst], flen);
- ptr = c4dtoa((double)ftmp, lnum, ldec);
- strncpy(&CB_buff[so], ptr, lnum);
- so += lnum;
- break;
- case DBLTYP :
- bytecpy(&dtmp, &P_buff[ofst], flen);
- ptr = c4dtoa(dtmp, lnum, ldec);
- strncpy(&CB_buff[so], ptr, lnum);
- so += lnum;
- break;
- case LOGTYP :
- CB_buff[so] = P_buff[ofst];
- so += 1;
- break;
- case MEMTYP :
- if (P_buff[ofst]) /* memo field is not empty */
- {
- memset(&CB_buff[so], 0, 10); /* FOR NOW holds the place */
- strcpy(memobuff, &P_buff[ofst]);
- memcpy(tbuff, CB_buff, fptr->rec_len);
- if (m3write(dptr->fld_ref[i], dptr->recnum, memobuff, flen) == -1)
- errmsg(FileMemoNoWrite_ss, fptr->flds[i].fldname, fptr->filname);
- memcpy(&tbuff[so], &CB_buff[so], 10); /* save memo pointer */
- memcpy(CB_buff, tbuff, fptr->rec_len); /* restore CB_buff */
- }
- so += 10;
- break;
- }
- }
- if ((errcode = d4write(dptr->recnum)) != IOGOOD)
- return((errcode == -2) ? IODUP : io_xlate(fd_sys, v4error, "CB4 UPD"));
- return(IOGOOD);
- }
-
-
- static struct optab pconf[] = {
- { 2, 34, "No " },
- { 2, 34, "Yes" },
- { NORMAL, REVVID, NULL }
- };
-
-
- /*
- * Delete the current record.
- * - locking and updating of index files is automatic with d4write
- * - PACK is optional, will reindex open index files
- */
- static int i_delrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int errcode, rslt;
-
- i_selectinx(fd_sys, buffer); /* ensure required file & index selected */
-
- if ((errcode = d4delete(fdbf[fd_sys].recnum)) != IOGOOD)
- return((errcode == 1) ? IONOKEY : io_xlate(fd_sys, v4error, "CB4 DEL"));
-
- #ifdef ALLOW_PACKING
- create_w(11, 19, 3, 40);
- border_w(boxset, BOLD);
- disp_w(2, 3, NORMAL, "Do you want to PACK the file? ");
- rslt = do_options(pconf, rslt, 0);
- if (ichar == K_ESC)
- rslt = FALSE;
- delete_w();
- if (rslt)
- if (d4pack())
- errmsg(FilePackFail_s, fd[fd_sys].filname);
- #endif
-
- return(IOGOOD);
- }
-
-
- /*
- * Lock Record
- */
- static int i_lockrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int errcode = -1;
-
- if ((fd[fd_sys].lockmode == NOLOCK) || (fdbf[fd_sys].recnum == 0L))
- return(IOGOOD); /* no retry if recnum not defined */
-
- errcode = d4lock(fdbf[fd_sys].recnum, 0); /* lock on current record */
-
- if (errcode == -2)
- return(IOLOCKED);
- if (errcode == -1)
- return(io_xlate(fd_sys, v4error, "CB4 LOCK"));
-
- return(errcode ? IONOKEY : IOGOOD); /* errcode 0 if lock successful */
- }
-
- /*
- * Unlock Record
- * - d4unlock does not unlock index files, so this must be done manually
- */
- static int i_unlock_rec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int errcode;
-
- if (fd[fd_sys].lockmode == NOLOCK)
- return(IOGOOD);
-
- if ((errcode = d4unlock((long)-1)) == CBERROR)
- return io_xlate(fd_sys, v4error, "CB4 ULOCK1");
-
- if ((errcode = i4unlock(-1)) == CBERROR)
- return io_xlate(fd_sys, v4error, "CB4 ULOCK2");
-
- return(IOGOOD);
- }
-
-
- /*
- * Login
- */
- static int i_login(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(IOGOOD);
- }
-
- /*
- * Logoff
- */
- static int i_logoff(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(IOGOOD);
- }
-
- /*
- * End (Commit) transaction
- */
- static int i_commit(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(IOGOOD);
- }
-
- /*
- * Rollback transaction
- */
- static int i_rollback(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(IOGOOD);
- }
-
- /*
- * Start transaction
- */
- static int i_transact(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(IOGOOD);
- }
-
- /*
- * This routine translates CodeBase Error codes into PRO-C error codes.
- * If no PRO-C equivalent, displays the error number.
- */
- static int io_xlate(fd_sys, ernum, rtnname)
- int fd_sys;
- int ernum;
- char *rtnname;
- {
- switch(ernum)
- {
- case 120 :
- return IOBADOPEN;
- case 200 :
- case 240 :
- case 320 :
- return IONOFILE;
- case 330 :
- case 380 :
- return IONOKEY;
- case 400 :
- return IOLOCKED;
- case 450 :
- return IONOLOCK;
- }
-
- if (fd_sys > 0)
- errmsg(FileDbgError_sdss, "CodeBase", ernum, fd[fd_sys].filname, rtnname);
- else /* if routines called from generated apps without valid fd_sys */
- errmsg(FileDbgError_sds, "CodeBase", ernum, rtnname);
- return(IOERROR);
- }
-
-
- void assign_IO_CL(dbnum)
- {
- assign_IO_CB(dbnum);
- enable_clipper = TRUE;
- }
-
-
- /*
- * Assign section
- */
-
- void assign_IO_CB(dbnum)
- int dbnum;
- {
- Fntab[dbnum - 1][0] = (int(*)())0; /* Empty */
- Fntab[dbnum - 1][1] = i_init_file;
- Fntab[dbnum - 1][2] = i_open_file;
- Fntab[dbnum - 1][3] = i_close_file;
- Fntab[dbnum - 1][4] = i_addrec;
- Fntab[dbnum - 1][5] = i_delrec;
- Fntab[dbnum - 1][6] = i_findkey;
- Fntab[dbnum - 1][7] = i_firstkey;
- Fntab[dbnum - 1][8] = i_lastkey;
- Fntab[dbnum - 1][9] = i_lockrec;
- Fntab[dbnum - 1][10] = i_nextrec;
- Fntab[dbnum - 1][11] = i_prevrec;
- Fntab[dbnum - 1][12] = i_unlock_rec;
- Fntab[dbnum - 1][13] = i_updrec;
- Fntab[dbnum - 1][14] = i_commit;
- Fntab[dbnum - 1][15] = i_login;
- Fntab[dbnum - 1][16] = i_logoff;
- Fntab[dbnum - 1][17] = i_rollback;
- Fntab[dbnum - 1][18] = i_transact;
- Fntab[dbnum - 1][19] = i_selectinx;
- Fntab[dbnum - 1][20] = i_rereadrec;
- Fntab[dbnum - 1][21] = i_filename;
- enable_clipper = FALSE;
- }
-
-