📄 tododb.c
字号:
/******************************************************************************
*
* Copyright (c) 1995-2003 PalmSource, Inc. All rights reserved.
*
* File: ToDoDB.c
*
* Release: Palm OS 5 SDK (68K) R3.
*
* Description:
* To Do Manager routines
*
*****************************************************************************/
// Set this to get to private database defines
#define __TODOMGR_PRIVATE__
#include <PalmOS.h>
#include "ToDo.h"
#include "ToDoDB.h"
// Export error checking routines
void ECToDoDBValidate(DmOpenRef dbP);
/************************************************************
* Private routines used only in this module
*************************************************************/
/************************************************************
*
* FUNCTION: ECToDoDBValidate
*
* DESCRIPTION: This routine validates the integrity of the to do
* datebase.
*
* PARAMETERS: database pointer
*
* RETURNS: nothing
*
* CREATED: 6/22/95
*
* BY: Art Lamb
*
*************************************************************/
#if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL
#define maxDescLen 256
#define maxNoteLen 4096
void ECToDoDBValidate (DmOpenRef dbP)
{
UInt16 i;
UInt16 size;
UInt16 cLen;
UInt16 recSize;
UInt16 descLen;
UInt16 noteLen;
UInt16 numRecord;
UInt16 priority;
Char * c;
Char * note;
MemHandle recH;
ToDoDBRecordPtr rec;
numRecord = DmNumRecords (dbP);
for (i = 0 ; i < numRecord; i++)
{
recH = DmQueryRecord (dbP, i);
if (! recH) continue;
rec = MemHandleLock (recH);
priority = rec->priority & priorityOnly;
ErrFatalDisplayIf (priority > toDoMaxPriority, "DB integrity error");
descLen = StrLen (&rec->description);
ErrFatalDisplayIf (descLen > maxDescLen, "DB integrity error");
note = &rec->description + descLen + 1;
noteLen = StrLen (note);
ErrFatalDisplayIf (noteLen > maxNoteLen, "DB integrity error");
// Validate the record size.
size = sizeof (DateType) + 1;
c = &rec->description;
cLen = StrLen(c) + 1;
size += cLen;
c += cLen;
size += StrLen(c) + 1;
recSize = MemPtrSize (rec);
ErrFatalDisplayIf ( (recSize != size), "DB integrity error");
MemPtrUnlock (rec);
}
}
#endif
/************************************************************
*
* FUNCTION: DateTypeCmp
*
* DESCRIPTION: Compare two dates
*
* PARAMETERS:
*
* RETURNS:
*
* CREATED: 1/20/95
*
* BY: Roger Flores
*
*************************************************************/
static Int16 DateTypeCmp(DateType d1, DateType d2)
{
Int16 result;
result = d1.year - d2.year;
if (result != 0)
{
if (DateToInt(d1) == 0xffff)
return 1;
if (DateToInt(d2) == 0xffff)
return -1;
return result;
}
result = d1.month - d2.month;
if (result != 0)
return result;
result = d1.day - d2.day;
return result;
}
/************************************************************
*
* FUNCTION: CategoryCompare
*
* DESCRIPTION: Compare two categories
*
* PARAMETERS: attr1, attr2 - record attributes, which contain
* the category.
* appInfoH - MemHandle of the applications category info
*
* RETURNS: 0 if they match, non-zero if not
* + if s1 > s2
* - if s1 < s2
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 8/5/96 Initial Revision
*
*************************************************************/
static Int16 CategoryCompare (UInt8 attr1, UInt8 attr2, MemHandle appInfoH)
{
Int16 result;
UInt8 category1;
UInt8 category2;
ToDoAppInfoPtr appInfoP;
category1 = attr1 & dmRecAttrCategoryMask;
category2 = attr2 & dmRecAttrCategoryMask;
result = category1 - category2;
if (result != 0)
{
if (category1 == dmUnfiledCategory)
return (1);
else if (category2 == dmUnfiledCategory)
return (-1);
appInfoP = MemHandleLock (appInfoH);
result = StrCompare (appInfoP->categoryLabels[category1],
appInfoP->categoryLabels[category2]);
MemPtrUnlock (appInfoP);
return result;
}
return result;
}
/************************************************************
*
* FUNCTION: ToDoAppInfoInit
*
* DESCRIPTION: Create an app info chunk if missing. Set
* the strings to a default.
*
* PARAMETERS: database pointer
*
* RETURNS: 0 if successful, errorcode if not
*
* CREATED: 1/20/95
*
* BY: Roger Flores
*
*************************************************************/
Err ToDoAppInfoInit(DmOpenRef dbP)
{
UInt16 cardNo;
UInt16 wordValue;
MemHandle h;
LocalID dbID;
LocalID appInfoID;
ToDoAppInfoPtr nilP = 0;
ToDoAppInfoPtr appInfoP;
if (DmOpenDatabaseInfo(dbP, &dbID, NULL, NULL, &cardNo, NULL))
return dmErrInvalidParam;
if (DmDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, &appInfoID, NULL, NULL, NULL))
return dmErrInvalidParam;
if (appInfoID == 0)
{
h = DmNewHandle(dbP, sizeof (ToDoAppInfoType));
if (! h) return dmErrMemError;
appInfoID = MemHandleToLocalID (h);
DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, &appInfoID, NULL, NULL, NULL);
}
appInfoP = MemLocalIDToLockedPtr(appInfoID, cardNo);
// Clear the app info block.
DmSet (appInfoP, 0, sizeof(ToDoAppInfoType), 0);
// Initialize the categories.
CategoryInitialize ((AppInfoPtr) appInfoP, LocalizedAppInfoStr);
// I don't know what this field is used for.
wordValue = 0xFFFF;
DmWrite (appInfoP, (UInt32)&nilP->dirtyAppInfo, &wordValue,
sizeof(appInfoP->dirtyAppInfo));
// Initialize the sort order.
DmSet (appInfoP, (UInt32)&nilP->sortOrder, sizeof(appInfoP->sortOrder),
soPriorityDueDate);
MemPtrUnlock (appInfoP);
return 0;
}
/************************************************************
*
* FUNCTION: ToDoGetAppInfo
*
* DESCRIPTION: Get the app info chunk
*
* PARAMETERS: database pointer
*
* RETURNS: MemHandle to the to do application info block (ToDoAppInfoType)
*
* CREATED: 5/12/95
*
* BY: Art Lamb
*
*************************************************************/
MemHandle ToDoGetAppInfo (DmOpenRef dbP)
{
Err error;
UInt16 cardNo;
LocalID dbID;
LocalID appInfoID;
error = DmOpenDatabaseInfo (dbP, &dbID, NULL, NULL, &cardNo, NULL);
ErrFatalDisplayIf (error, "Get getting to do app info block");
error = DmDatabaseInfo (cardNo, dbID, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, &appInfoID, NULL, NULL, NULL);
ErrFatalDisplayIf (error, "Get getting to do app info block");
return ((MemHandle) MemLocalIDToGlobal (appInfoID, cardNo));
}
/************************************************************
*
* FUNCTION: ToDoGetSortOrder
*
* DESCRIPTION: This routine gets the sort order value from the
* 'to do' application info block.
*
* PARAMETERS: database pointer
*
* RETURNS: true - if the 'to do' record are sorted by priority,
* false - if the records are sorted by due date.
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 5/12/95 Initial Revision
* art 3/22/96 Rename routine and added more sort orders
*
*************************************************************/
UInt8 ToDoGetSortOrder (DmOpenRef dbP)
{
UInt8 sortOrder;
ToDoAppInfoPtr appInfoP;
appInfoP = MemHandleLock (ToDoGetAppInfo (dbP));
sortOrder = appInfoP->sortOrder;
MemPtrUnlock (appInfoP);
return (sortOrder);
}
/************************************************************
*
* FUNCTION: ToDoCompareRecords
*
* DESCRIPTION: Compare two records.
*
* PARAMETERS: database record 1
* database record 2
*
* RETURNS: -n if record one is less (n != 0)
* n if record two is less
*
* CREATED: 1/23/95
*
* BY: Roger Flores
*
* COMMENTS: Compare the two records key by key until
* there is a difference. Return -n if r1 is less or n if r2
* is less. A zero is never returned because if two records
* seem identical then their unique IDs are compared!
*
* This function accepts record data chunk pointers to avoid
* requiring that the record be within the database. This is
* important when adding records to a database. This prevents
* determining if a record is a deleted record (which are kept
* at the end of the database and should be considered "greater").
* The caller should test for deleted records before calling this
* function!
*
*************************************************************/
static Int16 ToDoCompareRecords(ToDoDBRecordPtr r1,
ToDoDBRecordPtr r2, Int16 sortOrder,
SortRecordInfoPtr info1, SortRecordInfoPtr info2,
MemHandle appInfoH)
{
Int16 result;
// Sort by priority, due date, and category.
if (sortOrder == soPriorityDueDate)
{
result = (r1->priority & priorityOnly) - (r2->priority & priorityOnly);
if (result == 0)
{
result = DateTypeCmp (r1->dueDate, r2->dueDate);
if (result == 0)
{
result = CategoryCompare (info1->attributes, info2->attributes, appInfoH);
}
}
}
// Sort by due date, priority, and category.
else if (sortOrder == soDueDatePriority)
{
result = DateTypeCmp(r1->dueDate, r2->dueDate);
if (result == 0)
{
result = (r1->priority & priorityOnly) - (r2->priority & priorityOnly);
if (result == 0)
{
result = CategoryCompare (info1->attributes, info2->attributes, appInfoH);
}
}
}
// Sort by category, priority, due date
else if (sortOrder == soCategoryPriority)
{
result = CategoryCompare (info1->attributes, info2->attributes, appInfoH);
if (result == 0)
{
result = (r1->priority & priorityOnly) - (r2->priority & priorityOnly);
if (result == 0)
{
result = DateTypeCmp (r1->dueDate, r2->dueDate);
}
}
}
// Sort by category, due date, priority
else if (sortOrder == soCategoryDueDate)
{
result = CategoryCompare (info1->attributes, info2->attributes, appInfoH);
if (result == 0)
{
result = DateTypeCmp (r1->dueDate, r2->dueDate);
if (result == 0)
{
result = (r1->priority & priorityOnly) - (r2->priority & priorityOnly);
}
}
}
return result;
}
/************************************************************
*
* FUNCTION: ToDoSize
*
* DESCRIPTION: Return the size of a ToDoDBRecordType
*
* PARAMETERS: database record
*
* RETURNS: the size in bytes
*
* CREATED: 1/10/95
*
* BY: Roger Flores
*
*************************************************************/
static UInt16 ToDoSize(ToDoDBRecordPtr r)
{
UInt16 size;
char *c;
int cLen;
c = &r->description;
cLen = StrLen(c) + 1;
size = sizeof (DateType) + 1 + cLen;
c += cLen;
size += StrLen(c) + 1;
return size;
}
/************************************************************
*
* FUNCTION: ToDoFindSortPosition
*
* DESCRIPTION: Return where a record is or should be.
* Useful to find a record or find where to insert a record.
*
* PARAMETERS: database record (not deleted!)
*
* RETURNS: the size in bytes
*
* CREATED: 1/11/95
*
* BY: Roger Flores
*
*************************************************************/
static UInt16 ToDoFindSortPosition(DmOpenRef dbP, ToDoDBRecord *newRecord,
SortRecordInfoPtr newRecordInfo)
{
int sortOrder;
sortOrder = ToDoGetSortOrder (dbP);
return (DmFindSortPosition (dbP, newRecord, newRecordInfo,
(DmComparF *)ToDoCompareRecords, sortOrder));
}
/************************************************************
*
* FUNCTION: ToDoNewRecord
*
* DESCRIPTION: Create a new record in sorted position
*
* PARAMETERS: database pointer
* database record
*
* RETURNS: ##0 if successful, errorcode if not
*
* CREATED: 1/10/95
*
* BY: Roger Flores
*
*************************************************************/
Err ToDoNewRecord(DmOpenRef dbP, ToDoItemPtr item, UInt16 category, UInt16 *index)
{
Err err;
UInt16 size;
Char zero=0;
UInt16 attr;
UInt16 newIndex;
UInt32 offset;
ToDoDBRecordPtr nilP=0;
ToDoDBRecordPtr recordP;
MemHandle recordH;
SortRecordInfoType sortInfo;
// Compute the size of the new to do record.
size = sizeDBRecord;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -