339 lines
5.7 KiB
C++
339 lines
5.7 KiB
C++
#include "stdafx.h"
|
|
#include "FPTMemoFile.h"
|
|
#include <math.h>
|
|
|
|
#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
|