home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Jason Aller Floppy Collection
/
125.img
/
PRO-C4.ZIP
/
BENCH1.ZIP
/
BENCH
/
IASCII.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-28
|
21KB
|
830 lines
/* ==( io/src/iascii.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 VvA 28-Mar-90 See comments below */
/* ----------------------------------------------- */
/* %W% (%H% %T%) */
/*
* Modifications
*
* 28-Mar-90 VvA - adjustments for locking modes, transactions
* 06-Feb-90 VvA - return IOEOF in lastkey for autonum
* 02-Feb-90 VvA - adjust return vals in lastkey
* 01-Feb-90 VvA - Enabled openmode in open_file()
* 12-Dec-89 Geo - V2 version with variable lines
* 25-Oct-89 Geo - 1.32 Merge
* 3-Aug-89 VvA - Modified for generic IO interface
* 26-Jul-89 BF/BC - Patched (by the terrible twosome)
* 23-Mar-88 Geo - Rejigged, code shrunk (yes it was)
*/
/*
* -- D R A F T -- ASCII Sequential I/O via general IOGEN.C interface
* WARNING Brian C reckons this is incorrect 13-Dec-89
*/
/*
* This module handles the interface between the i/o calls from within
* PRO-C and an ASCII file with fixed length records, but varying length
* fields within the records
*/
# include <iodef.h>
# include <iomsg.h>
# include <proc.io>
# include <bench.h>
# include <iosup.h>
/* Open control (Geo will correct this into o_open & o_creat 13-Dec-89) */
# ifndef QNX
#include <fileio.h>
# endif
#ifdef QNX
#include <file_io.h>
#define OPN_FILE(fname) sopen(fname, O_BINARY | O_RDWR | O_CACHE, SH_DENYNO )
#define CRT_FILE(fname) sopen(fname, O_CREAT | O_BINARY | O_RDWR | O_CACHE, SH_DENYNO, S_IREAD | S_IWRITE)
#endif
#ifdef MSC
#define OPN_FILE(fname) open(fname, O_BINARY | O_RDWR )
#define CRT_FILE(fname) open(fname, O_CREAT | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
#endif
#ifdef PC
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#define OPN_FILE(fname) open(fname, O_BINARY | O_RDWR )
#define CRT_FILE(fname) open(fname, O_CREAT | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
#endif
#ifdef __TURBOC__
#include <fcntl.h>
#include <sys/stat.h>
#define OPN_FILE(fname) open(fname, O_RDWR | O_BINARY)
#define CRT_FILE(fname) open(fname, O_CREAT | O_RDWR | O_BINARY, S_IREAD | S_IWRITE)
#endif
#ifdef __WATCOMC__
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <stdlib.h>
#define OPN_FILE(fname) open(fname, O_BINARY | O_RDWR , S_IREAD | S_IWRITE)
#define CRT_FILE(fname) open(fname, O_CREAT | O_BINARY | O_RDWR, S_IREAD | S_IWRITE)
#endif
#ifdef LC
#include <fcntl.h>
#define OPN_FILE(fname) open(fname, O_RAW | O_RDWR)
#define CRT_FILE(fname) open(fname, O_CREAT | O_RAW | O_RDWR)
#endif
#ifdef __ZTC__
#include <io.h>
#include <dos.h>
#include <sys\stat.h>
#include <stdlib.h>
#define OPN_FILE(fname) open(fname, O_RDWR)
#define CRT_FILE(fname) creat(fname, S_IREAD | S_IWRITE)
#endif
#ifdef DC
#include <dos.h>
#define OPN_FILE(fname) open(fname, O_RDWR)
#define CRT_FILE(fname) creat(fname, 2)
#endif
# ifdef UNIX
# define OPN_FILE(fname) open(fname, O_RDWR)
# define CRT_FILE(fname) open(fname, O_RDWR | O_CREAT | O_TRUNC, 0666)
# endif
# ifndef USELOCK
/*# define USELOCK*/ /* Dummy out this if no locking */
# endif
/* Function prototypes */
# ifdef ANSI
static int isdeleted(char *, int);
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 read_rec(int, char *);
static int write_rec(int, char *);
static void checkopen(int);
# else
static int isdeleted();
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 read_rec();
static int write_rec();
static void checkopen();
# endif
/* EXTERNs */
extern long lseek();
extern char *alloc();
extern struct fd_def fd[]; /* iogen.c */
/*
* Plus any externs required by the file manager for error codes etc.
*/
/* structure for ASCII file specific values */
struct asc_def
{
long offset; /* Current offset into file for Read/Write */
int nextrec; /* Next Record to Read */
char *localbuf; /* Local Record Buffer for Read/Write */
int max_f; /* Number of fields in Record */
int f_idx[128]; /* Offset of All Fields into Record. Sequential */
int f_len[128]; /* Length of All Fields in Record. Sequential */
int locked;
long lockoff;
};
static struct asc_def afd[MAX_FILES];
/*
static FILE *fdbg = NULL;
*/
/*
*
* Interface Functions
*
*/
/*
* Sets up File Name extension - dummy function here
*/
static int i_filename(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(IOGOOD);
}
/*
* File initialization - all descriptors start out as -1
*/
static int i_init_file(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int n;
for (n = 0; n < MAX_FILES; n++) /* initialize all descriptors to -1 */
fd[n].fd_num = -1;
return(IOGOOD);
}
/*
* File open function - required parameters are in fd structure
*/
static int i_open_file(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int fds;
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
/*
* If the desired mode is OUTPUT, then delete any existing files.
*/
if (fptr->openmode & OUTPUT_FLAG)
unlink(fptr->filname);
if ((fds = OPN_FILE(fptr->filname)) < 0)
fds = CRT_FILE(fptr->filname);
if (fds < 0) /* failed to open or create */
{
errmsg(FileNotFound_s, fptr->filname);
return(IOERROR);
}
fptr->fd_num = fds;
aptr->localbuf = alloc(fptr->rec_len);
aptr->nextrec = -1;
aptr->locked = 0;
aptr->lockoff = 0L;
return(IOGOOD);
}
/*
* File close function
*/
static int i_close_file(fd_sys, buffer)
int fd_sys;
char *buffer;
{
close(fd[fd_sys].fd_num);
fd[fd_sys].fd_num = -1;
return(IOGOOD);
}
/*
* Select an index to perform processing on - done in IOGEN.C
*/
static int i_selectinx(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(IOGOOD);
}
/*
* Check and error message for unassigned descriptors
*/
static void checkopen(fd_sys)
int fd_sys;
{
if (fd[fd_sys].fd_num < 0)
abort_mess("Invalid file descriptor in GET_REC");
}
/*
* Find a record by key value
* - For partial match, the first record GTE than given key will be returned.
*/
static int i_findkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int ilen, olen, klen, ktype;
char *src, *key;
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
struct keyinfo *kptr = &fd[fd_sys].keys[fd[fd_sys].cur_key];
checkopen(fd_sys);
if (lseek(fptr->fd_num, 0L, FDIR_BEGIN) < 0L)
return(IONOKEY);
klen = kptr->seglen[0]; /* key information */
ktype = fptr->flds[kptr->fldindex[0]].fldtype;
key = buffer + kptr->segstart[0];
src = aptr->localbuf + kptr->segstart[0];
ilen = (ktype == CHRTYP) ? fstrlen(key, klen) : klen;
aptr->nextrec = 0;
for (;;)
{
if (read_rec(fd_sys, aptr->localbuf) != IOGOOD)
return(IONOKEY);
aptr->nextrec++;
if (fptr->exact) /* compare field length and match the key */
{
olen = (ktype == CHRTYP) ? fstrlen(src, klen) : klen;
if ((ilen == olen) && !memcmp(key, src, olen))
break; /* found one... lengths and key match */
}
else /* partial match only, return first record that is GTE keys */
{
if (ktype == CHRTYP && memcmp(key, src, ilen) <= 0)
break;
else if (ktype == INTTYP && *(int *)key <= *(int *)src)
break;
else if (ktype == LNGTYP && *(long *)key <= *(long *)src)
break;
else if (ktype == FLTTYP && *(float *)key <= *(float *)src)
break;
else if (ktype == DBLTYP && *(double *)key <= *(double *)src)
break;
}
}
aptr->offset = (long) fptr->rec_len * (long) (aptr->nextrec - 1);
if (i_lockrec(fd_sys, buffer) != IOGOOD)
return(IOLOCKED);
bytecpy(buffer, aptr->localbuf, fptr->rec_len); /* copy to real buffer */
return(IOGOOD);
}
/*
* Find first record in the file - first physical record for ASCII file
*/
static int i_firstkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int stat;
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
checkopen(fd_sys);
if (lseek(fptr->fd_num, 0L, FDIR_BEGIN) < 0L)
return(IOERROR);
if ((stat = read_rec(fd_sys, aptr->localbuf)) != IOGOOD)
return(stat); /* allows return of IOEOF for ELEMOD */
if (isdeleted(aptr->localbuf, fptr->rec_len) == TRUE) /* rec deleted */
{
aptr->nextrec = 1;
return(i_nextrec(fd_sys, buffer));
}
if (i_lockrec(fd_sys, buffer) != IOGOOD)
return(IOLOCKED);
bytecpy(buffer, aptr->localbuf, fptr->rec_len); /* copy to real buffer */
aptr->nextrec = 1;
return(IOGOOD);
}
/*
* Find last physical record in the file
*/
static int i_lastkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int stat;
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
checkopen(fd_sys);
if ((aptr->offset = lseek(fptr->fd_num, 0L, FDIR_EOF)) <= 0L)
return(IOEOF);
do /* skip back past any deleted records */
{
aptr->offset -= (long)fptr->rec_len; /* one record previous */
if (lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN) < 0L)
return(IOEOF); /* reqd for autonumbering */
if ((stat = read_rec(fd_sys, aptr->localbuf)) != IOGOOD)
return(stat);
}
while(isdeleted(aptr->localbuf, fptr->rec_len) == TRUE);
if (i_lockrec(fd_sys, buffer) != IOGOOD)
return(IOLOCKED);
bytecpy(buffer, aptr->localbuf, fptr->rec_len); /* copy to real buffer */
aptr->nextrec = 1;
return(IOGOOD);
}
/*
* Find next record in the file
* - Although IOGEN does checking for duplicate key records in an EXACT
* search, ASCII sequential files are not indexed; thus this function
* will continue traversing the file to find all occurrences matching
* the original exact-matched key.
*/
static int i_nextrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int ilen, olen, klen, ktype;
long iosignal;
char *src, *key;
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
struct keyinfo *kptr = &fd[fd_sys].keys[fd[fd_sys].cur_key];
checkopen(fd_sys);
if (fptr->exact) /* get key information */
{
klen = kptr->seglen[0];
ktype = fptr->flds[kptr->fldindex[0]].fldtype;
key = buffer + kptr->segstart[0];
src = aptr->localbuf + kptr->segstart[0];
ilen = (ktype == CHRTYP) ? fstrlen(key, klen) : klen;
}
do
{
aptr->offset = (long) aptr->nextrec * (long) fptr->rec_len;
iosignal = lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
if(iosignal < 0L)
return(IOEOF);
if (!fptr->exact)
{
if(read_rec(fd_sys, aptr->localbuf) != IOGOOD)
return(IOEOF);
aptr->nextrec++;
}
else /* following exact match, retry exact match */
{
do
{
if (read_rec(fd_sys, aptr->localbuf) != IOGOOD)
return(IOEOF);
olen = (ktype == CHRTYP) ? fstrlen(src, klen) : klen;
aptr->nextrec++;
}
while(ilen != olen || memcmp(key, src, olen) != 0);
}
}
while(isdeleted(aptr->localbuf, fptr->rec_len) == TRUE); /* rec deleted */
if(i_lockrec(fd_sys, buffer) != IOGOOD)
return(IOLOCKED);
bytecpy(buffer, aptr->localbuf, fptr->rec_len); /* copy to real buffer */
return(IOGOOD);
}
/*****************************************************************************
* Find previous record in the file
* - No checks are done at this level (as for nextrec) for exact key match.
*/
static int i_prevrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
checkopen(fd_sys);
do
{
aptr->nextrec -= 2;
aptr->offset = (long) aptr->nextrec * (long) fptr->rec_len;
if (lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN) < 0L)
{
aptr->nextrec = 1;
return(IOTOF);
}
if (read_rec(fd_sys, aptr->localbuf) != IOGOOD)
{
aptr->nextrec = 1;
return(IOTOF);
}
aptr->nextrec++;
}
while(isdeleted(aptr->localbuf, fptr->rec_len) == TRUE); /* deleted rec */
if(i_lockrec(fd_sys, buffer) != IOGOOD)
return(IOLOCKED);
bytecpy(buffer, aptr->localbuf, fptr->rec_len); /* copy to real buffer */
return(IOGOOD);
}
/*
* re-read/reposition record pointer function - dummy function here
*/
static int i_rereadrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(IOGOOD);
}
/*
* Read a record from ASCII sequential file
*/
static int read_rec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int stat;
struct fd_def *fptr = &fd[fd_sys];
stat = read(fptr->fd_num, buffer, fptr->rec_len);
if (stat < 0)
return(IOERROR);
else if (stat != fptr->rec_len)
return(IOEOF);
return(IOGOOD);
}
/*
* Write a record to ASCII sequential file
*/
static int write_rec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int stat;
struct fd_def *fptr = &fd[fd_sys];
stat = write(fptr->fd_num, buffer, fptr->rec_len);
if (stat != fptr->rec_len)
return(IOERROR);
return(IOGOOD);
}
/*
* Check for deleted records in ASCII sequential file
*/
static int isdeleted(pp, plen)
char *pp;
int plen;
{
int i;
for (i = 0; i < plen; i++, pp++)
if(*pp != '\0')
break;
if (i == plen)
return(TRUE);
return(FALSE);
}
/*
* Record add function
*/
static int i_addrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
do
{
afd[fd_sys].offset = lseek(fd[fd_sys].fd_num, 0L, FDIR_EOF);
}
while(i_lockrec(fd_sys, buffer) == IOLOCKED);
return(write_rec(fd_sys, buffer));
}
/*
* Record update function
*/
static int i_updrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
int iosignal;
aptr->nextrec--;
aptr->offset = (long) aptr->nextrec * (long) fptr->rec_len;
lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
iosignal = write_rec(fd_sys, buffer);
aptr->nextrec++;
return(iosignal);
}
/*
* Record delete function
* - deleted records are not removed from the file, but simply zeroed out
*/
static int i_delrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int iosignal;
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
zerorec(aptr->localbuf, fptr->rec_len);
aptr->nextrec--;
aptr->offset = (long) aptr->nextrec * (long) fptr->rec_len;
lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
iosignal = write_rec(fd_sys, aptr->localbuf);
aptr->nextrec++; /* Always point to next record */
return(iosignal);
}
/*
* Lock Record
*/
static int i_lockrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
long iosignal;
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
if (fptr->lockmode == NOLOCK)
return(IOGOOD);
/*
if (fdbg == NULL)
fdbg = fopen("lok.log", "w");
fprintf(fdbg, " LOCK - %ld\n", aptr->offset);
*/
# ifdef USELOCK
if (aptr->locked == 1)
i_unlock_rec(fd_sys, buffer);
iosignal = lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
if(iosignal < 0L) /* this should not happen */
return(IOLOCKED);
if (lockf(fptr->fd_num, F_TEST, (long) fptr->rec_len) != 0)
return(IOLOCKED);
/*
* Now Re-Lock the same area with just read locks.
* If we don't do this, then the read() called in read_rec() to get
* the next record will sleep, but we want it to be able to read.
* The lock above is responsible for catching any locked regions.
* Re-locking below means that all records in the file can be read ok
* but the above locking() call will find the record is locked.
*/
iosignal = lseek(fptr->fd_num, aptr->offset, FDIR_BEGIN);
if (lockf(fptr->fd_num, F_LOCK, (long) fptr->rec_len) != 0)
return(IOLOCKED);
aptr->locked = 1;
aptr->lockoff = aptr->offset;
# endif /* USELOCK */
return(IOGOOD);
}
/*
* Unlock Record
*/
static int i_unlock_rec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
struct fd_def *fptr = &fd[fd_sys];
struct asc_def *aptr = &afd[fd_sys];
if (fptr->lockmode == NOLOCK)
return(IOGOOD);
/*
if (fdbg == NULL)
fdbg = fopen("lok.log", "w");
fprintf(fdbg, "UNLOCK - %ld\n", aptr->lockoff);
*/
# ifdef USELOCK
if (lseek(fptr->fd_num, aptr->lockoff, FDIR_BEGIN) < 0L)
return(IOLOCKED);
if (lockf(fptr->fd_num, F_ULOCK, (long) fptr->rec_len) < 0)
return(IOERROR);
aptr->locked = 0;
aptr->lockoff = 0L;
# endif /* USELOCK */
return(IOGOOD);
}
/*
* Login - dummy call
*/
static int i_login(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(IOGOOD);
}
/*
* Logoff - dummy call
*/
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);
}
/*
* Assign section
*/
void assign_IO_AS(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;
}