📄 datedb.c
字号:
/******************************************************************************
*
* Copyright (c) 1995-2003 PalmSource, Inc. All rights reserved.
*
* File: DateDB.c
*
* Release: Palm OS 5 SDK (68K) R3.
*
* Description:
* Appointment Manager routines
*
*****************************************************************************/
#include <PalmOS.h>
// Set this to get to private database defines
#define __APPTMGR_PRIVATE__
#include "Datebook.h"
/***********************************************************************
*
* Internal Structutes
*
***********************************************************************/
// The following structure doesn't really exist. The first field
// varies depending on the data present. However, it is convient
// (and less error prone) to use when accessing the other information.
typedef struct {
ApptDateTimeType when;
ApptDBRecordFlags flags; // A flag set for each datum present
char firstField;
UInt8 reserved;
} ApptPackedDBRecordType;
typedef ApptPackedDBRecordType * ApptPackedDBRecordPtr;
typedef struct {
DmOpenRef dbP;
UInt16 cardNo;
LocalID dbID;
DatebookPreferenceType prefs;
} AlarmPostingData;
typedef AlarmPostingData * AlarmPostingDataPtr;
typedef Int16 comparF (const void *, const void *, UInt16 other);
/***********************************************************************
*
* Internal Routines
*
***********************************************************************/
void ECApptDBValidate (DmOpenRef dbP);
static Int16 TimeCompare (TimeType t1, TimeType t2);
static Int16 DateCompare (DateType d1, DateType d2);
/************************************************************
*
* FUNCTION: ECApptDBValidate
*
* DESCRIPTION: This routine validates the integrity of a
* datebook datebase.
*
* PARAMETERS: database pointer
*
* RETURNS: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 11/15/95 Initial Revision
*
*************************************************************/
#if EMULATION_LEVEL != EMULATION_NONE
#define maxDescLen tableMaxTextItemSize
#define maxNoteLen noteViewMaxLength
void ECApptDBValidate (DmOpenRef dbP)
{
UInt16 i;
UInt16 size;
UInt16 len;
UInt16 blockSize;
UInt16 numRecord;
MemHandle recH;
DateType date;
ApptDBRecordType rec;
numRecord = DmNumRecords (dbP);
for (i = 0 ; i < numRecord; i++)
{
recH = DmQueryRecord (dbP, i);
if (! recH) continue;
ApptGetRecord (dbP, i, &rec, &recH);
// Is the event an untimed event?
if (TimeToInt(rec.when->startTime) == apptNoTime)
{
// There should not be and end time if there is no start time.
if (TimeToInt(rec.when->endTime) != apptNoTime)
ErrDisplay ("DB integrity error");
}
// Validate the event date.
if ((rec.when->date.month == 0) ||
(rec.when->date.month > 12) ||
(rec.when->date.day == 0) ||
(rec.when->date.day > DaysInMonth (rec.when->date.month,
rec.when->date.year + firstYear)))
ErrDisplay ("DB integrity error");
// The start time may not be greater than the end time.
else if (TimeCompare (rec.when->startTime, rec.when->endTime) > 0)
{
ErrDisplay ("DB integrity error");
}
// Validate the alarm info.
if (rec.alarm)
{
if (rec.alarm->advance > 99)
ErrDisplay ("DB integrity error");
if (rec.alarm->advanceUnit > aauDays)
ErrDisplay ("DB integrity error");
}
// Validate the repeat info.
if (rec.repeat)
{
// Validate the repeat type.
if (rec.repeat->repeatType > repeatYearly)
ErrDisplay ("DB integrity error");
// Validate the repeat end date.
date = rec.repeat->repeatEndDate;
if (DateToInt (date) != apptNoEndDate)
{
if (DateCompare (date, rec.when->date) < 0)
ErrDisplay ("DB integrity error");
if ((date.month == 0) ||
(date.month > 12) ||
(date.day == 0) ||
(date.day > DaysInMonth (date.month, date.year + firstYear)))
ErrDisplay ("DB integrity error");
}
// Validate the repeat frequency.
if (rec.repeat->repeatFrequency > 99)
ErrDisplay ("DB integrity error");
// Validate the "repeatOn" info
if (rec.repeat->repeatType == repeatWeekly)
{
if (rec.repeat->repeatOn == 0)
ErrDisplay ("DB integrity error");
}
else if (rec.repeat->repeatType == repeatMonthlyByDay)
{
if (rec.repeat->repeatOn > domLastSat)
ErrDisplay ("DB integrity error");
}
else
{
if (rec.repeat->repeatOn != 0)
ErrDisplay ("DB integrity error");
}
// Validate the "repeatStartOfWeek" info,
if (rec.repeat->repeatType == repeatWeekly)
{
if (rec.repeat->repeatStartOfWeek > monday)
ErrDisplay ("DB integrity error");
}
else if (rec.repeat->repeatStartOfWeek)
ErrDisplay ("DB integrity error");
}
// Validate the record size.
size = sizeof (ApptDateTimeType) + sizeof (ApptDBRecordFlags);
if (rec.alarm)
size += sizeof (AlarmInfoType);
if (rec.repeat)
size += sizeof (RepeatInfoType);
if (rec.exceptions)
size += sizeof (DateType) * rec.exceptions->numExceptions +
sizeof (UInt16);
if (rec.description)
{
len = StrLen (rec.description);
ErrFatalDisplayIf (len > maxDescLen, "DB integrity error");
size += len + 1;
}
if (rec.note)
{
len = StrLen (rec.note);
ErrFatalDisplayIf (len > maxNoteLen, "DB integrity error");
size += len + 1;
}
blockSize = MemHandleSize (recH);
// ErrFatalDisplayIf ( (blockSize != size), "DB integrity error");
MemHandleUnlock (recH);
}
}
#endif
/***********************************************************************
*
* FUNCTION: DateCompare
*
* DESCRIPTION: This routine compares two dates.
*
* PARAMETERS: d1 - a date
* d2 - a date
*
* RETURNED: if d1 > d2 returns a positive int
* if d1 < d2 returns a negative int
* if d1 = d2 returns zero
*
* NOTE: This routine treats the DateType structure like an unsigned int,
* it depends on the fact the the members of the structure are ordered
* year, month, day form high bit to low low bit.
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 6/12/95 Initial Revision
*
***********************************************************************/
static Int16 DateCompare (DateType d1, DateType d2)
{
UInt16 int1, int2;
int1 = DateToInt(d1);
int2 = DateToInt(d2);
if (int1 > int2)
return (1);
else if (int1 < int2)
return (-1);
return 0;
}
/***********************************************************************
*
* FUNCTION: TimeCompare
*
* DESCRIPTION: This routine compares two times. "No time" is represented
* by minus one, and is considered less than all times.
*
* PARAMETERS: nothing
*
* RETURNED: if t1 > t2 returns a positive int
* if t1 < t2 returns a negative int
* if t1 = t2 returns zero
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 6/12/95 Initial Revision
*
***********************************************************************/
static Int16 TimeCompare (TimeType t1, TimeType t2)
{
Int16 int1, int2;
int1 = TimeToInt(t1);
int2 = TimeToInt(t2);
if (int1 > int2)
return (1);
else if (int1 < int2)
return (-1);
return 0;
}
/************************************************************
*
* FUNCTION: ApptAppInfoInit
*
* DESCRIPTION: Create and initialize the app info chunk if missing.
*
* PARAMETERS: database pointer
*
* RETURNS: 0 if successful, errorcode if not
*
* CREATED: 1/25/95
*
* BY: Roger Flores
*
*************************************************************/
Err ApptAppInfoInit(DmOpenRef dbP)
{
UInt16 cardNo;
MemHandle h;
LocalID dbID;
LocalID appInfoID;
ApptAppInfoPtr 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(ApptAppInfoType));
if (! h) return dmErrMemError;
appInfoID = MemHandleToLocalID (h);
DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &appInfoID, NULL, NULL, NULL);
}
// Get pointer to app Info chunk
appInfoP = MemLocalIDToLockedPtr(appInfoID, cardNo);
// Init it
DmSet(appInfoP, 0, sizeof(ApptAppInfoType), 0);
// Unlock it
MemPtrUnlock(appInfoP);
return 0;
}
/************************************************************
*
* FUNCTION: ApptComparePackedRecords
*
* DESCRIPTION: Compare two packed records.
*
* PARAMETERS: r1 - database record 1
* r2 - database record 2
* extra - extra data, not used in the function
*
* RETURNS: -1 if record one is less
* 1 if record two is less
*
* CREATED: 1/14/95
*
* BY: Roger Flores
*
* COMMENTS: Compare the two records key by key until
* there is a difference. Return -1 if r1 is less or 1 if r2
* is less. A zero is never returned because if two records
* seem identical then their unique IDs are compared!
*
*************************************************************/
static Int16 ApptComparePackedRecords (ApptPackedDBRecordPtr r1,
ApptPackedDBRecordPtr r2, Int16 extra, SortRecordInfoPtr info1,
SortRecordInfoPtr info2, MemHandle appInfoH)
{
#pragma unused (extra, info1, info2, appInfoH)
Int16 result;
if ((r1->flags.repeat) || (r2->flags.repeat))
{
if ((r1->flags.repeat) && (r2->flags.repeat))
result = 0;
else if (r1->flags.repeat)
result = -1;
else
result = 1;
}
else
{
result = DateCompare (r1->when.date, r2->when.date);
if (result == 0)
{
result = TimeCompare (r1->when.startTime, r2->when.startTime);
}
}
return result;
}
/************************************************************
*
* FUNCTION: ApptPackedSize
*
* DESCRIPTION: Return the packed size of an ApptDBRecordType
*
* PARAMETERS: database record
*
* RETURNS: the size in bytes
*
* CREATED: 1/25/95
*
* BY: Roger Flores
*
*************************************************************/
static UInt16 ApptPackedSize (ApptDBRecordPtr r)
{
UInt16 size;
size = sizeof (ApptDateTimeType) + sizeof (ApptDBRecordFlags);
if (r->alarm != NULL)
size += sizeof (AlarmInfoType);
if (r->repeat != NULL)
size += sizeof (RepeatInfoType);
if (r->exceptions != NULL)
size += sizeof (UInt16) +
(r->exceptions->numExceptions * sizeof (DateType));
if (r->description != NULL)
size += StrLen(r->description) + 1;
if (r->note != NULL)
size += StrLen(r->note) + 1;
return size;
}
/************************************************************
*
* FUNCTION: ApptPack
*
* DESCRIPTION: Pack an ApptDBRecordType
*
* PARAMETERS: database record
*
* RETURNS: the ApptPackedDBRecord is packed
*
* CREATED: 1/25/95
*
* BY: Roger Flores
*
*************************************************************/
static void ApptPack(ApptDBRecordPtr s, ApptPackedDBRecordPtr d)
{
ApptDBRecordFlags flags;
UInt16 size;
UInt32 offset = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -