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++

#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;
}