You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
340 lines
7.4 KiB
C++
340 lines
7.4 KiB
C++
#include "stdafx.h"
|
|
#include "CDBF.h"
|
|
#include <algorithm>
|
|
#include "WriteLog.h"
|
|
|
|
using namespace std;
|
|
|
|
|
|
CDBF::CDBF(){
|
|
FIsOpened = false;
|
|
ZeroMemory(&head, sizeof(Tdbf_head));
|
|
FFieldCount = 0;
|
|
FRecNo = 0;
|
|
FieldInfo = NULL;
|
|
FCurrentBuffer = NULL;
|
|
FBuffers = NULL;
|
|
FDBF = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
CDBF::~CDBF(){
|
|
Close();
|
|
}
|
|
|
|
|
|
void CDBF::Close()
|
|
{
|
|
if(FDBF != INVALID_HANDLE_VALUE)
|
|
{
|
|
WriteLog("¹Ø±ÕDBFÎļþ:%s", FDBFFileName.c_str());
|
|
FDBFFileName = "";
|
|
CloseHandle(FDBF);
|
|
FDBF = INVALID_HANDLE_VALUE;
|
|
};
|
|
|
|
FIsOpened = false;
|
|
FFieldCount = 0;
|
|
FRecNo = 0;
|
|
ZeroMemory(FRecNos, sizeof(FRecNos));
|
|
|
|
if(FCurrentBuffer != NULL){
|
|
free(FCurrentBuffer);
|
|
FCurrentBuffer = NULL;
|
|
}
|
|
|
|
if(FBuffers != NULL){
|
|
free(FBuffers);
|
|
FBuffers = NULL;
|
|
}
|
|
|
|
if(FieldInfo != NULL){
|
|
free(FieldInfo);
|
|
FieldInfo = NULL;
|
|
};
|
|
}
|
|
|
|
|
|
bool CDBF::GetFiledInfo(){
|
|
|
|
unsigned long fields_count, ReadCount;
|
|
int OffSet;
|
|
bool bGetFieldInfo = false;
|
|
|
|
FRecNo = 0;
|
|
OffSet = 0;
|
|
|
|
fields_count =(head.head_len-sizeof(Tdbf_head)-1) / sizeof(Tfield_element);
|
|
FFieldCount = fields_count;
|
|
bGetFieldInfo = true;
|
|
|
|
FieldInfo = (Tfield_element *)malloc(fields_count*sizeof(Tfield_element));
|
|
for (int i=0;i<fields_count;i++)
|
|
{
|
|
//BlockRead(FDBF, FieldInfo[i].field_name, sizeof(Tfield_element), ReadCount);
|
|
ReadFile(FDBF, &FieldInfo[i], sizeof(Tfield_element), &ReadCount, NULL);
|
|
FieldInfo[i].offset = OffSet;
|
|
OffSet += FieldInfo[i].field_length;
|
|
if (ReadCount != sizeof(Tfield_element)){
|
|
bGetFieldInfo = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bGetFieldInfo == true) {
|
|
FCurrentBuffer = (char *)malloc(head.rec_len);
|
|
ZeroMemory(FCurrentBuffer, head.rec_len);
|
|
|
|
FBuffers = (char *)malloc(head.rec_len * PREREAD_RECORD_COUNT);
|
|
ZeroMemory(FBuffers, head.rec_len * PREREAD_RECORD_COUNT);
|
|
|
|
ZeroMemory(FRecNos, sizeof(FRecNos));
|
|
|
|
First();
|
|
}
|
|
return bGetFieldInfo;
|
|
};
|
|
|
|
|
|
bool CDBF::SetRecNo(const int nRecordNo){
|
|
unsigned long ReadCount;
|
|
int i;
|
|
|
|
if (nRecordNo == FRecNo){
|
|
return true;
|
|
}
|
|
|
|
if (nRecordNo > 0 && nRecordNo <= head.no_recs) {
|
|
for (i=0;i<PREREAD_RECORD_COUNT;i++)
|
|
if (nRecordNo == FRecNos[i]){
|
|
CopyMemory(FCurrentBuffer, &FBuffers[i*head.rec_len], head.rec_len);
|
|
FRecNo = nRecordNo;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
//Seek(FDBF, head.head_len + (Value - 1) * head.rec_len + 1);
|
|
//BlockRead(FDBF, FBuffers[0], Head.rec_len * PREREAD_RECORD_COUNT, ReadCount);
|
|
LARGE_INTEGER li;
|
|
li.QuadPart = (__int64)head.head_len + (__int64)(nRecordNo - 1) * (__int64)head.rec_len + 1;
|
|
if(SetFilePointer(FDBF, li.LowPart, &li.HighPart, 0) != INVALID_SET_FILE_POINTER){
|
|
ReadFile(FDBF, FBuffers, head.rec_len * PREREAD_RECORD_COUNT, &ReadCount, NULL);
|
|
if (ReadCount >= head.rec_len){
|
|
CopyMemory(FCurrentBuffer, FBuffers, head.rec_len);
|
|
ZeroMemory(FRecNos, sizeof(FRecNos));
|
|
for(i=0;i<ReadCount / head.rec_len;i++) {
|
|
FRecNos[i] = nRecordNo + i;
|
|
};
|
|
FRecNo = nRecordNo;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
void CDBF::First(){
|
|
SetRecNo(1);
|
|
}
|
|
|
|
void CDBF::Prior(){
|
|
SetRecNo(FRecNo - 1);
|
|
}
|
|
|
|
void CDBF::Next(){
|
|
SetRecNo(FRecNo + 1);
|
|
};
|
|
|
|
void CDBF::Last(){
|
|
SetRecNo(head.no_recs);
|
|
};
|
|
|
|
|
|
int CDBF::getFieldIndex(string FieldName){
|
|
for(int i=0; i<FFieldCount; i++){
|
|
string fa = FieldInfo[i].field_name;
|
|
fa.erase(0, fa.find_first_not_of(" "));
|
|
fa.erase(fa.find_last_not_of(" ") + 1);
|
|
transform(fa.begin(), fa.end(), fa.begin(), toupper);
|
|
|
|
string fb = FieldName;
|
|
fb.erase(0, fb.find_first_not_of(" "));
|
|
fb.erase(fb.find_last_not_of(" ") + 1);
|
|
transform(fb.begin(), fb.end(), fb.begin(), toupper);
|
|
if(fa.compare(fb) == 0)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
int CDBF::GetFieldCount(){
|
|
return FFieldCount;
|
|
};
|
|
|
|
|
|
int CDBF::GetFieldLength(int FieldNo){
|
|
int fieldLen = 0;
|
|
|
|
if (FieldNo < 1 || FieldNo > FFieldCount)
|
|
return fieldLen;
|
|
|
|
return FieldInfo[FieldNo - 1].field_length;
|
|
}
|
|
|
|
string CDBF::GetFieldName(int FieldNo){
|
|
if (FieldNo < 1 || FieldNo > FFieldCount)
|
|
return "";
|
|
|
|
return FieldInfo[FieldNo - 1].field_name;
|
|
}
|
|
|
|
string CDBF::GetFieldType(int FieldNo){
|
|
if (FieldNo < 1 || FieldNo > FFieldCount)
|
|
return "";
|
|
|
|
return &FieldInfo[FieldNo - 1].field_type;
|
|
}
|
|
|
|
string CDBF::GetFieldValue(int FieldNo){
|
|
if (FieldNo < 1 || FieldNo > FFieldCount)
|
|
return "";
|
|
size_t fieldLen = strlen(&FCurrentBuffer[FieldInfo[FieldNo - 1].offset]); ;
|
|
if(FieldInfo[FieldNo - 1].field_length < fieldLen)
|
|
{
|
|
fieldLen = FieldInfo[FieldNo - 1].field_length;
|
|
}
|
|
|
|
string Value(&FCurrentBuffer[FieldInfo[FieldNo - 1].offset], fieldLen);
|
|
Value.erase(0, Value.find_first_not_of(" "));
|
|
Value.erase(Value.find_last_not_of(" ") + 1);
|
|
transform(Value.begin(), Value.end(), Value.begin(), toupper);
|
|
return Value;
|
|
}
|
|
|
|
string CDBF::GetFieldValueByName(string FieldName){
|
|
int fieldIndex = getFieldIndex(FieldName);
|
|
return GetFieldValue(fieldIndex + 1);
|
|
}
|
|
|
|
|
|
|
|
int CDBF::GetRecordCount(){
|
|
if(FIsOpened)
|
|
return head.no_recs;
|
|
return 0;
|
|
};
|
|
|
|
|
|
string CDBF::GetFileDate()
|
|
{
|
|
if (FIsOpened)
|
|
{
|
|
FILETIME WriteTime;
|
|
if (GetFileTime(FDBF, NULL, NULL, &WriteTime))
|
|
{
|
|
FILETIME localTime;
|
|
if(FileTimeToLocalFileTime(&WriteTime, &localTime))
|
|
{
|
|
SYSTEMTIME sysTime;
|
|
if (FileTimeToSystemTime(&localTime, &sysTime))
|
|
{
|
|
char strTime[50] = {0};
|
|
sprintf(strTime, "%04d-%02d-%02dT%02d:%02d:%02d", sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
|
|
return strTime;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return "2000-01-01T00:00:00";
|
|
}
|
|
|
|
|
|
bool CDBF::Open(string FileName){
|
|
unsigned long ReadCount;
|
|
unsigned long LFileCount;
|
|
unsigned long HFileCount;
|
|
__int64 iFileSize;
|
|
__int64 iFileSize2;
|
|
bool bGetFieldInfo = false;
|
|
|
|
if (FIsOpened){
|
|
WriteLog("ÎļþÒѾ´ò¿ª:%s", FileName.c_str());
|
|
return true;
|
|
}
|
|
|
|
//WriteLog("¹Ø±ÕÎļþ¿ªÊ¼:%s", FileName.c_str());
|
|
Close();
|
|
//WriteLog("¹Ø±ÕÎļþÍê³É:%s", FileName.c_str());
|
|
|
|
//AssignFile(FDBF, FileName);
|
|
FDBF = CreateFile(FileName.c_str(), GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
|
|
if (FDBF != INVALID_HANDLE_VALUE){
|
|
FRecNo = 0;
|
|
//Reset(FDBF, 1);
|
|
//BlockRead(FDBF, head, sizeof(Tdbf_head), ReadCount);
|
|
ReadFile(FDBF, &head, sizeof(Tdbf_head), &ReadCount, NULL);
|
|
if (ReadCount == sizeof(Tdbf_head)) {
|
|
if (head.vers==0x02 || head.vers==0x03 || head.vers==0x30 ||
|
|
head.vers==0x43 || head.vers==0x63 || head.vers==0x83 ||
|
|
head.vers==0x8B || head.vers==0xCB || head.vers==0xF5 || head.vers==0xFB){
|
|
//iFileSize := FileSize(FDBF);
|
|
FDBFFileName = FileName;
|
|
LFileCount = GetFileSize(FDBF, &HFileCount);
|
|
iFileSize = HFileCount;
|
|
iFileSize = (iFileSize << 32) | LFileCount;
|
|
iFileSize2 = head.rec_len;
|
|
iFileSize2 *= head.no_recs;
|
|
iFileSize2 += head.head_len + 1;
|
|
if (iFileSize <= iFileSize2 + 1 && iFileSize >= iFileSize2 - 1){
|
|
bGetFieldInfo = GetFiledInfo();
|
|
if(bGetFieldInfo == false){
|
|
WriteLog("»ñÈ¡×Ö¶ÎÐÅϢʧ°Ü(%s)");
|
|
}
|
|
}else{
|
|
WriteLog("Îļþ´óСУÑéʧ°Ü(%s)", FileName.c_str());
|
|
}
|
|
}else{
|
|
WriteLog("ÎļþÍ·ÐÅϢУÑéʧ°Ü(%s)", FileName.c_str());
|
|
}
|
|
}else{
|
|
WriteLog("¶ÁÈ¡ÎļþÍ·ÐÅϢʧ°Ü(%s)", FileName.c_str());
|
|
}
|
|
} else {
|
|
WriteLog("´ò¿ªÎļþʧ°Ü(%s), error=%d", FileName.c_str(), GetLastError());
|
|
}
|
|
|
|
FIsOpened = bGetFieldInfo;
|
|
if (bGetFieldInfo == false)
|
|
{
|
|
Close();
|
|
};
|
|
return FIsOpened;
|
|
};
|
|
|
|
|
|
|
|
|
|
int CDBF::GetRecordSize(){
|
|
return head.rec_len;
|
|
}
|
|
|
|
void *CDBF::GetActiveBuffer(){
|
|
return FCurrentBuffer;
|
|
}
|
|
|
|
|
|
bool CDBF::IsOpened()
|
|
{
|
|
return FIsOpened;
|
|
}
|
|
|
|
int CDBF::GetRecNo()
|
|
{
|
|
return FRecNo;
|
|
}
|
|
|
|
string CDBF::GetDBFFileName()
|
|
{
|
|
return FDBFFileName;
|
|
} |