#include "stdafx.h" #include "MemoFile.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // CMemoFile IMPLEMENT_DYNAMIC(CMemoFile, CObject) CMemoFile::CMemoFile() { m_bOpen = FALSE; m_pDBTHead = NULL; } CMemoFile::~CMemoFile() { Close(); } BOOL CMemoFile::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; } BOOL CMemoFile::IsOpen() const { return m_bOpen; } void CMemoFile::Close() { if(m_bOpen) CFile::Close(); m_bOpen = FALSE; if(m_pDBTHead != NULL) delete m_pDBTHead; m_pDBTHead = NULL; } UINT CMemoFile::GetMemoFileType() { return MEMO_TYPE_DBASE; } BOOL CMemoFile::ReadHeader() { if (!m_hFile) return FALSE; TRY { Seek(0, CFile::begin); if(m_pDBTHead == NULL) m_pDBTHead = new DBT_HEAD; if(Read(m_pDBTHead, sizeof(DBT_HEAD)) != sizeof(DBT_HEAD)) return FALSE; m_nBlockSize = m_pDBTHead->block_size; if(m_nBlockSize <= 0) m_nBlockSize = 512; return TRUE; } CATCH(CFileException, e) { e->ReportError(); e->Delete(); } END_CATCH return FALSE; } BOOL CMemoFile::WriteHeader() { if (!m_hFile) return FALSE; TRY { Seek(0, CFile::begin); Write(m_pDBTHead, sizeof(DBT_HEAD)); return TRUE; } CATCH(CFileException, e) { e->ReportError(); e->Delete(); } END_CATCH return FALSE; } BOOL CMemoFile::ReadMemoRecord(DBF_ULONG lOffsetRec, DBF_LONG& nLen, CTDbfString& strMemo) { if (lOffsetRec < 0) return FALSE; strMemo = ""; if(!IsOpen()) return FALSE; // TRY // { DBF_UCHAR* pBuffer; DBF_CHAR chCurChar = 0x0; DBF_UINT nBlockCount = 1; DBF_LONG nLenMemo = 0; DBF_LONG lMaxLen; Seek(lOffsetRec * m_nBlockSize,CFile::begin); pBuffer = new DBF_UCHAR[m_nBlockSize]; lMaxLen = (DBF_LONG)(GetLength() - GetPosition()); while(chCurChar != REC_EOF && nLenMemo < lMaxLen) { if(Read(&chCurChar, sizeof(chCurChar)) != sizeof(DBF_UCHAR)) { delete[] pBuffer; TGThrowDBFException(TG_DBF_ERROR_MEMO_FIELD_READ); } else { if(chCurChar == REC_EOF) pBuffer[nLenMemo] = '\0'; else pBuffer[nLenMemo] = chCurChar; nLenMemo++; if(nLenMemo >= nBlockCount * m_nBlockSize) { DBF_UCHAR* pBuff; nBlockCount++; pBuff = new DBF_UCHAR[nBlockCount * m_nBlockSize]; memcpy(pBuff,pBuffer,(nBlockCount - 1) * m_nBlockSize); delete[] pBuffer; pBuffer = pBuff; } } } char *_buf = new char[nLenMemo]; memcpy(_buf/*strMemo.GetBuffer(nLenMemo)*/,pBuffer,nLenMemo); // strMemo.ReleaseBuffer(nLenMemo); strMemo = _buf; delete[] _buf; delete[] pBuffer; _buf = NULL; nLen = nLenMemo; // } // CATCH(CFileException, e) // { // e->ReportError(); // e->Delete(); // // TGThrowDBFException(TG_DBF_ERROR_MEMO_FIELD_READ); // // } END_CATCH return TRUE; } BOOL CMemoFile::ReadMemoRecord(DBF_ULONG lOffsetRec, DBF_LONG& nLen, unsigned char** pMemoData) { if (lOffsetRec < 0) return FALSE; *pMemoData = NULL; if(!IsOpen()) return FALSE; // TRY // { DBF_CHAR chCurChar = 0x0; DBF_UINT nBlockCount = 1; DBF_LONG nLenMemo = 0; DBF_LONG lMaxLen; Seek(lOffsetRec * m_nBlockSize,CFile::begin); *pMemoData = new DBF_UCHAR[m_nBlockSize]; lMaxLen = (DBF_LONG)(GetLength() - GetPosition()); while(chCurChar != REC_EOF && nLenMemo < lMaxLen) { if(Read(&chCurChar, sizeof(chCurChar)) != sizeof(DBF_UCHAR)) { delete[] *pMemoData; *pMemoData = NULL; TGThrowDBFException(TG_DBF_ERROR_MEMO_FIELD_READ); } else { if(chCurChar == REC_EOF) (*pMemoData)[nLenMemo] = '\0'; else (*pMemoData)[nLenMemo] = chCurChar; nLenMemo++; if(nLenMemo >= nBlockCount * m_nBlockSize) { DBF_UCHAR* pBuff; nBlockCount++; pBuff = new DBF_UCHAR[nBlockCount * m_nBlockSize]; memcpy(pBuff,*pMemoData,(nBlockCount - 1) * m_nBlockSize); delete[] *pMemoData; *pMemoData = pBuff; } } } nLen = nLenMemo; // } // CATCH(CFileException, e) // { // e->ReportError(); // e->Delete(); // // TGThrowDBFException(TG_DBF_ERROR_MEMO_FIELD_READ); // // } END_CATCH return TRUE; } BOOL CMemoFile::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) { CTDbfString strCurMemoData; ReadMemoRecord(lOffsetRec, nLenMemo, strCurMemoData); Seek(lOffsetRec * m_nBlockSize + sizeof(DBF_LONG),CFile::begin); nLenMemo = (DBF_LONG) ceil(((double)(nLenMemo + sizeof(DBF_CHAR)))/((double)m_nBlockSize)) * m_nBlockSize - sizeof(DBF_CHAR); 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; } #ifdef _DEBUG void CMemoFile::AssertValid() const { CObject::AssertValid(); } void CMemoFile::Dump(CDumpContext& dc) const { CObject::Dump(dc); dc << "m_bOpen = " << m_bOpen; dc << "\n"; } #endif //_DEBUG DBF_LONG CMemoFile::AddMemoRecord(CTDbfString& strMemo) { DBF_ULONG lOffsetRec = 0; TRY { DBF_LONG nLenMemo = strMemo.GetLength(); ReadHeader(); lOffsetRec = m_pDBTHead->next_block; m_pDBTHead->next_block += (DBF_LONG) ceil((double)(nLenMemo + sizeof(DBF_CHAR)) / (double)m_nBlockSize); Seek(lOffsetRec * m_nBlockSize,CFile::begin); Write(strMemo.toLPCSTR(), strMemo.GetLength()); DBF_CHAR eof = REC_EOF; Write(&eof, sizeof(eof)); WriteHeader(); } CATCH(CFileException, e) { e->ReportError(); e->Delete(); } END_CATCH return lOffsetRec; } void CMemoFile::UpdateMemoRecord(DBF_ULONG lOffsetRec, CTDbfString& strMemo) { TRY { DBF_LONG nLenMemo = strMemo.GetLength(); Seek(lOffsetRec * m_nBlockSize,CFile::begin); Write(strMemo.toLPCSTR(), strMemo.GetLength()); DBF_CHAR eof = REC_EOF; Write(&eof, sizeof(eof)); } CATCH(CFileException, e) { e->ReportError(); e->Delete(); } END_CATCH }