Ejemplo n.º 1
0
/*
Function:
EnumEraNames

Enumerates all the era names of the specified locale and calendar, invoking the callback function
for each era name.
*/
bool EnumEraNames(Locale& locale, CalendarId calendarId, CalendarDataType dataType, EnumCalendarInfoCallback callback, const void* context)
{
	UErrorCode err = U_ZERO_ERROR;
	const char* calendarName = GetCalendarName(calendarId);
	DateFormatSymbols dateFormatSymbols(locale, calendarName, err);
	if (U_FAILURE(err))
		return false;

	int32_t eraNameCount;
	const UnicodeString* eraNames;

	if (dataType == EraNames)
	{
		eraNames = dateFormatSymbols.getEras(eraNameCount);
	}
	else if (dataType == AbbrevEraNames)
	{
		eraNames = dateFormatSymbols.getNarrowEras(eraNameCount);
	}
	else
	{
		assert(false);
		return false;
	}

	return EnumCalendarArray(eraNames, eraNameCount, callback, context);
}
Ejemplo n.º 2
0
/*
Function:
GetNativeCalendarName

Gets the native calendar name.
*/
CalendarDataResult GetNativeCalendarName(Locale& locale, CalendarId calendarId, UChar* nativeName, int32_t stringCapacity)
{
	LocalPointer<LocaleDisplayNames> displayNames(LocaleDisplayNames::createInstance(locale));

	UnicodeString calendarName;
	displayNames->keyValueDisplayName("calendar", GetCalendarName(calendarId), calendarName);

	UErrorCode err = U_ZERO_ERROR;
	calendarName.extract(nativeName, stringCapacity, err);

	return GetCalendarDataResult(err);
}
Ejemplo n.º 3
0
/*
Function:
GetNativeCalendarName

Gets the native calendar name.
*/
static ResultCode GetNativeCalendarName(const char* locale,
                                        CalendarId calendarId,
                                        UChar* nativeName,
                                        int32_t stringCapacity)
{
    UErrorCode err = U_ZERO_ERROR;
    ULocaleDisplayNames* pDisplayNames = uldn_open(locale, ULDN_STANDARD_NAMES, &err);

    uldn_keyValueDisplayName(pDisplayNames, "calendar", GetCalendarName(calendarId), nativeName, stringCapacity, &err);

    uldn_close(pDisplayNames);
    return GetResultCode(err);
}
Ejemplo n.º 4
0
/*
Function:
EnumMonths

Enumerates all the month names of the specified context and width, invoking the callback function
for each month name.
*/
bool EnumMonths(
	Locale& locale,
	CalendarId calendarId,
	DateFormatSymbols::DtContextType dtContext,
	DateFormatSymbols::DtWidthType dtWidth,
	EnumCalendarInfoCallback callback,
	const void* context)
{
	UErrorCode err = U_ZERO_ERROR;
	DateFormatSymbols dateFormatSymbols(locale, GetCalendarName(calendarId), err);
	if (U_FAILURE(err))
		return false;

	int32_t monthsCount;
	const UnicodeString* monthNames = dateFormatSymbols.getMonths(monthsCount, dtContext, dtWidth);
	return EnumCalendarArray(monthNames, monthsCount, callback, context);
}
Ejemplo n.º 5
0
/*
Function:
EnumWeekdays

Enumerates all the weekday names of the specified context and width, invoking the callback function
for each weekday name.
*/
bool EnumWeekdays(
	Locale& locale,
	CalendarId calendarId,
	DateFormatSymbols::DtContextType dtContext,
	DateFormatSymbols::DtWidthType dtWidth,
	EnumCalendarInfoCallback callback,
	const void* context)
{
	UErrorCode err = U_ZERO_ERROR;
	DateFormatSymbols dateFormatSymbols(locale, GetCalendarName(calendarId), err);
	if (U_FAILURE(err))
		return false;

	int32_t daysCount;
	const UnicodeString* dayNames = dateFormatSymbols.getWeekdays(daysCount, dtContext, dtWidth);

	// ICU returns an empty string for the first/zeroth element in the weekdays array.
	// So skip the first element.
	dayNames++;
	daysCount--;

	return EnumCalendarArray(dayNames, daysCount, callback, context);
}
Ejemplo n.º 6
0
/*
Function:
EnumAbbrevEraNames

Enumerates all the abbreviated era names of the specified locale and calendar, invoking the
callback function for each era name.
*/
static int32_t EnumAbbrevEraNames(const char* locale,
                                  CalendarId calendarId,
                                  EnumCalendarInfoCallback callback,
                                  const void* context)
{
    // The C-API for ICU provides no way to get at the abbreviated era names for a calendar (so we can't use EnumSymbols
    // here). Instead we will try to walk the ICU resource tables directly and fall back to regular era names if can't
    // find good data.
    char localeNameBuf[ULOC_FULLNAME_CAPACITY];
    char parentNameBuf[ULOC_FULLNAME_CAPACITY];

    char* localeNamePtr = localeNameBuf;
    char* parentNamePtr = parentNameBuf;

    strncpy(localeNamePtr, locale, ULOC_FULLNAME_CAPACITY);

    while (TRUE)
    {
        UErrorCode status = U_ZERO_ERROR;
        const char* name = GetCalendarName(calendarId);

        UResourceBundle* rootResBundle = ures_open(NULL, localeNamePtr, &status);
        UResourceBundle* calResBundle = ures_getByKey(rootResBundle, "calendar", NULL, &status);
        UResourceBundle* targetCalResBundle = ures_getByKey(calResBundle, name, NULL, &status);
        UResourceBundle* erasColResBundle = ures_getByKey(targetCalResBundle, "eras", NULL, &status);
        UResourceBundle* erasResBundle = ures_getByKey(erasColResBundle, "narrow", NULL, &status);

        if (U_SUCCESS(status))
        {
            EnumUResourceBundle(erasResBundle, callback, context);
            CloseResBundle(rootResBundle, calResBundle, targetCalResBundle, erasColResBundle, erasResBundle);
            return TRUE;
        }

        // Couldn't find the data we need for this locale, we should fallback.
        if (localeNameBuf[0] == 0x0)
        {
            CloseResBundle(rootResBundle, calResBundle, targetCalResBundle, erasColResBundle, erasResBundle);
            // We are already at the root locale so there is nothing to fall back to, just use the regular eras.
            break;
        }

        uloc_getParent(localeNamePtr, parentNamePtr, ULOC_FULLNAME_CAPACITY, &status);

        if (U_FAILURE(status))
        {
            CloseResBundle(rootResBundle, calResBundle, targetCalResBundle, erasColResBundle, erasResBundle);
            // Something bad happened getting the parent name, bail out.
            break;
        }

        // Swap localeNamePtr and parentNamePtr, parentNamePtr is what we want to use on the next iteration
        // and we can use the current localeName as scratch space if we have to fall back on that
        // iteration.

        char* temp = localeNamePtr;
        localeNamePtr = parentNamePtr;
        parentNamePtr = temp;

        CloseResBundle(rootResBundle, calResBundle, targetCalResBundle, erasColResBundle, erasResBundle);
    }

    // Walking the resource bundles didn't work, just use the regular eras.
    return EnumSymbols(locale, calendarId, UDAT_ERAS, 0, callback, context);
}
Ejemplo n.º 7
0
/*
Function:
EnumSymbols

Enumerates all of the symbols of a type for a locale and calendar and invokes a callback
for each value.
*/
static int32_t EnumSymbols(const char* locale,
                           CalendarId calendarId,
                           UDateFormatSymbolType type,
                           int32_t startIndex,
                           EnumCalendarInfoCallback callback,
                           const void* context)
{
    UErrorCode err = U_ZERO_ERROR;
    UDateFormat* pFormat = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, locale, NULL, 0, NULL, 0, &err);

    if (U_FAILURE(err))
        return FALSE;

    char localeWithCalendarName[ULOC_FULLNAME_CAPACITY];
    strncpy(localeWithCalendarName, locale, ULOC_FULLNAME_CAPACITY);
    uloc_setKeywordValue("calendar", GetCalendarName(calendarId), localeWithCalendarName, ULOC_FULLNAME_CAPACITY, &err);

    UCalendar* pCalendar = ucal_open(NULL, 0, localeWithCalendarName, UCAL_DEFAULT, &err);

    if (U_FAILURE(err))
    {
        udat_close(pFormat);
        return FALSE;
    }

    udat_setCalendar(pFormat, pCalendar);

    int32_t symbolCount = udat_countSymbols(pFormat, type);
    UChar stackSymbolBuf[100];
    UChar* symbolBuf;

    for (int32_t i = startIndex; U_SUCCESS(err) && i < symbolCount; i++)
    {
        UErrorCode ignore = U_ZERO_ERROR;
        int symbolLen = udat_getSymbols(pFormat, type, i, NULL, 0, &ignore) + 1;

        if (symbolLen <= sizeof(stackSymbolBuf) / sizeof(stackSymbolBuf[0]))
        {
            symbolBuf = stackSymbolBuf;
        }
        else
        {
            symbolBuf = calloc(symbolLen, sizeof(UChar));
            if (symbolBuf == NULL)
            {
                err = U_MEMORY_ALLOCATION_ERROR;
                break;
            }
        }

        udat_getSymbols(pFormat, type, i, symbolBuf, symbolLen, &err);

        if (U_SUCCESS(err))
        {
            callback(symbolBuf, context);
        }

        if (symbolBuf != stackSymbolBuf)
        {
            free(symbolBuf);
        }
    }

    udat_close(pFormat);
    ucal_close(pCalendar);
    return UErrorCodeToBool(err);
}