Path: blob/master/src/java.base/macosx/native/libjava/HostLocaleProviderAdapter_md.c
41119 views
/*1* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h"26#include "jni_util.h"27#include <CoreFoundation/CoreFoundation.h>28#include <stdio.h>2930#define BUFLEN 2563132// java.util.Calendar constants33#define CALENDAR_FIELD_ERA 0 // Calendar.ERA34#define CALENDAR_FIELD_DAY_OF_WEEK 7 // Calendar.DAY_OF_WEEK35#define CALENDAR_FIELD_AM_PM 9 // Calendar.AM_PM36#define JAPANESE_MEIJI_INDEX 2323738static CFDateFormatterStyle convertDateFormatterStyle(jint javaStyle);39static CFNumberFormatterStyle convertNumberFormatterStyle(jint javaStyle);40static void copyArrayElements(JNIEnv *env, CFArrayRef cfarray, jobjectArray jarray, CFIndex sindex, int dindex, int count);41static jstring getNumberSymbolString(JNIEnv *env, jstring jlangtag, jstring jdefault, CFStringRef type);42static jchar getNumberSymbolChar(JNIEnv *env, jstring jlangtag, jchar jdefault, CFStringRef type);43jobjectArray getErasImpl(JNIEnv *env, jstring jlangtag, jint style, jobjectArray eras);44jobjectArray getWeekdaysImpl(JNIEnv *env, jclass cls, jstring jlangtag, jint style, jobjectArray wdays);45jobjectArray getAmPmImpl(JNIEnv *env, jclass cls, jstring jlangtag, jint style, jobjectArray ampms);4647// from java_props_macosx.c48extern char * getMacOSXLocale(int cat);49extern char * getPosixLocale(int cat);5051/*52* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl53* Method: getDefaultLocale54* Signature: (I)Ljava/lang/String;55*/56JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDefaultLocale57(JNIEnv *env, jclass cls, jint cat) {58char * localeString = NULL;59int posixCat;60jstring ret = NULL;6162switch (cat) {63case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_DISPLAY:64posixCat = LC_MESSAGES;65break;66case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_FORMAT:67default:68posixCat = LC_CTYPE;69break;70}7172localeString = getMacOSXLocale(posixCat);73if (localeString == NULL) {74localeString = getPosixLocale(posixCat);75if (localeString == NULL) {76JNU_ThrowOutOfMemoryError(env, NULL);77return NULL;78}79}80ret = (*env)->NewStringUTF(env, localeString);81free(localeString);8283return ret;84}8586/*87* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl88* Method: getDateTimePatternNative89* Signature: (IILjava/lang/String;)Ljava/lang/String;90*/91JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDateTimePatternNative92(JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) {93jstring ret = NULL;94CFLocaleRef cflocale = CFLocaleCopyCurrent();9596if (cflocale != NULL) {97CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,98cflocale,99convertDateFormatterStyle(dateStyle),100convertDateFormatterStyle(timeStyle));101if (df != NULL) {102char buf[BUFLEN];103CFStringRef formatStr = CFDateFormatterGetFormat(df);104CFStringGetCString(formatStr, buf, BUFLEN, kCFStringEncodingUTF8);105ret = (*env)->NewStringUTF(env, buf);106CFRelease(df);107}108CFRelease(cflocale);109}110111return ret;112}113114/*115* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl116* Method: getCalendarID117* Signature: (Ljava/lang/String;)Ljava/lang/String;118*/119JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarID120(JNIEnv *env, jclass cls, jstring jlangtag) {121jstring ret = NULL;122CFLocaleRef cflocale = CFLocaleCopyCurrent();123124if (cflocale != NULL) {125char buf[BUFLEN];126CFTypeRef calid = CFLocaleGetValue(cflocale, kCFLocaleCalendarIdentifier);127CFStringGetCString((CFStringRef)calid, buf, BUFLEN, kCFStringEncodingUTF8);128ret = (*env)->NewStringUTF(env, buf);129CFRelease(cflocale);130}131132return ret;133}134135/*136* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl137* Method: getAmPmStrings138* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;139*/140JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings141(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) {142return getAmPmImpl(env, cls, jlangtag, 0, ampms);143}144145/*146* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl147* Method: getEras148* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;149*/150JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getEras151(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray eras) {152return getErasImpl(env, jlangtag, 0, eras);153}154155/*156* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl157* Method: getMonths158* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;159*/160JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonths161(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray months) {162CFLocaleRef cflocale = CFLocaleCopyCurrent();163if (cflocale != NULL) {164CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,165cflocale,166kCFDateFormatterFullStyle,167kCFDateFormatterFullStyle);168if (df != NULL) {169CFArrayRef cfmonths = CFDateFormatterCopyProperty(df, kCFDateFormatterMonthSymbols);170if (cfmonths != NULL) {171copyArrayElements(env, cfmonths, months, 0, 0, CFArrayGetCount(cfmonths));172CFRelease(cfmonths);173}174CFRelease(df);175}176CFRelease(cflocale);177}178179return months;180}181182/*183* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl184* Method: getShortMonths185* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;186*/187JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortMonths188(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray smonths) {189CFLocaleRef cflocale = CFLocaleCopyCurrent();190if (cflocale != NULL) {191CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,192cflocale,193kCFDateFormatterFullStyle,194kCFDateFormatterFullStyle);195if (df != NULL) {196CFArrayRef cfsmonths = CFDateFormatterCopyProperty(df, kCFDateFormatterShortMonthSymbols);197if (cfsmonths != NULL) {198copyArrayElements(env, cfsmonths, smonths, 0, 0, CFArrayGetCount(cfsmonths));199CFRelease(cfsmonths);200}201CFRelease(df);202}203CFRelease(cflocale);204}205206return smonths;207}208209/*210* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl211* Method: getWeekdays212* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;213*/214JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getWeekdays215(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray wdays) {216return getWeekdaysImpl(env, cls, jlangtag, 0, wdays);217}218219/*220* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl221* Method: getShortWeekdays222* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;223*/224JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortWeekdays225(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray swdays) {226CFLocaleRef cflocale = CFLocaleCopyCurrent();227if (cflocale != NULL) {228CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,229cflocale,230kCFDateFormatterFullStyle,231kCFDateFormatterFullStyle);232if (df != NULL) {233CFArrayRef cfswdays = CFDateFormatterCopyProperty(df, kCFDateFormatterShortWeekdaySymbols);234if (cfswdays != NULL) {235copyArrayElements(env, cfswdays, swdays, 0, 1, CFArrayGetCount(cfswdays));236CFRelease(cfswdays);237}238CFRelease(df);239}240CFRelease(cflocale);241}242243return swdays;244}245246/*247* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl248* Method: getNumberPatternNative249* Signature: (ILjava/lang/String;)Ljava/lang/String;250*/251JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNumberPatternNative252(JNIEnv *env, jclass cls, jint numberStyle, jstring jlangtag) {253jstring ret = NULL;254CFLocaleRef cflocale = CFLocaleCopyCurrent();255if (cflocale != NULL) {256CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault,257cflocale,258convertNumberFormatterStyle(numberStyle));259if (nf != NULL) {260char buf[BUFLEN];261CFStringRef formatStr = CFNumberFormatterGetFormat(nf);262CFStringGetCString(formatStr, buf, BUFLEN, kCFStringEncodingUTF8);263ret = (*env)->NewStringUTF(env, buf);264CFRelease(nf);265}266CFRelease(cflocale);267}268269return ret;270}271272/*273* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl274* Method: getCurrencySymbol275* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;276*/277JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol278(JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) {279return getNumberSymbolString(env, jlangtag, currencySymbol, kCFNumberFormatterCurrencySymbol);280}281282/*283* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl284* Method: getDecimalSeparator285* Signature: (Ljava/lang/String;C)C286*/287JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDecimalSeparator288(JNIEnv *env, jclass cls, jstring jlangtag, jchar decimalSeparator) {289return getNumberSymbolChar(env, jlangtag, decimalSeparator, kCFNumberFormatterDecimalSeparator);290}291292/*293* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl294* Method: getGroupingSeparator295* Signature: (Ljava/lang/String;C)C296*/297JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getGroupingSeparator298(JNIEnv *env, jclass cls, jstring jlangtag, jchar groupingSeparator) {299return getNumberSymbolChar(env, jlangtag, groupingSeparator, kCFNumberFormatterGroupingSeparator);300}301302/*303* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl304* Method: getInfinity305* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;306*/307JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInfinity308(JNIEnv *env, jclass cls, jstring jlangtag, jstring infinity) {309return getNumberSymbolString(env, jlangtag, infinity, kCFNumberFormatterInfinitySymbol);310}311312/*313* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl314* Method: getInternationalCurrencySymbol315* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;316*/317JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInternationalCurrencySymbol318(JNIEnv *env, jclass cls, jstring jlangtag, jstring internationalCurrencySymbol) {319return getNumberSymbolString(env, jlangtag, internationalCurrencySymbol, kCFNumberFormatterInternationalCurrencySymbol);320}321322/*323* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl324* Method: getMinusSign325* Signature: (Ljava/lang/String;C)C326*/327JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMinusSign328(JNIEnv *env, jclass cls, jstring jlangtag, jchar minusSign) {329return getNumberSymbolChar(env, jlangtag, minusSign, kCFNumberFormatterMinusSign);330}331332/*333* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl334* Method: getMonetaryDecimalSeparator335* Signature: (Ljava/lang/String;C)C336*/337JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonetaryDecimalSeparator338(JNIEnv *env, jclass cls, jstring jlangtag, jchar monetaryDecimalSeparator) {339return getNumberSymbolChar(env, jlangtag, monetaryDecimalSeparator, kCFNumberFormatterCurrencyDecimalSeparator);340}341342/*343* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl344* Method: getNaN345* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;346*/347JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNaN348(JNIEnv *env, jclass cls, jstring jlangtag, jstring nan) {349return getNumberSymbolString(env, jlangtag, nan, kCFNumberFormatterNaNSymbol);350}351352/*353* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl354* Method: getPercent355* Signature: (Ljava/lang/String;C)C356*/357JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPercent358(JNIEnv *env, jclass cls, jstring jlangtag, jchar percent) {359return getNumberSymbolChar(env, jlangtag, percent, kCFNumberFormatterPercentSymbol);360}361362/*363* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl364* Method: getPerMill365* Signature: (Ljava/lang/String;C)C366*/367JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPerMill368(JNIEnv *env, jclass cls, jstring jlangtag, jchar perMill) {369return getNumberSymbolChar(env, jlangtag, perMill, kCFNumberFormatterPerMillSymbol);370}371372/*373* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl374* Method: getZeroDigit375* Signature: (Ljava/lang/String;C)C376*/377JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getZeroDigit378(JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) {379// The following code *should* work, but not for some reason :o380//381//return getNumberSymbolChar(env, jlangtag, zeroDigit, kCFNumberFormatterZeroSymbol);382//383// so here is a workaround.384jchar ret = zeroDigit;385CFLocaleRef cflocale = CFLocaleCopyCurrent();386387if (cflocale != NULL) {388CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault,389cflocale,390kCFNumberFormatterNoStyle);391if (nf != NULL) {392int zero = 0;393CFStringRef str = CFNumberFormatterCreateStringWithValue(kCFAllocatorDefault,394nf, kCFNumberIntType, &zero);395if (str != NULL) {396if (CFStringGetLength(str) > 0) {397ret = CFStringGetCharacterAtIndex(str, 0);398}399CFRelease(str);400}401402CFRelease(nf);403}404405CFRelease(cflocale);406}407408return ret;409}410411/*412* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl413* Method: getExponentSeparator414* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;415*/416JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getExponentSeparator417(JNIEnv *env, jclass cls, jstring jlangtag, jstring exponent) {418return getNumberSymbolString(env, jlangtag, exponent, kCFNumberFormatterExponentSymbol);419}420421/*422* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl423* Method: getCalendarInt424* Signature: (Ljava/lang/String;I)I425*/426JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarInt427(JNIEnv *env, jclass cls, jstring jlangtag, jint type) {428jint ret = 0;429CFCalendarRef cfcal = CFCalendarCopyCurrent();430431if (cfcal != NULL) {432switch (type) {433case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK:434ret = CFCalendarGetFirstWeekday(cfcal);435break;436case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_MINIMALDAYSINFIRSTWEEK:437ret = CFCalendarGetMinimumDaysInFirstWeek(cfcal);438break;439default:440ret = 0;441}442443CFRelease(cfcal);444}445446return ret;447}448449/*450* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl451* Method: getCalendarDisplayStrings452* Signature: (Ljava/lang/String;III)[Ljava/lang/String;453*/454JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDisplayStrings455(JNIEnv *env, jclass cls, jstring jlangtag, jint field, jint style) {456switch (field) {457case CALENDAR_FIELD_ERA:458return getErasImpl(env, jlangtag, style, NULL);459460case CALENDAR_FIELD_DAY_OF_WEEK:461return getWeekdaysImpl(env, cls, jlangtag, style, NULL);462463case CALENDAR_FIELD_AM_PM:464return getAmPmImpl(env, cls, jlangtag, style, NULL);465466default:467// not supported468return NULL;469}470}471472/*473* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl474* Method: getDisplayString475* Signature: (Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;476*/477JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDisplayString478(JNIEnv *env, jclass cls, jstring jlangtag, jint type, jstring value) {479jstring ret = NULL;480481const char *clangtag = (*env)->GetStringUTFChars(env, jlangtag, 0);482if (clangtag != NULL) {483const char *cvalue = (*env)->GetStringUTFChars(env, value, 0);484if (cvalue != NULL) {485CFStringRef cflangtag =486CFStringCreateWithCString(kCFAllocatorDefault, clangtag, kCFStringEncodingUTF8);487if (cflangtag != NULL) {488CFLocaleRef cflocale = CFLocaleCreate(kCFAllocatorDefault, cflangtag);489if (cflocale != NULL) {490CFStringRef cfvalue =491CFStringCreateWithCString(kCFAllocatorDefault, cvalue, kCFStringEncodingUTF8);492if (cfvalue != NULL) {493CFStringRef str = NULL;494switch (type) {495case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_LANGUAGE:496str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleLanguageCode, cfvalue);497break;498case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_SCRIPT:499str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleScriptCode, cfvalue);500break;501case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_REGION:502str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleCountryCode, cfvalue);503break;504case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_VARIANT:505str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleVariantCode, cfvalue);506break;507case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_CODE:508str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleCurrencyCode, cfvalue);509break;510case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_SYMBOL:511str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleCurrencySymbol, cfvalue);512break;513}514if (str != NULL) {515char buf[BUFLEN];516CFStringGetCString(str, buf, BUFLEN, kCFStringEncodingUTF8);517CFRelease(str);518ret = (*env)->NewStringUTF(env, buf);519}520CFRelease(cfvalue);521}522CFRelease(cflocale);523}524CFRelease(cflangtag);525}526(*env)->ReleaseStringUTFChars(env, value, cvalue);527}528(*env)->ReleaseStringUTFChars(env, jlangtag, clangtag);529}530531return ret;532}533534/*535* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl536* Method: getTimeZoneDisplayString537* Signature: (Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;538*/539JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getTimeZoneDisplayString540(JNIEnv *env, jclass cls, jstring jlangtag, jint type, jstring tzid) {541jstring ret = NULL;542543const char *clangtag = (*env)->GetStringUTFChars(env, jlangtag, 0);544if (clangtag != NULL) {545const char *ctzid = (*env)->GetStringUTFChars(env, tzid, 0);546if (ctzid != NULL) {547CFStringRef cflangtag =548CFStringCreateWithCString(kCFAllocatorDefault, clangtag, kCFStringEncodingUTF8);549if (cflangtag != NULL) {550CFLocaleRef cflocale = CFLocaleCreate(kCFAllocatorDefault, cflangtag);551if (cflocale != NULL) {552CFStringRef cftzid =553CFStringCreateWithCString(kCFAllocatorDefault, ctzid, kCFStringEncodingUTF8);554if (cftzid != NULL) {555CFTimeZoneRef cftz = CFTimeZoneCreateWithName(kCFAllocatorDefault, cftzid, false);556if (cftz != NULL) {557CFStringRef str = NULL;558switch (type) {559case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_TZ_SHORT_STANDARD:560str = CFTimeZoneCopyLocalizedName(cftz, kCFTimeZoneNameStyleShortStandard, cflocale);561break;562case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_TZ_SHORT_DST:563str = CFTimeZoneCopyLocalizedName(cftz, kCFTimeZoneNameStyleShortDaylightSaving, cflocale);564break;565case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_TZ_LONG_STANDARD:566str = CFTimeZoneCopyLocalizedName(cftz, kCFTimeZoneNameStyleStandard, cflocale);567break;568case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_TZ_LONG_DST:569str = CFTimeZoneCopyLocalizedName(cftz, kCFTimeZoneNameStyleDaylightSaving, cflocale);570break;571}572if (str != NULL) {573char buf[BUFLEN];574CFStringGetCString(str, buf, BUFLEN, kCFStringEncodingUTF8);575CFRelease(str);576ret = (*env)->NewStringUTF(env, buf);577}578CFRelease(cftz);579}580CFRelease(cftzid);581}582CFRelease(cflocale);583}584CFRelease(cflangtag);585}586(*env)->ReleaseStringUTFChars(env, tzid, ctzid);587}588(*env)->ReleaseStringUTFChars(env, jlangtag, clangtag);589}590591return ret;592}593594static CFDateFormatterStyle convertDateFormatterStyle(jint javaStyle) {595switch (javaStyle) {596case 0: // FULL597return kCFDateFormatterFullStyle;598case 1: // LONG599return kCFDateFormatterLongStyle;600case 2: // MEDIUM601return kCFDateFormatterMediumStyle;602case 3: // LONG603return kCFDateFormatterShortStyle;604case -1: // No style605default:606return kCFDateFormatterNoStyle;607}608}609610static CFNumberFormatterStyle convertNumberFormatterStyle(jint javaStyle) {611switch (javaStyle) {612case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY:613return kCFNumberFormatterCurrencyStyle;614case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER:615return kCFNumberFormatterDecimalStyle;616case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER:617return kCFNumberFormatterDecimalStyle;618case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT:619return kCFNumberFormatterPercentStyle;620default:621return kCFNumberFormatterNoStyle;622}623}624625static void copyArrayElements(JNIEnv *env, CFArrayRef cfarray, jobjectArray jarray, CFIndex sindex, int dindex, int count) {626char buf[BUFLEN];627jstring tmp_string;628629for (; count > 0; sindex++, dindex++, count--) {630CFStringGetCString(CFArrayGetValueAtIndex(cfarray, sindex), buf, BUFLEN, kCFStringEncodingUTF8);631tmp_string = (*env)->NewStringUTF(env, buf);632if (tmp_string != NULL) {633(*env)->SetObjectArrayElement(env, jarray, dindex, tmp_string);634} else {635break;636}637}638}639640static jstring getNumberSymbolString(JNIEnv *env, jstring jlangtag, jstring jdefault, CFStringRef type) {641char buf[BUFLEN];642jstring ret = jdefault;643CFLocaleRef cflocale = CFLocaleCopyCurrent();644645if (cflocale != NULL) {646CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault,647cflocale,648kCFNumberFormatterNoStyle);649if (nf != NULL) {650CFStringRef str = CFNumberFormatterCopyProperty(nf, type);651if (str != NULL) {652CFStringGetCString(str, buf, BUFLEN, kCFStringEncodingUTF8);653CFRelease(str);654ret = (*env)->NewStringUTF(env, buf);655}656657CFRelease(nf);658}659660CFRelease(cflocale);661}662663return ret;664}665666static jchar getNumberSymbolChar(JNIEnv *env, jstring jlangtag, jchar jdefault, CFStringRef type) {667jchar ret = jdefault;668CFLocaleRef cflocale = CFLocaleCopyCurrent();669670if (cflocale != NULL) {671CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault,672cflocale,673kCFNumberFormatterNoStyle);674if (nf != NULL) {675CFStringRef str = CFNumberFormatterCopyProperty(nf, type);676if (str != NULL) {677if (CFStringGetLength(str) > 0) {678ret = CFStringGetCharacterAtIndex(str, 0);679}680CFRelease(str);681}682683CFRelease(nf);684}685686CFRelease(cflocale);687}688689return ret;690}691692jobjectArray getErasImpl(JNIEnv *env, jstring jlangtag, jint style, jobjectArray eras) {693jobjectArray ret = eras;694CFLocaleRef cflocale = CFLocaleCopyCurrent();695if (cflocale != NULL) {696CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,697cflocale,698convertDateFormatterStyle(style),699convertDateFormatterStyle(style));700if (df != NULL) {701CFArrayRef cferas = CFDateFormatterCopyProperty(df, kCFDateFormatterEraSymbols);702if (cferas != NULL) {703int eraCount = CFArrayGetCount(cferas);704705if (eras == NULL) {706ret = (*env)->NewObjectArray(env, (jsize)eraCount,707(*env)->FindClass(env, "java/lang/String"), NULL);708}709CFTypeRef cal = CFLocaleGetValue(cflocale, kCFLocaleCalendarIdentifier);710int sindex = cal == kCFJapaneseCalendar ? JAPANESE_MEIJI_INDEX : 0;711int dindex = cal == kCFJapaneseCalendar ? 1 : 0; // 0 is "BeforeMeiji" in JCal712copyArrayElements(env, cferas, ret, sindex, dindex, eraCount - sindex);713CFRelease(cferas);714}715CFRelease(df);716}717CFRelease(cflocale);718}719720return ret;721}722723jobjectArray getWeekdaysImpl(JNIEnv *env, jclass cls, jstring jlangtag, jint style, jobjectArray wdays) {724jobjectArray ret = wdays;725CFLocaleRef cflocale = CFLocaleCopyCurrent();726if (cflocale != NULL) {727CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,728cflocale,729convertDateFormatterStyle(style),730convertDateFormatterStyle(style));731if (df != NULL) {732CFArrayRef cfwdays = CFDateFormatterCopyProperty(df, kCFDateFormatterWeekdaySymbols);733if (cfwdays != NULL) {734int dayCount = CFArrayGetCount(cfwdays);735736if (wdays == NULL) {737ret = (*env)->NewObjectArray(env, dayCount + 1,738(*env)->FindClass(env, "java/lang/String"), NULL);739}740copyArrayElements(env, cfwdays, ret, 0, 1, dayCount);741CFRelease(cfwdays);742}743CFRelease(df);744}745CFRelease(cflocale);746}747748return ret;749}750751jobjectArray getAmPmImpl(JNIEnv *env, jclass cls, jstring jlangtag, jint style, jobjectArray ampms) {752CFLocaleRef cflocale = CFLocaleCopyCurrent();753jstring tmp_string;754if (cflocale != NULL) {755CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,756cflocale,757convertDateFormatterStyle(style),758convertDateFormatterStyle(style));759if (df != NULL) {760char buf[BUFLEN];761if (ampms == NULL) {762ampms = (*env)->NewObjectArray(env, 2,763(*env)->FindClass(env, "java/lang/String"), NULL);764}765CFStringRef amStr = CFDateFormatterCopyProperty(df, kCFDateFormatterAMSymbol);766if (amStr != NULL) {767CFStringGetCString(amStr, buf, BUFLEN, kCFStringEncodingUTF8);768CFRelease(amStr);769tmp_string = (*env)->NewStringUTF(env, buf);770if (tmp_string != NULL) {771(*env)->SetObjectArrayElement(env, ampms, 0, tmp_string);772}773}774if (!(*env)->ExceptionCheck(env)){775CFStringRef pmStr = CFDateFormatterCopyProperty(df, kCFDateFormatterPMSymbol);776if (pmStr != NULL) {777CFStringGetCString(pmStr, buf, BUFLEN, kCFStringEncodingUTF8);778CFRelease(pmStr);779tmp_string = (*env)->NewStringUTF(env, buf);780if (tmp_string != NULL) {781(*env)->SetObjectArrayElement(env, ampms, 1, tmp_string);782}783}784}785CFRelease(df);786}787CFRelease(cflocale);788}789790return ampms;791}792793794