📄 datedb.c
字号:
*(UInt8 *)&flags = 0; // clear the flags
// copy the ApptDateTimeType
//c = (char *) d;
offset = 0;
DmWrite(d, offset, s->when, sizeof(ApptDateTimeType));
offset += sizeof (ApptDateTimeType) + sizeof (ApptDBRecordFlags);
if (s->alarm != NULL)
{
DmWrite(d, offset, s->alarm, sizeof(AlarmInfoType));
offset += sizeof (AlarmInfoType);
flags.alarm = 1;
}
if (s->repeat != NULL)
{
DmWrite(d, offset, s->repeat, sizeof(RepeatInfoType));
offset += sizeof (RepeatInfoType);
flags.repeat = 1;
}
if (s->exceptions != NULL)
{
size = sizeof (UInt16) +
(s->exceptions->numExceptions * sizeof (DateType));
DmWrite(d, offset, s->exceptions, size);
offset += size;
flags.exceptions = 1;
}
if (s->description != NULL)
{
size = StrLen(s->description) + 1;
DmWrite(d, offset, s->description, size);
offset += size;
flags.description = 1;
}
if (s->note != NULL)
{
size = StrLen(s->note) + 1;
DmWrite(d, offset, s->note, size);
offset += size;
flags.note = 1;
}
DmWrite(d, sizeof(ApptDateTimeType), &flags, sizeof(flags));
}
/************************************************************
*
* FUNCTION: ApptUnpack
*
* DESCRIPTION: Fills in the ApptDBRecord structure
*
* PARAMETERS: database record
*
* RETURNS: the record unpacked
*
* CREATED: 1/25/95
*
* BY: Roger Flores
*
*************************************************************/
static void ApptUnpack(ApptPackedDBRecordPtr src, ApptDBRecordPtr dest)
{
ApptDBRecordFlags flags;
char *p;
flags = src->flags;
p = &src->firstField;
dest->when = (ApptDateTimeType *) src;
if (flags.alarm)
{
dest->alarm = (AlarmInfoType *) p;
p += sizeof (AlarmInfoType);
}
else
dest->alarm = NULL;
if (flags.repeat)
{
dest->repeat = (RepeatInfoType *) p;
p += sizeof (RepeatInfoType);
}
else
dest->repeat = NULL;
if (flags.exceptions)
{
dest->exceptions = (ExceptionsListType *) p;
p += sizeof (UInt16) +
(((ExceptionsListType *) p)->numExceptions * sizeof (DateType));
}
else
dest->exceptions = NULL;
if (flags.description)
{
dest->description = p;
p += StrLen(p) + 1;
}
else
dest->description = NULL;
if (flags.note)
{
dest->note = p;
}
else
dest->note = NULL;
}
/************************************************************
*
* FUNCTION: ApptFindSortPosition
*
* DESCRIPTION: Return where a record is or should be
* Useful to find or find where to insert a record.
*
* PARAMETERS: database record
*
* RETURNS: position where a record should be
*
* CREATED: 1/25/95
*
* BY: Roger Flores
*
*************************************************************/
static UInt16 ApptFindSortPosition(DmOpenRef dbP, ApptPackedDBRecordPtr newRecord)
{
return (DmFindSortPosition (dbP, newRecord, NULL, (DmComparF *)ApptComparePackedRecords, 0));
}
/************************************************************
*
* FUNCTION: ApptSort
*
* DESCRIPTION: Sort the appointment database.
*
* PARAMETERS: database record
*
* RETURNS: nothing
*
* CREATED: 9/5/95
*
* BY: Art Lamb
*
*************************************************************/
void ApptSort (DmOpenRef dbP)
{
DmQuickSort(dbP, (DmComparF *)ApptComparePackedRecords, 0);
}
/***********************************************************************
*
* FUNCTION: ApptFindFirst
*
* DESCRIPTION: This routine finds the first appointment on the specified
* day.
*
* PARAMETERS: dbP - pointer to the database
* date - date to search for
* indexP - pointer to the index of the first record on the
* specified day (returned value)
*
* RETURNED: true if a record has found
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 6/15/95 Initial Revision
*
***********************************************************************/
Boolean ApptFindFirst (DmOpenRef dbP, DateType date, UInt16* indexP)
{
Err err;
Int16 numOfRecords;
Int16 kmin, probe, i; // all positions in the database.
Int16 result = 0; // result of comparing two records
UInt16 index;
MemHandle recordH;
Boolean found = false;
ApptPackedDBRecordPtr r;
kmin = probe = 0;
numOfRecords = DmNumRecords(dbP);
while (numOfRecords > 0)
{
i = numOfRecords >> 1;
probe = kmin + i;
index = probe;
recordH = DmQueryNextInCategory (dbP, &index, dmAllCategories);
if (recordH)
{
r = (ApptPackedDBRecordPtr) MemHandleLock (recordH);
if (r->flags.repeat)
result = 1;
else
result = DateCompare (date, r->when.date);
MemHandleUnlock (recordH);
}
// If no handle, assume the record is deleted, deleted records
// are greater.
else
result = -1;
// If the date passed is less than the probe's date, keep searching.
if (result < 0)
numOfRecords = i;
// If the date passed is greater than the probe's date, keep searching.
else if (result > 0)
{
kmin = probe + 1;
numOfRecords = numOfRecords - i - 1;
}
// If the records are equal find the first record on the day.
else
{
found = true;
*indexP = index;
while (true)
{
err = DmSeekRecordInCategory (dbP, &index, 1, dmSeekBackward,
dmAllCategories);
if (err == dmErrSeekFailed) break;
recordH = DmQueryRecord(dbP, index);
r = (ApptPackedDBRecordPtr) MemHandleLock (recordH);
if (r->flags.repeat)
result = 1;
else
result = DateCompare (date, r->when.date);
MemHandleUnlock (recordH);
if (result != 0) break;
*indexP = index;
}
break;
}
}
// If that were no appointments on the specified day, return the
// index of the next appointment (on a future day).
if (! found)
{
if (result < 0)
*indexP = probe;
else if (DmNumRecords(dbP) == 0)
*indexP = 0;
else
*indexP = probe + 1;
}
return (found);
}
/***********************************************************************
*
* FUNCTION: ApptAddException
*
* DESCRIPTION: This routine adds an entry to the exceptions list of the
* specified record.
*
* PARAMETERS: database pointer
* database index
* exception date
*
* RETURNED: error code
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 7/26/95 Initial Revision
*
***********************************************************************/
Err ApptAddException (DmOpenRef dbP, UInt16 *index, DateType date)
{
Err error;
UInt16 size;
MemHandle recordH;
ApptDBRecordType r;
ExceptionsListPtr exceptions;
ApptDBRecordFlags changedFields;
error = ApptGetRecord(dbP, *index, &r, &recordH);
if (error) return error;
// If the record already has an expections list, add an entry to
// the list.
if (r.exceptions)
{
size = sizeof (ExceptionsListType) +
(sizeof (DateType) * r.exceptions->numExceptions);
exceptions = MemPtrNew (size);
ErrFatalDisplayIf ((!exceptions), "Out of memory");
MemMove (exceptions, r.exceptions, size - sizeof (DateType));
exceptions->numExceptions++;
*(&exceptions->exception + r.exceptions->numExceptions) = date;
}
// Create an expections list.
else
{
size = sizeof (ExceptionsListType);
exceptions = MemPtrNew (size);
ErrFatalDisplayIf ((!exceptions), "Out of memory");
exceptions->numExceptions = 1;
exceptions->exception = date;
}
MemHandleUnlock (recordH);
// Update the record
r.exceptions = exceptions;
MemSet (&changedFields, sizeof (changedFields), 0);
changedFields.exceptions = true;
error = ApptChangeRecord (dbP, index, &r, changedFields);
MemPtrFree (exceptions);
return (error);
}
/***********************************************************************
*
* FUNCTION: ApptRepeatsOnDate
*
* DESCRIPTION: This routine returns true if a repeating appointment
* occurrs on the specified date.
*
* PARAMETERS: apptRec - a pointer to an appointment record
* date - date to check
*
* RETURNED: true if the appointment occurs on the date specified
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 6/14/95 Initial Revision
*
***********************************************************************/
Boolean ApptRepeatsOnDate (ApptDBRecordPtr apptRec, DateType date)
{
Int16 i;
UInt16 freq;
UInt16 weeksDiff;
UInt16 dayInMonth;
UInt16 dayOfWeek;
UInt16 dayOfMonth;
UInt16 firstDayOfWeek;
Int32 dateInDays;
Int32 startInDays;
Boolean onDate;
DatePtr exceptions;
DateType startDate;
// Is the date passed before the start date of the appointment?
if (DateCompare (date, apptRec->when->date) < 0)
return (false);
// Is the date passed after the end date of the appointment?
if (DateCompare (date, apptRec->repeat->repeatEndDate) > 0)
return (false);
// Get the frequency of occurrecne (ex: every 2nd day, every 3rd month, etc.).
freq = apptRec->repeat->repeatFrequency;
// Get the date of the first occurrecne of the appointment.
startDate = apptRec->when->date;
switch (apptRec->repeat->repeatType)
{
// Daily repeating appointment.
case repeatDaily:
dateInDays = DateToDays (date);
startInDays = DateToDays (startDate);
onDate = ((dateInDays - startInDays) % freq) == 0;
break;
// Weekly repeating appointment (ex: every Monday and Friday).
// Yes, weekly repeating appointment can occur more then once a
// week.
case repeatWeekly:
// Are we on a day of the week that the appointment repeats on.
dayOfWeek = DayOfWeek (date.month, date.day, date.year+firstYear);
onDate = ((1 << dayOfWeek) & apptRec->repeat->repeatOn);
if (! onDate) break;
// Are we in a week in which the appointment occurrs, if not
// move to that start of the next week in which the appointment
// does occur.
dateInDays = DateToDays (date);
startInDays = DateToDays (startDate);
firstDayOfWeek = (DayOfWeek (1, 1, firstYear) -
apptRec->repeat->repeatStartOfWeek + daysInWeek) % daysInWeek;
weeksDiff = (((dateInDays + firstDayOfWeek) / daysInWeek) -
((startInDays + firstDayOfWeek) / daysInWeek)) %freq;
onDate = (weeksDiff == 0);
break;
// // Compute the first occurrence of the appointment that occurs
// // on the same day of the week as the date passed.
// startDayOfWeek = DayOfWeek (startDate.month, startDate.day,
// startDate.year+firstYear);
// startInDays = DateToDays (startDate);
// if (startDayOfWeek < dayOfWeek)
// startInDays += dayOfWeek - startDayOfWeek;
// else if (startDayOfWeek > dayOfWeek)
// startInDays += dayOfWeek+ (daysInWeek *freq) - startDayOfWeek;
//
// // Are we in a week in which the appointment repeats.
// dateInDays = DateToDays (date);
// onDate = (((dateInDays - startInDays) / daysInWeek) % freq) == 0;
// break;
// Monthly-by-day repeating appointment (ex: the 3rd Friday of every
// month).
case repeatMonthlyByDay:
// Are we in a month in which the appointment repeats.
onDate = ((((date.year - startDate.year) * monthsInYear) +
(date.month - startDate.month)) % freq) == 0;
if (! onDate) break;
// Do the days of the month match (ex: 3rd Friday)
dayOfMonth = DayOfMonth (date.month, date.day, date.year+firstYear);
onDate = (dayOfMonth == apptRec->repeat->repeatOn);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -