static jobjectArray getContentImpl(JNIEnv* env, jclass clazz, jstring locale, jboolean needsTZ) { UErrorCode status = U_ZERO_ERROR; const char *loc = env->GetStringUTFChars(locale, NULL); UResourceBundle *root = ures_openU(NULL, loc, &status); env->ReleaseStringUTFChars(locale, loc); if(U_FAILURE(status)) { LOGI("Error getting resources"); status = U_ZERO_ERROR; return NULL; } jclass obj_class = env->FindClass("java/lang/Object"); jclass integer_class = env->FindClass("java/lang/Integer"); jmethodID integerInit = env->GetMethodID(integer_class, "<init>", "(I)V"); jobjectArray result; jobject firstDayOfWeek = NULL; jobject minimalDaysInFirstWeek = NULL; jobjectArray amPmMarkers = NULL; jobjectArray eras = NULL; jstring localPatternChars = NULL; jobjectArray weekdays = NULL; jobjectArray shortWeekdays = NULL; jobjectArray months = NULL; jobjectArray shortMonths = NULL; jstring time_SHORT = NULL; jstring time_MEDIUM = NULL; jstring time_LONG = NULL; jstring time_FULL = NULL; jstring date_SHORT = NULL; jstring date_MEDIUM = NULL; jstring date_LONG = NULL; jstring date_FULL = NULL; jstring decimalPatternChars = NULL; jstring naN = NULL; jstring infinity = NULL; jstring currencySymbol = NULL; jstring intCurrencySymbol = NULL; jstring numberPattern = NULL; jstring integerPattern = NULL; jstring currencyPattern = NULL; jstring percentPattern = NULL; jobjectArray zones = NULL; int counter = 0; int firstDayVals[2] = {-1, -1}; const jchar* nan = (const jchar *)NULL; const jchar* inf = (const jchar *)NULL; int nanL, infL; UResourceBundle *gregorian; UResourceBundle *gregorianElems; UResourceBundle *rootElems; // get the resources needed rootElems = ures_getByKey(root, "calendar", NULL, &status); if(U_FAILURE(status)) { return NULL; } gregorian = ures_getByKey(rootElems, "gregorian", NULL, &status); if(U_FAILURE(status)) { ures_close(rootElems); return NULL; } // adding the first day of week and minimal days in first week values getDayInitVector(env, gregorian, firstDayVals); if((firstDayVals[0] != -1) && (firstDayVals[1] != -1)) { firstDayOfWeek = env->NewObject(integer_class, integerInit, firstDayVals[0]); minimalDaysInFirstWeek = env->NewObject(integer_class, integerInit, firstDayVals[1]); // adding First_Day and Minimal_Days integer to the result counter += 2; } // adding ampm string array to the result"); amPmMarkers = getAmPmMarkers(env, gregorian); if(amPmMarkers != NULL) { counter++; } // adding eras string array to the result eras = getEras(env, gregorian); if(eras != NULL) { counter++; } // local pattern chars are initially always the same localPatternChars = env->NewStringUTF("GyMdkHmsSEDFwWahKzZ"); // adding local pattern chars string to the result counter++; // adding month names string array to the result months = getMonthNames(env, gregorian); if(months != NULL) { counter++; } // adding short month names string array to the result shortMonths = getShortMonthNames(env, gregorian); if(shortMonths != NULL) { counter++; } // adding day names string array to the result weekdays = getWeekdayNames(env, gregorian); if(weekdays != NULL) { counter++; } // adding short day names string array to the result shortWeekdays = getShortWeekdayNames(env, gregorian); if(shortWeekdays != NULL) { counter++; } const UChar *pattern; jchar check[2] = {0, 0}; u_uastrcpy(check, "v"); jchar replacement[2] = {0, 0}; u_uastrcpy(replacement, "z"); jchar *pos; jchar *patternCopy; int patternLength; // adding date and time format patterns to the result gregorianElems = ures_getByKey(gregorian, "DateTimePatterns", NULL, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } pattern = ures_getStringByIndex(gregorianElems, 0, &patternLength, &status); // there are some patterns in icu that use the pattern character 'v' // java doesn't accept this, so it gets replaced by 'z' which has // about the same result as 'v', the timezone name. // 'v' -> "PT", 'z' -> "PST", v is the generic timezone and z the standard tz // "vvvv" -> "Pacific Time", "zzzz" -> "Pacific Standard Time" patternCopy = (jchar *) malloc((patternLength + 1) * sizeof(jchar)); u_strcpy(patternCopy, pattern); if(U_FAILURE(status)) { free(patternCopy); status = U_ZERO_ERROR; goto endOfCalendar; } while((pos = u_strchr(patternCopy, check[0])) != NULL) { u_memset(pos, replacement[0], 1); } time_FULL = env->NewString(patternCopy, patternLength); free(patternCopy); counter++; pattern = ures_getStringByIndex(gregorianElems, 1, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } time_LONG = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 2, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } time_MEDIUM = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 3, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } time_SHORT = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 4, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } date_FULL = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 5, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } date_LONG = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 6, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } date_MEDIUM = env->NewString(pattern, patternLength); counter++; pattern = ures_getStringByIndex(gregorianElems, 7, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto endOfCalendar; } date_SHORT = env->NewString(pattern, patternLength); counter++; endOfCalendar: if(gregorianElems != NULL) { ures_close(gregorianElems); } ures_close(gregorian); ures_close(rootElems); rootElems = ures_getByKey(root, "NumberElements", NULL, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; } if(ures_getSize(rootElems) >= 11) { // adding decimal pattern chars to the result decimalPatternChars = getDecimalPatternChars(env, rootElems); if(decimalPatternChars != NULL) { counter++; } // adding NaN pattern char to the result nan = ures_getStringByIndex(rootElems, 10, &nanL, &status); if(U_SUCCESS(status)) { naN = env->NewString(nan, nanL); counter++; } status = U_ZERO_ERROR; // adding infinity pattern char to the result inf = ures_getStringByIndex(rootElems, 9, &infL, &status); if(U_SUCCESS(status)) { infinity = env->NewString(inf, infL); counter++; } status = U_ZERO_ERROR; } ures_close(rootElems); // adding intl currency code to result intCurrencySymbol = getIntCurrencyCode(env, clazz, locale); if(intCurrencySymbol != NULL) { // adding currency symbol to result currencySymbol = getCurrencySymbol(env, clazz, locale, intCurrencySymbol); } else { intCurrencySymbol = env->NewStringUTF("XXX"); } if(currencySymbol == NULL) { currencySymbol = env->NewStringUTF("\u00a4"); } counter += 2; // adding number format patterns to the result int numOfEntries; int decSepOffset; NumberFormat *nf; jchar *tmpPattern; rootElems = ures_getByKey(root, "NumberPatterns", NULL, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; goto zones; } numOfEntries = ures_getSize(rootElems); if(numOfEntries < 3) { ures_close(rootElems); goto zones; } // number pattern pattern = ures_getStringByIndex(rootElems, 0, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; ures_close(rootElems); goto zones; } numberPattern = env->NewString(pattern, patternLength); counter++; // integer pattern derived from number pattern decSepOffset = u_strcspn(pattern, (jchar *)".\0"); tmpPattern = (jchar *) malloc((decSepOffset + 1) * sizeof(jchar)); u_strncpy(tmpPattern, pattern, decSepOffset); integerPattern = env->NewString(tmpPattern, decSepOffset); free(tmpPattern); counter++; // currency pattern pattern = ures_getStringByIndex(rootElems, 1, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; ures_close(rootElems); goto zones; } currencyPattern = env->NewString(pattern, patternLength); counter++; // percent pattern pattern = ures_getStringByIndex(rootElems, 2, &patternLength, &status); if(U_FAILURE(status)) { status = U_ZERO_ERROR; ures_close(rootElems); goto zones; } percentPattern = env->NewString(pattern, patternLength); counter++; ures_close(rootElems); zones: ures_close(root); if(needsTZ == JNI_TRUE) { counter++; //add empty timezone } // collect all content and put it into an array result = env->NewObjectArray(counter, obj_class, NULL); int index = 0; if(needsTZ == JNI_TRUE) { addObject(env, result, "timezones", NULL, index++); } if(firstDayOfWeek != NULL && index < counter) { addObject(env, result, "First_Day", firstDayOfWeek, index++); } if(minimalDaysInFirstWeek != NULL && index < counter) { addObject(env, result, "Minimal_Days", minimalDaysInFirstWeek, index++); } if(amPmMarkers != NULL && index < counter) { addObject(env, result, "ampm", amPmMarkers, index++); } if(eras != NULL && index < counter) { addObject(env, result, "eras", eras, index++); } if(localPatternChars != NULL && index < counter) { addObject(env, result, "LocalPatternChars", localPatternChars, index++); } if(weekdays != NULL && index < counter) { addObject(env, result, "weekdays", weekdays, index++); } if(shortWeekdays != NULL && index < counter) { addObject(env, result, "shortWeekdays", shortWeekdays, index++); } if(months != NULL && index < counter) { addObject(env, result, "months", months, index++); } if(shortMonths != NULL && index < counter) { addObject(env, result, "shortMonths", shortMonths, index++); } if(time_SHORT != NULL && index < counter) { addObject(env, result, "Time_SHORT", time_SHORT, index++); } if(time_MEDIUM != NULL && index < counter) { addObject(env, result, "Time_MEDIUM", time_MEDIUM, index++); } if(time_LONG != NULL && index < counter) { addObject(env, result, "Time_LONG", time_LONG, index++); } if(time_FULL != NULL && index < counter) { addObject(env, result, "Time_FULL", time_FULL, index++); } if(date_SHORT != NULL && index < counter) { addObject(env, result, "Date_SHORT", date_SHORT, index++); } if(date_MEDIUM != NULL && index < counter) { addObject(env, result, "Date_MEDIUM", date_MEDIUM, index++); } if(date_LONG != NULL && index < counter) { addObject(env, result, "Date_LONG", date_LONG, index++); } if(date_FULL != NULL && index < counter) { addObject(env, result, "Date_FULL", date_FULL, index++); } if(decimalPatternChars != NULL && index < counter) { addObject(env, result, "DecimalPatternChars", decimalPatternChars, index++); } if(naN != NULL && index < counter) { addObject(env, result, "NaN", naN, index++); } if(infinity != NULL && index < counter) { addObject(env, result, "Infinity", infinity, index++); } if(currencySymbol != NULL && index < counter) { addObject(env, result, "CurrencySymbol", currencySymbol, index++); } if(intCurrencySymbol != NULL && index < counter) { addObject(env, result, "IntCurrencySymbol", intCurrencySymbol, index++); } if(numberPattern != NULL && index < counter) { addObject(env, result, "Number", numberPattern, index++); } if(integerPattern != NULL && index < counter) { addObject(env, result, "Integer", integerPattern, index++); } if(currencyPattern != NULL && index < counter) { addObject(env, result, "Currency", currencyPattern, index++); } if(percentPattern != NULL && index < counter) { addObject(env, result, "Percent", percentPattern, index++); } return result; }
static jboolean initLocaleDataImpl(JNIEnv* env, jclass clazz, jstring locale, jobject localeData) { const char* loc = env->GetStringUTFChars(locale, NULL); UErrorCode status = U_ZERO_ERROR; ScopedResourceBundle root(ures_openU(NULL, loc, &status)); env->ReleaseStringUTFChars(locale, loc); if (U_FAILURE(status)) { LOGE("Error getting ICU resource bundle: %s", u_errorName(status)); status = U_ZERO_ERROR; return JNI_FALSE; } ScopedResourceBundle calendar(ures_getByKey(root.get(), "calendar", NULL, &status)); if (U_FAILURE(status)) { LOGE("Error getting ICU calendar resource bundle: %s", u_errorName(status)); return JNI_FALSE; } ScopedResourceBundle gregorian(ures_getByKey(calendar.get(), "gregorian", NULL, &status)); if (U_FAILURE(status)) { LOGE("Error getting ICU gregorian resource bundle: %s", u_errorName(status)); return JNI_FALSE; } int firstDayVals[2]; if (getDayIntVector(env, gregorian.get(), firstDayVals)) { setIntegerField(env, localeData, "firstDayOfWeek", firstDayVals[0]); setIntegerField(env, localeData, "minimalDaysInFirstWeek", firstDayVals[1]); } setStringArrayField(env, localeData, "amPm", getAmPmMarkers(env, gregorian.get())); setStringArrayField(env, localeData, "eras", getEras(env, gregorian.get())); setStringArrayField(env, localeData, "longMonthNames", getLongMonthNames(env, gregorian.get())); setStringArrayField(env, localeData, "shortMonthNames", getShortMonthNames(env, gregorian.get())); setStringArrayField(env, localeData, "longWeekdayNames", getLongWeekdayNames(env, gregorian.get())); setStringArrayField(env, localeData, "shortWeekdayNames", getShortWeekdayNames(env, gregorian.get())); ScopedResourceBundle gregorianElems(ures_getByKey(gregorian.get(), "DateTimePatterns", NULL, &status)); if (U_SUCCESS(status)) { setStringField(env, localeData, "fullTimeFormat", gregorianElems.get(), 0); setStringField(env, localeData, "longTimeFormat", gregorianElems.get(), 1); setStringField(env, localeData, "mediumTimeFormat", gregorianElems.get(), 2); setStringField(env, localeData, "shortTimeFormat", gregorianElems.get(), 3); setStringField(env, localeData, "fullDateFormat", gregorianElems.get(), 4); setStringField(env, localeData, "longDateFormat", gregorianElems.get(), 5); setStringField(env, localeData, "mediumDateFormat", gregorianElems.get(), 6); setStringField(env, localeData, "shortDateFormat", gregorianElems.get(), 7); } status = U_ZERO_ERROR; ScopedResourceBundle numberElements(ures_getByKey(root.get(), "NumberElements", NULL, &status)); if (U_SUCCESS(status) && ures_getSize(numberElements.get()) >= 11) { setStringField(env, localeData, "decimalPatternChars", getDecimalPatternChars(env, numberElements.get())); setStringField(env, localeData, "infinity", numberElements.get(), 9); setStringField(env, localeData, "NaN", numberElements.get(), 10); } status = U_ZERO_ERROR; jstring internationalCurrencySymbol = getIntCurrencyCode(env, locale); jstring currencySymbol = NULL; if (internationalCurrencySymbol != NULL) { currencySymbol = getCurrencySymbolNative(env, clazz, 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); ScopedResourceBundle numberPatterns(ures_getByKey(root.get(), "NumberPatterns", NULL, &status)); if (U_SUCCESS(status) && ures_getSize(numberPatterns.get()) >= 3) { setStringField(env, localeData, "numberPattern", numberPatterns.get(), 0); setStringField(env, localeData, "currencyPattern", numberPatterns.get(), 1); setStringField(env, localeData, "percentPattern", numberPatterns.get(), 2); } return JNI_TRUE; }
static jboolean ICU_initLocaleDataImpl(JNIEnv* env, jclass, jstring locale, jobject localeData) { ScopedUtfChars localeName(env, locale); UErrorCode status = U_ZERO_ERROR; ScopedResourceBundle root(ures_open(NULL, localeName.c_str(), &status)); if (U_FAILURE(status)) { LOGE("Error getting ICU resource bundle: %s", u_errorName(status)); status = U_ZERO_ERROR; return JNI_FALSE; } ScopedResourceBundle calendar(ures_getByKey(root.get(), "calendar", NULL, &status)); if (U_FAILURE(status)) { LOGE("Error getting ICU calendar resource bundle: %s", u_errorName(status)); return JNI_FALSE; } ScopedResourceBundle gregorian(ures_getByKey(calendar.get(), "gregorian", NULL, &status)); if (U_FAILURE(status)) { LOGE("Error getting ICU gregorian resource bundle: %s", u_errorName(status)); return JNI_FALSE; } int firstDayVals[] = { 0, 0 }; if (getDayIntVector(env, gregorian.get(), firstDayVals)) { setIntegerField(env, localeData, "firstDayOfWeek", firstDayVals[0]); setIntegerField(env, localeData, "minimalDaysInFirstWeek", firstDayVals[1]); } setStringArrayField(env, localeData, "amPm", getAmPmMarkers(env, gregorian.get())); setStringArrayField(env, localeData, "eras", getEras(env, gregorian.get())); ScopedResourceBundle dayNames(ures_getByKey(gregorian.get(), "dayNames", NULL, &status)); ScopedResourceBundle monthNames(ures_getByKey(gregorian.get(), "monthNames", NULL, &status)); // Get the regular month and weekday names. jobjectArray longMonthNames = getNames(env, monthNames.get(), true, REGULAR, LONG); jobjectArray shortMonthNames = getNames(env, monthNames.get(), true, REGULAR, SHORT); jobjectArray longWeekdayNames = getNames(env, dayNames.get(), false, REGULAR, LONG); jobjectArray shortWeekdayNames = getNames(env, dayNames.get(), false, REGULAR, SHORT); setStringArrayField(env, localeData, "longMonthNames", longMonthNames); setStringArrayField(env, localeData, "shortMonthNames", shortMonthNames); setStringArrayField(env, localeData, "longWeekdayNames", longWeekdayNames); setStringArrayField(env, localeData, "shortWeekdayNames", shortWeekdayNames); // Get the stand-alone month and weekday names. If they're not available (as they aren't for // English), we reuse the regular names. If we returned null to Java, the usual fallback // mechanisms would come into play and we'd end up with the bogus stand-alone names from the // root locale ("1" for January, and so on). jobjectArray longStandAloneMonthNames = getNames(env, monthNames.get(), true, STAND_ALONE, LONG); if (longStandAloneMonthNames == NULL) { longStandAloneMonthNames = longMonthNames; } jobjectArray shortStandAloneMonthNames = getNames(env, monthNames.get(), true, STAND_ALONE, SHORT); if (shortStandAloneMonthNames == NULL) { shortStandAloneMonthNames = shortMonthNames; } jobjectArray longStandAloneWeekdayNames = getNames(env, dayNames.get(), false, STAND_ALONE, LONG); if (longStandAloneWeekdayNames == NULL) { longStandAloneWeekdayNames = longWeekdayNames; } jobjectArray shortStandAloneWeekdayNames = getNames(env, dayNames.get(), false, STAND_ALONE, SHORT); if (shortStandAloneWeekdayNames == NULL) { shortStandAloneWeekdayNames = shortWeekdayNames; } setStringArrayField(env, localeData, "longStandAloneMonthNames", longStandAloneMonthNames); setStringArrayField(env, localeData, "shortStandAloneMonthNames", shortStandAloneMonthNames); setStringArrayField(env, localeData, "longStandAloneWeekdayNames", longStandAloneWeekdayNames); setStringArrayField(env, localeData, "shortStandAloneWeekdayNames", shortStandAloneWeekdayNames); 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); } status = U_ZERO_ERROR; ScopedResourceBundle numberElements(ures_getByKey(root.get(), "NumberElements", NULL, &status)); if (U_SUCCESS(status) && ures_getSize(numberElements.get()) >= 11) { setCharField(env, localeData, "zeroDigit", numberElements.get(), 4); setCharField(env, localeData, "digit", numberElements.get(), 5); setCharField(env, localeData, "decimalSeparator", numberElements.get(), 0); setCharField(env, localeData, "groupingSeparator", numberElements.get(), 1); setCharField(env, localeData, "patternSeparator", numberElements.get(), 2); setCharField(env, localeData, "percent", numberElements.get(), 3); setCharField(env, localeData, "perMill", numberElements.get(), 8); setCharField(env, localeData, "monetarySeparator", numberElements.get(), 0); setCharField(env, localeData, "minusSign", numberElements.get(), 6); setStringField(env, localeData, "exponentSeparator", numberElements.get(), 7); setStringField(env, localeData, "infinity", numberElements.get(), 9); setStringField(env, localeData, "NaN", numberElements.get(), 10); } status = U_ZERO_ERROR; jstring internationalCurrencySymbol = getIntCurrencyCode(env, locale); jstring currencySymbol = NULL; if (internationalCurrencySymbol != NULL) { currencySymbol = ICU_getCurrencySymbolNative(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); ScopedResourceBundle numberPatterns(ures_getByKey(root.get(), "NumberPatterns", NULL, &status)); if (U_SUCCESS(status) && ures_getSize(numberPatterns.get()) >= 3) { setStringField(env, localeData, "numberPattern", numberPatterns.get(), 0); setStringField(env, localeData, "currencyPattern", numberPatterns.get(), 1); setStringField(env, localeData, "percentPattern", numberPatterns.get(), 2); } return JNI_TRUE; }