From 7dfcc480ba1e19bd3232349fc733caef94034292 Mon Sep 17 00:00:00 2001 From: stainer_t Date: Mon, 8 Sep 2025 13:48:49 +0200 Subject: Initial commit from Polytechnique Montreal --- Dragon/src/sdbm.c | 482 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 Dragon/src/sdbm.c (limited to 'Dragon/src/sdbm.c') diff --git a/Dragon/src/sdbm.c b/Dragon/src/sdbm.c new file mode 100644 index 0000000..867eee9 --- /dev/null +++ b/Dragon/src/sdbm.c @@ -0,0 +1,482 @@ +/* + * $Id: sdbm.c,v 1.10 1997/05/21 20:47:59 laughton Exp laughton $ + * + *--------------------------------------------------------------------------- + * + * Peter J. Laughton + * AECL + * Chalk River Laboratories + * Chalk River, Ontario + * CANADA K0J 1J0 + * + * Phone: (613) 584-8811, extension 4267 + * FAX: (613) 584-1108 + * + * Internet: laughtonp@crl.aecl.ca + * + *--------------------------------------------------------------------------- + * + * Revision history (as of 1995 October 25): + * + * $Log: sdbm.c,v $ + * Revision 1.11 99/03/11 17:03:56 17:03:56 laughton + * proper type-dependent calloc calls now used + * + * Revision 1.10 1997/05/21 20:47:59 laughton + * maximum number of records in one file doubled + * + * Revision 1.9 1996/12/19 19:34:56 laughton + * Intel-x86/Windows95 support added (the list sep is a ';', not a ':') + * + * Revision 1.8 1996/06/28 13:04:34 laughton + * support for NDAS file conversion started + * + * Revision 1.7 1995/12/12 22:21:27 laughton + * more GDBM updates + * + * Revision 1.6 1995/12/07 20:10:45 laughton + * minor SGI compiler warnings rectified + * + * Revision 1.5 1995/12/05 21:08:47 laughton + * emitTitle bug fixed. + * + * Revision 1.4 1995/12/04 14:46:12 laughton + * continuing development + * + * Revision 1.3 1995/12/01 21:27:19 laughton + * more error handling and identification of library titles + * + * Revision 1.2 1995/11/30 20:22:37 laughton + * continuing development + * + * Revision 1.1 1995/11/07 16:32:06 laughton + * Initial revision + * + */ + +#include +#include +#include +#include "sdbm.h" + +#define MAXKEYLENGTH 64 +#define StringTypeC 8 +#define MAKE_ARRAY(thing,number) \ + ((thing *) calloc((unsigned) (number),sizeof(thing))) + +static int magicNumber=0x198802ab; /* file-type marker */ + +typedef struct { + char key[MAXKEYLENGTH+1]; /* string of printable characters */ + int dataType; /* numeric flag indicating real, integer, etc */ + int size; /* in bytes */ + int dataOffset; /* from the beginning of the file */ +} HeaderElement; + +typedef struct { + char *filename; + FILE *filePointer; + int nValidRecords; /* > 0 means active */ + HeaderElement *header; +} SDBFile; + +#define size_HE (sizeof(HeaderElement)) + +#define MAXDBFILES 10 +#define MAXFNLENGTH 100 +static SDBFile dbFile[MAXDBFILES]; +static int dbfCount=0; + +static int initReadF=0; + +/* =============================================== */ +/* Prototypes of static functions appearing below: */ +/* =============================================== */ + +static int installDBF(char *filename); +static int compareHeaderElements(const void *h1, const void *h2); +static int searchHeader(HeaderElement *header, char *searchKey, int n); + +/* =============================================== */ + +int initRead(char *flist) { + int i; + char nbuf[MAXFNLENGTH+1]; + int fc, lc; + int retval; + char flistSep; + +#ifdef PC_TargetCPU + flistSep=';'; +#else + flistSep=':'; +#endif + + initReadF=1; + + for (i=0; i MAXFNLENGTH) + return FixedLimitExceeded; + + strncpy(nbuf, flist+fc, lc-fc); + nbuf[lc-fc]='\0'; + retval=installDBF(nbuf); + + if (retval) + return retval; /* non-zero is an error code */ + + fc=lc; + } + + emitTitles(); + return 0; /* success */ +} + +int countRecs(int *nRecs, int dbFileIndex) { + *nRecs=0; + if (dbFileIndex < 0 || dbFileIndex > MAXDBFILES-1) + return BadFile; + + *nRecs=dbFile[dbFileIndex].nValidRecords; + return 0; /* success */ +} + +static int installDBF(char *filename) { + int mn=0; + int i; + + /* Later, add a check to make sure this is not a new file. */ + + if (dbfCount >= MAXDBFILES) + return FixedLimitExceeded; + + dbFile[dbfCount].filename=strdup(filename); + if (!dbFile[dbfCount].filename) + return MemoryAllocFailure; + + dbFile[dbfCount].filePointer=fopen(filename,"rb"); + if (!dbFile[dbfCount].filePointer) + return OpenFailure; + + /* Check that the magic number is present. */ + if(fread(&mn,sizeof(int),1,dbFile[dbfCount].filePointer) < 1) goto L10; + if (mn!=magicNumber) + return BadFile; + + if(fread(&dbFile[dbfCount].nValidRecords, sizeof(int), 1, + dbFile[dbfCount].filePointer) < 1) goto L10; + + dbFile[dbfCount].header=MAKE_ARRAY(HeaderElement, + dbFile[dbfCount].nValidRecords); + if (!dbFile[dbfCount].header) + return MemoryAllocFailure; + + /* Load the header into memory (for now) */ + for (i=0; i < dbFile[dbfCount].nValidRecords; i++) + if(fread(&dbFile[dbfCount].header[i], size_HE, 1, + dbFile[dbfCount].filePointer) < 1) goto L10; + + dbfCount++; + return 0; /* success */ +L10: + printf("\n XSDB error 1: fread failure -- %s\n",filename); + fflush(stdout); + exit(1); +} + +static int compareHeaderElements(const void *h1, const void *h2) { + return strcmp(((HeaderElement *)h1)->key, ((HeaderElement *)h2)->key); +} + +void closeSDBRead() { + int i,irc; + + for (i=0; i= l) { + midPoint=(l+u)/2; /* floor results automatically */ + sign=strcmp(searchKey,header[midPoint].key); + + if (sign < 0) + u=midPoint-1; + else if (sign > 0) + l=midPoint+1; + else + return midPoint; + } + + return FAIL; +} + +datum readRecord(char *recordName) { + + int keyIndex; + datum record; + int nbytes; + int i; + int found=0; + + /* Failure is indicated if these values remain intact on exit. */ + record.dptr=0; + record.dsize=0; + + if (!initReadF) + return record; + + for (i=0; i> 2, 4); + + if (!record.dptr) + return record; + + record.dsize=nbytes; + + /* Jump to the location in the file and read the record into memory. */ + fseek(dbFile[i].filePointer, dbFile[i].header[keyIndex].dataOffset, SEEK_SET); + if(fread((char*)record.dptr, 1, nbytes, dbFile[i].filePointer) < 1) goto L10; + + return record; +L10: + printf("\n XSDB error: fread failure 2 -- %s\n",recordName); + fflush(stdout); + exit(1); +} + +datum readIndexedRecord(int keyIndex, int dbFileIndex, char *recordKey, int *dataType) { + + datum record; + int nbytes; + + /* Failure is indicated if these values remain intact on exit. */ + record.dptr=0; + record.dsize=0; + + if (dbFileIndex < 0 || dbFileIndex > MAXDBFILES-1) + return record; + + if (!initReadF) + return record; + + if (keyIndex >= dbFile[dbFileIndex].nValidRecords) + return record; + + strcpy(recordKey, dbFile[dbFileIndex].header[keyIndex].key); + *dataType=dbFile[dbFileIndex].header[keyIndex].dataType; + + nbytes=dbFile[dbFileIndex].header[keyIndex].size; + + if (*dataType == StringTypeC) + record.dptr=calloc(nbytes, 1); + else + record.dptr=calloc(nbytes >> 2, 4); + + if (!record.dptr) + return record; + + record.dsize=nbytes; + + /* Jump to the location in the file and read the record into memory. */ + fseek(dbFile[dbFileIndex].filePointer, + dbFile[dbFileIndex].header[keyIndex].dataOffset, + SEEK_SET); + + if(fread((char*)record.dptr, 1, nbytes, dbFile[dbFileIndex].filePointer) < 1) goto L10; + + return record; +L10: + printf("\n XSDB error: fread failure 3 -- %s\n",recordKey); + fflush(stdout); + exit(1); +} + +void emitTitles() { + int keyIndex; + datum record; + int i; + + for (i=0; i MAXKEYLENGTH) + return InvalidKey; + + strcat(header[writeRecordIndex].key,recordName); + header[writeRecordIndex].dataType=dataType; + header[writeRecordIndex].size=nbytes; + + header[writeRecordIndex].dataOffset=nextDataOffset; + offset=nbytes; + fseek(sdbFile,offset,SEEK_END); /* extend the file */ + fseek(sdbFile,nextDataOffset,SEEK_SET); /* position for write */ + fwrite((char*)data, 1, nbytes, sdbFile); + + writeRecordIndex++; + nextDataOffset+=offset; + + return 0; +} -- cgit v1.2.3