#include "stdafx.h" #include "FPTMemoFile.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNAMIC(CFPTMemoFile, CMemoFile) CFPTMemoFile::CFPTMemoFile() { } CFPTMemoFile::~CFPTMemoFile() { Close(); } BOOL CFPTMemoFile::Open(LPCTSTR lpszName, UINT nOpenFlag) { if (!lpszName) return FALSE; nOpenFlag = nOpenFlag | CFile::typeBinary; // Re-open is invalid if (IsOpen()) { return FALSE; } // TRY // { DBF_CHECK_ERROR( CFile::Open(lpszName, nOpenFlag), TG_DBF_ERROR_MEMO_OPEN); DBF_CHECK_ERROR( ReadHeader(),TG_DBF_ERROR_MEMO_HEAD_READ); DBF_CHECK_ERROR(m_nBlockSize > 0,TG_DBF_ERROR_MEMO_BLOCK_SIZE); m_bOpen = TRUE; // } // CATCH(CFileException, e) // { // e->ReportError(); // e->Delete(); // Close(); // } // END_CATCH return TRUE; } void CFPTMemoFile::Close() { if(m_bOpen) CMemoFile::Close(); } UINT CFPTMemoFile::GetMemoFileType() { return MEMO_TYPE_FOXPRO; } BOOL CFPTMemoFile::ReadHeader() { if (!m_hFile) return FALSE; TRY { Seek(0, CFile::begin); if(Read(&m_FPTHead, sizeof(FPT_HEAD)) != sizeof(FPT_HEAD)) return FALSE; m_nNextBlock = SWAP_DWORD_BYTE(m_FPTHead.next_block); m_nBlockSize = SWAP_WORD_BYTE(m_FPTHead.block_size); return TRUE; } CATCH(CFileException, e) { e->ReportError(); e->Delete(); } END_CATCH return FALSE; } BOOL CFPTMemoFile::WriteHeader() { if (!m_hFile) return FALSE; TRY { Seek(0, CFile::begin); Write(&m_FPTHead, sizeof(FPT_HEAD)); return TRUE; } CATCH(CFileException, e) { e->ReportError(); e->Delete(); } END_CATCH return FALSE; } BOOL CFPTMemoFile::ReadMemoRecord(DBF_ULONG lOffsetRec, DBF_LONG& nLen, CTDbfString& strMemo) { if (lOffsetRec < 0) return FALSE; strMemo = ""; if(!IsOpen()) return FALSE; // TRY // { DBF_LONG nLenMemo = 0; Seek(lOffsetRec * m_nBlockSize + sizeof(DBF_LONG),CFile::begin); DBF_CHECK_ERROR( Read(&nLenMemo, sizeof(nLenMemo)) == sizeof(DBF_LONG), TG_DBF_ERROR_MEMO_FIELD_READ); nLenMemo = SWAP_DWORD_BYTE(nLenMemo); DBF_CHECK_ERROR(nLenMemo > 0,TG_DBF_ERROR_MEMO_FIELD_READ); char* buffer = new char[nLenMemo+1]/*strMemo.GetBuffer(nLenMemo + 1)*/; DBF_CHECK_ERROR( Read(buffer, nLenMemo) == (UINT)nLenMemo, TG_DBF_ERROR_MEMO_FIELD_READ); buffer[nLenMemo] = '\0'; // strMemo.ReleaseBuffer(nLenMemo + 1); strMemo = buffer; delete [] buffer; buffer = NULL; nLen = nLenMemo; // } // CATCH(CFileException, e) // { // e->ReportError(); // e->Delete(); // // TGThrowDBFException(TG_DBF_ERROR_MEMO_FIELD_READ); // // } END_CATCH return TRUE; } BOOL CFPTMemoFile::ReadMemoRecord(DBF_ULONG lOffsetRec, DBF_LONG& nLen, unsigned char** pMemoData) { if (lOffsetRec < 0) return FALSE; *pMemoData = NULL; if(!IsOpen()) return FALSE; // TRY // { DBF_LONG nLenMemo = 0; Seek(lOffsetRec * m_nBlockSize + sizeof(DBF_LONG),CFile::begin); DBF_CHECK_ERROR( Read(&nLenMemo, sizeof(nLenMemo)) == sizeof(DBF_LONG), TG_DBF_ERROR_MEMO_FIELD_READ); nLenMemo = SWAP_DWORD_BYTE(nLenMemo); DBF_CHECK_ERROR(nLenMemo > 0,TG_DBF_ERROR_MEMO_FIELD_READ); *pMemoData = new unsigned char[nLenMemo]; DBF_CHECK_ERROR( Read(*pMemoData, nLenMemo) == (UINT)nLenMemo, TG_DBF_ERROR_MEMO_FIELD_READ); nLen = nLenMemo; // } // CATCH(CFileException, e) // { // e->ReportError(); // e->Delete(); // // TGThrowDBFException(TG_DBF_ERROR_MEMO_FIELD_READ); // // } END_CATCH return TRUE; } BOOL CFPTMemoFile::WriteMemoRecord(DBF_ULONG& lOffsetRec, DBF_LONG& nLen, CTDbfString& strMemo) { if(!IsOpen()) return FALSE; // TRY // { DBF_LONG nLenMemo = 0; if(strMemo.IsEmpty()) lOffsetRec = 0; else if(lOffsetRec > 0) { Seek(lOffsetRec * m_nBlockSize + sizeof(DBF_LONG),CFile::begin); DBF_CHECK_ERROR( Read(&nLenMemo, sizeof(nLenMemo)) == sizeof(DBF_LONG), TG_DBF_ERROR_MEMO_FIELD_READ); nLenMemo = SWAP_DWORD_BYTE(nLenMemo); nLenMemo = (DBF_LONG) ceil(((double)(nLenMemo + sizeof(DBF_LONG)))/((double)m_nBlockSize)) * m_nBlockSize - sizeof(DBF_LONG); if(nLenMemo < (int)strMemo.GetLength()) lOffsetRec = AddMemoRecord(strMemo); else UpdateMemoRecord(lOffsetRec, strMemo); } else lOffsetRec = AddMemoRecord(strMemo); // } // CATCH(CFileException, e) // { // e->ReportError(); // e->Delete(); // // TGThrowDBFException(TG_DBF_ERROR_MEMO_FIELD_WRITE); // // } END_CATCH return TRUE; } DBF_LONG CFPTMemoFile::AddMemoRecord(CTDbfString& strMemo) { DBF_ULONG lOffsetRec = 0; TRY { DBF_LONG nSign = MF_TEXTREC; DBF_LONG nLenMemo = strMemo.GetLength(); ReadHeader(); lOffsetRec = m_nNextBlock; m_nNextBlock += (DBF_LONG) ceil((double)(nLenMemo + sizeof(nSign)) / (double)m_nBlockSize); m_FPTHead.next_block = SWAP_DWORD_BYTE(m_nNextBlock); Seek(lOffsetRec * m_nBlockSize,CFile::begin); nSign = SWAP_DWORD_BYTE(nSign); Write(&nSign, sizeof(nSign)); nLenMemo = SWAP_DWORD_BYTE(nLenMemo); Write(&nLenMemo, sizeof(nLenMemo)); Write(strMemo.toLPCSTR(), strMemo.GetLength()); WriteHeader(); } CATCH(CFileException, e) { e->ReportError(); e->Delete(); } END_CATCH return lOffsetRec; } void CFPTMemoFile::UpdateMemoRecord(DBF_ULONG lOffsetRec, CTDbfString& strMemo) { TRY { DBF_LONG nLenMemo = strMemo.GetLength(); Seek(lOffsetRec * m_nBlockSize + sizeof(DBF_LONG),CFile::begin); nLenMemo = SWAP_DWORD_BYTE(nLenMemo); Write(&nLenMemo, sizeof(nLenMemo)); Write(strMemo.toLPCSTR(), strMemo.GetLength()); } CATCH(CFileException, e) { e->ReportError(); e->Delete(); } END_CATCH } #ifdef _DEBUG void CFPTMemoFile::AssertValid() const { CMemoFile::AssertValid(); } void CFPTMemoFile::Dump(CDumpContext& dc) const { CMemoFile::Dump(dc); dc << "m_nNextBlock = " << m_nNextBlock; dc << "m_nBlockSize = " << m_nBlockSize; dc << "\n"; } #endif //_DEBUG