📄 datetransfer.c
字号:
return monday;
break;
case 'tu':
return tuesday;
break;
case 'we':
return wednesday;
break;
case 'th':
return thursday;
break;
case 'fr':
return friday;
break;
case 'sa':
return saturday;
break;
default:
// Bad weekday token
ErrNonFatalDisplay("Bad weekday");
return 255;
break;
}
}
/************************************************************
*
* FUNCTION: MatchDayOrPositionToken
*
* DESCRIPTION:
* Extracts a day or position value and its sign from
* the given token string
*
* PARAMETERS:
* tokenP - string ptr from which to extract
* valueP - ptr of where to store day/position value
* negativeP - true if valueP is negative
*
* RETURNS: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* frigino 12/3/97 Original
*
*************************************************************/
static void MatchDayPositionToken(
const char* tokenP,
UInt32* valueP,
Boolean* negativeP)
{
// Get token length
UInt16 len = StrLen(tokenP);
// Determine sign from last char if present
*negativeP = (tokenP[len - 1] == '-');
// Convert string value to integer. Any non-numeric chars
// after the digits will be ignored
*valueP = StrAToI(tokenP);
// Return sign
}
/************************************************************
*
* FUNCTION: DateImportVEvent
*
* DESCRIPTION: Import a VCal record of type vEvent
*
* PARAMETERS:
* ruleTextP - pointer to the imported rule string
*
* RETURNS: a pointer to the resulting RepeatInfoType or NULL
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* djk 8/9/97 Created
* art 10/17/97 Added parameter to return unique id
* art 2/2/98 Handle yearly events better (but not great).
* tlw 2/9/98 Use UInt16 for yearly (monthly repeatFrequency) so its not truncated.
* roger 8/4/98 Broke out of DateImportVEvent.
* grant 8/31/99 Return NULL if the repeat rule is invalid.
* jmp 10/21/99 Eliminated "incomplete notes" warning, and added a DOLATER comment.
*
*************************************************************/
static RepeatInfoPtr
DateImportRepeatingRule(Char * ruleTextP)
{
MemHandle repeatInfoH;
RepeatInfoPtr repeatInfoP = NULL;
Char * fieldP;
Char identifier[identifierLengthMax];
#if EMULATION_LEVEL != EMULATION_NONE
// Spec allows for both a duration AND and end date for all repeat rule cases.
// This parsing will only work for Datebook beamed records for now.
//
// DOLATER: Document this more fully!
#endif
// If some rule was read
if (ruleTextP != NULL)
{
// Allocate repeat info handle
repeatInfoH = MemHandleNew(sizeof(RepeatInfoType));
// Debug check
ErrFatalDisplayIf(repeatInfoH == NULL, "Memory full");
repeatInfoP = MemHandleLock(repeatInfoH);
// Save repeat info into datebook record
// Initialize all fields
repeatInfoP->repeatType = repeatNone;
DateToInt(repeatInfoP->repeatEndDate) = defaultRepeatEndDate;
repeatInfoP->repeatFrequency = 0;
repeatInfoP->repeatOn = 0;
repeatInfoP->repeatStartOfWeek = 0;
// Convert entire field to lower-case
StrToLower(ruleTextP, ruleTextP);
// Get the rule type and interval token (required)
fieldP = GetToken(ruleTextP, identifier);
// Determine rule type from first char
switch (identifier[0])
{
case 'd':
{
// Daily
repeatInfoP->repeatType = repeatDaily;
// Convert interval string to integer
repeatInfoP->repeatFrequency = StrAToI(&identifier[1]);
// If there's more to read (optional)
if (fieldP != NULL)
{
// Read duration or end-date
fieldP = GetToken(fieldP, identifier);
// Is literal a duration or end-date?
if (identifier[0] == '#')
{
// It's a duration. Extract it.
UInt32 duration = StrAToI(&identifier[1]);
// If duration is not zero
if (duration != 0)
{
// Compute end-date from available data and duration
}
}
else
{
// It's an end-date. Read & convert to Palm OS date.
MatchDateTimeToken(identifier, &repeatInfoP->repeatEndDate, NULL);
}
}
}
break;
case 'w':
{
// Boolean foundWeekday = false;
// Weekly
repeatInfoP->repeatType = repeatWeekly;
// Convert interval string to integer
repeatInfoP->repeatFrequency = StrAToI(&identifier[1]);
// Read remaining tokens: weekdays, occurrences, duration, end date
while (fieldP != NULL)
{
// Read a token
fieldP = GetToken(fieldP, identifier);
// Determine token type
if (identifier[0] == '#')
{
// It's a duration. Extract it.
UInt32 duration = StrAToI(&identifier[1]);
// If duration is not zero
if (duration != 0)
{
// Compute end-date from available data and duration
}
}
else if (TxtCharIsDigit(identifier[0]))
{
// It's an end-date. Read & convert to Palm OS date.
MatchDateTimeToken(identifier, &repeatInfoP->repeatEndDate, NULL);
}
else
{
UInt8 weekDay;
// Try to match weekday token
weekDay = MatchWeekDayToken(identifier);
if (weekDay != 255)
{
// Set the bit for this day
SetBitMacro(repeatInfoP->repeatOn, weekDay);
// We found at least one weekday
// foundWeekday = true;
}
}
}
}
break;
case 'm':
{
// Monthly
// Convert interval string to integer
UInt16 repeatFrequency = StrAToI(&identifier[2]);
// Determine if monthly by day or by position
switch (identifier[1])
{
case 'p':
{
// Monthly by position
UInt32 position;
Boolean fromEndOfMonth;
repeatInfoP->repeatType = repeatMonthlyByDay;
repeatInfoP->repeatFrequency = repeatFrequency;
// Read remaining tokens: weekdays, occurrences, duration, end date
while (fieldP != NULL)
{
// Read a token
fieldP = GetToken(fieldP, identifier);
// Determine token type
if (identifier[0] == '#')
{
// It's a duration. Extract it.
UInt32 duration = StrAToI(&identifier[1]);
// If duration is not zero
if (duration != 0)
{
// Compute end-date from available data and duration
}
}
else if (TxtCharIsDigit(identifier[0]))
{
// It's an occurrence or an end-date. Judge by length
if (StrLen(identifier) > 2)
{
// It should be an end-date
MatchDateTimeToken(identifier, &repeatInfoP->repeatEndDate, NULL);
}
else
{
// It should be an occurrence
// Extract day/position and sign
MatchDayPositionToken(identifier, &position,
&fromEndOfMonth);
// Validate position
if (position < 1)
position = 1;
else if (position > 5)
position = 5;
}
}
else
{
// It should be a weekday
UInt8 weekDay;
// Try to match weekday token
weekDay = MatchWeekDayToken(identifier);
if (weekDay != 255)
{
// Calc day of week to repeat. Note that an
// occurrence should already have been found
if (fromEndOfMonth)
// assume the position is 1, since datebook doesn't handle
// things like 2nd-to-the-last Monday...
repeatInfoP->repeatOn = domLastSun + weekDay;
else
repeatInfoP->repeatOn = dom1stSun + ((position - 1) * daysInWeek) + weekDay;
}
}
}
}
break;
case 'd':
{
// Monthly By day or Yearly
//
// Yearly repeating events are passed a monthly-by-date repeating
// event with the frequency in months instead of years. This is due
// to the fact that vCal's years rule uses days by number, which creates
// problems in leap years.
if (repeatFrequency % monthsInYear)
{
repeatInfoP->repeatType = repeatMonthlyByDate;
repeatInfoP->repeatFrequency = repeatFrequency;
}
else
{
repeatInfoP->repeatType = repeatYearly;
repeatInfoP->repeatFrequency = repeatFrequency / monthsInYear;
// Has no meaning for this case
repeatInfoP->repeatOn = 0;
}
// Read remaining tokens: occurrences, duration, end date
while (fieldP != NULL)
{
// Read a token
fieldP = GetToken(fieldP, identifier);
// Determine token type
if (identifier[0] == '#')
{
// It's a duration. Extract it.
UInt32 duration = StrAToI(&identifier[1]);
// If duration is not zero
if (duration != 0)
{
// Compute end-date from available data and duration
}
}
else if (TxtCharIsAlNum(identifier[0]))
{
// It's an occurrence or an end-date. Judge by length
if (StrLen(identifier) > 3)
{
// It should be an end-date
MatchDateTimeToken(identifier, &repeatInfoP->repeatEndDate, NULL);
}
else
{
#if 1
// Datebook doesnt support repeating on a day which isnt the
// same as the start day. Thus, occurrences are not used and
// this value should be zero
repeatInfoP->repeatOn = 0;
#else
// It should be an occurrence
// Check for the "LD" special case
if (StrCompare(identifier, "LD") == 0)
{
// It's the "last day" occurrence. Use maximum
repeatInfoP->repeatOn = 31;
}
else
{
UInt32 position;
Boolean fromEndOfMonth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -