📄 cdbf.cpp
字号:
// DBF.cpp: implementation of the CFDBF class.
//
//////////////////////////////////////////////////////////////////////
#include "CDBF.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFDBF::CFDBF()
{
m_nCurrOffset = 0;
m_nRecBeginOffset= 0;
m_nStructSize = 0;
m_nCurrRecNo = 0;
_open = false;
recInfo.rec_num = 0;
recInfo.rec_size = 0;
recInfo.fld_num = 0;
_open = false;
m_CurrLockType = _AutoLock;
m_FieldNum = 0;
}
CFDBF::~CFDBF()
{
ClearFieldInfo();
Close();
}
int CFDBF::Space(char *p)
{
char *s = p;
while (*s) {
if(*s == ' ')
s++;
else
return 0;
}
return 1;
}
void CFDBF::Ltrim(char *s)
{
int i=0;
int len;
char *tmp;
len=strlen(s);
if(Space(s)){
*s='\0';
return;
}
tmp=s;
for(i=0; *tmp && *tmp==' '; tmp++,i++);
memmove(s,tmp,len);
}
void CFDBF::Rtrim(char *s)
{
int len;
len=strlen(s);
char *p=s+len-1;
if (Space(s)){
*s='\0';
return;
}
while(*p==' ') p--;
*(++p)='\0';
}
void CFDBF::Alltrim(char *s)
{
if (s==NULL) return;
Ltrim(s);
Rtrim(s);
}
int CFDBF::Open(const char *filename, int opentype, int lockType)
{
unsigned char tmpstr[33];
int i,offset;
long tmpoffset;
if (_open)
{
strcpy(errMessage,"opened.");
return DBF_FAIL;
}
m_CurrLockType = lockType;
m_nCurrOffset=0;
m_nRecBeginOffset=0;
m_nStructSize=0;
m_nCurrRecNo=0;
_open=false;
recInfo.rec_num=0;
recInfo.rec_size=0;
recInfo.fld_num=0;
if (opentype == O_RDONLY)
_dbfhandle = _sopen(filename, O_RDONLY | O_BINARY, SH_DENYNO, S_IREAD );
else
_dbfhandle = _sopen(filename, O_RDWR | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE );
if (_dbfhandle==-1)
{
strcpy(errMessage,"open dbf failed.");
return DBF_FAIL;
}
if (m_CurrLockType == _AutoLock)
{
LockHead();
}
//取记录数
memset(tmpstr, 0, sizeof(tmpstr));
lseek(_dbfhandle,4L,SEEK_SET);
read(_dbfhandle,tmpstr,4L);
recInfo.rec_num = *(unsigned long *)&tmpstr;
//取记录长度
memset(tmpstr, 0, sizeof(tmpstr));
lseek(_dbfhandle, 10L, SEEK_SET);
read(_dbfhandle, tmpstr, 2L);
recInfo.rec_size = *(unsigned short *)&tmpstr;
//取文件结构长度
memset(tmpstr, 0, sizeof(tmpstr));
lseek(_dbfhandle, 8L, SEEK_SET);
read(_dbfhandle, tmpstr, 2L);
m_nStructSize = *(unsigned short *)&tmpstr;
//取字段信息
i = 0;
offset = 0;
tmpoffset= 32;
while(i < MAX_FLD_NUM)
{
lseek(_dbfhandle,tmpoffset,SEEK_SET);
//取字段名
read(_dbfhandle,tmpstr,32);
recInfo.fld_num++;
memcpy(fld_info[i].name,tmpstr,10);
fld_info[i].name[10]=0;
Alltrim(fld_info[i].name);
//取字段类型
fld_info[i].type=tmpstr[11];
//取字段长度
fld_info[i].width=tmpstr[16];
//取字段偏移量
fld_info[i].offset=offset;
//取小数位数
fld_info[i].dec_d=tmpstr[17];
offset+=fld_info[i].width;
tmpoffset+=32;
if (tmpoffset >= (long)m_nStructSize - 1)
break;
i++;
}
if (m_CurrLockType == _AutoLock)
{
UnlockHead();
}
m_nRecBeginOffset = m_nStructSize;
m_nCurrOffset = m_nRecBeginOffset;
_open = true;
strcpy(m_FileName, filename);
return DBF_SUCCESS;
}
void CFDBF::Close()
{
if (_open)
close(_dbfhandle);
m_nCurrOffset = 0;
m_nRecBeginOffset = 0;
m_nStructSize = 0;
m_nCurrRecNo = 0;
_open = false;
recInfo.rec_num = 0;
recInfo.rec_size = 0;
recInfo.fld_num = 0;
_open = false;
}
int CFDBF::LockRecord()
{
long offset;
time_t t1, t2;
int RetCode;
time(&t1);
offset = BASE_LOCK_OFFSET + m_nCurrOffset;//锁定当前
do {
RetCode = lock( _dbfhandle, offset, recInfo.rec_size);
time(&t2);
}while(difftime(t2, t1) <= 5 && RetCode != 0);
return DBF_SUCCESS;
}
int CFDBF::UnlockRecord()
{
long offset;
int RetCode = 0;
offset = BASE_LOCK_OFFSET + m_nCurrOffset;//解锁当前
RetCode =unlock(_dbfhandle, offset, recInfo.rec_size);
if(RetCode == 0)
return DBF_SUCCESS;
else
return DBF_FAIL;
}
int CFDBF::LockHead()
{
long offset;
offset = BASE_LOCK_OFFSET + 1L;
if (lock(_dbfhandle, offset, 32L)==-1)
{
strcpy(errMessage,"locking failed.");
return DBF_FAIL;
}
return DBF_SUCCESS;
}
int CFDBF::UnlockHead()
{
long offset;
offset = BASE_LOCK_OFFSET + 1L;
if (unlock(_dbfhandle, offset, 32L)==-1)
{
strcpy(errMessage,"Unlocking failed.");
return DBF_FAIL;
}
return DBF_SUCCESS;
}
int CFDBF::GoTo(long recNo)
{
m_nCurrOffset = m_nRecBeginOffset + (recNo-1) * recInfo.rec_size;
if (IsEof() || IsBof())
{
strcpy(errMessage,"is eof or bof.");
return DBF_FAIL;
}
m_nCurrRecNo=recNo;
return DBF_SUCCESS;
}
//功能:读取指定记录序号的内容到内部缓冲区
//返回值:成功:DBF_SUCCESS,失败:DBF_FAIL;
int CFDBF::ReadRecord(long recNo)
{
char tmpstr[MAX_RECORD_SIZE+1];
int nRc;
tmpstr[0]=0;
if ( recNo < 1L || recNo > GetRecordNum() )
{
return DBF_FAIL;
}
if ( (nRc = GoTo(recNo)) == DBF_FAIL )
{
return nRc;
}
if ( m_CurrLockType == _AutoLock )
{
if ((nRc = LockRecord()) == DBF_FAIL)
{
return nRc;
}
}
lseek( _dbfhandle, m_nCurrOffset, SEEK_SET );
if ( read(_dbfhandle, tmpstr, recInfo.rec_size) != recInfo.rec_size )
{
nRc = DBF_FAIL;
}
if ( m_CurrLockType == _AutoLock )
{
if ( (nRc = UnlockRecord()) == DBF_FAIL )
{
return nRc;
}
}
m_nCurrRecNo = recNo;
memcpy(recInfo.rec_data, tmpstr, recInfo.rec_size);
return DBF_SUCCESS;
}
//功能:读取当前记录的内容到内部缓冲区
int CFDBF::ReadRecord(void)
{
if (IsBof() || IsEof())
{
strcpy(errMessage,"Is Bof or Eof!");
return DBF_FAIL;
}
return ReadRecord(m_nCurrRecNo);
}
//功能:判断此记录是否已经被打上删除标记
//注意:此函数必须在读取了一条记录内容后才能使用
bool CFDBF::IsDelete()
{
if (recInfo.rec_data[0] == RECORD_DEL_FLAG)
return true;
return false;
}
//功能:根据字段名查找字段
//返回值:成功-字段序号; 失败--1
int CFDBF::FindFld(const char *fldName)
{
int i;
for(i=0; i<recInfo.fld_num; i++)
{
if ( stricmp(fld_info[i].name,fldName) == 0 )
{
return i;
}
}
return -1;
}
int CFDBF::GetFldValue(const char *fldName,char *fldValue)
{
long i;
i = FindFld(fldName);
if (i < 0)
return DBF_FAIL;
memcpy(fldValue,recInfo.rec_data+fld_info[i].offset+1,fld_info[i].width);
fldValue[fld_info[i].width]='\0';
Alltrim(fldValue);
return DBF_SUCCESS;
}
int CFDBF::GetFldValue(const char *fldName, char &fldValue)
{
long i;
i = FindFld(fldName);
if (i < 0)
return DBF_FAIL;
fldValue = recInfo.rec_data[fld_info[i].offset+1];
return DBF_SUCCESS;
}
int CFDBF::GetFldValue(const char *fldName,double &fldValue)
{
long i;
char tmpstr[30];
i = FindFld(fldName);
if (i < 0)
return DBF_FAIL;
memcpy(tmpstr,recInfo.rec_data+fld_info[i].offset+1,fld_info[i].width);
tmpstr[fld_info[i].width]='\0';
Alltrim(tmpstr);
if (memcmp(tmpstr, "-.", 2) == 0)
strcpy(tmpstr, "0");
fldValue = atof(tmpstr);
return DBF_SUCCESS;
}
int CFDBF::GetFldValue(const char *fldName,int &fldValue)
{
long i;
char tmpstr[30];
i = FindFld(fldName);
if (i < 0)
return DBF_FAIL;
memcpy(tmpstr,recInfo.rec_data+fld_info[i].offset+1,fld_info[i].width);
tmpstr[fld_info[i].width]='\0';
Alltrim(tmpstr);
if (stricmp(tmpstr, "-") == 0)
strcpy(tmpstr, "0");
fldValue = atoi(tmpstr);
return DBF_SUCCESS;
}
int CFDBF::GetFldValue(const char *fldName,long &fldValue)
{
long i;
char tmpstr[30];
i = FindFld(fldName);
if (i < 0)
return DBF_FAIL;
memcpy(tmpstr,recInfo.rec_data+fld_info[i].offset+1,fld_info[i].width);
tmpstr[fld_info[i].width]='\0';
Alltrim(tmpstr);
if (stricmp(tmpstr, "-") == 0)
strcpy(tmpstr, "0");
fldValue = atol(tmpstr);
return DBF_SUCCESS;
}
//功能:判断记录指针是否在最后一条记录之后
bool CFDBF::IsEof()
{
if (m_nCurrOffset >= (m_nRecBeginOffset + recInfo.rec_num * recInfo.rec_size) )
{
return true;
}
return false;
}
//功能:判断是否记录指针在第一条记录之前
bool CFDBF::IsBof()
{
if (m_nCurrOffset < m_nRecBeginOffset)
{
return true;
}
return false;
}
int CFDBF::ModifyFileDate()
{
int nRc;
time_t t;
struct tm tmlocal;
t = ::time(&t);
tmlocal = *(::localtime(&t));
f_date[0] = (unsigned char)(tmlocal.tm_year % 100);
f_date[1] = (unsigned char)(tmlocal.tm_mon + 1);
f_date[2] = (unsigned char)tmlocal.tm_mday;
lseek(_dbfhandle, 1L, SEEK_SET);
if (m_HeadLockType == 'H')
{
if ((nRc = LockHead())==DBF_FAIL)
{
return nRc;
}
}
write(_dbfhandle, f_date, 3);
if (m_HeadLockType == 'H')
{
if ((nRc = UnlockHead())==DBF_FAIL)
{
return nRc;
}
}
return DBF_SUCCESS;
}
int CFDBF::GetRecordNum()
{
char tmpstr[10];
//取记录数
if (m_CurrLockType == _AutoLock)
{
LockHead();
}
memset(tmpstr, 0, sizeof(tmpstr));
lseek(_dbfhandle,4L,SEEK_SET);
read(_dbfhandle,tmpstr,4L);
recInfo.rec_num = *(unsigned long *)&tmpstr;
if (m_CurrLockType == _AutoLock)
{
UnlockHead();
}
return recInfo.rec_num;
}
/*int CFDBF::EditBegin()
{
int nRc;
if (!_open)
{
strcpy(errMessage,"not open");
return DBF_FAIL;
}
nRc=LockRecord();
if (nRc==DBF_FAIL)
return nRc;
return DBF_FAIL;
}
int CFDBF::EditEnd()
{
int nRc;
if (!_open)
{
strcpy(errMessage,"not open");
return DBF_FAIL;
}
nRc=UnlockRecord();
if (nRc==DBF_FAIL)
return nRc;
return DBF_FAIL;
}
*/
long CFDBF::AddNewEmptyRecord()
{
memset(recInfo.rec_data, ' ', sizeof(recInfo.rec_data)); //置空
return recInfo.rec_num++;
}
int CFDBF::UpdateNewRecord()
{
//在AddNewEmptyRecord,FillFldValue 填写recInfo.rec_data值之后调用
int nRc;
unsigned long tmp_rec_num=0;
char tmpchr[2];
/////////////////////
if (LockFile() == DBF_FAIL)
return ((int)DBF_FAIL);
GetRecordNum();
m_nCurrOffset = m_nRecBeginOffset + recInfo.rec_num * recInfo.rec_size;
lseek(_dbfhandle, m_nCurrOffset + recInfo.rec_size, SEEK_SET); //偏移到文件未
nRc = write(_dbfhandle, recInfo.rec_data, recInfo.rec_size);//写纪录
if (nRc != recInfo.rec_size)
{
UnlockFile();
return ((int)DBF_FAIL);
}
tmp_rec_num = recInfo.rec_num + 1L;
//写记录数
lseek(_dbfhandle, 4L, SEEK_SET);
nRc = write(_dbfhandle, &tmp_rec_num, 4);
recInfo.rec_num++; //纪录数增加
////////////
lseek(_dbfhandle, m_nCurrOffset + recInfo.rec_size, SEEK_SET); //写文件结束符
tmpchr[0] = FILE_EOF_FLAG;
nRc = write(_dbfhandle, tmpchr, 1);
m_HeadLockType = 'F';
ModifyFileDate();
if (UnlockFile() == DBF_FAIL)
return ((int)DBF_FAIL);
return DBF_SUCCESS;
}
int CFDBF::FillFldValue(const char *fldName, const char *fldValue)
{
char fmt[30], tmpstr[MAX_FLD_DATALEN];
long i;
i = FindFld(fldName);
if (i < 0)
return DBF_FAIL;
sprintf(fmt,"%%-%ds",fld_info[i].width);
sprintf(tmpstr,fmt,fldValue);
memcpy(recInfo.rec_data+1+fld_info[i].offset, tmpstr, fld_info[i].width);
return DBF_SUCCESS;
}
int CFDBF::FillFldValue(const char *fldName, int fldValue)
{
char fmt[30], tmpstr[MAX_FLD_DATALEN];
long i;
i = FindFld(fldName);
if (i < 0)
return DBF_FAIL;
sprintf(fmt,"%%%dd",fld_info[i].width);
sprintf(tmpstr,fmt,fldValue);
memcpy(recInfo.rec_data+1+fld_info[i].offset, tmpstr, fld_info[i].width);
return DBF_SUCCESS;
}
int CFDBF::FillFldValue(const char *fldName, char fldValue)
{
long i;
i = FindFld(fldName);
if (i < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -