#pragma once #pragma pack(push, 1) struct DBHeader { unsigned short m_usRecordLength; // Record length unsigned short m_usHeaderLength; // Length of the header block. unsigned char m_ucFileType; // File type // 00 - DB file for an keyed table // 02 - DB file for an unkeyed table unsigned char m_ucBlockSize; // Data block size code 01 - Block size is 1k 02 - Block size is 2k 03 - Block size is 3k (not used in 4.5) 04 - Block size is 4k unsigned int m_uiRecordNum; // Number of records in DB unsigned short m_usBlockNum; // Number of blocks in use unsigned short m_usTotalBlockNum; // Total blocks in file unsigned short m_usFirstBlock; // First data block (always 1) unsigned short m_usLastBlock; // Last block in use char m_cSpace1[15]; // unsigned char m_ucFieldNum; // Number of fields char m_cSpace2; unsigned char m_ucKeyFieldNum; // Number of key fields char m_cSpace3[41]; unsigned short m_usFreeBlock; // Block number of first free block }; struct DBBlock { unsigned short m_usNextBlock; // Next block number (Zero if last block) unsigned short m_usPrevBlock; // Previous block number (Zero if first block) unsigned short m_usLastBlockOffset; // Offset of last record in block }; struct FieldInfo { unsigned char m_ucType;//字段的类型 unsigned char m_ucLength;//字段的长度 }; #pragma pack(pop) //一个Record里面最多255个Field #define MAX_FIELD 256 class CDBFile : public NiMemObject { private: DBHeader* m_pkHeader; char* m_pcData; unsigned int m_uiSize; unsigned int m_uiFieldOffsets[MAX_FIELD]; unsigned int* m_puiRecordOffsets; public: CDBFile(void); virtual ~CDBFile(void); virtual bool Load(const char* pcName); virtual void Unload(); unsigned int GetRecordCount() const { return m_pkHeader->m_uiRecordNum; } const void* GetField(unsigned int uiRecord, unsigned int uiField) { NIASSERT( uiRecord < GetRecordCount() ); NIASSERT( uiField < m_pkHeader->m_ucFieldNum ); return m_pcData + (m_puiRecordOffsets[uiRecord] + m_uiFieldOffsets[uiField]); } unsigned int GetFieldLength(unsigned int uiField) { return m_uiFieldOffsets[uiField + 1] - m_uiFieldOffsets[uiField]; } char GetChar(unsigned int uiRecord, unsigned int uiField) { return *(char*)GetField(uiRecord, uiField); } unsigned char GetUChar(unsigned int uiRecord, unsigned int uiField) { return *(unsigned char*)GetField(uiRecord, uiField); } short GetShort(unsigned int uiRecord, unsigned int uiField) { short sValue = *(short*)GetField(uiRecord, uiField); NiEndian::Swap16((char*)&sValue); return (sValue^0x8000);//反转符号位 } unsigned short GetUShort(unsigned int uiRecord, unsigned int uiField) { unsigned short usValue = *(unsigned short*)GetField(uiRecord, uiField); NiEndian::Swap16((char*)&usValue); return (usValue^0x8000);//反转符号位 } int GetInt(unsigned int uiRecord, unsigned int uiField) { int iValue = *(int*)GetField(uiRecord, uiField); NiEndian::Swap32((char*)&iValue); return (iValue^0x80000000);//反转符号位 } unsigned int GetUInt(unsigned int uiRecord, unsigned int uiField) { unsigned int uiValue = *(unsigned int*)GetField(uiRecord, uiField); NiEndian::Swap32((char*)&uiValue); return (uiValue^0x80000000);//反转符号位 } float GetFloat(unsigned int uiRecord, unsigned int uiField) { uint64 uiValue = *(uint64*)GetField(uiRecord, uiField); NiEndian::Swap64((char*)&uiValue); uiValue ^= 0x8000000000000000; double d = *reinterpret_cast(&uiValue); return (float)d; } void GetString(unsigned int uiRecord, unsigned int uiField, std::string& str); void GetTranString(unsigned int uiRecord, unsigned int uiField, std::string& str); void GetTranAddString(unsigned int uiRecord, unsigned int uiField, std::string& str); void GetUTF8String(unsigned int uiRecord, unsigned int uiField, std::string& str); };