src/macosx/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c

Print this page
rev 6809 : imported patch 7091601

@@ -30,12 +30,13 @@
 #define BUFLEN 256
 
 static CFDateFormatterStyle convertDateFormatterStyle(jint javaStyle);
 static CFNumberFormatterStyle convertNumberFormatterStyle(jint javaStyle);
 static void copyArrayElements(JNIEnv *env, CFArrayRef cfarray, jobjectArray jarray, CFIndex sindex, int dindex, int count);
-static jstring getNumberSymbolString(JNIEnv *env, jstring jdefault, CFStringRef type);
-static jchar getNumberSymbolChar(jchar jdefault, CFStringRef type);
+static jstring getNumberSymbolString(JNIEnv *env, jstring jlangtag, jstring jdefault, CFStringRef type);
+static jchar getNumberSymbolChar(JNIEnv *env, jstring jlangtag, jchar jdefault, CFStringRef type);
+static CFLocaleRef createCFLocale(JNIEnv *env, jstring jlangtag);
 
 // from java_props_macosx.c
 extern char * getMacOSXLocale(int cat);
 extern char * getPosixLocale(int cat);
 

@@ -76,11 +77,11 @@
  * Signature: (IILjava/lang/String;)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDateTimePatternNative
   (JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) {
     jstring ret = NULL;
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
 
     if (cflocale != NULL) {
         CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
                                                   convertDateFormatterStyle(dateStyle),

@@ -104,11 +105,11 @@
  * Signature: (Ljava/lang/String;)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarID
   (JNIEnv *env, jclass cls, jstring jlangtag) {
     jstring ret = NULL;
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
 
     if (cflocale != NULL) {
         char buf[BUFLEN];
         CFTypeRef calid = CFLocaleGetValue(cflocale, kCFLocaleCalendarIdentifier);
         CFStringGetCString((CFStringRef)calid, buf, BUFLEN, kCFStringEncodingUTF8);

@@ -124,11 +125,11 @@
  * Method:    getAmPmStrings
  * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings
   (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) {
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
     if (cflocale != NULL) {
         CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
                                                   kCFDateFormatterFullStyle,
                                                   kCFDateFormatterFullStyle);

@@ -159,11 +160,11 @@
  * Method:    getEras
  * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getEras
   (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray eras) {
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
     if (cflocale != NULL) {
         CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
                                                   kCFDateFormatterFullStyle,
                                                   kCFDateFormatterFullStyle);

@@ -186,11 +187,11 @@
  * Method:    getMonths
  * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonths
   (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray months) {
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
     if (cflocale != NULL) {
         CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
                                                   kCFDateFormatterFullStyle,
                                                   kCFDateFormatterFullStyle);

@@ -213,11 +214,11 @@
  * Method:    getShortMonths
  * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortMonths
   (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray smonths) {
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
     if (cflocale != NULL) {
         CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
                                                   kCFDateFormatterFullStyle,
                                                   kCFDateFormatterFullStyle);

@@ -240,11 +241,11 @@
  * Method:    getWeekdays
  * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getWeekdays
   (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray wdays) {
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
     if (cflocale != NULL) {
         CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
                                                   kCFDateFormatterFullStyle,
                                                   kCFDateFormatterFullStyle);

@@ -267,11 +268,11 @@
  * Method:    getShortWeekdays
  * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortWeekdays
   (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray swdays) {
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
     if (cflocale != NULL) {
         CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
                                                   kCFDateFormatterFullStyle,
                                                   kCFDateFormatterFullStyle);

@@ -295,11 +296,11 @@
  * Signature: (ILjava/lang/String;)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNumberPatternNative
   (JNIEnv *env, jclass cls, jint numberStyle, jstring jlangtag) {
     jstring ret = NULL;
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
     if (cflocale != NULL) {
         CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
                                                   convertNumberFormatterStyle(numberStyle));
         if (nf != NULL) {

@@ -320,121 +321,150 @@
  * Method:    getCurrencySymbol
  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol
   (JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) {
-    return getNumberSymbolString(env, currencySymbol, kCFNumberFormatterCurrencySymbol);
+    return getNumberSymbolString(env, jlangtag, currencySymbol, kCFNumberFormatterCurrencySymbol);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getDecimalSeparator
  * Signature: (Ljava/lang/String;C)C
  */
 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDecimalSeparator
   (JNIEnv *env, jclass cls, jstring jlangtag, jchar decimalSeparator) {
-    return getNumberSymbolChar(decimalSeparator, kCFNumberFormatterDecimalSeparator);
+    return getNumberSymbolChar(env, jlangtag, decimalSeparator, kCFNumberFormatterDecimalSeparator);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getGroupingSeparator
  * Signature: (Ljava/lang/String;C)C
  */
 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getGroupingSeparator
   (JNIEnv *env, jclass cls, jstring jlangtag, jchar groupingSeparator) {
-    return getNumberSymbolChar(groupingSeparator, kCFNumberFormatterGroupingSeparator);
+    return getNumberSymbolChar(env, jlangtag, groupingSeparator, kCFNumberFormatterGroupingSeparator);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getInfinity
  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInfinity
   (JNIEnv *env, jclass cls, jstring jlangtag, jstring infinity) {
-    return getNumberSymbolString(env, infinity, kCFNumberFormatterInfinitySymbol);
+    return getNumberSymbolString(env, jlangtag, infinity, kCFNumberFormatterInfinitySymbol);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getInternationalCurrencySymbol
  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInternationalCurrencySymbol
   (JNIEnv *env, jclass cls, jstring jlangtag, jstring internationalCurrencySymbol) {
-    return getNumberSymbolString(env, internationalCurrencySymbol, kCFNumberFormatterInternationalCurrencySymbol);
+    return getNumberSymbolString(env, jlangtag, internationalCurrencySymbol, kCFNumberFormatterInternationalCurrencySymbol);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getMinusSign
  * Signature: (Ljava/lang/String;C)C
  */
 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMinusSign
   (JNIEnv *env, jclass cls, jstring jlangtag, jchar minusSign) {
-    return getNumberSymbolChar(minusSign, kCFNumberFormatterMinusSign);
+    return getNumberSymbolChar(env, jlangtag, minusSign, kCFNumberFormatterMinusSign);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getMonetaryDecimalSeparator
  * Signature: (Ljava/lang/String;C)C
  */
 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonetaryDecimalSeparator
   (JNIEnv *env, jclass cls, jstring jlangtag, jchar monetaryDecimalSeparator) {
-    return getNumberSymbolChar(monetaryDecimalSeparator, kCFNumberFormatterCurrencyDecimalSeparator);
+    return getNumberSymbolChar(env, jlangtag, monetaryDecimalSeparator, kCFNumberFormatterCurrencyDecimalSeparator);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getNaN
  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNaN
   (JNIEnv *env, jclass cls, jstring jlangtag, jstring nan) {
-    return getNumberSymbolString(env, nan, kCFNumberFormatterNaNSymbol);
+    return getNumberSymbolString(env, jlangtag, nan, kCFNumberFormatterNaNSymbol);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getPercent
  * Signature: (Ljava/lang/String;C)C
  */
 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPercent
   (JNIEnv *env, jclass cls, jstring jlangtag, jchar percent) {
-    return getNumberSymbolChar(percent, kCFNumberFormatterPercentSymbol);
+    return getNumberSymbolChar(env, jlangtag, percent, kCFNumberFormatterPercentSymbol);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getPerMill
  * Signature: (Ljava/lang/String;C)C
  */
 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPerMill
   (JNIEnv *env, jclass cls, jstring jlangtag, jchar perMill) {
-    return getNumberSymbolChar(perMill, kCFNumberFormatterPerMillSymbol);
+    return getNumberSymbolChar(env, jlangtag, perMill, kCFNumberFormatterPerMillSymbol);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getZeroDigit
  * Signature: (Ljava/lang/String;C)C
  */
 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getZeroDigit
   (JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) {
-    return getNumberSymbolChar(zeroDigit, kCFNumberFormatterZeroSymbol);
+    // The following code *should* work, but not for some reason :o
+    //
+    //return getNumberSymbolChar(env, jlangtag, zeroDigit, kCFNumberFormatterZeroSymbol);
+    //
+    // so here is a workaround.
+    jchar ret = zeroDigit;
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
+
+    if (cflocale != NULL) {
+        CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault,
+                                                  cflocale,
+                                                  kCFNumberFormatterNoStyle);
+        if (nf != NULL) {
+            int zero = 0;
+            CFStringRef str = CFNumberFormatterCreateStringWithValue(kCFAllocatorDefault,
+                              nf, kCFNumberIntType, &zero);
+            if (str != NULL) {
+                if (CFStringGetLength(str) > 0) {
+                    ret = CFStringGetCharacterAtIndex(str, 0);
+                }
+                CFRelease(str);
+            }
+
+            CFRelease(nf);
+        }
+
+        CFRelease(cflocale);
+    }
+
+    return ret;
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getExponentSeparator
  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
  */
 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getExponentSeparator
   (JNIEnv *env, jclass cls, jstring jlangtag, jstring exponent) {
-    return getNumberSymbolString(env, exponent, kCFNumberFormatterExponentSymbol);
+    return getNumberSymbolString(env, jlangtag, exponent, kCFNumberFormatterExponentSymbol);
 }
 
 /*
  * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
  * Method:    getCalendarInt

@@ -623,19 +653,19 @@
         CFStringGetCString(CFArrayGetValueAtIndex(cfarray, sindex), buf, BUFLEN, kCFStringEncodingUTF8);
         (*env)->SetObjectArrayElement(env, jarray, dindex, (*env)->NewStringUTF(env, buf));
     }
 }
 
-static jstring getNumberSymbolString(JNIEnv *env, jstring jdefault, CFStringRef type) {
+static jstring getNumberSymbolString(JNIEnv *env, jstring jlangtag, jstring jdefault, CFStringRef type) {
     char buf[BUFLEN];
     jstring ret = jdefault;
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
 
     if (cflocale != NULL) {
         CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
-                                                  kCFNumberFormatterDecimalStyle);
+                                                  kCFNumberFormatterNoStyle);
         if (nf != NULL) {
             CFStringRef str = CFNumberFormatterCopyProperty(nf, type);
             if (str != NULL) {
                 CFStringGetCString(str, buf, BUFLEN, kCFStringEncodingUTF8);
                 CFRelease(str);

@@ -649,30 +679,49 @@
     }
 
     return ret;
 }
 
-static jchar getNumberSymbolChar(jchar jdefault, CFStringRef type) {
-    char buf[BUFLEN];
+static jchar getNumberSymbolChar(JNIEnv *env, jstring jlangtag, jchar jdefault, CFStringRef type) {
     jchar ret = jdefault;
-    CFLocaleRef cflocale = CFLocaleCopyCurrent();
+    CFLocaleRef cflocale = createCFLocale(env, jlangtag);
 
     if (cflocale != NULL) {
         CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault,
                                                   cflocale,
-                                                  kCFNumberFormatterDecimalStyle);
+                                                  kCFNumberFormatterNoStyle);
         if (nf != NULL) {
             CFStringRef str = CFNumberFormatterCopyProperty(nf, type);
             if (str != NULL) {
-                CFStringGetCString(str, buf, BUFLEN, kCFStringEncodingUTF8);
+                if (CFStringGetLength(str) > 0) {
+                    ret = CFStringGetCharacterAtIndex(str, 0);
+                }
                 CFRelease(str);
-                ret = buf[0];
             }
 
             CFRelease(nf);
         }
 
         CFRelease(cflocale);
     }
 
+    return ret;
+}
+
+static CFLocaleRef createCFLocale(JNIEnv *env, jstring jlangtag) {
+    CFLocaleRef ret = NULL;
+    const char *clangtag = (*env)->GetStringUTFChars(env, jlangtag, 0);
+
+    if (clangtag != NULL) {
+        CFStringRef localeID = CFStringCreateWithCString(kCFAllocatorDefault,
+                                   clangtag,
+                                   CFStringGetSystemEncoding());
+        if (localeID != NULL) {
+            ret = CFLocaleCreate(kCFAllocatorDefault, localeID);
+            CFRelease(localeID);
+        }
+
+        (*env)->ReleaseStringUTFChars(env, jlangtag, clangtag);
+    }
+
     return ret;
 }