📄 fldrmgr.c
字号:
/*
* Copyright (C) Obigo AB, 2002-2005.
* All rights reserved.
*
* This software is covered by the license agreement between
* the end user and Obigo AB, and may be
* used and copied only in accordance with the terms of the
* said agreement.
*
* Obigo AB assumes no responsibility or
* liability for any errors or inaccuracies in this software,
* or any consequential, incidental or indirect damage arising
* out of the use of the software.
*
*/
#include "cansilib.h"
#include "cmnconf.h"
#include "aapifile.h"
#include "aapicmn.h"
#include "gmem.h"
#include "fldrmgr.h"
#include "cache.h"
#include "checksum.h"
typedef struct
{
UINT8 flag;
UINT8 client;
UINT16 folder;
UINT32 msgFile;
UINT32 infoFile;
UINT32 date;
} IndexInfo;
typedef struct
{
UINT32 chkSum;
UINT32 version;
UINT32 date;
IndexInfo msg[CMN_MAX_NO_OF_MESSAGES];
} IndexFile;
typedef struct
{
#ifdef CMN_INDEX_DYNAMIC
UINT8 client;
#endif
CMN_BOOL isDirty;
CMN_BOOL isDirtyBackup;
int numOfMsg;
IndexFile indexFile;
} IndexTable;
typedef enum
{
FM_OPER_ANY,
FM_OPER_CREATE,
FM_OPER_DELETE,
FM_OPER_MOVE,
FM_OPER_SET_DATE,
FM_OPER_SET_METADATA,
FM_OPER_SET_FLAG,
FM_OPER_TERMINATE
} FmOperation;
#define FM_INDEX_FILE 0UL
#define FM_RETURN_ERROR -1L
#define FM_VERSION_CURRENT 1
#define FM_SAVE_BOTH_FILES 0
#define FM_SAVE_INDEX_ONLY 1
#define FM_SAVE_BACKUP_ONLY 2
#define SIZE_OF_MSGDATA (UINT32)(CMN_MAX_NO_OF_MESSAGES * sizeof(IndexInfo))
#define FM_VERSION_1_INDEX_SIZE (long)(SIZE_OF_MSGDATA + sizeof(UINT32))
#define FLDRMGR_FLAG_VALID(x) ((x) & CMN_ATTRIBUTE_VALID)
static IndexTable *myTable = NULL;
static FmResult indexTableEntryCreate( CmnClientId client, IndexTable *table,
UINT16 folder, UINT8 isNotif, UINT32 msgFile, UINT32 infoFile);
static void indexTableEntryRemove( IndexTable *table, int pos);
static FmResult indexTableClear(IndexTable *table, char category);
static void indexTableCompress(IndexTable *table);
static FmResult indexTableConvert1( CmnClientId client, IndexTable *table);
static FmResult indexTableInit( CmnClientId client, IndexTable *table);
static FmResult indexTableRead( IndexTable *to, char category);
static FmResult indexTableRead1( IndexTable *to, char category);
static FmResult indexTableSave(FmOperation operation, int save);
static FmResult indexTableSort( CmnClientId client, IndexTable *table);
static FmResult indexTableValidate( IndexTable *table, const UINT32 files[], int nr);
static CMN_BOOL indexTableVerifyChecksum( IndexTable *table);
static FmResult indexTableWrite( IndexTable *from, char category);
static CMN_BOOL initDisk( const UINT32 allFileIds[], int nrOfFiles);
static FmResult getData(CmnClientId client, UINT32 msgId, UINT32 *bytesRead,
unsigned char *data, UINT32 startPos, UINT32 bytesToRead, CMN_BOOL isList);
static FmResult setData(CmnClientId client, UINT32 msgId,unsigned char *data,
UINT32 fileSize, UINT32 startPos, CMN_BOOL isList);
static FmResult getSize(CmnClientId client, UINT32 msgId, UINT32 *chunkSize,
CMN_BOOL isList);
static FmResult setSize(CmnClientId client, UINT32 msgId, CMN_BOOL isList,
UINT32 size);
static int findIx(CmnClientId client, UINT32 msgId);
UINT32 fldrmgrGetId(CmnClientId client, UINT32 msgId, CMN_BOOL isList)
{
int i = findIx( client, msgId);
if (i >= CMN_MAX_NO_OF_MESSAGES)
{
return FM_INDEX_FILE;
}
if (isList)
{
return myTable->indexFile.msg[i].infoFile;
}
else
{
return myTable->indexFile.msg[i].msgFile;
}
}
static int findIx(CmnClientId client, UINT32 msgId)
{
int low;
int high;
int mid;
if (msgId == FM_INDEX_FILE)
{
return CMN_MAX_NO_OF_MESSAGES;
}
low = 0;
high = myTable->numOfMsg - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (msgId < myTable->indexFile.msg[mid].msgFile)
{
high = mid - 1;
}
else if (msgId > myTable->indexFile.msg[mid].msgFile)
{
low = mid + 1;
}
else if (myTable->indexFile.msg[mid].client == client)
{
return mid;
}
else
{
CMN_LOG_I(("%s(%d): Trying to access msg %d belonging to %d (%d)\n",
__FILE__, __LINE__, msgId, myTable->indexFile.msg[mid].client,
client));
return CMN_MAX_NO_OF_MESSAGES;
}
}
return CMN_MAX_NO_OF_MESSAGES;
}
FmResult fldrmgrCloseList(void *cache)
{
return cacheFileClose(cache);
}
FmResult fldrmgrCloseMessage(CmnClientId client, UINT32 msgId)
{
FmResult ret = FM_RESULT_MSGID_NOT_FOUND;
msgId = fldrmgrGetId( client, msgId, FALSE);
if (msgId != FM_INDEX_FILE)
{
FILEa_close( CMN_FILE_CATEGORY_MSG, msgId);
ret = FM_RESULT_OK;
}
return ret;
}
FmResult fldrmgrCreateMsg( CmnClientId client, UINT32 *msgId, UINT16 folderType,
UINT8 isNotif)
{
int ret;
UINT16 folder;
UINT32 infoFile = 0;
UINT32 msgFile =0;
FmResult fmResult = FM_RESULT_DISK_FULL;
*msgId = 0;
if (myTable->numOfMsg >= CMN_MAX_NO_OF_MESSAGES)
{
CMN_LOG_I(("%s(%d): Maximum number of allowed messages reached %d\n",
__FILE__, __LINE__, myTable->numOfMsg));
return FM_RESULT_INDEX_FILE_FULL;
}
ret = FILEa_create( CMN_FILE_CATEGORY_MSG, NULL, &msgFile);
if (ret == 0)
{
ret = FILEa_create( CMN_FILE_CATEGORY_MSG, NULL, &infoFile);
if (ret == 0)
{
FILEa_close( CMN_FILE_CATEGORY_MSG, infoFile);
folder = (UINT16)(client * CMN_MAX_FOLDERS + folderType);
fmResult = indexTableEntryCreate( client, myTable, folder, isNotif,
msgFile, infoFile);
if (fmResult != FM_RESULT_OK)
{
CMN_LOG_I(("%s(%d): Failed to create indexTableEntry %d\n",
__FILE__, __LINE__, fmResult));
FILEa_delete( CMN_FILE_CATEGORY_MSG, infoFile);
}
}
if (fmResult == FM_RESULT_OK)
{
*msgId = msgFile;
myTable->isDirty = TRUE;
myTable->isDirtyBackup = TRUE;
}
else
{
CMN_LOG_I(("%s(%d): Failed to create both msgFile and infoFile %d\n",
__FILE__, __LINE__, fmResult));
FILEa_close( CMN_FILE_CATEGORY_MSG, msgFile);
FILEa_delete( CMN_FILE_CATEGORY_MSG, msgFile);
}
}
return fmResult;
}
FmResult fldrmgrDeleteMsg(CmnClientId client, UINT32 msgId, CMN_BOOL shouldSave)
{
FmResult fmResult = FM_RESULT_OK;
int i = findIx( client, msgId);
if (i >= CMN_MAX_NO_OF_MESSAGES)
{
return FM_RESULT_MSGID_NOT_FOUND;
}
FILEa_close( CMN_FILE_CATEGORY_MSG, myTable->indexFile.msg[i].msgFile);
FILEa_close( CMN_FILE_CATEGORY_MSG, myTable->indexFile.msg[i].infoFile);
FILEa_delete( CMN_FILE_CATEGORY_MSG, myTable->indexFile.msg[i].msgFile);
FILEa_delete( CMN_FILE_CATEGORY_MSG, myTable->indexFile.msg[i].infoFile);
indexTableEntryRemove( myTable, i);
myTable->isDirty = TRUE;
myTable->isDirtyBackup = TRUE;
if (shouldSave)
{
fmResult = indexTableSave( FM_OPER_DELETE, FM_SAVE_BOTH_FILES);
}
return fmResult;
}
UINT32 fldrmgrGetDate(CmnClientId client, UINT32 msgId)
{
int i = findIx( client, msgId);
if (i >= CMN_MAX_NO_OF_MESSAGES)
{
return 0;
}
return myTable->indexFile.msg[i].date;
}
FmResult fldrmgrGetFlag(CmnClientId client, UINT32 msgId, UINT8 pos,
CMN_BOOL *flag)
{
int i = findIx( client, msgId);
*flag = FALSE;
if (i >= CMN_MAX_NO_OF_MESSAGES)
{
return FM_RESULT_MSGID_NOT_FOUND;
}
*flag = (myTable->indexFile.msg[i].flag & pos) != 0;
return FM_RESULT_OK;
}
FmResult fldrmgrGetList( void *cache, UINT32 startPos,
UINT32 bytesToRead, UINT32 *bytesRead, unsigned char *data)
{
return cacheFileRead( cache, data, bytesToRead, startPos, bytesRead);
}
FmResult fldrmgrGetListSize(CmnClientId client, UINT32 msgId, UINT32 *listSize)
{
return getSize( client, msgId, listSize, TRUE);
}
FmResult fldrmgrGetMessage(CmnClientId client, UINT32 msgId, UINT32 startPos,
UINT32 bytesToRead, UINT32 *bytesRead, unsigned char *data)
{
return getData( client, msgId, bytesRead, data, startPos, bytesToRead, FALSE);
}
FmResult fldrmgrGetMessageSize( CmnClientId client, UINT32 msgId,
UINT32 *messageSize)
{
return getSize( client, msgId, messageSize, FALSE);
}
UINT8 fldrmgrGetMetadata(CmnClientId client, UINT32 msgId)
{
int i = findIx( client, msgId);
if (i >= CMN_MAX_NO_OF_MESSAGES)
{
return 0xff;
}
return (UINT8)((myTable->indexFile.msg[i].flag & 0xf0) >> 4);
}
FmResult fldrmgrGetMsgDataList( CmnClientId client, UINT8 ignoreFilter,
UINT16 folderType, UINT32 startPos, UINT32 maxItems, UINT32 *items,
UINT32 arr[], UINT32 dates[], UINT8 metadata[], UINT8 attributes[])
{
UINT32 i;
UINT32 found = 0;
UINT16 folder = 0;
*items = 0;
if (folderType > CMN_MAX_FOLDERS && folderType != FM_ALL_FOLDERS)
{
return FM_RESULT_FOLDER_NOT_FOUND;
}
else if (startPos >= CMN_MAX_NO_OF_MESSAGES)
{
return FM_RESULT_ERROR;
}
if (folderType == FM_ALL_FOLDERS)
{
folder = folderType;
}
else
{
folder = (UINT16)(client * CMN_MAX_FOLDERS + folderType);
}
for (i = 0;
i < CMN_MAX_NO_OF_MESSAGES && found < maxItems &&
myTable->indexFile.msg[i].msgFile != 0; ++i)
{
if (myTable->indexFile.msg[i].client != client)
{
}
else if ((myTable->indexFile.msg[i].flag & ignoreFilter) != 0)
{
}
else if (FLDRMGR_FLAG_VALID(myTable->indexFile.msg[i].flag) == FALSE)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -