?? mydbf.cpp
字號:
#include "stdafx.h"
#include "MyDBF.h"
#include <iostream>
CMyDBF::CMyDBF()
{
}
CMyDBF::~CMyDBF()
{
}
void CMyDBF::SetDBFFile(std::string &FilePath)
{
m_strDBFFile = FilePath;
}
// 設(shè)置 內(nèi)存池大小 及 增減值
// 數(shù)據(jù)讀取完成之后 可用空間 小于 StepNum 申請 StepNum 空間
// 可用空間 大于 StepNum 釋放 (StepNum / 2)空間
void CMyDBF::SetPoolParms(int InitNum, int StepNum)
{
m_szPoolInitNum = InitNum;
m_szPoolStepNum = StepNum;
}
// 讀取 dbf 頭部 字段參數(shù)
// 內(nèi)存池 申請 足夠的空間
bool CMyDBF::Init()
{
std::fstream fs;
fs.open(m_strDBFFile.c_str(),std::ios::in | std::ios::binary);
if (! fs.good())
return false;
// 讀取頭部
// 讀取前面 32 字節(jié)
unsigned char Data[36];
unsigned char c;
fs.seekg(0);
int i = 0;
memset(Data,0,sizeof(Data));
while(i < 32)
{
c = fs.get();
if (fs.eof())
{
fs.close();
return false;
}
Data[i++] = c;
}
long * pRecordNum = (long*)(Data + 4);
m_szHeader.RecordsNum = *pRecordNum;
short * pHeaderSize = (short *)(Data + 8);
m_szHeader.HeaderSize = *pHeaderSize;
short * pRecordSize = (short *)(Data + 10);
m_szHeader.RecordSize = *pRecordSize;
//字段數(shù)據(jù)
m_szFieldsVec.clear();
// 最后一個字符 0x0D 不讀取
int Size = m_szHeader.HeaderSize - 32 - 1;
// 最多 100 字段 100 * 32 字節(jié) = 3200
char Buff[1024*4];
memset(Buff,0,sizeof(Buff));
fs.seekg(32);
i = 0;
while(i < Size)
{
c = fs.get();
if (fs.eof())
{
fs.close();
return false;
}
Buff[i] = c;
i++;
}
// 關(guān)閉文件
fs.close();
// 所有的頭部分?jǐn)?shù)據(jù)讀完
i = 0;
int Offsize = 1;
while(i < Size)
{
// 分析字段
memset(Data,0,sizeof(Data));
int j = 0;
while(j < 32)
{
Data[j++] = Buff[i++];//*((unsigned char*)pData + (i++));
}
_FIELD szField;
memset(&szField,0,sizeof(_FIELD));
strcpy(szField.Name,(char*)Data);
_strupr(szField.Name);
long *pOffsize = (long*)(Data + 12);
if (*pOffsize == 0)
szField.RecordOffsize = Offsize;
else
szField.RecordOffsize = *pOffsize;
szField.Len = (short)Data[16];
Offsize += szField.Len;
m_szFieldsVec.push_back(szField);
}
// 內(nèi)存池
m_szFreeVec.clear();
for(i = 0; i < m_szPoolInitNum; i++)
{
void *pRecord = malloc(m_szHeader.RecordSize);
if (pRecord == NULL)
{
// 內(nèi)存不足 直接返回
return false;
}
m_szFreeVec.push_back(pRecord);
}
return true;
}
// 釋放內(nèi)存池
void CMyDBF::Uninit()
{
int i;
// 釋放已經(jīng)使用的空間
for(i = 0; i < m_szRecordVec.size(); i++)
{
void *pRecord = m_szRecordVec.at(i);
free(pRecord);
m_szRecordVec.at(i) = NULL;
}
// 釋放未被使用的空間
for(i = 0; i < m_szFreeVec.size(); i++)
{
void *pRecord = m_szFreeVec.at(i);
free(pRecord);
m_szFreeVec.at(i) = NULL;
}
}
// 讀取記錄集數(shù)據(jù)
bool CMyDBF::ReadRecordsets()
{
// 讀取文件大小
std::fstream fs;
fs.open(m_strDBFFile.c_str(),std::ios::in | std::ios::binary);
if (! fs.good())
return false;
unsigned char c;
int i;
fs.seekg(m_szHeader.HeaderSize);
bool bInvalid = false;
// 讀取所有記錄
while(! fs.eof())
{
void *pRecord = NULL;
if (! GetPoolSpaceItem(&pRecord))
break;
i = 0;
while(i < m_szHeader.RecordSize)
{
c = fs.get();
if (fs.eof())
{
bInvalid = true;
break;
}
*((unsigned char*)pRecord + i) = c;
i++;
}
if (! bInvalid)
{
m_szRecordVec.push_back(pRecord);
}
else
{
// 放回去
m_szFreeVec.push_back(pRecord);
break;
}
}
fs.close();
// 查看是否釋放空間
if(m_szFreeVec.size() > m_szPoolStepNum)
{
int FreeNum = m_szFreeVec.size() - m_szPoolStepNum;
for(i = 0; i < FreeNum; i++)
{
void *pRecord = m_szFreeVec.at(m_szFreeVec.size() - 1);
m_szFreeVec.erase(m_szFreeVec.end() - 1);
free(pRecord);
}
}
return true;
}
// 釋放記錄集數(shù)據(jù)
void CMyDBF::ReleaseRecordsets()
{
int i;
// 將使用過的空間 放入未用列表
for(i = 0; i < m_szRecordVec.size(); i++)
{
void *pRecord = m_szRecordVec.at(i);
if (pRecord != NULL)
m_szFreeVec.push_back(pRecord);
m_szRecordVec.at(i) = NULL;
}
m_szRecordVec.clear();
}
bool CMyDBF::GetPoolSpaceItem(void **pSpaceItem)
{
if (m_szFreeVec.empty())
return false;
*pSpaceItem = m_szFreeVec.at(m_szFreeVec.size() - 1);
m_szFreeVec.erase(m_szFreeVec.end() - 1);
// 查看是否要增加空間
if (m_szFreeVec.size() < m_szPoolStepNum)
{
for(int i = 0; i < m_szPoolStepNum; i++)
{
void *pRecord = malloc(m_szHeader.RecordSize);
if (pRecord == NULL)
{
// 內(nèi)存不足
break;
}
m_szFreeVec.push_back(pRecord);
}
}
return true;
}
// 獲取某條記錄某個字段的值
bool CMyDBF::GetFieldValue(void* pRecord, char *pFieldName, char* pData)
{
char Data[64];
memset(Data,0,sizeof(Data));
strcpy(Data,pFieldName);
_strupr(Data);
std::string strName = Data;
int FieldIndex = -1;
for(int i = 0; i < m_szFieldsVec.size(); i++)
{
if (strName == m_szFieldsVec.at(i).Name)
{
FieldIndex = i;
break;
}
}
if (FieldIndex < 0)
return false;
memcpy(pData,((unsigned char*)pRecord + m_szFieldsVec.at(FieldIndex).RecordOffsize),
m_szFieldsVec.at(FieldIndex).Len);
return true;
}
void CMyDBF::GetDataChar(char* pData, std::string &strData)
{
char Data[512];
memset(Data,0,sizeof(Data));
strcpy(Data,pData);
strData = Data;
BWSMGFun::TrimString(strData);
}
void CMyDBF::GetDataInteger(char* pData, long &szData)
{
szData = *(long*)pData;
}
void CMyDBF::GetDataNumber(char* pData, double &dbData)
{
char Data[64];
memset(Data,0,sizeof(Data));
strcpy(Data,pData);
dbData = atof(Data);
}
// theTm 只存儲數(shù)據(jù) 不做 tm 格式處理
void CMyDBF::GetDataDate(char* pData, tm &theTm)
{
// 20070702
char Data[64];
memset(Data,0,sizeof(Data));
memcpy(Data,pData,8);
memset(&theTm,0,sizeof(tm));
std::string strData = Data;
theTm.tm_year = atol(strData.substr(0,4).c_str());
theTm.tm_mon = atol(strData.substr(4,2).c_str());
theTm.tm_mday = atol(strData.substr(6,2).c_str());
}
void CMyDBF::GetDataDatetime(char* pData, tm &theTm)
{
char Data[64];
memset(Data,0,sizeof(Data));
memcpy(Data,pData,8);
memset(&theTm,0,sizeof(tm));
long DayNum = *(long*)Data;
long MillionSeconds = *(long*)(Data + 4);
/*
The datevalue is stored as a day number since -4831 (or something like
that). A real date like 1 jan 1900 is daynumber 0x24d9ad and therefore
stored as ad d9 24 00
Time is stored in number of milliseconds since 12 o'clock so 23.59.59
will be 0x05265818 and therefore stored as 18 58 26 05
Sometimes the entered time from the user will be slightly different
from was is stored. e.g. the user enters 0:0:1 and it is stored as 999
msec instead of 1000. So be sure to round the values instead of
trunicating.
*/
// 0001-01-01 0x001a4452
//
theTm.tm_year = 1;
theTm.tm_mon = 1;
theTm.tm_mday = 1;
theTm.tm_hour = 0;
theTm.tm_min = 0;
theTm.tm_sec = 0;
int AddDays = DayNum - 0x001a4452;
if (AddDays < 0)
return ;
int TheYear = 1;
int TheMonth = 1;
while(AddDays > 0)
{
int Day1 = BWSMGFun::GetDaysOfYears(TheYear);
if (AddDays >= Day1)
{
// 增加 1 年
theTm.tm_year += 1;
TheYear ++;
AddDays -= Day1;
}
else
{
// 增加一個月
int Day1 = BWSMGFun::GetDaysOfMonth(TheYear,TheMonth);
if (AddDays >= Day1)
{
theTm.tm_mon += 1;
TheMonth++;
AddDays -= Day1;
}
else
{
// 直接更改天數(shù)
theTm.tm_mday += AddDays;
AddDays = 0;
}
}
}
int AddSeconds = MillionSeconds / 1000 + (MillionSeconds % 1000 > 500 ? 1 : 0);
while(AddSeconds > 0)
{
if (AddSeconds >= 3600)
{
theTm.tm_hour += 1;
AddSeconds -= 3600;
}
else if (AddSeconds >= 60)
{
theTm.tm_min += 1;
AddSeconds -= 60;
}
else
{
theTm.tm_sec += AddSeconds;
AddSeconds = 0;
}
}
}
//int CMyDBF::GetDaysOfYears(int Year)
//{
// if ((Year % 4 == 0) && ((Year % 100 != 0) || (Year % 400 == 0)))
// return 366;
// else
// return 365;
//}
//
//int CMyDBF::GetDaysOfMonth(int Year, int Month)
//{
// switch(Month) {
// case 1:
// return 31;
// case 2:
// if ((Year % 4 == 0) && ((Year % 100 != 0) || (Year % 400 == 0)))
// return 29;
// else
// return 28;
// case 3:
// return 31;
// case 4:
// return 30;
// case 5:
// return 31;
// case 6:
// return 30;
// case 7:
// return 31;
// case 8:
// return 31;
// case 9:
// return 30;
// case 10:
// return 31;
// case 11:
// return 30;
// case 12:
// return 31;
// default:
// return 0;
// }
// }
//
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -