/*
Function:
EnumCalendarInfo

Retrieves a collection of calendar string data specified by the locale,
calendar, and data type.
Allows for a collection of calendar string data to be retrieved by invoking
the callback for each value in the collection.
The context parameter is passed through to the callback along with each string.
*/
int32_t GlobalizationNative_EnumCalendarInfo(EnumCalendarInfoCallback callback,
                                             const UChar* localeName,
                                             CalendarId calendarId,
                                             CalendarDataType dataType,
                                             const void* context)
{
    UErrorCode err = U_ZERO_ERROR;
    char locale[ULOC_FULLNAME_CAPACITY];
    GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, FALSE, &err);

    if (U_FAILURE(err))
        return FALSE;

    switch (dataType)
    {
        case CalendarData_ShortDates:
            // ShortDates to map kShort and kMedium in ICU, but also adding the "yMd"
            // skeleton as well, as this closely matches what is used on Windows
            return InvokeCallbackForDatePattern(locale, UDAT_SHORT, callback, context) &&
                   InvokeCallbackForDatePattern(locale, UDAT_MEDIUM, callback, context) &&
                   InvokeCallbackForDateTimePattern(locale, UDAT_YEAR_NUM_MONTH_DAY_UCHAR, callback, context);
        case CalendarData_LongDates:
            // LongDates map to kFull and kLong in ICU.
            return InvokeCallbackForDatePattern(locale, UDAT_FULL, callback, context) &&
                   InvokeCallbackForDatePattern(locale, UDAT_LONG, callback, context);
        case CalendarData_YearMonths:
            return InvokeCallbackForDateTimePattern(locale, UDAT_YEAR_MONTH_UCHAR, callback, context);
        case CalendarData_DayNames:
            return EnumSymbols(locale, calendarId, UDAT_STANDALONE_WEEKDAYS, 1, callback, context);
        case CalendarData_AbbrevDayNames:
            return EnumSymbols(locale, calendarId, UDAT_STANDALONE_SHORT_WEEKDAYS, 1, callback, context);
        case CalendarData_MonthNames:
            return EnumSymbols(locale, calendarId, UDAT_STANDALONE_MONTHS, 0, callback, context);
        case CalendarData_AbbrevMonthNames:
            return EnumSymbols(locale, calendarId, UDAT_STANDALONE_SHORT_MONTHS, 0, callback, context);
        case CalendarData_SuperShortDayNames:
            // UDAT_STANDALONE_SHORTER_WEEKDAYS was added in ICU 51, and CentOS 7 currently uses ICU 50.
            // fallback to UDAT_STANDALONE_NARROW_WEEKDAYS in that case.
#if HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS
            return EnumSymbols(locale, calendarId, UDAT_STANDALONE_SHORTER_WEEKDAYS, 1, callback, context);
#else
            return EnumSymbols(locale, calendarId, UDAT_STANDALONE_NARROW_WEEKDAYS, 1, callback, context);
#endif
        case CalendarData_MonthGenitiveNames:
            return EnumSymbols(locale, calendarId, UDAT_MONTHS, 0, callback, context);
        case CalendarData_AbbrevMonthGenitiveNames:
            return EnumSymbols(locale, calendarId, UDAT_SHORT_MONTHS, 0, callback, context);
        case CalendarData_EraNames:
            return EnumSymbols(locale, calendarId, UDAT_ERAS, 0, callback, context);
        case CalendarData_AbbrevEraNames:
            return EnumAbbrevEraNames(locale, calendarId, callback, context);
        default:
            assert(FALSE);
            return FALSE;
    }
}
Exemple #2
0
UINT PASCAL _Cover_EnumSymbols(LPSYG lpsyg, WORD maxstr, ENUMPROC lpfn,
                LPVOID data )
{
    return( EnumSymbols( lpsyg, maxstr,
                SetProc( (FARPROC)lpfn, GETPROC_PENWIN_ENUMPROC ), data ) );

}
/*
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);
}