dbf文件C、C++的操作库程序.doc
求:dbf文件C/C+的操作库程序。/* DBFOP for C+ V1.00 ,1995.1.10 Develop by John,Liao Modified by Zhanghao. 1998.05.18 This Module include the C+ headfile dbfop.hpp, and C+ resource file dbfop.cpp. This module is develop for use DBF(DBASEIII,DBASEII,MFOXBASE,FOXPRO 2.x) and IDX(MFOXBASE).but use IDX only allow read or change the field that isn't key word. Support netware share .flielock,fileunlock,recordlock,recordunlock.*/* - The class DBF is interface to custom,all function that given can be invoked by use the class DBF. - 1995.7.29 Change file option fxxx to xxx like _fsopen replace with sopen 1995.7.31 Change dowith option when type='N' 1995.7.31 Add option DBF:append(),DBF:clear(); 1998.5.18 Add Foxpro 2.x DBF process.-*/#include "stdafx.h"#ifdef DEBUG#define debugm AfxMessageBox#define new DEBUG_NEW#endifstatic INT2 ccc(CHAR *,INT2,INT2);INT2 ccc(CHAR * ptsr,INT2 len,INT2 bit) CHAR temp130,temp1130,i1; CHAR temp230,temp2230,i2; INT2 tempi,i; CHAR * ps,*ps1; for(ps1=ptsr;(*ps1=' ')&&(*ps1!='x0');ps1+); ps=strchr(ps1,'.'); if(ps=NULL) / NOT HAVE '.' strcpy(temp1,ps1); temp20='x0' else *ps='x0' strcpy(temp1,ps1); ps+; strcpy(temp2,ps); i1=len-(bit?(bit+1):0); if(int)strlen(temp1)>(int)i1) strncpy(temp11,temp1,i1); temp11i1='x0' else tempi=i1-strlen(temp1); for(i=0;i<tempi;i+) temp11=' ' strcpy(temp11+tempi,temp1); / - if(bit>0) if(int)strlen(temp2)>(int)bit) strncpy(temp22,temp2,bit); temp22bit='x0' else i2=strlen(temp2); tempi=bit-strlen(temp2); strcpy(temp22,temp2); for(i=0;i<tempi;i+) (temp22+i2)='0' temp22bit='x0' strcpy(ptsr,temp11); if(bit!=0) strcat(ptsr,"." strcat(ptsr,temp22); return 0;INT2 IDX_BLOCK:skip() if(curp>=(INT2)items-1) return -2; curp+; / double return 0;INT2 IDX_BLOCK:find(CHAR * key) INT2 compi=keylen; CHAR *p=buff+12; INT2 RetCode,i; if(int)strlen(key)<(int)keylen) compi=strlen(key); for(i=0,p=buff+12;i<items;i+,p+=keylen+4) RetCode=strncmp(key,p,compi); if(RetCode=0) / Founded this key if(flag>=2) / .and. this is a leaf or leaf&root node curp=i; return 0; / Founded ,OK return to master else / .and. this is a frame or root node curp=i; return -10; / This is a ROOT,Maybe in gaven BLOCK if(RetCode<0) /if the key < curent key in idx file if(flag<2) /and this is FRAME or ROOT node curp=i; /in FRAME or ROOT node key is MAXKEY in given node return -10;/This is a ROOT,Maybe in gaven BLOCK return -3; / Maybe in NextBlockIDX:IDX() Installed=0; /fp=NULL; handle=-1; rootpos=blocks=0l; key_len=0; return ;IDX:IDX() if(this->handle!=-1) close(handle); handle=-1; / open function open the idx fileINT2 IDX:pen(CHAR * filename) CHAR buff30; / fp=_fsopen(filename,"rb",SH_DENYNONE); / change by liaoj int 1999.3.22 handle=sopen(filename,_O_RDONLY|_O_BINARY,_SH_DENYNO,_S_IREAD); /* handle=sopen(filename,O_RDWR|O_BINARY|O_DENYNONE, SH_DENYNONE,S_IREAD|S_I_write); */ / if(fp=NULL) return -1; if(handle=-1) return -1; if(_lseek(handle,0,SEEK_SET)!=0) return -1; if(read(handle,buff,30)!=30) return -1; rootpos=*(UINT4 *)buff; blocks=*(UINT4 *)(buff+; key_len=*(INT2 *)(buff+12); block.SetKeyLen(key_len); block.ReadBlock(this->handle,rootpos); while(block.GetFlag()<2) block.ReadBlock(this->handle,block.GetResult(); GoHome(); return 0;INT2 IDX:rev() UINT4 PrevBlock; if(block.Prev()!=0) PrevBlock=block.GetPrev(); if(PrevBlock=0xffffffffl) return -1; block.ReadBlock(this->handle,(INT4)PrevBlock); block.End(); return 0;INT2 IDX:Next() UINT4 NextBlock; if(block.Next()!=0) / Is already in the last node in this block NextBlock=block.GetNext(); if(NextBlock=0xffffffffl) return -2; block.ReadBlock(this->handle,(INT4)NextBlock); block.Home(); return 0;INT2 IDX:Find(CHAR * key) INT2 RetCode; block.ReadBlock(this->handle,rootpos); for(; RetCode=block.find(key); switch(RetCode) case 0: return 0; case -1: return -1; case -2: if(block.GetPrev()=(UINT4)0xffffffffl) return -1; else block.ReadBlock(this->handle,block.GetPrev(); break; case -3: if(block.GetNext()=(UINT4)0xffffffffl) return -1; else block.ReadBlock(this->handle,block.GetNext(); break; case -10: block.ReadBlock(this->handle,block.GetResult(); break; default: / - / Fatal Error : return code is not allow / in class IDX_BLOCK:find(CHAR * ); / - break; INT2 IDX:Skip() return Next();INT2 IDX:GoHome() while(block.GetPrev()!=(UINT4)0xffffffffl) block.ReadBlock(this->handle,block.GetPrev(); ; block.Home(); return 0;INT2 IDX:GoEnd() while(block.GetNext()!=(UINT4)0xffffffffl) block.ReadBlock(this->handle,block.GetNext(); ; block.End(); return 0;UINT4 IDX_BLOCK:GetResult() CHAR tf5; CHAR * p=buff+12+curp*(keylen+4); p+=keylen; tf3=p0;tf2=p1;tf1=p2;tf0=p3; return *(UINT4 * )tf;/INT2 IDX_BLOCK:ReadBlock(FILE * fp,UINT4 pos)INT2 IDX_BLOCK:ReadBlock(INT2 handle,UINT4 pos) / fseek(fp,pos,SEEK_SET); _lseek(handle,pos,SEEK_SET); / fread(buff,512l,1,fp); read(handle,buff,512); flag=buff0; count=buff1; items=buff2; prev=*(UINT4 *)(buff+4); next=*(UINT4 *)(buff+; curp=0; return 0;/-Next is DBF -DBF:BF() Installed=0; First=NULL; pIDX=NULL; handle=-1; buff=NULL; / - SwapBuffer=NULL; MaxRecNum=0; CurRecNum=0; / - current_recno=record_no=0l; record_len=0; Name0='x0' changeflag=0; dbferrno=0; fieldvalue=NULL;DBF:DBF() if(First!=NULL) delete First; First=NULL; if(SwapBuffer!=NULL) delete SwapBuffer; SwapBuffer=NULL; MaxRecNum=0; CurRecNum=0; if(pIDX!=NULL) delete First; pIDX=NULL; if(handle!=-1) / this :close(handle); handle=-1; if(buff!=NULL) delete buff; buff=NULL; if(fieldvalue!=NULL) delete fieldvalue; fieldvalue=NULL; return;INT2 DBF:Clear() memset(buff,' ',record_len); return 0;INT2 DBF:AppendBlank() CHAR tempbuf100; UINT4 temp_recno; INT2 i; INT4 offset; /- if(!Installed) / Not open this file dbferrno=ClassNotInit; sprintf(this->dbferrmsg,"ClassNotInit!" return ClassNotInit; if(_lseek(handle,0l,SEEK_SET)!=0) dbferrno=SeekFileError; sprintf(this->dbferrmsg,"SeekFileError!" return this->dbferrno; if(read(handle,tempbuf,!= this->dbferrno=ReadFileError; sprintf(this->dbferrmsg,"ReadFileError!" return this->dbferrno; temp_recno=+(*(UINT4*)(tempbuf+4); if(_lseek(handle,0l,SEEK_SET)!=0) this->dbferrno=SeekFileError; sprintf(this->dbferrmsg,"SeekFileError!" return dbferrno; if(_write(handle,tempbuf,!= this->dbferrno=WriteFileError; sprintf(this->dbferrmsg,"WriteFileError!" return dbferrno; offset=(INT4)head_len+(temp_recno-1l)*record_len; _lseek(handle,offset,SEEK_SET); for(i=0;i<record_len;i+) / fputc(0x20,fp); / FILL BLANK _write(handle," ",1); _write(handle,"x1a",1); this->ReOpen(); this->GoTo(temp_recno); return 0;INT2 DBF:Append() CHAR tempbuf100; UINT4 temp_recno; INT4 offset; if(!Installed) / Not open this file dbferrno=ClassNotInit; sprintf(this->dbferrmsg,"ClassNotInit!" return ClassNotInit; if(_lseek(handle,0l,SEEK_SET)!=0) dbferrno=SeekFileError; sprintf(this->dbferrmsg,"SeekFileError!" return SeekFileError; if(read(handle,tempbuf,!= this->dbferrno=ReadFileError; sprintf(this->dbferrmsg,"ReadFileError!" return dbferrno; temp_recno=+(*(UINT4*)(tempbuf+4);/ recordnum+1; if(_lseek(handle,0l,SEEK_SET)!=0) this->dbferrno=SeekFileError; sprintf(this->dbferrmsg,"SeekFileError!"); return dbferrno; if(_write(handle,tempbuf,!= this->dbferrno=WriteFileError; sprintf(this->dbferrmsg,"WriteFileError!"); return dbferrno; offset=(INT4)head_len+(temp_recno-1l)*record_len; if(_lseek(handle,offset,SEEK_SET)!=offset) this->dbferrno=SeekFileError; sprintf(this->dbferrmsg,"SeekFileError!"); return dbferrno; _write(handle,buff,(UINT2)record_len); _write(handle,"x1a",1); this->ReOpen(); this->GoTo(temp_recno); return 0;INT2 DBF:dbf_wbuff() /CHAR tempbuf100; INT4 offset; offset=(INT4)head_len+(current_recno-1l)*record_len; if(current_recno<=0) dbferrno=RecordOutOfRange; sprintf(this->dbferrmsg,"RecordOutOfRange!"); return dbferrno; if(changeflag=0) dbferrno=DBFOK; sprintf(this->dbferrmsg,"DBFOK!"); return DBFOK; if(_lseek(handle,offset,SEEK_SET)!=offset) dbferrno=SeekFileError; sprintf(this->dbferrmsg,"SeekFileError!"); return dbferrno; if(_write(handle,buff,(UINT2)record_len)!=(UINT2)record_len) dbferrno=WriteFileError; sprintf(this->dbferrmsg,"WriteFileError!"); return dbferrno; dbferrno=DBFOK; sprintf(this->dbferrmsg,"DBFOK!"); return DBFOK;INT2 DBF:dbf_buff() INT4 offset=(INT4)head_len+(current_recno-1l)*record_len; if(current_recno<=0) dbferrno=RecordOutOfRange; sprintf(this->dbferrmsg,"RecordOutOfRange!"); return dbferrno; if(_lseek(handle,offset,SEEK_SET)!=offset) dbferrno=SeekFileError; sprintf(this->dbferrmsg,"SeekFileError!"); return dbferrno; if(:eof(handle) dbferrno=SeekFileError; sprintf(this->dbferrmsg,"SeekFileError!"); return dbferrno; if(read(handle,buff,(UINT2)record_len)!=(UINT2)record_len) dbferrno=ReadFileError; sprintf(this->dbferrmsg,"ReadFileError!"); return dbferrno; changeflag=0; dbferrno=0; sprintf(this->dbferrmsg,"DBFOK!"); return 0;INT2 DBF:Zap() CHAR tempbuf100; if(!Installed) / Not open this file dbferrno=ClassNotInit; sprintf(this->dbferrmsg,"ClassNotInit!"); return dbferrno; _lseek(handle,0l,SEEK_SET); /if(fread(tempbuf,32l,1l,fp)!=1) if(read(handle,tempbuf,32)!=32) this->Close(); dbferrno=NotDBFFile; sprintf(this->dbferrmsg