Пример #1
0
static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLanguageTag, jobject localeData) {
    ScopedUtfChars languageTag(env, javaLanguageTag);
    if (languageTag.c_str() == NULL) {
        return JNI_FALSE;
    }
    if (languageTag.size() >= ULOC_FULLNAME_CAPACITY) {
        return JNI_FALSE; // ICU has a fixed-length limit.
    }

    ScopedIcuLocale icuLocale(env, javaLanguageTag);
    if (!icuLocale.valid()) {
      return JNI_FALSE;
    }

    // Get the DateTimePatterns.
    UErrorCode status = U_ZERO_ERROR;
    bool foundDateTimePatterns = false;
    for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) {
      if (getDateTimePatterns(env, localeData, it.Get())) {
          foundDateTimePatterns = true;
          break;
      }
    }
    if (!foundDateTimePatterns) {
        ALOGE("Couldn't find ICU DateTimePatterns for %s", languageTag.c_str());
        return JNI_FALSE;
    }

    // Get the "Yesterday", "Today", and "Tomorrow" strings.
    bool foundYesterdayTodayAndTomorrow = false;
    for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) {
      if (getYesterdayTodayAndTomorrow(env, localeData, icuLocale.locale(), it.Get())) {
        foundYesterdayTodayAndTomorrow = true;
        break;
      }
    }
    if (!foundYesterdayTodayAndTomorrow) {
      ALOGE("Couldn't find ICU yesterday/today/tomorrow for %s", languageTag.c_str());
      return JNI_FALSE;
    }

    // Get the narrow "AM" and "PM" strings.
    bool foundAmPmMarkersNarrow = false;
    for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) {
      if (getAmPmMarkersNarrow(env, localeData, it.Get())) {
        foundAmPmMarkersNarrow = true;
        break;
      }
    }
    if (!foundAmPmMarkersNarrow) {
      ALOGE("Couldn't find ICU AmPmMarkersNarrow for %s", languageTag.c_str());
      return JNI_FALSE;
    }

    status = U_ZERO_ERROR;
    UniquePtr<Calendar> cal(Calendar::createInstance(icuLocale.locale(), status));
    if (U_FAILURE(status)) {
        return JNI_FALSE;
    }

    setIntegerField(env, localeData, "firstDayOfWeek", cal->getFirstDayOfWeek());
    setIntegerField(env, localeData, "minimalDaysInFirstWeek", cal->getMinimalDaysInFirstWeek());

    // Get DateFormatSymbols.
    status = U_ZERO_ERROR;
    DateFormatSymbols dateFormatSym(icuLocale.locale(), status);
    if (U_FAILURE(status)) {
        return JNI_FALSE;
    }

    // Get AM/PM and BC/AD.
    int32_t count = 0;
    const UnicodeString* amPmStrs = dateFormatSym.getAmPmStrings(count);
    setStringArrayField(env, localeData, "amPm", amPmStrs, count);
    const UnicodeString* erasStrs = dateFormatSym.getEras(count);
    setStringArrayField(env, localeData, "eras", erasStrs, count);

    const UnicodeString* longMonthNames =
       dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
    setStringArrayField(env, localeData, "longMonthNames", longMonthNames, count);
    const UnicodeString* shortMonthNames =
        dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
    setStringArrayField(env, localeData, "shortMonthNames", shortMonthNames, count);
    const UnicodeString* tinyMonthNames =
        dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
    setStringArrayField(env, localeData, "tinyMonthNames", tinyMonthNames, count);
    const UnicodeString* longWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
    setStringArrayField(env, localeData, "longWeekdayNames", longWeekdayNames, count);
    const UnicodeString* shortWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
    setStringArrayField(env, localeData, "shortWeekdayNames", shortWeekdayNames, count);
    const UnicodeString* tinyWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
    setStringArrayField(env, localeData, "tinyWeekdayNames", tinyWeekdayNames, count);

    const UnicodeString* longStandAloneMonthNames =
        dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
    setStringArrayField(env, localeData, "longStandAloneMonthNames", longStandAloneMonthNames, count);
    const UnicodeString* shortStandAloneMonthNames =
        dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
    setStringArrayField(env, localeData, "shortStandAloneMonthNames", shortStandAloneMonthNames, count);
    const UnicodeString* tinyStandAloneMonthNames =
        dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
    setStringArrayField(env, localeData, "tinyStandAloneMonthNames", tinyStandAloneMonthNames, count);
    const UnicodeString* longStandAloneWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
    setStringArrayField(env, localeData, "longStandAloneWeekdayNames", longStandAloneWeekdayNames, count);
    const UnicodeString* shortStandAloneWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
    setStringArrayField(env, localeData, "shortStandAloneWeekdayNames", shortStandAloneWeekdayNames, count);
    const UnicodeString* tinyStandAloneWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
    setStringArrayField(env, localeData, "tinyStandAloneWeekdayNames", tinyStandAloneWeekdayNames, count);

    status = U_ZERO_ERROR;

    // For numberPatterns and symbols.
    setNumberPatterns(env, localeData, icuLocale.locale());
    setDecimalFormatSymbolsData(env, localeData, icuLocale.locale());

    jstring countryCode = env->NewStringUTF(icuLocale.locale().getCountry());
    jstring internationalCurrencySymbol = ICU_getCurrencyCode(env, NULL, countryCode);
    env->DeleteLocalRef(countryCode);
    countryCode = NULL;

    jstring currencySymbol = NULL;
    if (internationalCurrencySymbol != NULL) {
        currencySymbol = ICU_getCurrencySymbol(env, NULL, javaLanguageTag, internationalCurrencySymbol);
    } else {
        internationalCurrencySymbol = env->NewStringUTF("XXX");
    }
    if (currencySymbol == NULL) {
        // This is the UTF-8 encoding of U+00A4 (CURRENCY SIGN).
        currencySymbol = env->NewStringUTF("\xc2\xa4");
    }
    setStringField(env, localeData, "currencySymbol", currencySymbol);
    setStringField(env, localeData, "internationalCurrencySymbol", internationalCurrencySymbol);

    return JNI_TRUE;
}
Пример #2
0
static jboolean ICU_initLocaleDataImpl(JNIEnv* env, jclass, jstring locale, jobject localeData) {
    ScopedUtfChars localeName(env, locale);
    if (localeName.c_str() == NULL) {
        return JNI_FALSE;
    }

    // Get DateTimePatterns
    UErrorCode status;
    char currentLocale[ULOC_FULLNAME_CAPACITY];
    int32_t localeNameLen = 0;
    if (localeName.size() >= ULOC_FULLNAME_CAPACITY) {
        return JNI_FALSE;  // Exceed ICU defined limit of the whole locale ID.
    }
    strcpy(currentLocale, localeName.c_str());
    do {
        status = U_ZERO_ERROR;
        ScopedResourceBundle root(ures_open(NULL, currentLocale, &status));
        if (U_FAILURE(status)) {
            if (localeNameLen == 0) {
                break;  // No parent locale, report this error outside the loop.
            } else {
                status = U_ZERO_ERROR;
                continue;  // get parent locale.
            }
        }
        ScopedResourceBundle calendar(ures_getByKey(root.get(), "calendar", NULL, &status));
        if (U_FAILURE(status)) {
            status = U_ZERO_ERROR;
            continue;  // get parent locale.
        }

        ScopedResourceBundle gregorian(ures_getByKey(calendar.get(), "gregorian", NULL, &status));
        if (U_FAILURE(status)) {
            status = U_ZERO_ERROR;
            continue;  // get parent locale.
        }
        ScopedResourceBundle dateTimePatterns(ures_getByKey(gregorian.get(), "DateTimePatterns", NULL, &status));
        if (U_SUCCESS(status)) {
            setStringField(env, localeData, "fullTimeFormat", dateTimePatterns.get(), 0);
            setStringField(env, localeData, "longTimeFormat", dateTimePatterns.get(), 1);
            setStringField(env, localeData, "mediumTimeFormat", dateTimePatterns.get(), 2);
            setStringField(env, localeData, "shortTimeFormat", dateTimePatterns.get(), 3);
            setStringField(env, localeData, "fullDateFormat", dateTimePatterns.get(), 4);
            setStringField(env, localeData, "longDateFormat", dateTimePatterns.get(), 5);
            setStringField(env, localeData, "mediumDateFormat", dateTimePatterns.get(), 6);
            setStringField(env, localeData, "shortDateFormat", dateTimePatterns.get(), 7);
            break;
        } else {
            status = U_ZERO_ERROR;  // get parent locale.
        }
    } while((localeNameLen = uloc_getParent(currentLocale, currentLocale, sizeof(currentLocale), &status)) >= 0);
    if (U_FAILURE(status)) {
        ALOGE("Error getting ICU resource bundle: %s", u_errorName(status));
        return JNI_FALSE;
    }

    status = U_ZERO_ERROR;
    Locale localeObj = getLocale(env, locale);

    UniquePtr<Calendar> cal(Calendar::createInstance(localeObj, status));
    if (U_FAILURE(status)) {
        return JNI_FALSE;
    }
    setIntegerField(env, localeData, "firstDayOfWeek", cal->getFirstDayOfWeek());
    setIntegerField(env, localeData, "minimalDaysInFirstWeek", cal->getMinimalDaysInFirstWeek());

    // Get DateFormatSymbols
    status = U_ZERO_ERROR;
    DateFormatSymbols dateFormatSym(localeObj, status);
    if (U_FAILURE(status)) {
        return JNI_FALSE;
    }
    int32_t count = 0;
    // Get AM/PM marker
    const UnicodeString* amPmStrs = dateFormatSym.getAmPmStrings(count);
    setStringArrayField(env, localeData, "amPm", amPmStrs, count);
    const UnicodeString* erasStrs = dateFormatSym.getEras(count);
    setStringArrayField(env, localeData, "eras", erasStrs, count);

    const UnicodeString* longMonthNames =
       dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
    setStringArrayField(env, localeData, "longMonthNames", longMonthNames, count);
    const UnicodeString* shortMonthNames =
        dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
    setStringArrayField(env, localeData, "shortMonthNames", shortMonthNames, count);
    const UnicodeString* longWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
    setStringArrayField(env, localeData, "longWeekdayNames", longWeekdayNames, count);
    const UnicodeString* shortWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
    setStringArrayField(env, localeData, "shortWeekdayNames", shortWeekdayNames, count);

    const UnicodeString* longStandAloneMonthNames =
        dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
    setStringArrayField(env, localeData, "longStandAloneMonthNames", longStandAloneMonthNames, count);
    const UnicodeString* shortStandAloneMonthNames =
        dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
    setStringArrayField(env, localeData, "shortStandAloneMonthNames", shortStandAloneMonthNames, count);
    const UnicodeString* longStandAloneWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
    setStringArrayField(env, localeData, "longStandAloneWeekdayNames", longStandAloneWeekdayNames, count);
    const UnicodeString* shortStandAloneWeekdayNames =
        dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
    setStringArrayField(env, localeData, "shortStandAloneWeekdayNames", shortStandAloneWeekdayNames, count);

    status = U_ZERO_ERROR;

    // For numberPatterns and symbols.
    setNumberPatterns(env, localeData, locale);
    setDecimalFormatSymbolsData(env, localeData, locale);

    jstring countryCode = env->NewStringUTF(Locale::createFromName(localeName.c_str()).getCountry());
    jstring internationalCurrencySymbol = ICU_getCurrencyCode(env, NULL, countryCode);
    env->DeleteLocalRef(countryCode);
    countryCode = NULL;

    jstring currencySymbol = NULL;
    if (internationalCurrencySymbol != NULL) {
        currencySymbol = ICU_getCurrencySymbol(env, NULL, locale, internationalCurrencySymbol);
    } else {
        internationalCurrencySymbol = env->NewStringUTF("XXX");
    }
    if (currencySymbol == NULL) {
        // This is the UTF-8 encoding of U+00A4 (CURRENCY SIGN).
        currencySymbol = env->NewStringUTF("\xc2\xa4");
    }
    setStringField(env, localeData, "currencySymbol", currencySymbol);
    setStringField(env, localeData, "internationalCurrencySymbol", internationalCurrencySymbol);

    return JNI_TRUE;
}