static jstring ICU_getISO3Language(JNIEnv* env, jclass, jstring javaLanguageTag) { ScopedIcuLocale icuLocale(env, javaLanguageTag); if (!icuLocale.valid()) { return NULL; } return env->NewStringUTF(icuLocale.locale().getISO3Language()); }
static jlong DateIntervalFormat_createDateIntervalFormat(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLocaleName, jstring javaTzName) { ScopedIcuLocale icuLocale(env, javaLocaleName); if (!icuLocale.valid()) { return 0; } ScopedJavaUnicodeString skeletonHolder(env, javaSkeleton); if (!skeletonHolder.valid()) { return 0; } UErrorCode status = U_ZERO_ERROR; DateIntervalFormat* formatter(DateIntervalFormat::createInstance(skeletonHolder.unicodeString(), icuLocale.locale(), status)); if (maybeThrowIcuException(env, "DateIntervalFormat::createInstance", status)) { return 0; } ScopedJavaUnicodeString tzNameHolder(env, javaTzName); if (!tzNameHolder.valid()) { return 0; } formatter->adoptTimeZone(TimeZone::createTimeZone(tzNameHolder.unicodeString())); return reinterpret_cast<uintptr_t>(formatter); }
static jstring ICU_getScript(JNIEnv* env, jclass, jstring javaLocaleName) { ScopedIcuLocale icuLocale(env, javaLocaleName); if (!icuLocale.valid()) { return NULL; } return env->NewStringUTF(icuLocale.locale().getScript()); }
static void ICU_setDefaultLocale(JNIEnv* env, jclass, jstring javaLanguageTag) { ScopedIcuLocale icuLocale(env, javaLanguageTag); if (!icuLocale.valid()) { return; } UErrorCode status = U_ZERO_ERROR; Locale::setDefault(icuLocale.locale(), status); maybeThrowIcuException(env, "Locale::setDefault", status); }
static void nSetLocale(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleName, jlong nativeHyphenator) { ScopedIcuLocale icuLocale(env, javaLocaleName); LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr); Hyphenator* hyphenator = reinterpret_cast<Hyphenator*>(nativeHyphenator); if (icuLocale.valid()) { b->setLocale(icuLocale.locale(), hyphenator); } }
static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring javaLocaleName, jobjectArray result) { ScopedIcuLocale icuLocale(env, javaLocaleName); if (!icuLocale.valid()) { return; } UErrorCode status = U_ZERO_ERROR; UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(icuLocale.locale(), status)); if (maybeThrowIcuException(env, "TimeZoneNames::createInstance", status)) { return; } const UDate now(Calendar::getNow()); static const UnicodeString kUtc("UTC", 3, US_INV); size_t id_count = env->GetArrayLength(result); for (size_t i = 0; i < id_count; ++i) { ScopedLocalRef<jobjectArray> java_row(env, reinterpret_cast<jobjectArray>(env->GetObjectArrayElement(result, i))); ScopedLocalRef<jstring> java_zone_id(env, reinterpret_cast<jstring>(env->GetObjectArrayElement(java_row.get(), 0))); ScopedJavaUnicodeString zone_id(env, java_zone_id.get()); if (!zone_id.valid()) { return; } UnicodeString long_std; names->getDisplayName(zone_id.unicodeString(), UTZNM_LONG_STANDARD, now, long_std); UnicodeString short_std; names->getDisplayName(zone_id.unicodeString(), UTZNM_SHORT_STANDARD, now, short_std); UnicodeString long_dst; names->getDisplayName(zone_id.unicodeString(), UTZNM_LONG_DAYLIGHT, now, long_dst); UnicodeString short_dst; names->getDisplayName(zone_id.unicodeString(), UTZNM_SHORT_DAYLIGHT, now, short_dst); if (isUtc(zone_id.unicodeString())) { // ICU doesn't have names for the UTC zones; it just says "GMT+00:00" for both // long and short names. We don't want this. The best we can do is use "UTC" // for everything (since we don't know how to say "Universal Coordinated Time" in // every language). // TODO: check CLDR doesn't actually have this somewhere. long_std = short_std = long_dst = short_dst = kUtc; } bool okay = setStringArrayElement(env, java_row.get(), 1, long_std) && setStringArrayElement(env, java_row.get(), 2, short_std) && setStringArrayElement(env, java_row.get(), 3, long_dst) && setStringArrayElement(env, java_row.get(), 4, short_dst); if (!okay) { return; } } }
static jstring ICU_toUpperCase(JNIEnv* env, jclass, jstring javaString, jstring javaLanguageTag) { ScopedJavaUnicodeString scopedString(env, javaString); if (!scopedString.valid()) { return NULL; } ScopedIcuLocale icuLocale(env, javaLanguageTag); if (!icuLocale.valid()) { return NULL; } UnicodeString& s(scopedString.unicodeString()); UnicodeString original(s); s.toUpper(icuLocale.locale()); return s == original ? javaString : env->NewString(s.getBuffer(), s.length()); }
static jstring ICU_getDisplayVariantNative(JNIEnv* env, jclass, jstring javaTargetLanguageTag, jstring javaLanguageTag) { ScopedIcuLocale icuLocale(env, javaLanguageTag); if (!icuLocale.valid()) { return NULL; } ScopedIcuLocale icuTargetLocale(env, javaTargetLanguageTag); if (!icuTargetLocale.valid()) { return NULL; } UnicodeString str; icuTargetLocale.locale().getDisplayVariant(icuLocale.locale(), str); return env->NewString(str.getBuffer(), str.length()); }
BTimeUnitFormat::BTimeUnitFormat(const time_unit_style style) : Inherited() { Locale icuLocale(fLanguage.Code()); UErrorCode icuStatus = U_ZERO_ERROR; if (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL) { fFormatter = NULL; fInitStatus = B_BAD_VALUE; return; } fFormatter = new TimeUnitFormat(icuLocale, kTimeUnitStyleToICU[style], icuStatus); if (fFormatter == NULL) { fInitStatus = B_NO_MEMORY; return; } if (!U_SUCCESS(icuStatus)) fInitStatus = B_ERROR; }
static jstring TimeZoneNames_getExemplarLocation(JNIEnv* env, jclass, jstring javaLocaleName, jstring javaTz) { ScopedIcuLocale icuLocale(env, javaLocaleName); if (!icuLocale.valid()) { return NULL; } UErrorCode status = U_ZERO_ERROR; UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(icuLocale.locale(), status)); if (maybeThrowIcuException(env, "TimeZoneNames::createInstance", status)) { return NULL; } ScopedJavaUnicodeString tz(env, javaTz); if (!tz.valid()) { return NULL; } UnicodeString s; const UDate now(Calendar::getNow()); names->getDisplayName(tz.unicodeString(), UTZNM_EXEMPLAR_LOCATION, now, s); return env->NewString(s.getBuffer(), s.length()); }
static jstring ICU_getBestDateTimePatternNative(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLanguageTag) { ScopedIcuLocale icuLocale(env, javaLanguageTag); if (!icuLocale.valid()) { return NULL; } UErrorCode status = U_ZERO_ERROR; UniquePtr<DateTimePatternGenerator> generator(DateTimePatternGenerator::createInstance(icuLocale.locale(), status)); if (maybeThrowIcuException(env, "DateTimePatternGenerator::createInstance", status)) { return NULL; } ScopedJavaUnicodeString skeletonHolder(env, javaSkeleton); if (!skeletonHolder.valid()) { return NULL; } UnicodeString result(generator->getBestPattern(skeletonHolder.unicodeString(), status)); if (maybeThrowIcuException(env, "DateTimePatternGenerator::getBestPattern", status)) { return NULL; } return env->NewString(result.getBuffer(), result.length()); }
static jintArray nLineBreakOpportunities(JNIEnv* env, jclass, jstring javaLocaleName, jcharArray inputText, jint length, jintArray recycle) { jintArray ret; std::vector<jint> breaks; ScopedIcuLocale icuLocale(env, javaLocaleName); if (icuLocale.valid()) { UErrorCode status = U_ZERO_ERROR; BreakIterator* it = BreakIterator::createLineInstance(icuLocale.locale(), status); if (!U_SUCCESS(status) || it == NULL) { if (it) { delete it; } } else { ScopedBreakIterator breakIterator(env, it, inputText, length); for (int loc = breakIterator->first(); loc != BreakIterator::DONE; loc = breakIterator->next()) { breaks.push_back(loc); } } } breaks.push_back(-1); // sentinel terminal value if (recycle != NULL && static_cast<size_t>(env->GetArrayLength(recycle)) >= breaks.size()) { ret = recycle; } else { ret = env->NewIntArray(breaks.size()); } if (ret != NULL) { env->SetIntArrayRegion(ret, 0, breaks.size(), &breaks.front()); } return ret; }
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; }