palm-os-sdk/PalmOne/Samples/Conduit/MLConduit/MLConduitPcMgr.cpp

673 lines
18 KiB
C++

/*****************************************************************************
*
* File: MLConduitPcMgr.h
* Description: Generic Conduit CMLConduitPCMgr Src File
* History: May 15 2006 - DTS
* Derived CMLConduitPCMgr from CPcMgr class
*
****************************************************************************/
#define ASSERT(f) ((void)0)
#define TRACE0(sz)
#define TRACE(sz)
#include <windows.h>
#include <string.h>
#include <stdio.h>
#ifdef METROWERKS_WIN
#include <wmem.h>
#else
#include <memory.h>
#endif
#include <sys/stat.h>
#include <TCHAR.H>
#include <syncmgr.h>
#include "MLConduitPCMgr.h"
#include "resource.h"
#ifndef NO_HSLOG
extern HANDLE hLangInstance;
#endif
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: Constructor
*
* Description: This method initializes the class object.
*
* Parameter(s): szDbName - a pointer to a character buffer specifying the
* name of the database being synced.
* pFileName - a pointer to a character buffer specifying the
* filename of the database.
* pDirName - a pointer to a character buffer specifying the
* directory where the database is stored.
* syncType - an enum value specifying the sync type to be performed.
*
* Return Value(s): None.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 03/25/98 KRM initial revision
*
*****************************************************************************/
CMLConduitPCMgr::CMLConduitPCMgr(CPLogging *pLogging, DWORD dwGenericFlags, char *szDbName, TCHAR *pFileName, TCHAR *pDirName, eSyncTypes syncType)
: CPcMgr(pLogging, dwGenericFlags, szDbName, pFileName, pDirName, syncType)
{
}
CMLConduitPCMgr::~CMLConduitPCMgr()
{
TRACE0("CMLConduitPCMgr Destructor\n");
if (m_hFile != INVALID_HANDLE_VALUE)
{
fclose((FILE *)m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
if (m_pDBInfo)
{
free( m_pDBInfo);
m_pDBInfo = NULL;
}
if (m_pSortInfo) {
free( m_pSortInfo);
m_pSortInfo = NULL;
}
if (m_pAppInfo)
{
free( m_pAppInfo);
m_pAppInfo = NULL;
}
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: ConvertPCtoGeneric()
*
* Description: This method converts records from the PC storage type to the
* CPalmRecord record type.
*
* Parameter(s): pRec - a pointer to a StorageRecordType record to be converted.
* palmRec - a CPalmRecord object to receive the converted record.
*
* Return Value(s): 0 - no error
* <0 - error code.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 03/25/98 KRM initial revision
* 05/16/06 DTS derived CPcMgr class for music library
*
*****************************************************************************/
long CMLConduitPCMgr::ConvertPCtoGeneric(StorageRecordType *pRec, CPalmRecord &palmRec)
{
long retval = 0;
DWORD dwAttrs;
MusicLibEntry mlEntry;
MusicLibEntry *pMlEntry;
ASSERT(pRec);
//Create PalmRecord from music library structure
CMLPcRecord *pcRec = (CMLPcRecord *)pRec;
char *sTitle = pcRec->GetTitle();
char *sArtist = pcRec->GetArtist();
strcpy(mlEntry.sTitle, sTitle);
strcpy(mlEntry.sArtist, sArtist);
pMlEntry = &mlEntry;
palmRec.SetRawData(sizeof(MusicLibEntry), (BYTE *)pMlEntry);
palmRec.SetCategory(pcRec->GetCategory());
//palmRec.SetIndex(pcRec->GetIndex());
palmRec.SetID(pcRec->GetRecordID());
palmRec.SetIndex((DWORD)-1);
palmRec.ResetAttribs();
dwAttrs = pcRec->GetAttributes();
//Set record attributes used during sync
if (dwAttrs & ATTRIB_UPDATE)
palmRec.SetUpdate();
if (dwAttrs & ATTRIB_DELETE)
palmRec.SetDeleted();
if (dwAttrs & ATTRIB_ARCHIVE)
palmRec.SetArchived();
if (dwAttrs & ATTRIB_NEW)
palmRec.SetNew();
// bug in not retrieving the private attribute from file
palmRec.SetPrivate((BOOL)(dwAttrs & ATTRIB_PRIVATE));
return retval;
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: ReadNextRecEntry()
*
* Description: Parse and extract entry from buffer string. The buffer contains
the following:
* <artist> <title> <recordID> <record index> <record attributes>
*
* Parameter(s): sRecord - buffer to parse
* sRecEntry - the extracted entry
dwIndex - the start index in the buffer
*
* Return Value(s): 0 - not done
* <0 - done
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 05/16/06 DTS initial version
*
*****************************************************************************/
BOOL CMLConduitPCMgr::ReadNextRecEntry(char *sRecord, char *sRecEntry, DWORD &dwIndex)
{
BOOL bDone = FALSE;
DWORD dwNewIndex = 0;
char sTmpEntry[MAX_STR_LENGTH];
for(; *(sRecord + dwIndex) != '\n' && *(sRecord + dwIndex) != '\t'; dwIndex++) {
sTmpEntry[dwNewIndex] = *(sRecord + dwIndex);
dwNewIndex++;
}
sTmpEntry[dwNewIndex] = '\0';
strcpy(sRecEntry, sTmpEntry);
if(*(sRecord + dwIndex) == '\n') {
bDone = TRUE;
}
dwIndex++;
return bDone;
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: CreatePcRecord()
*
* Description: Create pc record from buffer string
*
* Parameter(s): sRecord - buffer to parse
* pcRec - pc record to fill
*
* Return Value(s): 0 - not done
* <0 - done
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 05/16/06 DTS initial version
*
*****************************************************************************/
long CMLConduitPCMgr::CreatePcRecord(char *sRecord, CMLPcRecord *pcRec)
{
BOOL bDone;
DWORD dwIndex = 0;
char sRecEntry[MAX_STR_LENGTH];
bDone = ReadNextRecEntry(sRecord, sRecEntry, dwIndex);
pcRec->SetArtist(sRecEntry);
strcpy(sRecEntry, "");
if(!bDone) {
bDone = ReadNextRecEntry(sRecord, sRecEntry, dwIndex);
pcRec->SetTitle(sRecEntry);
strcpy(sRecEntry, "");
}
if(!bDone) {
bDone = ReadNextRecEntry(sRecord, sRecEntry, dwIndex);
DWORD dwRecID = atoi(sRecEntry);
pcRec->SetRecordID(dwRecID);
strcpy(sRecEntry, "");
}
if(!bDone) {
bDone = ReadNextRecEntry(sRecord, sRecEntry, dwIndex);
DWORD dwIndex = atoi(sRecEntry);
pcRec->SetIndex(dwIndex);
strcpy(sRecEntry, "");
}
if(!bDone) {
bDone = ReadNextRecEntry(sRecord, sRecEntry, dwIndex);
WORD wAttrs = atoi(sRecEntry);
pcRec->SetAttributes(wAttrs);
}
return 0;
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: ReadOneRecFromFile()
*
* Description: Read one music library record from file
*
* Parameter(s): palmRec -
* bDone -
*
* Return Value(s): 0 - not done
* <0 - done
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 05/16/06 DTS initial version
*
*****************************************************************************/
long CMLConduitPCMgr::ReadOneRecFromFile(CPalmRecord *palmRec, BOOL &bDone)
{
long retval = 0;
char sRecord[MAX_BUFFER_LENGTH];
CMLPcRecord *pcRec = new CMLPcRecord;
if(fgets(sRecord, MAX_BUFFER_LENGTH, (FILE *)m_hFile) == NULL || strlen(sRecord) == 0) {
bDone = TRUE;
} else if(!sRecord) {
retval = GEN_ERR_READING_DATA;
} else {
Sleep(100);
CreatePcRecord(sRecord, pcRec);
ConvertPCtoGeneric((StorageRecordType *)pcRec, *palmRec);
}
delete pcRec;
return retval;
}
/***************************************************************************
*
* Class: CPcMgr
*
* Method: RetrieveDB()
*
* Description: This method loads the database from file.
*
* Parameter(s): None.
*
* Return Value(s): 0 - no error
* <0 - error code.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 03/25/98 KRM initial revision
* 05/16/06 DTS adapted to music library conduit
*****************************************************************************/
long CMLConduitPCMgr::RetrieveDB(void)
{
m_bNeedToSave = FALSE;
if(!_tcslen((const char *)m_szDataFile))
return(GEN_ERR_INVALID_DB_NAME);
if (m_hFile == INVALID_HANDLE_VALUE)
return GEN_ERR_INVALID_DB;
BOOL bDone = FALSE;
long retval = 0;
CPalmRecord *palmRec = new CPalmRecord;
for(int i = 0; !retval && !bDone; i++){
retval = ReadOneRecFromFile(palmRec, bDone);
if(bDone || retval)
break;
AddRec(*palmRec);
palmRec->Initialize();
}
delete palmRec;
return retval;
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: ReadInData()
*
* Description: This method is used to load data in from files.
*
* Parameter(s): pBuffer - a pointer to a buffer to receive the read in data.
* dwCharsToRead - a DWORD specifying how much data to
* attempt to read.
*
* Return Value(s): 0>= - no error
* <0 - error code.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 03/25/98 KRM initial revision
* 05/15/06 DTS adapt to music library conduit
*****************************************************************************/
long CMLConduitPCMgr::ReadInData(LPVOID pBuffer, DWORD dwCharsToRead)
{
if(!fgets((char *)pBuffer, dwCharsToRead, (FILE *)m_hFile))
return GEN_ERR_READING_DATA;
return 0;
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: StoreDB()
*
* Description: This method is called to store changes back into the
* storage medium.
*
* Parameter(s): None.
*
* Return Value(s): 0 - no error
* <0 - error code.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 03/25/98 KRM initial revision
* 05/15/06 DTS adapted for music library conduit
*****************************************************************************/
long CMLConduitPCMgr::StoreDB(void)
{
if ( !m_bNeedToSave) { // if no changes, don't waste time saving
if ((!m_pCatMgr) || (!m_pCatMgr->IsChanged()))
return 0;
}
long retval = OpenDB();
if (retval)
return GEN_ERR_UNABLE_TO_SAVE;
if (m_pAppInfo) {
if (retval != 0){
CloseDB(true);
return GEN_ERR_UNABLE_TO_SAVE;
}
}
BOOL bClearAttrs = false;
CMLPcRecord *mlPcRec = new CMLPcRecord();
for (DWORD dwIndex = 0; (dwIndex < m_dwMaxRecordCount) && (!retval); dwIndex++){
if (!m_pRecordList[dwIndex]) // if there is no record, skip ahead
continue;
retval = ConvertGenericToPc(m_pRecordList[dwIndex], (BYTE *)mlPcRec, bClearAttrs);
if (retval) {
break;
}
mlPcRec->SetIndex(dwIndex);
retval = WriteOutData(mlPcRec, MAX_RECORD_SIZE);
if (retval){
CloseDB(true);
delete mlPcRec;
return GEN_ERR_UNABLE_TO_SAVE;
}
mlPcRec->Init();
}
delete mlPcRec;
CloseDB(true);
m_bNeedToSave = FALSE;
return 0;
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: WriteOutDBInfo()
*
* Description:
*
* Parameter(s):
*
* Return Value(s): 0 - no error
* <0 - error code.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
*
*
*****************************************************************************/
/*
long CMLConduitPCMgr::WriteOutDBInfo(DWORD dwRecCount)
{
long retval = 0;
BOOL bSuccess;
DWORD dwItemsToWrite = 1;
DWORD dwItemsWritten;
dwItemsWritten = fwrite(&dwRecCount, sizeof(DWORD), sizeof(dwRecCount), (FILE *)m_hFile);
Sleep(100);
return retval;
}
*/
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: ConvertGenericToPc()
*
* Description: This method converts records from the PC storage type to the
* CPalmRecord record type.
*
* Parameter(s): palmRec - a CPalmRecord object to be converted.
* pMLPcRec - a pointer to a StorageRecordType record to receive the converted data.
* bClearAttributes - a boolean specifying whether the attributes should be kept(FALSE)
* or cleared (TRUE). The default is TRUE.
*
*
* Return Value(s): 0 - no error
* <0 - error code.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 04/07/98 KRM initial revision
* 05/15/06 DTS adapted to music library conduit
*****************************************************************************/
long CMLConduitPCMgr::ConvertGenericToPc(CPalmRecord *pPalmRec, BYTE *pMLPcRec, BOOL bClearAttributes)
{
DWORD dwRecSize;
CMLPcRecord *pRecord;
BYTE *pData = NULL;
long retval = 0;
MusicLibEntry *pMLHHRec;
pRecord = (CMLPcRecord *)pMLPcRec;
pData = (BYTE *)malloc(MAX_RECORD_SIZE);
memset(pData, 0, MAX_RECORD_SIZE);
retval = pPalmRec->GetRawData(pData, &dwRecSize);
pMLHHRec = (MusicLibEntry *)pData;
pRecord->SetArtist(pMLHHRec->sArtist);
pRecord->SetTitle(pMLHHRec->sTitle);
pRecord->SetAttributes(0);
WORD wAttrs = pRecord->GetAttributes();
if (!bClearAttributes) {
if (pPalmRec->IsUpdate())
wAttrs |= ATTRIB_UPDATE;
if (pPalmRec->IsDeleted())
wAttrs |= ATTRIB_DELETE;
if (pPalmRec->IsArchived())
wAttrs |= ATTRIB_ARCHIVE;
if (pPalmRec->IsNew())
wAttrs |= ATTRIB_NEW;
if (pPalmRec->IsPrivate()) {
wAttrs |= ATTRIB_PRIVATE;
}
}
pRecord->SetAttributes(wAttrs);
pRecord->SetRecordID(pPalmRec->GetID());
pRecord->SetCategory(pPalmRec->GetCategory());
return retval;
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: WriteOutData()
*
* Description: Store the database
*
* Parameter(s): pBuffer - buffer to print to file
* dwNumberOfBytesToWrite - not used
*
*
* Return Value(s): 0 - no error
* <0 - error code.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 04/07/98 KRM initial revision
* 05/15/06 DTS adapted to music library conduit
*****************************************************************************/
long CMLConduitPCMgr::WriteOutData(LPVOID pBuffer, DWORD dwNumberOfBytesToWrite)
{
long retval = 0;
char buffer[MAX_BUFFER_LENGTH];
CMLPcRecord *rec = (CMLPcRecord *)pBuffer;
WORD wAttrs = rec->GetAttributes();
char *sTitle = rec->GetTitle();
char *sArtist = rec->GetArtist();
DWORD dwRecID = rec->GetRecordID();
DWORD dwIndex = rec->GetIndex();
sprintf(buffer, "%s\t%s\t%d\t%d\t%d\n", sArtist, sTitle, dwRecID, dwIndex, wAttrs);
fprintf((FILE *)m_hFile, "%s", buffer);
Sleep(100);
return retval;
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: CloseDB()
*
* Description: This method closes the Database file handle if it is open
*
* Parameter(s): bDontUpdate - an ignored boolean.
*
* Return Value(s): 0 - no error
* <0 - error code.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 03/25/98 KRM initial revision
* 22/05/06 DTS adapted to music library conduit
*
*****************************************************************************/
long CMLConduitPCMgr::CloseDB(BOOL bDontUpdate)
{
long retval = 0;
if (m_hFile != INVALID_HANDLE_VALUE) {
retval = fclose((FILE *)m_hFile);
Sleep(100);
m_hFile = INVALID_HANDLE_VALUE;
}
return retval;
}
/******************************************************************************
*
* Class: CMLConduitPCMgr
*
* Method: Open()
*
* Description: This method opens the actual database file.
*
* Parameter(s): mode - an enum value specifying how to open the database file.
*
* Return Value(s): 0 - no error
* <0 - error code.
*
* Revision History:
*
* Date Name Description
* ----------------------------------------------------------
* 03/25/98 KRM initial revision
* 22/05/06 DTS adapted to music library conduit
*
*****************************************************************************/
long CMLConduitPCMgr::Open(eOpenDbType mode)
{
long retval = 0;
Close();
switch (mode) {
case eRead:
m_hFile = fopen(m_szDataFile, "r");
break;
case eWrite:
m_hFile = fopen(m_szDataFile, "r+");
break;
case eReadWrite:
m_hFile = fopen(m_szDataFile, "r+");
if (m_hFile != NULL)
break;
case eCreate:
m_hFile = fopen(m_szDataFile, "w+");
break;
default:
break;
}
Sleep(100);
if (m_hFile == NULL) {
m_hFile = INVALID_HANDLE_VALUE;
retval = GEN_ERR_UNABLE_TO_OPEN_FILE;
}
return retval;
}