www.pudn.com > jpeg1.zip > DBF.C
/**************************************************/ /* DBMS Engine source File */ /*Copyright:WangHaiyun,HiSoft */ /*Date:1996/08/01 */ /*Last Modified: */ /**************************************************/ #include#include #include #include #include #include #include /*Open database*/ DBF *_Cdecl use(char* dbfname) { DBF *dbf; unsigned char byte_buf; int i; dbf=(DBF *)malloc(sizeof(DBF)); if((dbf->handle=open(dbf_name,O_RDWR|O_DENYNONE|O_BINARY)) ==-1) { free(dbf); return NULL; } read(dbf->handle,&byte_buf,1); if(byte_buf!=0x03&&byte_buf!=0x83) { close(dbf->handle); free(dbf); return NULL; } read(dbf->handle,&byte_buf,1); dbf->modify_date.da_year=byte_buf+1900; read(dbf->handle,&byte_buf,1); dbf->modify_date.da_mon=byte_buf; read(dbf->handle,&byte_buf,1); dbf->modify_date.da_day=byte_buf; read(dbf->handle,&(dbf->rec_count),4); read(dbf->handle,&(dbf->stru_len),2); dbf->fld_count=(dbf->stru_len-33)/32; read(dbf->handle,&(dbf->rec_len),2); dbf->dbf_stru=(DBF_STRU*)malloc(dbf->fld_count*sizeof(DBF_STRU)); lseek(dbf->handle,32L,SEEK_SET); for(i=0;i fld_count;i++) { read(dbf->handle,dbf->stru[i].field_name,11); read(dbf->handle,&(dbf->dbf_stru[i].field_type),1); read(dbf->handle,&(dbf->dbf_stru[i].field_pos),2); lseek(dbf->handle,2L,SEEK_CUR); read(dbf->handle,&(dbf->dbf_stru[i].field_len),1); read(dbf->handle,&(dbf->dbf_stru[i].field_dec),1); lseek(dbf->handle,14L,SEEK_CUR); } lseek(dbf->handle,1L,SEEK_CUR); dbf->curr_rec=(char*)malloc(dbf->rec_len+1); if(dbf->rec_count>0) { dbf->rec_no=1; read(dbf->handle,dbf->curr_rec,dbf->rec_len); dbf->curr_rec[dbf->rec_len]=0; dbf->eof=NO; } else { for(i=0;i rec_len;i++) dbf->curr_rec[i]=' '; dbf->curr_rec[dbf->rec_len]=0; dbf->rec_no=0; dbf->eof=YES; } dbf->update_tag=NO; return(dbf); } /* Close database */ int _Cdecl close_DBF(DBF* dbf) { char temp[3]; if(dbf==NULL) return 0; if(dbf->update_tag==YES) { getdate(&(dbf->modify_date)); lseek(dbf->handle,1L,SEEK_SET); tmp[0]=dbf->modify_date.da_year-1900; tmp[1]=dbf->modify_date.da_mon; tmp[2]=dbf->modify_date.da_day; write(dbf->handle,tmp,3); write(dbf->handle,&(dbf->rec_count),4); } free(dbf->curr_rec); free(dbf->dbf_stru); close(dbf->handle); free(dbf); return 1; } /*Database file pointer relative moving function */ long _Cdecl skip(DBF *dbf,int step) { if(dbf==NULL||dbf->rec_no==0) return 0; if(dbf->rec_no+step<1) step=1-dbf->rec_no; else if(dbf->rec_no+step>dbf->rec_count) { step=dbf->rec_count-dbf->rec_no; dbf->eof=YES; } dbf->rec_no+=step; if(step!=1) lseek(dbf->handle,dbf->rec_len*(step-1),SEEK_CUR); read(dbf->handle,dbf->curr_rec,dbf->rec_len); return(dbf->rec_no); } /*get current record*/ long _Cdecl get_record(DBF *dbf,char *fmt,...) { va_list arglist; int *ival; long *lval; char *sval; double *fval; GRAPH_TEXT *gval; struct date *dval; int no=1; int tmp; char *p; char word[MAX_FIELD_LEN]; if(dbf==NULL||dbf->eof==YES) return 0; va_start(arglist,fmt); for(;*fmt;fmt++) { tmp=0; while(*fmt&&isdigit(*fmt)) { tmp=tmp*10+*fmt-'0'; fmt++; } no=tmp==0?no:tmp; if(*fmt=='i'||*fmt=='l'||*fmt=='f'||*fmt=='d' ||*fmt=='s'||*fmt=='c'||*fmt=='g'||*fmt=='m') { p=dbf->curr_rec+dbf->dbf_stru[no-1].field_pos; strncpy(word,p,dbf->dbf_stru[no-1].field_len); word[dbf->dbf_stru[no-1].field_len]=0; switch(*fmt) { case 'i': ival=va_arg(arglist,int*); *ival=atoi(word); break; case 'l': lval=va_arg(arglist,long*); *lval=atol(word); break; case 'f': fval=va_arg(arglist,double *); *fval=atof(word); break; case 'd':/*note the 2000 year problem*/ dval=va_arg(arglist,struct date *); dval->da_day=atoi(word+6); word[6]=0; dval->da_mon=atoi(word+4); word[4]=0; dval->da_year=atoi(word); break; case 's': sval=va_arg(arglist,char *); strcpy(sval,word); break; case 'c': ival=va_arg(arglist,int *); *ival=word[0]; break; case 'g': gval=va_arg(arglist,GRAPH_TEXT *); memcpy(gval,word,10); break; case 'm': lval=va_arg(arglist,long *); *lval=atol(word); break; } no++; } } va_end(arglist); return(dbf->rec_no); } /*write database file current record function*/ long _Cdecl put_record(DBF *dbf,char *fmt,...) { va_list arglist; int ival; long lval; char *sval; double fval; struct date dval; GRAPH_TEXT gval; int no=1; int i; int tmp; char *p; char word[MAX_FIELD_LEN]; char format[20]; if(dbf==NULL||dbf->rec_no==0||dbf->eof==YES) return 0; va_start(arglist,fmt); for(;*fmt;fmt++) { tmp=0; while(*fmt&&isdigit(*fmt)) { tmp=tmp*10+*fmt-'0'; fmt++; } no=tmp==0?no:tmp; if(*fmt=='i'||*fmt='l'||*fmt=='f'||*fmt=='d'\ ||*fmt=='s'||*fmt=='c'||*fmt=='m'||*fmt=='g') { strcpy(format,"%"); switch(dbf->dbf_stru[no-1].field_type) { case 'N': itoa(dbf->dbf_stru[no-1].field_len,word,10); strcat(format,word); if(dbf->dbf_stru[no-1].field_dec==0) strcat(format,"d"); else { itoa(dbf->dbf_stru[no-1].field_dec,word,10); strcat(format,"."); strcat(format,word); strcat(format,"f"); } break; case 'C': strcat(format,"-"); itoa(dbf->dbf_stru[no-1].field_len,word,10); strcat(format,word); strcat(format,"s"); break; case 'D': strcat(format,"4d%02d%02d"); break; case 'L': format[0]='l'; break; case 'M': strcat(format,"010d"); } switch(*fmt) { case 'i': ival=va_arg(arglist,int); if(dbf->dbf_stru[no-1].field_dec==0) sprintf(word,format,ival); else { fval=ival; sprintf(word,format,fval); } break; case 'l': lval=va_arg(arglist,long); if(dbf->dbf_stru[no-1].field_dec==0) sprintf(word,format,lval); else { fval=lval; sprintf(word,format,fval); } break; case 'f': fval=va_arg(arglist,double); if(dbf->dbf_stru[no-1].field_dec!=0) sprintf(word,format,fval); else { lval=fval; sprintf(word,format,lval); } break; case 'd': dval=va_arg(arglist,struct date); sprintf(word,format,dval.da_year,dval.da_mon,dval.da_day); break; case 's': sval=va_arg(arglist,char *); sprintf(word,format,sval); break; case 'c': ival=va_arg(arglist,int); word[0]=format[0]=='l'?((ival=='y'||ival=='Y'||\ ival=='t'||ival=='T')?'T':'F'):ival; word[1]=0; break; case 'm': lval=va_arg(arglist,long); sprintf(word,format,lval); break; case 'g': gval=va_arg(arglist,GRAPH_TEXT); memcpy(word,&gval,10); } p=dbf->curr_rec+dbf->dbf_stru[no-1].field_pos; for(i=0;i dbf_stru[no-1].field_len;i++) *p++=word[i]; no++; } } va_end(arglist); lseek(dbf->handle,-dbf->rec_len,SEEK_CUR); write(dbf->handle,dbf->curr_rec,dbf->rec_len); dbf->update_tag=YES; return(dbf->rec_no); } /*append blank record at the end of database file*/ long _Cdecl append_blank(DBF *dbf) { if(dbf==NULL) return 0; lseek(dbf->handle,-1L,SEEK_END); strset(dbf->curr_rec,''); dbf->curr_rec[dbf->rec_len]=0x1a; write(dbf->handle,dbf->curr_rec,dbf->rec_len+1); lseek(dbf->handle,-1L,SEEK_END); dbf->curr_rec[dbf->rec_len]=0; dbf->update_tag=YES; dbf->rec_no=++(dbf->rec_count); dbf->eof=NO; return(dbf->rec_no); } /*create new database sub_rountine*/ DBF *_Cdecl create_DBF(char *dbf_name,int fld_count,DBF_STRU *dbf_stru) { DBF *dbf; unsigned char byte_buf; int i,j; int pos; char *p; dbf=(DBF*)malloc(sizeof(DBF)); _create(dbf_name,0); if((dbf->handle)=open(dbf_name,O_RDWR|O_DENYNONE|O_BINARY))==\ -1) { free(dbf); return NULL; } byte_buf=0x03; write(dbf->handle,&byte_buf,1); getdate(&(dbf->modify_date)); byte_buf=dbf->modify_date.da_year-1900; write(dbf->handle,&byte_buf,1); byte_buf=dbf->modify_date.da_mon; write(dbf->handle,&byte_buf,1); byte_buf=dbf->modify_date.da_day; write(dbf->handle,&byte_buf,1); dbf->rec_count=0; write(dbf->handle,&(dbf->rec_count),4); dbf->stru_len=fld_count*32+33; write(dbf->handle,&(dbf->stru_len),2); dbf->fld_count=fld_count; pos=1; dbf->rec_len=1; for(i=0;i rec_len+=dbf_stru[i].field_len; } write(dbf->handle,&(dbf->rec_len),2); dbf->dbf_stru=(DBF_STRU *)malloc(dbf->fld_count*sizeof(DBF_STRU)); memcpy((void *)(dbf->dbf_stru),(void*)dbf_stru,\ fld_count*sizeof(DBF_STRU)); byte_buf=0; for(i=0;i<20;i++) write(dbf->handle,&byte_buf,1); for(i=0;i handle,dbf->dbf_stru[i].field_name,11); write(dbf->handle,&(dbf->dbf_stru[i].field_type),1); write(dbf->handle,&(dbf->dbf_stru[i].field_pos),2); write(dbf->handle,&byte_buf,1); write(dbf->handle,&byte_buf,1); write(dbf->handle,&(dbf->dbf_stru[i].field_len),1); write(dbf->handle,&(dbf->dbf_stru[i].field_dec),1); for(j=0;j<14;j++) write(dbf->handle,&byte_buf,1); } byte_buf=0x0d; write(dbf->handle,&byte_buf,1); byte_buf=0x1a; write(dbf->handle,&byte_buf,1); lseek(dbf->handle,-1L,SEEK_CUR); dbf->curr_rec=(char*)malloc(dbf->rec_len+1); for(i=0;i rec_len;i++) dbf->curr_rec[i]=''; dbf->curr_rec[dbf->rec_len]=0; dbf->rec_no=0; dbf->eof=YES; dbf->update_tag=NO; return(dbf); } /*delete all the records in the database file*/ int _Cdecl zap(DBF *dbf) { char eof_tag=0x1a; if(dbf==NULL) return 0; dbf->update_tag=YES; dbf->rec_count=0; dbf->rec_no=0; dbf->eof=YES; strset(dbf->curr_rec,''); lseek(dbf->handle,4L,SEEK_SET); write(dbf->handle,&(dbf->rec_count),4); lseek(dbf->handle,dbf->stru_len,SEEK_SET); write(dbf->handle,&eof_tag,1); lseek(dbf->handle,-1L,SEEK_END); chsize(dbf->handle,dbf->stru_len+1); return 1; } /*make delete tag for the current record in the database*/ long _Cdecl delete(DBF *dbf) { if(dbf==NULL||dbf->eof==YES||dbf->rec_no==0) return 0; *(dbf->curr_rec)='*'; lseek(dbf->handle,-dbf->rec_len,SEEK_CUR); write(dbf->handle,dbf->curr_rec,dbf->rec_len); dbf->update_tag=YES; return(dbf->rec_no); } /*recall current deleted record in the database*/ long _Cdecl recall(DBF *dbf) { if(dbf==NULL||dbf->eof==YES||dbf->rec_no==0) return 0; if(*(dbf->curr_rec)=='*') { *(dbf->curr_rec)=='' lseek(dbf->handle,-dbf->rec_len,SEEK_CUR); write(dbf->handle,dbf->curr_rec,dbf->rec_len); dbf->update_tag=YES; } return(dbf->rec_no); } /*pack database:delete all delete-tagged records*/ long _Cdecl pack(DBF *dbf) { long i; char eof_tag=0x1a; if(dbf==NULL||dbf->rec_no==0) return 0; dbf->rec_no=0; for(i=0;i rec_count;i++) { lseek(dbf->handle,dbf->stru_len+i*dbf->rec_len,SEEK_SET); read(dbf->handle,dbf->curr_rec,dbf->rec_len); if(*dbf->curr_rec)!='*' { lseek(dbf->handle,dbf->stru_len+dbf->rec_no*dbf->rec_len,\ SEEK_SET); write(dbf->handle,dbf->curr_rec,dbf->rec_len); dbf->rec_no++; } } dbf->rec_count=dbf->rec_no; chsize(dbf->handle,dbf->stru_len+dbf->rec_count*dbf->rec_len+1); lseek(dbf->handle,-1L,SEEK_END); write(dbf->handle,&eof_tag,1); lseek(dbf->handle,dbf->stru_len,SEEK_SET); if(dbf->rec_count!=0) { read(dbf->handle,dbf->curr_rec,dbf->rec_len); dbf->rec_no=1; dbf->eof=NO; } else dbf->eof=YES; dbf->update_tag=YES; return(dbf->rec_count); } /*get the field number of a certain field*/ int _Cdecl field_no(DBF *dbf,char *field_name) { int i=1; while(i fld_count&&stricmp(dbf->dbf_stru[i].field_name,field_name)) i++; i=i>dbf->fld_count?i=0:i; return(i); } /*database project function*/ DBF *_Cdecl project(char *dest_name,DBF *sour,int para_num,...) { int i,k; int *no; DBF *dest; DBF_STRU *d_stru; va_list arglist; char *p,*q; d_stru=(DBF_STRU *)malloc(para_num*sizeof(DBF_STRU)); no=(int *)malloc(para_num*sizeof(int)); va_start(arglist,para_num); for(i=0;i dbf_stru[no[i]].field_name); d_stru[i].field_type=sour->dbf_stru[no[i]].field_type; d_stru[i].field_len =sour->dbf_stru[no[i]].field_len; d_stru[i].field_dec =sour->dbf_stru[no[i]].field_dec; } va_end(arglist); if((dest=create_DBF(dest_name,para_num,d_stru))=NULL) return NULL; go_record(sour,1); while(!eof_DBF(sour)) { append_blank(dest); if(isdeleted(sour)) *(dest->curr_rec)='*'; for(i=0;i curr_rec+dest->dbf_stru[i].field_pos; q=sour->curr_rec+sour->dbf_stru[no[i]].field_pos; for(k=0;k dbf_stru[i].field_len;k++) *p++=*q++; lseek(dest->handle,-(dest->rec_len),SEEK_CUR); write(dest->handle,dest->curr_rec,dest->rec_len); } skip(sour,1); } return(dest); } /*join function*/ DBF *_Cdecl join(char *dest_name,DBF *sour1,DBF *sour2,\ int field_no1,int field_no2) { int i,d_f_count,no,key_len; DBF *dest; DBF_STRU *d_stru; char *p,*q,*r,*s; d_f_count=sour1->fld_count+sour2->fld_count-1; d_stru=(DBF_STRU *)malloc(d_f_count*sizeof(DBF_STRU)); for(i=0;i fld_count;i++) { strcpy(d_stru[i].field_name,sour1->dbf_stru[i].field_name); d_stru[i].field_type=sour1->dbf_stru[i].field_type; d_stru[i].field_len =sour1->dbf_stru[i].field_len; d_stru[i].field_dec =sour1->dbf_stru[i].field_dec; } for(i=0;i fld_count;i++) { if(i!=field_no2) { no=i dbf_stru[no].field_name); d_stru[i].field_type=sour2->dbf_stru[no].field_type; d_stru[i].field_len =sour2->dbf_stru[no].field_len; d_stru[i].field_dec =sour2->dbf_stru[no].field_dec; } } if((dest=create_DBF(dest_name,d_f_count,d_stru))=NULL) return NULL; key_len=min(sour1->dbf_stru[field_no1].field_len,\ sour2->dbf_stru[field_no2].field_len); go_record(sour1,1); while(!eof_DBF(sour1)) { p=sour1->curr_rec+field_no1; go_record(sour2,1); while(!eof_DBF(sour2)) { q=sour2->curr_rec+field_no2; if(strncmp(p,q,key_len)==0) { append_blank(dest); r=dest->curr_rec+1; s=sour1->curr_rec+1; while(*s) *r++=*s++; s=sour2->curr_rec+1; while(s dbf_stru[field_no2].field_len; while(*s) *r++=*s++; lseek(dest->handle,-dest->rec_len,SEEK_END); write(dest->handle,dest->curr_rec,dest->rec_len); } skip(sour2,1); } skip(sour1,1); } return(dest); }