home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-386-Vol-2of3.iso
/
b
/
bfile2.zip
/
BFILE.CPP
next >
Wrap
Text File
|
1992-01-03
|
12KB
|
518 lines
/*
bfile.cpp
Btrieve class for Borland C++
09/06/91
Douglas J. Reilly
Access Microsystems Inc.
404 Midstreams Road
Brick, New Jersey 08724
(908) 892-2683
CompuServe 74040,607
Comments? Questions? Suggestions?
Have a paying C/C++ programming job you need done?
Give me a call.
Released into the public domain. Do with it as you see fit, but
if you do anything really neat with it, let me know...
11/11/91 DR Lots of little changes to better handle variable length
records.
11/12/91 DR Add support for just_update parm to put_rec();
01/03/92 DR Fix bug that cause file with owner to corrupt NULL pointer
(Thanks to Brian Levine in Orlando!). Don't use data
element when opening file.
*/
#define EOS '\0'
#include "stdio.h"
#include "stdlib.h"
#include "mem.h"
#include "string.h"
#include "ctype.h"
#include "bfile.h" // class description for bfile
class bfile;
// #define this, link it with the TURBCBTR module and see an example.
// USAGE: bfile /f:filename.ext /k:key_num
//#define TEST
#ifdef TEST
main(int argc,char *argv[])
{
char temp[100];
int ret;
int loop;
static char file[70]={""};
int key=-1;
temp[0]='\0';
memset(temp,'\0',100);
for ( loop=1 ; loop<argc ; loop++ )
{
if ( argv[loop][0]=='/' )
{
switch ( (toupper(argv[loop][1])) )
{
case 'K':
key=atoi(&argv[loop][3]);
break;
case 'F':
strcpy(file,&argv[loop][3]);
break;
}
}
}
bfile sum(file,4096,"SLUGGO",0);
sum.set_key_num(key);
printf("\nsum.get_rec(temp,B_GET_LO)=%d data=%30.30s temp=|%s|",
sum.get_rec(temp,B_GET_LO),
sum.get_data(),temp);
do {
printf("\nsum.get_rec(temp,B_GET_NEXT)=%d data=%30.30s temp=|%s|",
ret=sum.get_rec(temp,B_GET_NEXT),
sum.get_data(),temp);
} while ( ret==0 );
return(0);
}
#endif
bfile::bfile(char *name,int len,char *towner,int newmode)
{
int tlen=0;
char openowner[128];
key_num=0;
opened=0;
data=0;
strcpy(fname,name);
mode=newmode;
if ( towner!=0 )
{
tlen=(strlen(towner))+1;
strcpy(openowner,towner);
strcpy(owner,towner);
}
else
{
openowner[0]='\0';
tlen=len;
}
status=BTRV(B_OPEN,pos_blk,openowner,&tlen,fname,mode);
if ( status && status!=BERR_REC_BUF_ERR )
{
// printf("\nOpen failed for %s-status %d",fname,status);
}
else
{
opened=1;
// DECLARATION!
struct FIL_SPEC fil_spec;
get_bstat(&fil_spec);
file_flag=fil_spec.FILE_FLAG;
if ( len )
{
rec_len=len;
// get the fixed len from the FIL_SPEC
fixed_len=fil_spec.REC_LEN;
}
else
{
if ( variable_len() ) // variable len?
{
rec_len=5000; // assume 5000, what the heck...
}
else
{
rec_len=fil_spec.REC_LEN;
}
fixed_len=fil_spec.REC_LEN;
}
last_rec_len=0;
num_keys=fil_spec.NDX_CNT;
data=new char[rec_len];
if ( data==0 )
{
close();
opened=0;
status=BERR_MEM_ALLOC;
}
}
}
bfile::~bfile()
{
if ( !(opened) )
{
return;
}
else
{
status=BTRV(B_CLOSE,pos_blk,data,&rec_len,fname,mode);
delete data;
data=0;
opened=0;
}
}
bfile::newfile(char *name,int len,char *towner,int newmode)
{
int tlen=0;
key_num=0;
opened=0;
data=0;
strcpy(fname,name);
mode=newmode;
if ( towner!=0 )
{
strcpy(data,towner);
strcpy(owner,towner);
tlen=(strlen(towner))+1;
}
else
{
tlen=len;
}
status=BTRV(B_OPEN,pos_blk,data,&tlen,fname,mode);
if ( status && status!=BERR_REC_BUF_ERR )
{
// printf("\nOpen failed for %s-status %d",fname,status);
}
else
{
opened=1;
// DECLARATION!
struct FIL_SPEC fil_spec;
get_bstat(&fil_spec);
file_flag=fil_spec.FILE_FLAG;
if ( len )
{
rec_len=len;
// get the fixed len from the FIL_SPEC
fixed_len=fil_spec.REC_LEN;
}
else
{
if ( file_flag&1 ) // variable len?
{
rec_len=5000; // assume 5000, what the heck...
}
else
{
rec_len=fil_spec.REC_LEN;
}
fixed_len=fil_spec.REC_LEN;
}
last_rec_len=0;
num_keys=fil_spec.NDX_CNT;
data=new char[rec_len];
if ( data==0 )
{
close();
opened=0;
status=BERR_MEM_ALLOC;
}
}
return(status);
}
int bfile::close()
{
if ( data!=0 )
{
delete data;
data=0;
}
if ( !(opened) )
{
return 0;
}
else
{
status=BTRV(B_CLOSE,pos_blk,data,&rec_len,fname,mode);
opened=0;
return 1;
}
}
int bfile::open(int newmode)
{
if ( opened )
{
return 0;
}
if ( newmode!=-99 )
{
mode=newmode;
}
opened=0;
data=new char[rec_len];
if ( data==0 )
{
// printf("\nOpen failed for %s-No memory",fname);
status=BERR_MEM_ALLOC;
}
if ( owner!=0 )
{
strcpy(data,owner);
}
status=BTRV(B_OPEN,pos_blk,data,&rec_len,fname,mode);
if ( status )
{
delete data;
data=0;
}
else
{
opened=1;
}
return(status);
}
int bfile::get_rec(char *keystr,int op)
{
int tlen;
if ( !(opened) || data==0 )
{
return(BERR_NO_OPEN); // btrieve status for not opened...
}
tlen=rec_len;
memset(data,EOS,rec_len);
status=BTRV(op,pos_blk,data,&tlen,keystr,key_num);
last_rec_len=tlen;
return(status);
}
int bfile::put_rec(char *keystr,int tlen,int just_update)
{
char *tdata;
char tkey[128];
int stat;
tdata=new char[rec_len];
memcpy(tdata,data,rec_len);
memcpy(tkey,keystr,128);
// This is how I save btrieve data. I understand that there is some
// potential for problem with this, since by always re-establishing
// positioning, I won't know if someone changed the data since I last
// got the rec, but in things I have done, I lock the records first
// anyway...
// 11/12/91 IF just_update==1, then just update data using current pos
stat=BERR_NONE;
if ( !(just_update) && (stat=get_rec(keystr))!=0 )
{
if ( stat!=BERR_REC_NOT_FOUND && stat!=BERR_EOF && stat!=BERR_NONE )
{
delete tdata;
return(stat);
}
// new record?
if ( tlen==0 )
{
tlen=rec_len;
}
status=BTRV(B_INSERT,pos_blk,tdata,&tlen,tkey,key_num);
last_rec_len=tlen;
}
else
{
if ( tlen==0 )
{
tlen=rec_len;
}
status=BTRV(B_UPDATE,pos_blk,tdata,&tlen,tkey,key_num);
last_rec_len=tlen;
}
if ( !(status) )
{
memcpy(data,tdata,rec_len);
strcpy(keystr,tkey);
}
delete tdata;
return status;
}
int bfile::del_rec(char *tkeystr)
{
char *tdata;
char tkey[128];
char keystr[256];
int stat;
strcpy(keystr,tkeystr);
// use tdata so as not to destroy infor in data...
tdata=new char[rec_len];
memcpy(tdata,data,rec_len);
memcpy(tkey,keystr,128);
if ( tkeystr!=0 && (stat=get_rec(keystr))!=0 )
{
delete tdata;
return(stat);
}
else
{
status=BTRV(B_DELETE,pos_blk,tdata,&rec_len,tkey,key_num);
}
if ( !(status) )
{
memcpy(data,tdata,rec_len);
strcpy(keystr,tkey);
}
delete tdata;
return status;
}
void bfile::get_bstat(struct FIL_SPEC *fil_spec)
{
memset((char *)fil_spec,EOS,(sizeof(struct FIL_SPEC)));
int tlen=(sizeof(struct FIL_SPEC));
char temp[60]; // S/B big enough to hold extension file name if
// name is returned.
status=BTRV(B_STAT,pos_blk,(char *)fil_spec,&tlen,temp,mode);
if ( status==22 )
{
status=0;
}
}
int bfile::set_pos(char *buf,char *keystr)
{
int tlen=rec_len;
char temp[256];
memcpy(data,buf,4);
status=BTRV(B_GET_DIRECT,pos_blk,data,&tlen,temp,key_num);
if ( keystr )
{
strcpy(keystr,temp);
}
return(status);
}
int bfile::clone_file(char *destfname,int overwrite)
{
struct FIL_SPEC fil_spec;
int tlen=(sizeof(struct FIL_SPEC));
char new_pos[128];
int newstat;
int tkey;
if ( overwrite )
{
tkey=0;
}
else
{
tkey=-1;
}
get_bstat(&fil_spec);
if ( !(get_status()) )
{
newstat=BTRV(B_CREATE,new_pos,(char *)&fil_spec,&tlen,destfname,tkey);
}
else
{
newstat=get_status();
}
return(newstat);
}
int bfile::get_key_len(int tkey_num)
{
struct FIL_SPEC fil_spec;
int key_loop;
int key_len=0;
if ( tkey_num==-1 )
{
tkey_num=key_num;
}
get_bstat(&fil_spec);
int loop;
for ( loop=0,key_loop=0 ; key_loop<tkey_num && loop<24 ; loop++ )
{
if ( !(fil_spec.KEY_BUF[loop].KEY_FLAG&16) ) // last seg?
{
key_loop++;
}
}
while ( loop<24 &&
(fil_spec.KEY_BUF[loop].KEY_FLAG&16) ) // another seg?
{
key_len+=fil_spec.KEY_BUF[loop].KEY_LEN;
loop++;
}
key_len+=fil_spec.KEY_BUF[loop].KEY_LEN;
return(key_len);
}
// Insert. made seperate functions to force insert.
int bfile::insert(char *keystr,int tlen)
{
char tkey[128];
if ( keystr!=0 )
{
strcpy(tkey,keystr);
}
else
{
key_from_data(tkey);
}
if ( tlen==0 )
{
tlen=rec_len;
}
status=BTRV(B_INSERT,pos_blk,data,&tlen,tkey,key_num);
last_rec_len=tlen;
return status;
}
int bfile::key_from_data(char *t)
{
struct FIL_SPEC fil_spec;
int key_loop;
int key_len=0;
get_bstat(&fil_spec);
int loop;
for ( loop=0,key_loop=0 ; key_loop<key_num && loop<24 ; loop++ )
{
if ( !(fil_spec.KEY_BUF[loop].KEY_FLAG&16) ) // last seg?
{
key_loop++;
}
}
while ( loop<24 &&
(fil_spec.KEY_BUF[loop].KEY_FLAG&16) ) // another seg?
{
key_len+=fil_spec.KEY_BUF[loop].KEY_LEN;
memcpy(t,&data[fil_spec.KEY_BUF[loop].KEY_POS-1],
fil_spec.KEY_BUF[loop].KEY_LEN);
loop++;
}
key_len+=fil_spec.KEY_BUF[loop].KEY_LEN;
memcpy(t,&data[fil_spec.KEY_BUF[loop].KEY_POS-1],
fil_spec.KEY_BUF[loop].KEY_LEN);
return(key_len);
}
long bfile::num_links(int tkey)
{
struct FIL_SPEC fil_spec;
int key_loop;
get_bstat(&fil_spec);
int loop;
for ( loop=0,key_loop=0 ; key_loop<tkey && loop<24 ; loop++ )
{
if ( !(fil_spec.KEY_BUF[loop].KEY_FLAG&16) ) // last seg?
{
key_loop++;
}
}
return( fil_spec.KEY_BUF[loop].KEY_TOTAL );
}