Пример #1
0
int CALLBACK CSortListCtrl::CompareFunction( LPARAM lParam1, LPARAM lParam2, LPARAM lParamData )
{
	CSortListCtrl* pListCtrl = reinterpret_cast<CSortListCtrl*>( lParamData );
	ASSERT( pListCtrl->IsKindOf( RUNTIME_CLASS( CListCtrl ) ) );

	ItemData* pid1 = reinterpret_cast<ItemData*>( lParam1 );
	ItemData* pid2 = reinterpret_cast<ItemData*>( lParam2 );

	ASSERT( pid1 );
	ASSERT( pid2 );


		LPCTSTR pszText1 = pid1->arrpsz[ pListCtrl->m_iSortColumn ];
		LPCTSTR pszText2 = pid2->arrpsz[ pListCtrl->m_iSortColumn ];


	ASSERT_VALID_STRING( pszText1 );
	ASSERT_VALID_STRING( pszText2 );

	if( IsNumber( pszText1 ) )
		return pListCtrl->m_bSortAscending ? NumberCompare( pszText1, pszText2 ) : NumberCompare( pszText2, pszText1 );
	else if( IsDate( pszText1 ) )
		return pListCtrl->m_bSortAscending ? DateCompare( pszText1, pszText2 ) : DateCompare( pszText2, pszText1 );
	else
		// text.
		return pListCtrl->m_bSortAscending ? lstrcmp( pszText1, pszText2 ) : lstrcmp( pszText2, pszText1 );
}
Пример #2
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)
{
	Int16 result;

	if ((r1->flags.repeat) || (r2->flags.repeat))
		{
		if ((r1->flags.repeat) && (r2->flags.repeat))
			{
			// In the past, two repeating events were considered equal. Now we sort them
			// by their end date in order to more efficiently iterate over the repeating
			// events on a given date or date range. First step is to find the repeat
			// info in each of the records so we can compare their end dates.
			// No end date is represented as -1, which will sort last, as desired.
			result = DateCompare (ApptGetRepeatInfo(r1)->repeatEndDate, ApptGetRepeatInfo(r2)->repeatEndDate);
			if (result == 0)
				// Two events than end on the same date are sorted by their start time.
				// We don't in fact rely on this, but might in the future.
				result = TimeCompare (r1->when.startTime, r2->when.startTime);
			}
		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;
}
Пример #3
0
static Boolean IsException (ApptDBRecordPtr apptRec, DateType date) 
{
	int i;
	DatePtr exceptions;

	if (apptRec->exceptions)
    {
		exceptions = &apptRec->exceptions->exception;
		for (i = 0; i < apptRec->exceptions->numExceptions; i++)
        {
			if (DateCompare (date, exceptions[i]) == 0)
                return (true);
        }
    }
	return (false);
}
Пример #4
0
static void
fileDate(TSession * const sessionP,
         time_t     const statFilemodTime,
         TDate *    const fileDateP) {

    abyss_bool haveDate;
    TDate filemodDate;

    haveDate = DateFromLocal(&filemodDate, statFilemodTime);

    if (haveDate) {
        if (DateCompare(&sessionP->date, &filemodDate) < 0)
            *fileDateP = sessionP->date;
        else
            *fileDateP = filemodDate;
    } else
        *fileDateP = sessionP->date;
}
Пример #5
0
static abyss_bool
ServerFileHandler(TSession * const r,
                  char *     const z,
                  time_t     const fileModTime,
                  MIMEType * const mimeTypeP) {

    const char * mediatype;
    TFile file;
    uint64_t filesize;
    uint64_t start;
    uint64_t end;
    TDate date;
    char * p;
    TDate filedate;
    
    mediatype = MIMETypeGuessFromFile2(mimeTypeP, z);

    if (!FileOpen(&file,z,O_BINARY | O_RDONLY)) {
        ResponseStatusErrno(r);
        return TRUE;
    }

    fileDate(r, fileModTime, &filedate);

    p = RequestHeaderValue(r, "if-modified-since");
    if (p) {
        if (DateDecode(p,&date)) {
            if (DateCompare(&filedate, &date) <= 0) {
                ResponseStatus(r, 304);
                ResponseWrite(r);
                return TRUE;
            } else
                r->ranges.size = 0;
        }
    }
    filesize = FileSize(&file);

    switch (r->ranges.size) {
    case 0:
        ResponseStatus(r, 200);
        break;

    case 1: {
        abyss_bool decoded;
        decoded = RangeDecode((char *)(r->ranges.item[0]), filesize,
                              &start, &end);
        if (!decoded) {
            ListFree(&(r->ranges));
            ResponseStatus(r, 200);
            break;
        }
        
        sprintf(z, "bytes %llu-%llu/%llu", start, end, filesize);

        ResponseAddField(r, "Content-range", z);
        ResponseContentLength(r, end - start + 1);
        ResponseStatus(r, 206);
    } break;

    default:
        ResponseContentType(r, "multipart/ranges; boundary=" BOUNDARY);
        ResponseStatus(r, 206);
        break;
    }
    
    if (r->ranges.size == 0) {
        ResponseContentLength(r, filesize);
        ResponseContentType(r, mediatype);
    }
    
    if (DateToString(&filedate, z))
        ResponseAddField(r, "Last-Modified", z);

    ResponseWrite(r);

    if (r->request_info.method != m_head)
        sendBody(r, &file, filesize, mediatype, start, end, z);

    FileClose(&file);

    return TRUE;
}
Пример #6
0
static abyss_bool
ServerDirectoryHandler(TSession * const r,
                       char *     const z,
                       time_t     const fileModTime,
                       MIMEType * const mimeTypeP) {

    TList list;
    abyss_bool text;
    abyss_bool ascending;
    uint16_t sort;    /* 1=by name, 2=by date */
    TPool pool;
    TDate date;
    const char * error;
    uint16_t responseStatus;
    TDate dirdate;
    const char * imsHdr;
    
    determineSortType(r->request_info.query, &ascending, &sort, &text, &error);

    if (error) {
        ResponseStatus(r,400);
        xmlrpc_strfree(error);
        return TRUE;
    }

    fileDate(r, fileModTime, &dirdate);

    imsHdr = RequestHeaderValue(r, "If-Modified-Since");
    if (imsHdr) {
        if (DateDecode(imsHdr, &date)) {
            if (DateCompare(&dirdate, &date) <= 0) {
                ResponseStatus(r, 304);
                ResponseWrite(r);
                return TRUE;
            }
        }
    }

    if (!PoolCreate(&pool, 1024)) {
        ResponseStatus(r, 500);
        return TRUE;
    }

    generateListing(&list, z, r->request_info.uri,
                    &pool, &error, &responseStatus);
    if (error) {
        ResponseStatus(r, responseStatus);
        xmlrpc_strfree(error);
        PoolFree(&pool);
        return TRUE;
    }

    /* Send something to the user to show that we are still alive */
    ResponseStatus(r, 200);
    ResponseContentType(r, (text ? "text/plain" : "text/html"));

    if (DateToString(&dirdate, z))
        ResponseAddField(r, "Last-Modified", z);
    
    ResponseChunked(r);
    ResponseWrite(r);

    if (r->request_info.method!=m_head)
        sendDirectoryDocument(&list, ascending, sort, text,
                              r->request_info.uri, mimeTypeP, r, z);

    HTTPWriteEndChunk(r);

    /* Free memory and exit */
    ListFree(&list);
    PoolFree(&pool);

    return TRUE;
}
Пример #7
0
/***********************************************************************
 *
 * FUNCTION:    ApptGetAppointments
 *
 * DESCRIPTION: This routine returns a list of appointments that are on 
 *              the date specified
 *
 * PARAMETERS:  dbP    - pointer to the database
 *              date   - date to search for
 *              countP - number of appointments on the specified 
 *                       day (returned value)
 *
 * RETURNED:    handle of the appointment list (ApptInfoType)
 *
 * REVISION HISTORY:
 *          Name    Date        Description
 *          ----    ----        -----------
 *          art     6/15/95     Initial Revision
 *
 ***********************************************************************/
MemHandle ApptGetAppointments (DmOpenRef dbP, DateType date, UInt16 * countP) {
    Err error;
    Int16 result;
    Int16 count = 0;
    UInt16    recordNum;
    Boolean repeats;
    MemHandle recordH;
    MemHandle apptListH;
    ApptInfoPtr apptList;
    ApptDBRecordType apptRec;
    ApptPackedDBRecordPtr r;

    // Allocated a block to hold the appointment list.
    apptListH = MemHandleNew (sizeof (ApptInfoType) * apptMaxPerDay);
    ErrFatalDisplayIf(!apptListH, "Out of memory");
    if (! apptListH) return (0);

    apptList = MemHandleLock (apptListH);

    // Find the first non-repeating appointment of the day.
    if (ApptFindFirst (dbP, date, &recordNum)) {
        while (count < apptMaxPerDay) {
            // Check if the appointment is on the date passed, if it is
            // add it to the appointment list.
            recordH = DmQueryRecord (dbP, recordNum);
            r = MemHandleLock (recordH);
            result = DateCompare (r->when.date, date);

            if (result == 0) {
                // Add the record to the appoitment list.
                apptList[count].startTime = r->when.startTime;
                apptList[count].endTime = r->when.endTime;
                apptList[count].recordNum = recordNum;
                count++;
            }
            MemHandleUnlock (recordH);
            if (result != 0) break;

            // Get the next record.
            error = DmSeekRecordInCategory (dbP, &recordNum, 1,
                                            dmSeekForward,
                                            dmAllCategories);
            if (error == dmErrSeekFailed) break;
        }
    }

    // Add the repeating appointments to the list.  Repeating appointments
    // are stored at the beginning of the database.
    recordNum = 0;
    while (count < apptMaxPerDay) {
        recordH = DmQueryNextInCategory (dbP, &recordNum, dmAllCategories);
        if (! recordH) break;
        
        r = (ApptPackedDBRecordPtr) MemHandleLock (recordH);
        
        repeats = (r->flags.repeat != 0);
        if (repeats) {
            ApptUnpack (r, &apptRec);
            if (ApptRepeatsOnDate (&apptRec, date)) {
                // Add the record to the appoitment list.
                apptList[count].startTime = r->when.startTime;              
                apptList[count].endTime = r->when.endTime;              
                apptList[count].recordNum = recordNum;  
                count++;
            }
        }
        MemHandleUnlock (recordH);

        // If the record has no repeating info we've reached the end of the 
        // repeating appointments.
        if (! repeats) break;
        
        recordNum++;
    }

    // Sort the list by start time.
    // SysInsertionSort (apptList, count, sizeof (ApptInfoType),
    //          ApptListCompare, 0L);

    // If there are no appointments on the specified day, free the appointment
    // list.
    if (count == 0) {
        MemPtrFree (apptList);
        apptListH = 0;
    }
    // Resize the appointment list block to release any unused space.
    else {
        MemHandleUnlock (apptListH);
        MemHandleResize (apptListH, count * sizeof (ApptInfoType));
    }

    *countP = count;
    return (apptListH);
}
Пример #8
0
/***********************************************************************
 *
 * 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;
	long dateInDays;
	long startInDays;
	Boolean onDate = false;
	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);
        if (onDate) break;
			
        // If the appointment repeats on one of the last days of the month,
        // check if the date passed is also one of the last days of the 
        // month.  By last days of the month we mean: last sunday, 
        // last monday, etc.
        if ((apptRec->repeat->repeatOn >= domLastSun) &&
            (dayOfMonth >= dom4thSun))
        {
            dayOfWeek = DayOfWeek (date.month, date.day, date.year+firstYear);
            dayInMonth = DaysInMonth (date.month, date.year+firstYear);
            onDate = (((date.day + daysInWeek) > dayInMonth) &&
                      (dayOfWeek == (apptRec->repeat->repeatOn % daysInWeek)));
        }
        break;						


		// Monthly-by-date repeating appointment (ex: the 15th of every
		// month).
    case repeatMonthlyByDate:
        // 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;
			
        // Are we on the same day of the month as the start date.
        onDate = (date.day == startDate.day);
        if (onDate) break;

        // If the staring day of the appointment is greater then the 
        // number of day in the month passed, and the day passed is the 
        // last day of the month, then the appointment repeats on the day.
        dayInMonth = DaysInMonth (date.month, date.year+firstYear);
        onDate = ((startDate.day > dayInMonth) && (date.day == dayInMonth));
        break;


		// Yearly repeating appointment.
    case repeatYearly:
        // Are we in a year in which the appointment repeats.
        onDate = ((date.year - startDate.year) % freq) == 0;
        if (! onDate) break;
			
        // Are we on the month and day that the appointment repeats.
        onDate = (date.month == startDate.month) &&
            (date.day == startDate.day);
        if (onDate) break;
			
        // Specal leap day processing.
        if ( (startDate.month == february) && 
             (startDate.day == 29) &&
             (date.month == february) && 
             (date.day == DaysInMonth (date.month, date.year+firstYear)))
        {
            onDate = true;
        }				      
        break;
    default:
        break;
    }

	// Check for an exception.
	if ((onDate) && (apptRec->exceptions))
    {
		exceptions = &apptRec->exceptions->exception;
		for (i = 0; i < apptRec->exceptions->numExceptions; i++)
        {
			if (DateCompare (date, exceptions[i]) == 0)
            {
				onDate = false;
				break;
            }
        }
    }

	return (onDate);
}
Пример #9
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
            *indexP = probe + 1;
    }

    return (found);
}
Пример #10
0
/***********************************************************************
 *
 * FUNCTION:    NextRepeat
 *
 * DESCRIPTION: This routine computes the date of the next
 *              occurrence of a repeating appointment.
 *
 * PARAMETERS:  rec     - a pointer to a DiddleBug record
 *              date    - passed:   date to start from
 *                        returned: date of next occurrence
 *
 * RETURNED:    true if the appointment occurs again
 *
 ***********************************************************************/
Boolean NextRepeat(DiddleBugRecordType* rec, DateTimeType* dateP) {

  /*
  ** Get the frequency on occurrence
  **(ex: every 2nd day, every 3rd month, etc).
  */ 
  const UInt16 freq = rec->repeatInfo.repeatFrequency;
  
  Int16  i = 0;
  UInt16 day;
  UInt16 year;
  UInt16 adjust;
  UInt16 weeksDiff;
  UInt16 monthsDiff;
  UInt16 daysInMonth;
  UInt16 dayOfWeek;
  UInt16 apptWeekDay;
  UInt16 firstDayOfWeek;
  UInt16 daysTilNext;
  UInt16 monthsTilNext;
  UInt32 dateInDays;
  UInt32 startInDays;
  DateType start, date, when, next;
  DateTimeType nextReal;
  UInt32 startSecs, nextSecs;

  DateSecondsToDate(TimDateTimeToSeconds(dateP), &date);
  TimSecondsToDateTime(rec->alarmSecs, &nextReal);
  nextReal.year = dateP->year;
  nextReal.month = dateP->month;
  nextReal.day = dateP->day;
  nextReal.weekDay = dateP->weekDay;

  /* Calculate alarm date */
  DateSecondsToDate(rec->alarmSecs, &when);

  /* Is the date passed after the end date of the appointment? */
  if (DateCompare(date, rec->repeatInfo.repeatEndDate) > 0)
    return false;

  /* Is the date passed before the start date of the appointment? */
  if (DateCompare(date, when) < 0)
    date = when;
  
  /* Get the date of the first occurrecne of the appointment. */
  start = when;

  switch (rec->repeatInfo.repeatType) {
    /* Hourly repeating appointment */
  case repeatHourly:
    startSecs = TimDateTimeToSeconds(dateP);
    nextSecs = rec->alarmSecs;
    while (nextSecs < startSecs)
      nextSecs += freq * hoursInSeconds;
    
    TimSecondsToDateTime(nextSecs, &nextReal);
    DateSecondsToDate(nextSecs, &next);
    break;

    /* Daily repeating appointment. */
  case repeatDaily:
    dateInDays = DateToDays(date);
    startInDays = DateToDays(start);
    daysTilNext = (dateInDays - startInDays + freq - 1) / freq * freq;
    if (startInDays + daysTilNext > (UInt32) maxDays)
      return false;
    DateDaysToDate (startInDays + daysTilNext, &next);
    break;
    
    /*
    ** Weekly repeating appointment (ex: every Monday and Friday).
    ** Yes, weekly repeating appointment can occur more then once a
    ** week.
    */
  case repeatWeekly:
    dateInDays = DateToDays(date);
    startInDays = DateToDays(start);
    
    firstDayOfWeek = (DayOfWeek (1, 1, firstYear) -
		      rec->repeatInfo.repeatStartOfWeek + daysInWeek) % daysInWeek;

    dayOfWeek = DayOfWeek(date.month, date.day, date.year+firstYear);
    apptWeekDay = (dayOfWeek - rec->repeatInfo.repeatStartOfWeek +
		   daysInWeek) % daysInWeek;

    /*
    ** 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.
    */
    weeksDiff = (((dateInDays + firstDayOfWeek) / daysInWeek) -
		 ((startInDays + firstDayOfWeek) / daysInWeek)) % freq;
    if (weeksDiff) {
      adjust = ((freq - weeksDiff) * daysInWeek) - apptWeekDay;
      apptWeekDay = 0;
      dayOfWeek = (dayOfWeek + adjust) % daysInWeek;
    } else {
      adjust = 0;
    }

    /* Find the next day on which the appointment repeats. */
    for (; i < daysInWeek; i++) {
      if (rec->repeatInfo.repeatOn & (1 << dayOfWeek))
	break;
      
      adjust++;
      
      if (++dayOfWeek == daysInWeek)
	dayOfWeek = 0;

      if (++apptWeekDay == daysInWeek)
	adjust += (freq - 1) * daysInWeek;
    }

    if (dateInDays + adjust > (UInt32) maxDays)
      return false;
    
    DateDaysToDate (dateInDays + adjust, &next);
    break;

    /*
    ** Monthly-by-day repeating appointment
    ** (ex: the 3rd Friday of every month).
    */
  case repeatMonthlyByDay:
    /* Compute the number of month until the appointment repeats again. */
    monthsTilNext = ((((date.year - start.year) * monthsInYear) +
		      (date.month - start.month)) + freq - 1) / freq * freq;

    while (true) {
      year = start.year + (start.month - 1 + monthsTilNext) / monthsInYear;
      if (year >= numberOfYears)
	return false;
      
      next.year = year;
      next.month = (start.month - 1 + monthsTilNext) % monthsInYear + 1;
      
      dayOfWeek = DayOfWeek (next.month, 1, next.year+firstYear);
      if ((rec->repeatInfo.repeatOn % daysInWeek) >= dayOfWeek)
	day = rec->repeatInfo.repeatOn - dayOfWeek + 1;
      else
	day = rec->repeatInfo.repeatOn + daysInWeek - dayOfWeek + 1;
      
      /*
      ** If repeat-on day is between the last sunday and the last
      ** saturday, make sure we're not passed the end of the month.
      */
      if ( (rec->repeatInfo.repeatOn >= domLastSun) &&
	   (day > DaysInMonth (next.month, next.year+firstYear))) {
	day -= daysInWeek;
      }
      next.day = day;

      /*
      ** Its posible that "next date" calculated above is
      ** before the date passed.  If so, move forward
      ** by the length of the repeat freguency and preform
      ** the calculation again.
      */
      if (DateToInt(date) > DateToInt(next))
	monthsTilNext += freq;
      else
	break;
    }
    break;

    /*
    ** Monthly-by-date repeating appointment
    ** (ex: the 15th of every month).
    */
  case repeatMonthlyByDate:
    /* Compute the number of month until the appointment repeats again. */
    monthsDiff = (date.year - start.year) * monthsInYear + date.month - start.month;
    monthsTilNext = (monthsDiff + freq - 1) / freq * freq;

    if (date.day > start.day && !(monthsDiff % freq))
      monthsTilNext += freq;

    year = start.year +	(start.month - 1 + monthsTilNext) / monthsInYear;
    if (year >= numberOfYears)
      return false;

    next.year = year;
    next.month = (start.month - 1 + monthsTilNext) % monthsInYear + 1;
    next.day = start.day;

    /* Make sure we're not passed the last day of the month. */
    daysInMonth = DaysInMonth(next.month, next.year+firstYear);
    if (next.day > daysInMonth)
      next.day = daysInMonth;
    break;

    /* Yearly repeating appointment. */
  case repeatYearly:
    next.day = start.day;
    next.month = start.month;
    
    year = start.year + ((date.year - start.year + freq - 1) / freq * freq);

    if (date.month > start.month || 
	(date.month == start.month && date.day > start.day))
      year += freq;

    /* Specal leap day processing. */
    if (next.month == february && next.day == 29 &&
	next.day > DaysInMonth(next.month, year+firstYear)) {
      next.day = DaysInMonth (next.month, year+firstYear);
    }
    if (year >= numberOfYears)
      return false;
    
    next.year = year;
    break;

  default:
    /* ignore */
  }

  /* Is the next occurrence after the end date of the appointment? */
  if (DateCompare(next, rec->repeatInfo.repeatEndDate) > 0)
    return false;

  dateP->day = next.day;
  dateP->month = next.month;
  dateP->year = next.year + firstYear;
  dateP->hour = nextReal.hour;
  dateP->minute = nextReal.minute;
  dateP->second = nextReal.second;

  return true;
}
Пример #11
0
Boolean NextRepeat (ApptDBRecordPtr apptRec, DatePtr dateP) 
{
	Int16  i;
	UInt16 day;
	UInt16 freq;
	UInt16 year;
	UInt16 adjust;
	UInt16 weeksDiff;
	UInt16 monthsDiff;
	UInt16 daysInMonth;
	UInt16 dayOfWeek;
	UInt16 apptWeekDay;
	UInt16 firstDayOfWeek;
	UInt16 daysTilNext;
	UInt16 monthsTilNext;
	UInt32 dateInDays;
	UInt32 startInDays;
	DateType start;
	DateType date;
	DateType next;

	date = *dateP;

	// Is the date passed after the end date of the appointment?
	if (DateCompare (date, apptRec->repeat->repeatEndDate) > 0)
		return (false);
	
	// Is the date passed before the start date of the appointment?
	if (DateCompare (date, apptRec->when->date) < 0)
		date = apptRec->when->date;

	// Get the frequency on occurrecne (ex: every 2nd day, every 3rd month, etc).  
	freq = apptRec->repeat->repeatFrequency;
	
	// Get the date of the first occurrecne of the appointment.
	start = apptRec->when->date;
	

	switch (apptRec->repeat->repeatType)
    {
		// Daily repeating appointment.
    case repeatDaily:
        dateInDays = DateToDays (date);
        startInDays = DateToDays (start);
        daysTilNext = (dateInDays - startInDays + freq - 1) / freq * freq;
        if (startInDays + daysTilNext > (UInt32) maxDays)
            return (false);
        DateDaysToDate (startInDays + daysTilNext, &next);
        break;
			


		// Weekly repeating appointment (ex: every Monday and Friday). 
		// Yes, weekly repeating appointment can occur more then once a
		// week.
    case repeatWeekly:
        dateInDays = DateToDays (date);
        startInDays = DateToDays (start);

        firstDayOfWeek = (DayOfWeek (1, 1, firstYear) - 
                          apptRec->repeat->repeatStartOfWeek + daysInWeek) % daysInWeek;

        dayOfWeek = DayOfWeek (date.month, date.day, date.year+firstYear);
        apptWeekDay = (dayOfWeek - apptRec->repeat->repeatStartOfWeek +
                       daysInWeek) % daysInWeek;

        // 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.
        weeksDiff = (((dateInDays + firstDayOfWeek) / daysInWeek) - 
                     ((startInDays + firstDayOfWeek) / daysInWeek)) %freq;
        if (weeksDiff)
        {
            adjust = ((freq - weeksDiff) * daysInWeek)- apptWeekDay;
            apptWeekDay = 0;
            dayOfWeek = (dayOfWeek + adjust) % daysInWeek;
        }
        else
            adjust = 0;
			
        // Find the next day on which the appointment repeats.
        for (i = 0; i < daysInWeek; i++)
        {
            if (apptRec->repeat->repeatOn & (1 << dayOfWeek)) break;
            adjust++;
            if (++dayOfWeek == daysInWeek)
                dayOfWeek = 0;
            if (++apptWeekDay == daysInWeek)
                adjust += (freq - 1) * daysInWeek;
        }

        if (dateInDays + adjust > (UInt32) maxDays)
            return (false);
        DateDaysToDate (dateInDays + adjust, &next);
//			next = date;
//			DateAdjust (&next, adjust);
        break;



		// Monthly-by-day repeating appointment (ex: the 3rd Friday of every
		// month).
    case repeatMonthlyByDay:
        // Compute the number of month until the appointment repeats again.
        monthsTilNext = (date.month - start.month);

        monthsTilNext = ((((date.year - start.year) * monthsInYear) + 
                          (date.month - start.month)) + freq - 1) /
            freq * freq;

        while (true)
        {
            year = start.year + 
                (start.month - 1 + monthsTilNext) / monthsInYear;
            if (year >= numberOfYears)
                return (false);

            next.year = year;
            next.month = (start.month - 1 + monthsTilNext) % monthsInYear + 1;
	
            dayOfWeek = DayOfWeek (next.month, 1, next.year+firstYear);
            if ((apptRec->repeat->repeatOn % daysInWeek) >= dayOfWeek)
                day = apptRec->repeat->repeatOn - dayOfWeek + 1;
            else
                day = apptRec->repeat->repeatOn + daysInWeek - dayOfWeek + 1;
	
            // If repeat-on day is between the last sunday and the last
            // saturday, make sure we're not passed the end of the month.
            if ( (apptRec->repeat->repeatOn >= domLastSun) &&
                 (day > DaysInMonth (next.month, next.year+firstYear)))
            {
                day -= daysInWeek;
            }
            next.day = day;

            // Its posible that "next date" calculated above is 
            // before the date passed.  If so, move forward
            // by the length of the repeat freguency and preform
            // the calculation again.
            if ( DateToInt(date) > DateToInt (next))
                monthsTilNext += freq;
            else
                break;
        }
        break;						



		// Monthly-by-date repeating appointment (ex: the 15th of every
		// month).
    case repeatMonthlyByDate:
        // Compute the number of month until the appointment repeats again.
        monthsDiff = ((date.year - start.year) * monthsInYear) + 
            (date.month - start.month);
        monthsTilNext = (monthsDiff + freq - 1) / freq * freq;

        if ((date.day > start.day) && (!(monthsDiff % freq)))
            monthsTilNext += freq;
				
        year = start.year + 
            (start.month - 1 + monthsTilNext) / monthsInYear;
        if (year >= numberOfYears)
            return (false);

        next.year = year;
        next.month = (start.month - 1 + monthsTilNext) % monthsInYear + 1;
        next.day = start.day;

        // Make sure we're not passed the last day of the month.
        daysInMonth = DaysInMonth (next.month, next.year+firstYear);
        if (next.day > daysInMonth)
            next.day = daysInMonth;
        break;



		// Yearly repeating appointment.
    case repeatYearly:
        next.day = start.day;
        next.month = start.month;

        year = start.year + 
            ((date.year - start.year + freq - 1) / freq * freq);
			
        if ((date.month > start.month) ||
            ((date.month == start.month) && (date.day > start.day)))
            year += freq;

        // Specal leap day processing.
        if ( (next.month == february) && (next.day == 29) &&
             (next.day > DaysInMonth (next.month, year+firstYear)))
        {
            next.day = DaysInMonth (next.month, year+firstYear);
        }				      
        if (year >= numberOfYears)
            return (false);

        next.year = year;	
        break;
    default:
        break;
    }

	// Is the next occurrence after the end date of the appointment?
	if (DateCompare (next, apptRec->repeat->repeatEndDate) > 0)
		return (false);

	ErrFatalDisplayIf ((DateToInt (next) < DateToInt (*dateP)),
                       "Calculation error");

	*dateP = next;
	return (true);
}
Пример #12
0
static Int16 CompareAgeFunc(LineItemPtr p1, LineItemPtr p2, Int32 extra)
{   
	if (p1->age > p2->age) return 1*extra;
	else if (p1->age < p2->age) return -1*extra;
	else return DateCompare(p1->date, p2->date)*extra;
}
Пример #13
0
static Int16 CompareHappyDaysFunc(LineItemPtr p1, LineItemPtr p2, Int32 extra)
{   
    return DateCompare(p1->date, p2->date)*extra;
}