/*
 * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
 *
 * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
 * the terms of the APSL version 2.0 (see below).
 *
 * For information about changes from the original Apple source release can be found by reviewing the
 * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
 *
 * The original license information is as follows:
 * 
 * Copyright (c) 2008 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*	CFCalendar.c
	Copyright 2004-2004, Apple Computer, Inc. All rights reserved.
	Responsibility: Christopher Kane
*/

#include <CoreFoundation/CFCalendar.h>
#include <CoreFoundation/CFRuntime.h>
#include "CFInternal.h"
#include "CFPriv.h"
#include <unicode/ucal.h>

#define BUFFER_SIZE 512

struct __CFCalendar {
    CFRuntimeBase _base;
    CFStringRef _identifier;	// canonical identifier, never NULL
    CFLocaleRef _locale;
    CFStringRef _localeID;
    CFTimeZoneRef _tz;
    UCalendar *_cal;
};

static Boolean __CFCalendarEqual(CFTypeRef cf1, CFTypeRef cf2) {
    CFCalendarRef calendar1 = (CFCalendarRef)cf1;
    CFCalendarRef calendar2 = (CFCalendarRef)cf2;
    return CFEqual(calendar1->_identifier, calendar2->_identifier);
}

static CFHashCode __CFCalendarHash(CFTypeRef cf) {
    CFCalendarRef calendar = (CFCalendarRef)cf;
    return CFHash(calendar->_identifier);
}

static CFStringRef __CFCalendarCopyDescription(CFTypeRef cf) {
    CFCalendarRef calendar = (CFCalendarRef)cf;
    return CFStringCreateWithFormat(CFGetAllocator(calendar), NULL, CFSTR("<CFCalendar %p [%p]>{identifier = '%@'}"), cf, CFGetAllocator(calendar), calendar->_identifier);
}

static void __CFCalendarDeallocate(CFTypeRef cf) {
    CFCalendarRef calendar = (CFCalendarRef)cf;
    CFRelease(calendar->_identifier);
    if (calendar->_locale) CFRelease(calendar->_locale);
    if (calendar->_localeID) CFRelease(calendar->_localeID);
    CFRelease(calendar->_tz);
    if (calendar->_cal) ucal_close(calendar->_cal);
}

static CFTypeID __kCFCalendarTypeID = _kCFRuntimeNotATypeID;

static const CFRuntimeClass __CFCalendarClass = {
    0,
    "CFCalendar",
    NULL,	// init
    NULL,	// copy
    __CFCalendarDeallocate,
    __CFCalendarEqual,
    __CFCalendarHash,
    NULL,	// 
    __CFCalendarCopyDescription
};

static void __CFCalendarInitialize(void) {
    __kCFCalendarTypeID = _CFRuntimeRegisterClass(&__CFCalendarClass);
}

CFTypeID CFCalendarGetTypeID(void) {
    if (_kCFRuntimeNotATypeID == __kCFCalendarTypeID) __CFCalendarInitialize();
    return __kCFCalendarTypeID;
}

__private_extern__ UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRef localeID, CFTimeZoneRef tz) {
    if (calendarID) {
	CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorSystemDefault, localeID);
	CFMutableDictionaryRef mcomponents = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, 0, components);
	CFDictionarySetValue(mcomponents, kCFLocaleCalendarIdentifier, calendarID);
	localeID = CFLocaleCreateLocaleIdentifierFromComponents(kCFAllocatorSystemDefault, mcomponents);
	CFRelease(mcomponents);
	CFRelease(components);
    }

    char buffer[BUFFER_SIZE];
    const char *cstr = CFStringGetCStringPtr(localeID, kCFStringEncodingASCII);
    if (NULL == cstr) {
	if (CFStringGetCString(localeID, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer;
    }
    if (NULL == cstr) {
	if (calendarID) CFRelease(localeID);
	return NULL;
    }
    
    UChar ubuffer[BUFFER_SIZE];
    CFStringRef tznam = CFTimeZoneGetName(tz);
    CFIndex cnt = CFStringGetLength(tznam);
    if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
    CFStringGetCharacters(tznam, CFRangeMake(0, cnt), (UniChar *)ubuffer);

    UErrorCode status = U_ZERO_ERROR;
    UCalendar *cal = ucal_open(ubuffer, cnt, cstr, UCAL_TRADITIONAL, &status);
    if (calendarID) CFRelease(localeID);
    return cal;
}

static void __CFCalendarSetupCal(CFCalendarRef calendar) {
    calendar->_cal = __CFCalendarCreateUCalendar(calendar->_identifier, calendar->_localeID, calendar->_tz);
}

static void __CFCalendarZapCal(CFCalendarRef calendar) {
    ucal_close(calendar->_cal);
    calendar->_cal = NULL;
}

CFCalendarRef CFCalendarCopyCurrent(void) {
    CFLocaleRef locale = CFLocaleCopyCurrent();
    CFCalendarRef calID = (CFCalendarRef)CFLocaleGetValue(locale, kCFLocaleCalendarIdentifier);
    if (calID) {
        CFCalendarRef calendar = CFCalendarCreateWithIdentifier(kCFAllocatorSystemDefault, (CFStringRef)calID);
        CFCalendarSetLocale(calendar, locale);
	CFRelease(locale);
        return calendar;
    }
    return NULL;
}

CFCalendarRef CFCalendarCreateWithIdentifier(CFAllocatorRef allocator, CFStringRef identifier) {
    if (allocator == NULL) allocator = __CFGetDefaultAllocator();
    __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
    __CFGenericValidateType(identifier, CFStringGetTypeID());
    // return NULL until Chinese calendar is available
    if (identifier != kCFGregorianCalendar && identifier != kCFBuddhistCalendar && identifier != kCFJapaneseCalendar && identifier != kCFIslamicCalendar && identifier != kCFIslamicCivilCalendar && identifier != kCFHebrewCalendar) {
//    if (identifier != kCFGregorianCalendar && identifier != kCFBuddhistCalendar && identifier != kCFJapaneseCalendar && identifier != kCFIslamicCalendar && identifier != kCFIslamicCivilCalendar && identifier != kCFHebrewCalendar && identifier != kCFChineseCalendar) {
	if (CFEqual(kCFGregorianCalendar, identifier)) identifier = kCFGregorianCalendar;
	else if (CFEqual(kCFBuddhistCalendar, identifier)) identifier = kCFBuddhistCalendar;
	else if (CFEqual(kCFJapaneseCalendar, identifier)) identifier = kCFJapaneseCalendar;
	else if (CFEqual(kCFIslamicCalendar, identifier)) identifier = kCFIslamicCalendar;
	else if (CFEqual(kCFIslamicCivilCalendar, identifier)) identifier = kCFIslamicCivilCalendar;
	else if (CFEqual(kCFHebrewCalendar, identifier)) identifier = kCFHebrewCalendar;
//	else if (CFEqual(kCFChineseCalendar, identifier)) identifier = kCFChineseCalendar;
	else return NULL;
    }
    struct __CFCalendar *calendar = NULL;
    uint32_t size = sizeof(struct __CFCalendar) - sizeof(CFRuntimeBase);
    calendar = (struct __CFCalendar *)_CFRuntimeCreateInstance(allocator, CFCalendarGetTypeID(), size, NULL);
    if (NULL == calendar) {
	return NULL;
    }
    calendar->_identifier = (CFStringRef)CFRetain(identifier);
    calendar->_locale = NULL;
    calendar->_localeID = CFLocaleGetIdentifier(CFLocaleGetSystem());
    calendar->_tz = CFTimeZoneCopyDefault();
    calendar->_cal = NULL;
    return (CFCalendarRef)calendar;
}

CFStringRef CFCalendarGetIdentifier(CFCalendarRef calendar) {
    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFStringRef, calendar, "calendarIdentifier");
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    return calendar->_identifier;
}

CFLocaleRef CFCalendarCopyLocale(CFCalendarRef calendar) {
    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFLocaleRef, calendar, "_copyLocale");
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    return (CFLocaleRef)CFLocaleCreate(kCFAllocatorSystemDefault, calendar->_localeID);
}

void CFCalendarSetLocale(CFCalendarRef calendar, CFLocaleRef locale) {
    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "setLocale:", locale);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    __CFGenericValidateType(locale, CFLocaleGetTypeID());
    CFStringRef localeID = CFLocaleGetIdentifier(locale);
    if (localeID != calendar->_localeID) {
	CFRelease(calendar->_localeID);
	CFRetain(localeID);
	calendar->_localeID = localeID;
        if (calendar->_cal) __CFCalendarZapCal(calendar);
    }
}

CFTimeZoneRef CFCalendarCopyTimeZone(CFCalendarRef calendar) {
    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFTimeZoneRef, calendar, "_copyTimeZone");
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    return (CFTimeZoneRef)CFRetain(calendar->_tz);
}

void CFCalendarSetTimeZone(CFCalendarRef calendar, CFTimeZoneRef tz) {
    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "setTimeZone:", tz);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (tz) __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
    if (tz != calendar->_tz) {
	CFRelease(calendar->_tz);
	calendar->_tz = tz ? (CFTimeZoneRef)CFRetain(tz) : CFTimeZoneCopyDefault();
        if (calendar->_cal) __CFCalendarZapCal(calendar);
    }
}

CFIndex CFCalendarGetFirstWeekday(CFCalendarRef calendar) {
    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFIndex, calendar, "firstWeekday");
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	return ucal_getAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK);
    }
    return -1;
}

void CFCalendarSetFirstWeekday(CFCalendarRef calendar, CFIndex wkdy) {
    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "setFirstWeekday:", wkdy);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	ucal_setAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK, wkdy);
    }
}

CFIndex CFCalendarGetMinimumDaysInFirstWeek(CFCalendarRef calendar) {
    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFIndex, calendar, "minimumDaysInFirstWeek");
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    return calendar->_cal ? ucal_getAttribute(calendar->_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK) : -1;
}

void CFCalendarSetMinimumDaysInFirstWeek(CFCalendarRef calendar, CFIndex mwd) {
    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "setMinimumDaysInFirstWeek:", mwd);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) ucal_setAttribute(calendar->_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, mwd);
}

CFDateRef CFCalendarCopyGregorianStartDate(CFCalendarRef calendar) {
    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFDateRef, calendar, "_gregorianStartDate");
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    UErrorCode status = U_ZERO_ERROR;
    UDate udate = calendar->_cal ? ucal_getGregorianChange(calendar->_cal, &status) : 0;
    if (calendar->_cal && U_SUCCESS(status)) {
	CFAbsoluteTime at = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
	return CFDateCreate(CFGetAllocator(calendar), at);
    }
    return NULL;
}

void CFCalendarSetGregorianStartDate(CFCalendarRef calendar, CFDateRef date) {
    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "_setGregorianStartDate:", date);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (date) __CFGenericValidateType(date, CFDateGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (!calendar->_cal) return;
    if (!date) {
	UErrorCode status = U_ZERO_ERROR;
	UCalendar *cal = __CFCalendarCreateUCalendar(calendar->_identifier, calendar->_localeID, calendar->_tz);
	UDate udate = cal ? ucal_getGregorianChange(cal, &status) : 0;
	if (cal && U_SUCCESS(status)) {
	    status = U_ZERO_ERROR;
	    if (calendar->_cal) ucal_setGregorianChange(calendar->_cal, udate, &status);
	}
	if (cal) ucal_close(cal);
    } else {
	CFAbsoluteTime at = CFDateGetAbsoluteTime(date);
	UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
	UErrorCode status = U_ZERO_ERROR;
	if (calendar->_cal) ucal_setGregorianChange(calendar->_cal, udate, &status);
    }
}


static UCalendarDateFields __CFCalendarGetICUFieldCode(CFCalendarUnit unit) {
    switch (unit) {
    case kCFCalendarUnitEra: return UCAL_ERA;
    case kCFCalendarUnitYear: return UCAL_YEAR;
    case kCFCalendarUnitMonth: return UCAL_MONTH;
    case kCFCalendarUnitDay: return UCAL_DAY_OF_MONTH;
    case kCFCalendarUnitHour: return UCAL_HOUR_OF_DAY;
    case kCFCalendarUnitMinute: return UCAL_MINUTE;
    case kCFCalendarUnitSecond: return UCAL_SECOND;
    case kCFCalendarUnitWeek: return UCAL_WEEK_OF_YEAR;
    case kCFCalendarUnitWeekday: return UCAL_DAY_OF_WEEK;
    case kCFCalendarUnitWeekdayOrdinal: return UCAL_DAY_OF_WEEK_IN_MONTH;
    }
    return (UCalendarDateFields)-1;
}

static UCalendarDateFields __CFCalendarGetICUFieldCodeFromChar(char ch) {
    switch (ch) {
    case 'G': return UCAL_ERA;
    case 'y': return UCAL_YEAR;
    case 'M': return UCAL_MONTH;
    case 'd': return UCAL_DAY_OF_MONTH;
    case 'h': return UCAL_HOUR;
    case 'H': return UCAL_HOUR_OF_DAY;
    case 'm': return UCAL_MINUTE;
    case 's': return UCAL_SECOND;
    case 'S': return UCAL_MILLISECOND;
    case 'w': return UCAL_WEEK_OF_YEAR;
    case 'W': return UCAL_WEEK_OF_MONTH;
    case 'E': return UCAL_DAY_OF_WEEK;
    case 'D': return UCAL_DAY_OF_YEAR;
    case 'F': return UCAL_DAY_OF_WEEK_IN_MONTH;
    case 'a': return UCAL_AM_PM;
    case 'g': return UCAL_JULIAN_DAY;
    }
    return (UCalendarDateFields)-1;
}

static UCalendarDateFields __CFCalendarGetCalendarUnitFromChar(char ch) {
    switch (ch) {
    case 'G': return (UCalendarDateFields)kCFCalendarUnitEra;
    case 'y': return (UCalendarDateFields)kCFCalendarUnitYear;
    case 'M': return (UCalendarDateFields)kCFCalendarUnitMonth;
    case 'd': return (UCalendarDateFields)kCFCalendarUnitDay;
    case 'H': return (UCalendarDateFields)kCFCalendarUnitHour;
    case 'm': return (UCalendarDateFields)kCFCalendarUnitMinute;
    case 's': return (UCalendarDateFields)kCFCalendarUnitSecond;
    case 'w': return (UCalendarDateFields)kCFCalendarUnitWeek;
    case 'E': return (UCalendarDateFields)kCFCalendarUnitWeekday;
    case 'F': return (UCalendarDateFields)kCFCalendarUnitWeekdayOrdinal;
    }
    return (UCalendarDateFields)-1;
}

CFRange CFCalendarGetMinimumRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit) {
    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), CFRange, calendar, "_minimumRangeOfUnit:", unit);
    CFRange range = {kCFNotFound, kCFNotFound};
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	ucal_clear(calendar->_cal);
	UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit);
	UErrorCode status = U_ZERO_ERROR;
	range.location = ucal_getLimit(calendar->_cal, field, UCAL_GREATEST_MINIMUM, &status);
	range.length = ucal_getLimit(calendar->_cal, field, UCAL_LEAST_MAXIMUM, &status) - range.location + 1;
	if (UCAL_MONTH == field) range.location++;
	if (100000 < range.length) range.length = 100000;
    }
    return range;
}

CFRange CFCalendarGetMaximumRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit) {
    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), CFRange, calendar, "_maximumRangeOfUnit:", unit);
    CFRange range = {kCFNotFound, kCFNotFound};
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	ucal_clear(calendar->_cal);
	UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit);
	UErrorCode status = U_ZERO_ERROR;
	range.location = ucal_getLimit(calendar->_cal, field, UCAL_MINIMUM, &status);
	range.length = ucal_getLimit(calendar->_cal, field, UCAL_MAXIMUM, &status) - range.location + 1;
	if (UCAL_MONTH == field) range.location++;
	if (100000 < range.length) range.length = 100000;
    }
    return range;
}

static void __CFCalendarSetToFirstInstant(CFCalendarRef calendar, CFCalendarUnit unit, CFAbsoluteTime at) {
    // Set UCalendar to first instant of unit prior to 'at'
    UErrorCode status = U_ZERO_ERROR;
    UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
    ucal_setMillis(calendar->_cal, udate, &status);
    int target_era = INT_MIN;
    switch (unit) { // largest to smallest, we set the fields to their minimum value
    case kCFCalendarUnitWeek:
	{
	// reduce to first day of week, then reduce the rest of the day
        int32_t goal = ucal_getAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK);
	int32_t dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
	while (dow != goal) {
	    ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, -1, &status);
	    dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
	}
	goto day;
	}
    case kCFCalendarUnitEra:
	{
	target_era = ucal_get(calendar->_cal, UCAL_ERA, &status);
	ucal_set(calendar->_cal, UCAL_YEAR, ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_ACTUAL_MINIMUM, &status));
	}
    case kCFCalendarUnitYear:
	ucal_set(calendar->_cal, UCAL_MONTH, ucal_getLimit(calendar->_cal, UCAL_MONTH, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitMonth:
	ucal_set(calendar->_cal, UCAL_DAY_OF_MONTH, ucal_getLimit(calendar->_cal, UCAL_DAY_OF_MONTH, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitWeekday:
    case kCFCalendarUnitDay:
    day:;
	ucal_set(calendar->_cal, UCAL_HOUR_OF_DAY, ucal_getLimit(calendar->_cal, UCAL_HOUR_OF_DAY, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitHour:
	ucal_set(calendar->_cal, UCAL_MINUTE, ucal_getLimit(calendar->_cal, UCAL_MINUTE, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitMinute:
	ucal_set(calendar->_cal, UCAL_SECOND, ucal_getLimit(calendar->_cal, UCAL_SECOND, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitSecond:
	ucal_set(calendar->_cal, UCAL_MILLISECOND, 0);
    }
    if (INT_MIN != target_era && ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) {
	// In the Japanese calendar, and possibly others, eras don't necessarily
	// start on the first day of a year, so the previous code may have backed
	// up into the previous era, and we have to correct forward.
	UDate bad_udate = ucal_getMillis(calendar->_cal, &status);
	ucal_add(calendar->_cal, UCAL_MONTH, 1, &status);
	while (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) {
	    bad_udate = ucal_getMillis(calendar->_cal, &status);
	    ucal_add(calendar->_cal, UCAL_MONTH, 1, &status);
	}
	udate = ucal_getMillis(calendar->_cal, &status);
	// target date is between bad_udate and udate
	for (;;) {
	    UDate test_udate = (udate + bad_udate) / 2;
	    ucal_setMillis(calendar->_cal, test_udate, &status);
	    if (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) {
		bad_udate = test_udate;
	    } else {
		udate = test_udate;
	    }
	    if (fabs(udate - bad_udate) < 1000) break;
	}
	do {
	    bad_udate = floor((bad_udate + 1000) / 1000) * 1000;
	    ucal_setMillis(calendar->_cal, bad_udate, &status);
	} while (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era);
    }
}

static Boolean __validUnits(CFCalendarUnit smaller, CFCalendarUnit bigger) {
    switch (bigger) {
    case kCFCalendarUnitEra:
	if (kCFCalendarUnitEra == smaller) return false;
	if (kCFCalendarUnitWeekday == smaller) return false;
	if (kCFCalendarUnitMinute == smaller) return false;	// this causes CFIndex overflow in range.length
	if (kCFCalendarUnitSecond == smaller) return false;	// this causes CFIndex overflow in range.length
	return true;
    case kCFCalendarUnitYear:
	if (kCFCalendarUnitEra == smaller) return false;
	if (kCFCalendarUnitYear == smaller) return false;
	if (kCFCalendarUnitWeekday == smaller) return false;
	return true;
    case kCFCalendarUnitMonth:
	if (kCFCalendarUnitEra == smaller) return false;
	if (kCFCalendarUnitYear == smaller) return false;
	if (kCFCalendarUnitMonth == smaller) return false;
	if (kCFCalendarUnitWeekday == smaller) return false;
	return true;
    case kCFCalendarUnitDay:
	if (kCFCalendarUnitHour == smaller) return true;
	if (kCFCalendarUnitMinute == smaller) return true;
	if (kCFCalendarUnitSecond == smaller) return true;
	return false;
    case kCFCalendarUnitHour:
	if (kCFCalendarUnitMinute == smaller) return true;
	if (kCFCalendarUnitSecond == smaller) return true;
	return false;
    case kCFCalendarUnitMinute:
	if (kCFCalendarUnitSecond == smaller) return true;
	return false;
    case kCFCalendarUnitWeek:
	if (kCFCalendarUnitWeekday == smaller) return true;
	if (kCFCalendarUnitDay == smaller) return true;
	if (kCFCalendarUnitHour == smaller) return true;
	if (kCFCalendarUnitMinute == smaller) return true;
	if (kCFCalendarUnitSecond == smaller) return true;
	return false;
    case kCFCalendarUnitSecond:
    case kCFCalendarUnitWeekday:
    case kCFCalendarUnitWeekdayOrdinal:
	return false;
    }
    return false;
};

static CFRange __CFCalendarGetRangeOfUnit1(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
    CFRange range = {kCFNotFound, kCFNotFound};
    if (!__validUnits(smallerUnit, biggerUnit)) return range;
    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFRange, calendar, "_rangeOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	int32_t dow = -1;
	ucal_clear(calendar->_cal);
	UCalendarDateFields smallField = __CFCalendarGetICUFieldCode(smallerUnit);
	UCalendarDateFields bigField = __CFCalendarGetICUFieldCode(biggerUnit);
	if (kCFCalendarUnitWeekdayOrdinal == smallerUnit) {
	    UErrorCode status = U_ZERO_ERROR;
	    UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	    ucal_setMillis(calendar->_cal, udate, &status);
	    dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
	}
	// Set calendar to first instant of big unit
	__CFCalendarSetToFirstInstant(calendar, biggerUnit, at);
	UErrorCode status = U_ZERO_ERROR;
	UDate start = ucal_getMillis(calendar->_cal, &status);
	if (kCFCalendarUnitWeek == biggerUnit) {
	    range.location = ucal_get(calendar->_cal, smallField, &status);
	    if (kCFCalendarUnitMonth == smallerUnit) range.location++;
	} else {
	    range.location = (kCFCalendarUnitHour == smallerUnit || kCFCalendarUnitMinute == smallerUnit || kCFCalendarUnitSecond == smallerUnit) ? 0 : 1;
	}
	// Set calendar to first instant of next value of big unit
	if (UCAL_ERA == bigField) {
	    // ICU refuses to do the addition, probably because we are
	    // at the limit of UCAL_ERA.  Use alternate strategy.
	    CFIndex limit = ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_MAXIMUM, &status);
	    if (100000 < limit) limit = 100000;
	    ucal_add(calendar->_cal, UCAL_YEAR, limit, &status);
	} else {
	    ucal_add(calendar->_cal, bigField, 1, &status);
	}
	if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitYear == biggerUnit) {
	    ucal_add(calendar->_cal, UCAL_SECOND, -1, &status);
	    range.length = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status);
	    while (1 == range.length) {
		ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, -1, &status);
		range.length = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status);
	    }
	    range.location = 1;
	    return range;
	} else if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitMonth == biggerUnit) {
	    ucal_add(calendar->_cal, UCAL_SECOND, -1, &status);
	    range.length = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status);
	    range.location = 1;
	    return range;
	}
	UDate goal = ucal_getMillis(calendar->_cal, &status);
	// Set calendar back to first instant of big unit
	ucal_setMillis(calendar->_cal, start, &status);
	if (kCFCalendarUnitWeekdayOrdinal == smallerUnit) {
	    // roll day forward to first 'dow'
	    while (ucal_get(calendar->_cal, (kCFCalendarUnitMonth == biggerUnit) ? UCAL_WEEK_OF_MONTH : UCAL_WEEK_OF_YEAR, &status) != 1) {
		ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status);
	    }
	    while (ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != dow) {
		ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status);
	    }
	    start = ucal_getMillis(calendar->_cal, &status);
	    goal -= 1000;
	    range.location = 1;  // constant here works around ICU -- see 3948293
	}
	UDate curr = start;
	range.length = 	(kCFCalendarUnitWeekdayOrdinal == smallerUnit) ? 1 : 0;
	const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14};
	int multiple = (1 << multiple_table[flsl(smallerUnit) - 1]);
	Boolean divide = false, alwaysDivide = false;
	while (curr < goal) {
	    ucal_add(calendar->_cal, smallField, multiple, &status);
	    UDate newcurr = ucal_getMillis(calendar->_cal, &status);
	    if (curr < newcurr && newcurr <= goal) {
		range.length += multiple;
		curr = newcurr;
	    } else {
		// Either newcurr is going backwards, or not making
		// progress, or has overshot the goal; reset date
		// and try smaller multiples.
		ucal_setMillis(calendar->_cal, curr, &status);
		divide = true;
		// once we start overshooting the goal, the add at
		// smaller multiples will succeed at most once for
		// each multiple, so we reduce it every time through
		// the loop.
		if (goal < newcurr) alwaysDivide = true;
	    }
	    if (divide) {
		multiple = multiple / 2;
		if (0 == multiple) break;
		divide = alwaysDivide;
	    }
	}
    }
    return range;
}

#if __GNUC__
static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) __attribute__((noinline));
#endif
static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFRange, calendar, "_rangeOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    CFRange range = {kCFNotFound, kCFNotFound};
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	switch (smallerUnit) {
	case kCFCalendarUnitSecond:
            switch (biggerUnit) {
            case kCFCalendarUnitMinute:
            case kCFCalendarUnitHour:
            case kCFCalendarUnitDay:
            case kCFCalendarUnitWeekday:
            case kCFCalendarUnitWeek:
            case kCFCalendarUnitMonth:
            case kCFCalendarUnitYear:
            case kCFCalendarUnitEra:
		// goto calculate;
                range.location = 0;
                range.length = 60;
		break;
            }
	    break;
	case kCFCalendarUnitMinute:
            switch (biggerUnit) {
            case kCFCalendarUnitHour:
            case kCFCalendarUnitDay:
            case kCFCalendarUnitWeekday:
            case kCFCalendarUnitWeek:
            case kCFCalendarUnitMonth:
            case kCFCalendarUnitYear:
            case kCFCalendarUnitEra:
		// goto calculate;
                range.location = 0;
                range.length = 60;
		break;
            }
	    break;
	case kCFCalendarUnitHour:
            switch (biggerUnit) {
            case kCFCalendarUnitDay:
            case kCFCalendarUnitWeekday:
            case kCFCalendarUnitWeek:
            case kCFCalendarUnitMonth:
            case kCFCalendarUnitYear:
            case kCFCalendarUnitEra:
		// goto calculate;
                range.location = 0;
                range.length = 24;
		break;
            }
	    break;
	case kCFCalendarUnitDay:
            switch (biggerUnit) {
            case kCFCalendarUnitWeek:
            case kCFCalendarUnitMonth:
            case kCFCalendarUnitYear:
            case kCFCalendarUnitEra:
		goto calculate;
		break;
            }
	    break;
	case kCFCalendarUnitWeekday:
            switch (biggerUnit) {
            case kCFCalendarUnitWeek:
            case kCFCalendarUnitMonth:
            case kCFCalendarUnitYear:
            case kCFCalendarUnitEra:
		goto calculate;
		break;
            }
	    break;
	case kCFCalendarUnitWeekdayOrdinal:
            switch (biggerUnit) {
            case kCFCalendarUnitMonth:
            case kCFCalendarUnitYear:
            case kCFCalendarUnitEra:
		goto calculate;
		break;
            }
	    break;
	case kCFCalendarUnitWeek:
            switch (biggerUnit) {
            case kCFCalendarUnitMonth:
            case kCFCalendarUnitYear:
            case kCFCalendarUnitEra:
		goto calculate;
		break;
            }
	    break;
	case kCFCalendarUnitMonth:
            switch (biggerUnit) {
            case kCFCalendarUnitYear:
            case kCFCalendarUnitEra:
		goto calculate;
		break;
            }
	    break;
	case kCFCalendarUnitYear:
            switch (biggerUnit) {
            case kCFCalendarUnitEra:
		goto calculate;
		break;
            }
	    break;
	case kCFCalendarUnitEra:
	    break;
	}
    }
    return range;

    calculate:;
    ucal_clear(calendar->_cal);
    UCalendarDateFields smallField = __CFCalendarGetICUFieldCode(smallerUnit);
    UCalendarDateFields bigField = __CFCalendarGetICUFieldCode(biggerUnit);
    UCalendarDateFields yearField = __CFCalendarGetICUFieldCode(kCFCalendarUnitYear);
    UCalendarDateFields fieldToAdd = smallField;
    if (kCFCalendarUnitWeekday == smallerUnit) {
        fieldToAdd = __CFCalendarGetICUFieldCode(kCFCalendarUnitDay);
    }
    int32_t dow = -1;
    if (kCFCalendarUnitWeekdayOrdinal == smallerUnit) {
        UErrorCode status = U_ZERO_ERROR;
        UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
        ucal_setMillis(calendar->_cal, udate, &status);
        dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
        fieldToAdd = __CFCalendarGetICUFieldCode(kCFCalendarUnitWeek);
    }
    // Set calendar to first instant of big unit
    __CFCalendarSetToFirstInstant(calendar, biggerUnit, at);
    if (kCFCalendarUnitWeekdayOrdinal == smallerUnit) {
        UErrorCode status = U_ZERO_ERROR;
        // roll day forward to first 'dow'
        while (ucal_get(calendar->_cal, (kCFCalendarUnitMonth == biggerUnit) ? UCAL_WEEK_OF_MONTH : UCAL_WEEK_OF_YEAR, &status) != 1) {
	    ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status);
        }
        while (ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != dow) {
	    ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status);
        }
    }
    int32_t minSmallValue = INT32_MAX;
    int32_t maxSmallValue = INT32_MIN;
    UErrorCode status = U_ZERO_ERROR;
    int32_t bigValue = ucal_get(calendar->_cal, bigField, &status);
    for (;;) {
        int32_t smallValue = ucal_get(calendar->_cal, smallField, &status);
        if (smallValue < minSmallValue) minSmallValue = smallValue;
        if (smallValue > maxSmallValue) maxSmallValue = smallValue;
        ucal_add(calendar->_cal, fieldToAdd, 1, &status);
        if (bigValue != ucal_get(calendar->_cal, bigField, &status)) break;
        if (biggerUnit == kCFCalendarUnitEra && ucal_get(calendar->_cal, yearField, &status) > 10000) break;
	// we assume an answer for 10000 years can be extrapolated to 100000 years, to save time
    }
    status = U_ZERO_ERROR;
    range.location = minSmallValue;
    if (smallerUnit == kCFCalendarUnitMonth) range.location = 1;
    range.length = maxSmallValue - minSmallValue + 1;
    if (biggerUnit == kCFCalendarUnitEra && ucal_get(calendar->_cal, yearField, &status) > 10000) range.length = 100000;

    return range;
}

CFRange CFCalendarGetRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
    if (_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard)) {
	return __CFCalendarGetRangeOfUnit2(calendar, smallerUnit, biggerUnit, at);
    } else {
	return __CFCalendarGetRangeOfUnit1(calendar, smallerUnit, biggerUnit, at);
    }
}

CFIndex CFCalendarGetOrdinalityOfUnit(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
    CFIndex result = kCFNotFound;
    if (!__validUnits(smallerUnit, biggerUnit)) return result;
    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFIndex, calendar, "_ordinalityOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	UErrorCode status = U_ZERO_ERROR;
	ucal_clear(calendar->_cal);
	if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitYear == biggerUnit) {
	    UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	    ucal_setMillis(calendar->_cal, udate, &status);
	    int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status);
	    return val;
	} else if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitMonth == biggerUnit) {
	    UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	    ucal_setMillis(calendar->_cal, udate, &status);
	    int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_MONTH, &status);
	    return val;
	}
	UCalendarDateFields smallField = __CFCalendarGetICUFieldCode(smallerUnit);
	// Set calendar to first instant of big unit
	__CFCalendarSetToFirstInstant(calendar, biggerUnit, at);
	UDate curr = ucal_getMillis(calendar->_cal, &status);
        UDate goal = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	result = 1;
	const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14};
	int multiple = (1 << multiple_table[flsl(smallerUnit) - 1]);
	Boolean divide = false, alwaysDivide = false;
	while (curr < goal) {
	    ucal_add(calendar->_cal, smallField, multiple, &status);
	    UDate newcurr = ucal_getMillis(calendar->_cal, &status);
	    if (curr < newcurr && newcurr <= goal) {
		result += multiple;
		curr = newcurr;
	    } else {
		// Either newcurr is going backwards, or not making
		// progress, or has overshot the goal; reset date
		// and try smaller multiples.
		ucal_setMillis(calendar->_cal, curr, &status);
		divide = true;
		// once we start overshooting the goal, the add at
		// smaller multiples will succeed at most once for
		// each multiple, so we reduce it every time through
		// the loop.
		if (goal < newcurr) alwaysDivide = true;
	    }
	    if (divide) {
		multiple = multiple / 2;
		if (0 == multiple) break;
		divide = alwaysDivide;
	    }
	}
    }
    return result;
}

Boolean _CFCalendarComposeAbsoluteTimeV(CFCalendarRef calendar, /* out */ CFAbsoluteTime *atp, const char *componentDesc, int *vector, int count) {
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	UErrorCode status = U_ZERO_ERROR;
	ucal_clear(calendar->_cal);
	ucal_set(calendar->_cal, UCAL_YEAR, 1);
	ucal_set(calendar->_cal, UCAL_MONTH, 0);
	ucal_set(calendar->_cal, UCAL_DAY_OF_MONTH, 1);
	ucal_set(calendar->_cal, UCAL_HOUR_OF_DAY, 0);
	ucal_set(calendar->_cal, UCAL_MINUTE, 0);
	ucal_set(calendar->_cal, UCAL_SECOND, 0);
	const char *desc = componentDesc;
	Boolean doWOY = false;
	char ch = *desc;
	while (ch) {
	    UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch);
	    if (UCAL_WEEK_OF_YEAR == field) {
		doWOY = true;
	    }
	    desc++;
	    ch = *desc;
	}
	desc = componentDesc;
	ch = *desc;
	while (ch) {
	    UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch);
	    int value = *vector;
	    if (UCAL_YEAR == field && doWOY) field = UCAL_YEAR_WOY;
	    if (UCAL_MONTH == field) value--;
	    ucal_set(calendar->_cal, field, value);
	    vector++;
	    desc++;
	    ch = *desc;
	}
	UDate udate = ucal_getMillis(calendar->_cal, &status);
	CFAbsoluteTime at = (udate / 1000.0) - kCFAbsoluteTimeIntervalSince1970;
        if (atp) *atp = at;
	return U_SUCCESS(status) ? true : false;
    }
    return false;
}

Boolean _CFCalendarDecomposeAbsoluteTimeV(CFCalendarRef calendar, CFAbsoluteTime at, const char *componentDesc, int **vector, int count) {
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	UErrorCode status = U_ZERO_ERROR;
	ucal_clear(calendar->_cal);
	UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	ucal_setMillis(calendar->_cal, udate, &status);
	char ch = *componentDesc;
	while (ch) {
	    UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch);
	    int value = ucal_get(calendar->_cal, field, &status);
	    if (UCAL_MONTH == field) value++;
	    *(*vector) = value;
	    vector++;
	    componentDesc++;
	    ch = *componentDesc;
	}
	return U_SUCCESS(status) ? true : false;
    }
    return false;
}

Boolean _CFCalendarAddComponentsV(CFCalendarRef calendar, /* inout */ CFAbsoluteTime *atp, CFOptionFlags options, const char *componentDesc, int *vector, int count) {
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	UErrorCode status = U_ZERO_ERROR;
	ucal_clear(calendar->_cal);
	UDate udate = floor((*atp + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	ucal_setMillis(calendar->_cal, udate, &status);
	char ch = *componentDesc;
	while (ch) {
	    UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch);
            int amount = *vector;
	    if (options & kCFCalendarComponentsWrap) {
		ucal_roll(calendar->_cal, field, amount, &status);
	    } else {
		ucal_add(calendar->_cal, field, amount, &status);
	    }
	    vector++;
	    componentDesc++;
	    ch = *componentDesc;
	}
	udate = ucal_getMillis(calendar->_cal, &status);
	*atp = (udate / 1000.0) - kCFAbsoluteTimeIntervalSince1970;
	return U_SUCCESS(status) ? true : false;
    }
    return false;
}

Boolean _CFCalendarGetComponentDifferenceV(CFCalendarRef calendar, CFAbsoluteTime startingAT, CFAbsoluteTime resultAT, CFOptionFlags options, const char *componentDesc, int **vector, int count) {
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	UErrorCode status = U_ZERO_ERROR;
	ucal_clear(calendar->_cal);
	UDate curr = floor((startingAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	UDate goal = floor((resultAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	ucal_setMillis(calendar->_cal, curr, &status);
	int direction = (startingAT <= resultAT) ? 1 : -1;
	char ch = *componentDesc;
	while (ch) {
	    UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch);
	    const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14};
	    int multiple = direction * (1 << multiple_table[flsl(__CFCalendarGetCalendarUnitFromChar(ch)) - 1]);
	    Boolean divide = false, alwaysDivide = false;
	    int result = 0;
	    while ((direction > 0 && curr < goal) || (direction < 0 && goal < curr)) {
		ucal_add(calendar->_cal, field, multiple, &status);
		UDate newcurr = ucal_getMillis(calendar->_cal, &status);
		if ((direction > 0 && curr < newcurr && newcurr <= goal) || (direction < 0 && newcurr < curr && goal <= newcurr)) {
		    result += multiple;
		    curr = newcurr;
		} else {
		    // Either newcurr is going backwards, or not making
		    // progress, or has overshot the goal; reset date
		    // and try smaller multiples.
		    ucal_setMillis(calendar->_cal, curr, &status);
		    divide = true;
		    // once we start overshooting the goal, the add at
		    // smaller multiples will succeed at most once for
		    // each multiple, so we reduce it every time through
		    // the loop.
		    if ((direction > 0 && goal < newcurr) || (direction < 0 && newcurr < goal)) alwaysDivide = true;
		}
		if (divide) {
		    multiple = multiple / 2;
		    if (0 == multiple) break;
		    divide = alwaysDivide;
		}
	    }
	    *(*vector) = result;
	    vector++;
	    componentDesc++;
	    ch = *componentDesc;
	}
	return U_SUCCESS(status) ? true : false;
    }
    return false;
}

Boolean CFCalendarComposeAbsoluteTime(CFCalendarRef calendar, /* out */ CFAbsoluteTime *atp, const char *componentDesc, ...) {
    va_list args;
    va_start(args, componentDesc);
    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), Boolean, calendar, "_composeAbsoluteTime:::", atp, componentDesc, args);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    int idx, cnt = (int)strlen((char *)componentDesc);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
    STACK_BUFFER_DECL(int, vector, cnt);
#else
    int vector[256]; // Dynamic stack allocation is GNU specific
#endif
    for (idx = 0; idx < cnt; idx++) {
	int arg = va_arg(args, int);
	vector[idx] = arg;
    }
    va_end(args);
    return _CFCalendarComposeAbsoluteTimeV(calendar, atp, componentDesc, vector, cnt);
}

Boolean CFCalendarDecomposeAbsoluteTime(CFCalendarRef calendar, CFAbsoluteTime at, const char *componentDesc, ...) {
    va_list args;
    va_start(args, componentDesc);
    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), Boolean, calendar, "_decomposeAbsoluteTime:::", at, componentDesc, args);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    int idx, cnt = (int)strlen((char *)componentDesc);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
    STACK_BUFFER_DECL(int *, vector, cnt);
#else
    int* vector[256]; // Dynamic stack allocation is GNU specific
#endif
    for (idx = 0; idx < cnt; idx++) {
        int *arg = va_arg(args, int *);
        vector[idx] = arg;
    }
    va_end(args);
    return _CFCalendarDecomposeAbsoluteTimeV(calendar, at, componentDesc, vector, cnt);
}

Boolean CFCalendarAddComponents(CFCalendarRef calendar, /* inout */ CFAbsoluteTime *atp, CFOptionFlags options, const char *componentDesc, ...) {
    va_list args;
    va_start(args, componentDesc);
    CF_OBJC_FUNCDISPATCH4(CFCalendarGetTypeID(), Boolean, calendar, "_addComponents::::", atp, options, componentDesc, args);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    int idx, cnt = (int)strlen((char *)componentDesc);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
    STACK_BUFFER_DECL(int, vector, cnt);
#else
    int vector[256]; // Dynamic stack allocation is GNU specific
#endif
    for (idx = 0; idx < cnt; idx++) {
        int arg = va_arg(args, int);
        vector[idx] = arg;
    }
    va_end(args);
    return _CFCalendarAddComponentsV(calendar, atp, options, componentDesc, vector, cnt);    
}

Boolean CFCalendarGetComponentDifference(CFCalendarRef calendar, CFAbsoluteTime startingAT, CFAbsoluteTime resultAT, CFOptionFlags options, const char *componentDesc, ...) {
    va_list args;
    va_start(args, componentDesc);
    CF_OBJC_FUNCDISPATCH5(CFCalendarGetTypeID(), Boolean, calendar, "_diffComponents:::::", startingAT, resultAT, options, componentDesc, args);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    int idx, cnt = (int)strlen((char *)componentDesc);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
    STACK_BUFFER_DECL(int *, vector, cnt);
#else
    int* vector[256]; // Dynamic stack allocation is GNU specific
#endif
    for (idx = 0; idx < cnt; idx++) {
        int *arg = va_arg(args, int *);
        vector[idx] = arg;
    }
    va_end(args);
    Boolean ret = _CFCalendarGetComponentDifferenceV(calendar, startingAT, resultAT, options, componentDesc, vector, cnt);
    return ret;
}

Boolean CFCalendarGetTimeRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit, CFAbsoluteTime at, CFAbsoluteTime *startp, CFTimeInterval *tip) {
    CF_OBJC_FUNCDISPATCH4(CFCalendarGetTypeID(), Boolean, calendar, "_rangeOfUnit:startTime:interval:forAT:", unit, startp, tip, at);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (kCFCalendarUnitWeekdayOrdinal == unit) return false;
    if (kCFCalendarUnitWeekday == unit) unit = kCFCalendarUnitDay;
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
        ucal_clear(calendar->_cal);
        __CFCalendarSetToFirstInstant(calendar, unit, at);
        UErrorCode status = U_ZERO_ERROR;
        UDate start = ucal_getMillis(calendar->_cal, &status);
	UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit);
	ucal_add(calendar->_cal, field, 1, &status);
        UDate end = ucal_getMillis(calendar->_cal, &status);
	if (end == start && kCFCalendarUnitEra == unit) {
            // ICU refuses to do the addition, probably because we are
            // at the limit of UCAL_ERA.  Use alternate strategy.
            CFIndex limit = ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_MAXIMUM, &status);
            if (100000 < limit) limit = 100000;
            ucal_add(calendar->_cal, UCAL_YEAR, limit, &status);
	    end = ucal_getMillis(calendar->_cal, &status);
	}
	if (U_SUCCESS(status)) {
	    if (startp) *startp = (double)start / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
	    if (tip) *tip = (double)(end - start) / 1000.0;
	    return true;
	}
    }
    return false;
}

#undef BUFFER_SIZE

