home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR2
/
BYTE24.ZIP
/
DBSUBS.C
< prev
next >
Wrap
Text File
|
1990-05-11
|
7KB
|
334 lines
/* Database handling subroutines for benchmark interface
**
** BYTE Magazine, Spring 1990
**
** init_db: reads in db records, if file exists.
** lin_search_db: returns index with matching criteria
** sort_db: sorts on one field
** update_db: updates one field in one record
** add_entry_db: adds an entry, marks it current.
** dump_db: writes db out to a file
** free_db: frees up memory allocated by init_db
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
#include "db.h"
char init_db(char num_records_limit, db_rec** listptr, char * dbfilename)
/* looks for dbfilename. If it exists, reads in records */
/* returns number of records in database */
{
int i;
char num_records=0;
int dbfh;
dbfh=open(dbfilename, O_BINARY|O_RDONLY);
if(dbfh==-1)
return 0;
if( read(dbfh, &num_records, 1) <= 0){
close(dbfh);
return 0;
}
num_records=(num_records>num_records_limit-1)? \
num_records_limit-1:num_records;
/* allocate the memory */
for(i=0; i<(int)num_records; i++){
if ((*(listptr+i)=(db_rec*)malloc(sizeof(db_rec)))==NULL){
num_records=(char)i;
break;
}
}
/* read-em in*/
for(i=0; i<(int)num_records; i++){
read(dbfh, (char*)(*(listptr+i)), sizeof(db_rec));
}
close(dbfh);
return num_records;
}
int dump_db(char num_records, db_rec** listptr, char * dbfilename)
/* dumps records to file */
{
int i;
int dbfh;
/* open file */
dbfh=open(dbfilename, O_TRUNC|O_WRONLY|O_BINARY|O_CREAT);
if (dbfh==-1)
return 0;
if( write(dbfh, &num_records, 1) <= 0){
close(dbfh);
return 0;
}
/* write-em */
for(i=0; i<(int)num_records; i++){
write(dbfh, (char*)(*(listptr+i)), sizeof(db_rec));
}
close(dbfh);
return 1;
}
void free_db(char num_records, db_rec** listptr)
/* frees all memory allocated to records */
{
int i;
for(i=0; i<(int)num_records; i++){
free(*(listptr+i));
}
}
int lin_search_db(char startpos, char endpos, void** listptr, \
int struct_offset, char crit_type_code, double crit)
/* unsorted linear search. Return index of first match found, -1 on no match.
** crit=value to match. struct_offset=location of field to match.
*/
{
int i;
int temp;
switch(crit_type_code){
case CHARCODE:
for(i=(int)startpos;i<=(int)endpos;i++){
if(*((char*)
((char *)(*(listptr+i))+struct_offset)) \
==(char)crit)
return i;
}
return -1;
case INTCODE:
for(i=(int)startpos;i<=(int)endpos;i++){
if(*((unsigned int*) \
((char *)(*(listptr+i))+struct_offset)) \
==(unsigned int)crit)
return i;
}
return -1;
case FLOATCODE:
for(i=(int)startpos;i<=(int)endpos;i++){
if(*((double *) \
((char *)(*(listptr+i))+struct_offset)) \
==(double)crit)
return i;
}
return -1;
case CHARPTRCODE:
temp=(int) crit;
for(i=(int)startpos;i<=(int)endpos;i++){
if(strcmp( \
((char *)(*(listptr+i))+struct_offset),
(char*)temp)==0)
return i;
}
return -1;
default:
return -1;
}
}
void sort_db( char num_records, void** listptr, \
int struct_offset, char ft_code)
/*
** quicksort for these structures
** adapted from Esakov-Weiss, _Data_Structures_
**
*/
{
void** left;
void** right;
void** el;
char num_remaining;
void swap(void**, void**);
int comp_fld_ptr(void**, void**, int, char);
if (num_records<=1) return;
left=listptr;
right=listptr+(num_records-1);
el=left;
swap (el, right);
el=right;
while(left<right){
while((comp_fld_ptr(left,el,struct_offset, ft_code)<0)&&(left<right))
left++;
while((comp_fld_ptr(right,el,struct_offset,ft_code)>=0)&&(left<right))
right--;;
if(left<right){
swap(left,right);
left++;
}
}
if(right==listptr){
swap(right, el);
right++;
}
num_remaining=(right-listptr);
sort_db(num_remaining, listptr, struct_offset, ft_code);
sort_db(num_records-num_remaining, right, struct_offset, ft_code);
}
void swap(void** a, void** b)
{
void* temp;
temp=*a;
*a=*b;
*b=temp;
}
int comp_fld_ptr(void** a, void** b, int s_off, char f_code)
{
switch(f_code){
case CHARCODE:
if( *((char*) ((char *)(*a)+s_off)) <
*((char*) ((char *)(*b)+s_off)))
return 1;
if( *((char*) ((char *)(*a)+s_off)) >
*((char*) ((char *)(*b)+s_off)))
return -1;
return 0;
case INTCODE:
if( *((unsigned int*) ((char *)(*a)+s_off)) <
*((unsigned int*) ((char *)(*b)+s_off)))
return 1;
if( *((unsigned int*) ((char *)(*a)+s_off)) >
*((unsigned int*) ((char *)(*b)+s_off)))
return -1;
return 0;
case FLOATCODE:
if( *((double*) ((char *)(*a)+s_off)) <
*((double*) ((char *)(*b)+s_off)))
return 1;
if( *((double*) ((char *)(*a)+s_off)) >
*((double*) ((char *)(*b)+s_off)))
return -1;
return 0;
case CHARPTRCODE:
return strcmp(((char *)(*b)+s_off), \
((char *)(*a)+s_off));
}
return 0;
}
void update_db(int index, void** listptr, int struct_offset, \
char ft_code, double newvalue)
/*
** updates a db entry.
*/
{
int temp;
switch(ft_code){
case CHARCODE:
*((char*) \
((char*)(*(listptr+index))+struct_offset))= \
(char) newvalue;
break;
case INTCODE:
*((unsigned int*) \
((char*)(*(listptr+index))+struct_offset))= \
(unsigned int) newvalue;
break;
case FLOATCODE:
*((double *) \
((char*)(*(listptr+index))+struct_offset))= \
(double) newvalue;
break;
case CHARPTRCODE:
temp=(int) newvalue;
strcpy(
((char*)(*(listptr+index))+struct_offset), \
(char*) temp);
}
}
char add_entry_db( char num_records_limit, char num_records, \
db_rec** listptr, char* entryname)
/* adds a db entry. Returns number of records in new db. If records in
** equals records out, you're out of room.
*/
{
int i;
int curroff;
if(num_records==num_records_limit) return num_records;
/* allocate the memory */
if((*(listptr+num_records)=(db_rec*)malloc(sizeof(db_rec)))==NULL)
return num_records;
/* clear current entry */
if(num_records!=0){
curroff=lin_search_db(0, num_records-1, (void**) listptr, \
offset_in_struc(db_rec,currflag), INTCODE, 1);
if(curroff>(-1)){
update_db(curroff,(void**) listptr,
offset_in_struc(db_rec,currflag), INTCODE, 0);
}
}
/* zero out new entry */
for(i=0; i<sizeof(db_rec); i++)
*(*((char**)listptr+num_records)+i)=0;
/* make new entry current */
update_db((int)num_records,(void**) listptr,
offset_in_struc(db_rec,currflag), INTCODE, 1);
/* give it a name */
update_db((int)num_records,(void**) listptr,
offset_in_struc(db_rec,name), CHARPTRCODE, (int)entryname);
return num_records+1;
}
void dup_rec( void** listptr, int destoff, int sourceoff)
/*
** duplicates records.
*/
{
int i;
for(i=0; i<sizeof(db_rec); i++){
*(*((char**)listptr+destoff)+i)= \
*(*((char**)listptr+sourceoff)+i);
}
}