1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h" 27 #include "jni_util.h" 28 #include <CoreFoundation/CoreFoundation.h> 29 #include <stdio.h> 30 31 #define BUFLEN 256 32 33 static CFDateFormatterStyle convertDateFormatterStyle(jint javaStyle); 34 static CFNumberFormatterStyle convertNumberFormatterStyle(jint javaStyle); 35 static void copyArrayElements(JNIEnv *env, CFArrayRef cfarray, jobjectArray jarray, CFIndex sindex, int dindex, int count); 36 static jstring getNumberSymbolString(JNIEnv *env, jstring jlangtag, jstring jdefault, CFStringRef type); 37 static jchar getNumberSymbolChar(JNIEnv *env, jstring jlangtag, jchar jdefault, CFStringRef type); 38 39 // from java_props_macosx.c 40 extern char * getMacOSXLocale(int cat); 41 extern char * getPosixLocale(int cat); 42 43 /* 44 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 45 * Method: getDefaultLocale 46 * Signature: (I)Ljava/lang/String; 47 */ 48 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDefaultLocale 49 (JNIEnv *env, jclass cls, jint cat) { 50 char * localeString = NULL; 51 int posixCat; 52 jstring ret = NULL; 53 54 switch (cat) { 55 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_DISPLAY: 56 posixCat = LC_MESSAGES; 57 break; 58 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_FORMAT: 59 default: 60 posixCat = LC_CTYPE; 61 break; 62 } 63 64 localeString = getMacOSXLocale(posixCat); 65 if (localeString == NULL) { 66 localeString = getPosixLocale(posixCat); 67 if (localeString == NULL) { 68 JNU_ThrowOutOfMemoryError(env, NULL); 69 return NULL; 70 } 71 } 72 ret = (*env)->NewStringUTF(env, localeString); 73 free(localeString); 74 75 return ret; 76 } 77 78 /* 79 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 80 * Method: getDateTimePatternNative 81 * Signature: (IILjava/lang/String;)Ljava/lang/String; 82 */ 83 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDateTimePatternNative 84 (JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) { 85 jstring ret = NULL; 86 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 87 88 if (cflocale != NULL) { 89 CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault, 90 cflocale, 91 convertDateFormatterStyle(dateStyle), 92 convertDateFormatterStyle(timeStyle)); 93 if (df != NULL) { 94 char buf[BUFLEN]; 95 CFStringRef formatStr = CFDateFormatterGetFormat(df); 96 CFStringGetCString(formatStr, buf, BUFLEN, kCFStringEncodingUTF8); 97 ret = (*env)->NewStringUTF(env, buf); 98 CFRelease(df); 99 } 100 CFRelease(cflocale); 101 } 102 103 return ret; 104 } 105 106 /* 107 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 108 * Method: getCalendarID 109 * Signature: (Ljava/lang/String;)Ljava/lang/String; 110 */ 111 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarID 112 (JNIEnv *env, jclass cls, jstring jlangtag) { 113 jstring ret = NULL; 114 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 115 116 if (cflocale != NULL) { 117 char buf[BUFLEN]; 118 CFTypeRef calid = CFLocaleGetValue(cflocale, kCFLocaleCalendarIdentifier); 119 CFStringGetCString((CFStringRef)calid, buf, BUFLEN, kCFStringEncodingUTF8); 120 ret = (*env)->NewStringUTF(env, buf); 121 CFRelease(cflocale); 122 } 123 124 return ret; 125 } 126 127 /* 128 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 129 * Method: getAmPmStrings 130 * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String; 131 */ 132 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings 133 (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) { 134 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 135 jstring tmp_string; 136 if (cflocale != NULL) { 137 CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault, 138 cflocale, 139 kCFDateFormatterFullStyle, 140 kCFDateFormatterFullStyle); 141 if (df != NULL) { 142 char buf[BUFLEN]; 143 CFStringRef amStr = CFDateFormatterCopyProperty(df, kCFDateFormatterAMSymbol); 144 if (amStr != NULL) { 145 CFStringGetCString(amStr, buf, BUFLEN, kCFStringEncodingUTF8); 146 CFRelease(amStr); 147 tmp_string = (*env)->NewStringUTF(env, buf); 148 if (tmp_string != NULL) { 149 (*env)->SetObjectArrayElement(env, ampms, 0, tmp_string); 150 } 151 } 152 if (!(*env)->ExceptionCheck(env)){ 153 CFStringRef pmStr = CFDateFormatterCopyProperty(df, kCFDateFormatterPMSymbol); 154 if (pmStr != NULL) { 155 CFStringGetCString(pmStr, buf, BUFLEN, kCFStringEncodingUTF8); 156 CFRelease(pmStr); 157 tmp_string = (*env)->NewStringUTF(env, buf); 158 if (tmp_string != NULL) { 159 (*env)->SetObjectArrayElement(env, ampms, 1, tmp_string); 160 } 161 } 162 } 163 CFRelease(df); 164 } 165 CFRelease(cflocale); 166 } 167 168 return ampms; 169 } 170 171 /* 172 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 173 * Method: getEras 174 * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String; 175 */ 176 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getEras 177 (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray eras) { 178 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 179 if (cflocale != NULL) { 180 CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault, 181 cflocale, 182 kCFDateFormatterFullStyle, 183 kCFDateFormatterFullStyle); 184 if (df != NULL) { 185 CFArrayRef cferas = CFDateFormatterCopyProperty(df, kCFDateFormatterEraSymbols); 186 if (cferas != NULL) { 187 copyArrayElements(env, cferas, eras, 0, 0, CFArrayGetCount(cferas)); 188 CFRelease(cferas); 189 } 190 CFRelease(df); 191 } 192 CFRelease(cflocale); 193 } 194 195 return eras; 196 } 197 198 /* 199 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 200 * Method: getMonths 201 * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String; 202 */ 203 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonths 204 (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray months) { 205 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 206 if (cflocale != NULL) { 207 CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault, 208 cflocale, 209 kCFDateFormatterFullStyle, 210 kCFDateFormatterFullStyle); 211 if (df != NULL) { 212 CFArrayRef cfmonths = CFDateFormatterCopyProperty(df, kCFDateFormatterMonthSymbols); 213 if (cfmonths != NULL) { 214 copyArrayElements(env, cfmonths, months, 0, 0, CFArrayGetCount(cfmonths)); 215 CFRelease(cfmonths); 216 } 217 CFRelease(df); 218 } 219 CFRelease(cflocale); 220 } 221 222 return months; 223 } 224 225 /* 226 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 227 * Method: getShortMonths 228 * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String; 229 */ 230 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortMonths 231 (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray smonths) { 232 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 233 if (cflocale != NULL) { 234 CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault, 235 cflocale, 236 kCFDateFormatterFullStyle, 237 kCFDateFormatterFullStyle); 238 if (df != NULL) { 239 CFArrayRef cfsmonths = CFDateFormatterCopyProperty(df, kCFDateFormatterShortMonthSymbols); 240 if (cfsmonths != NULL) { 241 copyArrayElements(env, cfsmonths, smonths, 0, 0, CFArrayGetCount(cfsmonths)); 242 CFRelease(cfsmonths); 243 } 244 CFRelease(df); 245 } 246 CFRelease(cflocale); 247 } 248 249 return smonths; 250 } 251 252 /* 253 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 254 * Method: getWeekdays 255 * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String; 256 */ 257 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getWeekdays 258 (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray wdays) { 259 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 260 if (cflocale != NULL) { 261 CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault, 262 cflocale, 263 kCFDateFormatterFullStyle, 264 kCFDateFormatterFullStyle); 265 if (df != NULL) { 266 CFArrayRef cfwdays = CFDateFormatterCopyProperty(df, kCFDateFormatterWeekdaySymbols); 267 if (cfwdays != NULL) { 268 copyArrayElements(env, cfwdays, wdays, 0, 1, CFArrayGetCount(cfwdays)); 269 CFRelease(cfwdays); 270 } 271 CFRelease(df); 272 } 273 CFRelease(cflocale); 274 } 275 276 return wdays; 277 } 278 279 /* 280 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 281 * Method: getShortWeekdays 282 * Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String; 283 */ 284 JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortWeekdays 285 (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray swdays) { 286 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 287 if (cflocale != NULL) { 288 CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault, 289 cflocale, 290 kCFDateFormatterFullStyle, 291 kCFDateFormatterFullStyle); 292 if (df != NULL) { 293 CFArrayRef cfswdays = CFDateFormatterCopyProperty(df, kCFDateFormatterShortWeekdaySymbols); 294 if (cfswdays != NULL) { 295 copyArrayElements(env, cfswdays, swdays, 0, 1, CFArrayGetCount(cfswdays)); 296 CFRelease(cfswdays); 297 } 298 CFRelease(df); 299 } 300 CFRelease(cflocale); 301 } 302 303 return swdays; 304 } 305 306 /* 307 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 308 * Method: getNumberPatternNative 309 * Signature: (ILjava/lang/String;)Ljava/lang/String; 310 */ 311 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNumberPatternNative 312 (JNIEnv *env, jclass cls, jint numberStyle, jstring jlangtag) { 313 jstring ret = NULL; 314 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 315 if (cflocale != NULL) { 316 CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault, 317 cflocale, 318 convertNumberFormatterStyle(numberStyle)); 319 if (nf != NULL) { 320 char buf[BUFLEN]; 321 CFStringRef formatStr = CFNumberFormatterGetFormat(nf); 322 CFStringGetCString(formatStr, buf, BUFLEN, kCFStringEncodingUTF8); 323 ret = (*env)->NewStringUTF(env, buf); 324 CFRelease(nf); 325 } 326 CFRelease(cflocale); 327 } 328 329 return ret; 330 } 331 332 /* 333 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 334 * Method: getCurrencySymbol 335 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 336 */ 337 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol 338 (JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) { 339 return getNumberSymbolString(env, jlangtag, currencySymbol, kCFNumberFormatterCurrencySymbol); 340 } 341 342 /* 343 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 344 * Method: getDecimalSeparator 345 * Signature: (Ljava/lang/String;C)C 346 */ 347 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDecimalSeparator 348 (JNIEnv *env, jclass cls, jstring jlangtag, jchar decimalSeparator) { 349 return getNumberSymbolChar(env, jlangtag, decimalSeparator, kCFNumberFormatterDecimalSeparator); 350 } 351 352 /* 353 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 354 * Method: getGroupingSeparator 355 * Signature: (Ljava/lang/String;C)C 356 */ 357 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getGroupingSeparator 358 (JNIEnv *env, jclass cls, jstring jlangtag, jchar groupingSeparator) { 359 return getNumberSymbolChar(env, jlangtag, groupingSeparator, kCFNumberFormatterGroupingSeparator); 360 } 361 362 /* 363 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 364 * Method: getInfinity 365 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 366 */ 367 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInfinity 368 (JNIEnv *env, jclass cls, jstring jlangtag, jstring infinity) { 369 return getNumberSymbolString(env, jlangtag, infinity, kCFNumberFormatterInfinitySymbol); 370 } 371 372 /* 373 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 374 * Method: getInternationalCurrencySymbol 375 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 376 */ 377 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInternationalCurrencySymbol 378 (JNIEnv *env, jclass cls, jstring jlangtag, jstring internationalCurrencySymbol) { 379 return getNumberSymbolString(env, jlangtag, internationalCurrencySymbol, kCFNumberFormatterInternationalCurrencySymbol); 380 } 381 382 /* 383 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 384 * Method: getMinusSign 385 * Signature: (Ljava/lang/String;C)C 386 */ 387 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMinusSign 388 (JNIEnv *env, jclass cls, jstring jlangtag, jchar minusSign) { 389 return getNumberSymbolChar(env, jlangtag, minusSign, kCFNumberFormatterMinusSign); 390 } 391 392 /* 393 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 394 * Method: getMonetaryDecimalSeparator 395 * Signature: (Ljava/lang/String;C)C 396 */ 397 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonetaryDecimalSeparator 398 (JNIEnv *env, jclass cls, jstring jlangtag, jchar monetaryDecimalSeparator) { 399 return getNumberSymbolChar(env, jlangtag, monetaryDecimalSeparator, kCFNumberFormatterCurrencyDecimalSeparator); 400 } 401 402 /* 403 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 404 * Method: getNaN 405 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 406 */ 407 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNaN 408 (JNIEnv *env, jclass cls, jstring jlangtag, jstring nan) { 409 return getNumberSymbolString(env, jlangtag, nan, kCFNumberFormatterNaNSymbol); 410 } 411 412 /* 413 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 414 * Method: getPercent 415 * Signature: (Ljava/lang/String;C)C 416 */ 417 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPercent 418 (JNIEnv *env, jclass cls, jstring jlangtag, jchar percent) { 419 return getNumberSymbolChar(env, jlangtag, percent, kCFNumberFormatterPercentSymbol); 420 } 421 422 /* 423 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 424 * Method: getPerMill 425 * Signature: (Ljava/lang/String;C)C 426 */ 427 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPerMill 428 (JNIEnv *env, jclass cls, jstring jlangtag, jchar perMill) { 429 return getNumberSymbolChar(env, jlangtag, perMill, kCFNumberFormatterPerMillSymbol); 430 } 431 432 /* 433 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 434 * Method: getZeroDigit 435 * Signature: (Ljava/lang/String;C)C 436 */ 437 JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getZeroDigit 438 (JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) { 439 // The following code *should* work, but not for some reason :o 440 // 441 //return getNumberSymbolChar(env, jlangtag, zeroDigit, kCFNumberFormatterZeroSymbol); 442 // 443 // so here is a workaround. 444 jchar ret = zeroDigit; 445 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 446 447 if (cflocale != NULL) { 448 CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault, 449 cflocale, 450 kCFNumberFormatterNoStyle); 451 if (nf != NULL) { 452 int zero = 0; 453 CFStringRef str = CFNumberFormatterCreateStringWithValue(kCFAllocatorDefault, 454 nf, kCFNumberIntType, &zero); 455 if (str != NULL) { 456 if (CFStringGetLength(str) > 0) { 457 ret = CFStringGetCharacterAtIndex(str, 0); 458 } 459 CFRelease(str); 460 } 461 462 CFRelease(nf); 463 } 464 465 CFRelease(cflocale); 466 } 467 468 return ret; 469 } 470 471 /* 472 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 473 * Method: getExponentSeparator 474 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 475 */ 476 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getExponentSeparator 477 (JNIEnv *env, jclass cls, jstring jlangtag, jstring exponent) { 478 return getNumberSymbolString(env, jlangtag, exponent, kCFNumberFormatterExponentSymbol); 479 } 480 481 /* 482 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 483 * Method: getCalendarInt 484 * Signature: (Ljava/lang/String;I)I 485 */ 486 JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarInt 487 (JNIEnv *env, jclass cls, jstring jlangtag, jint type) { 488 jint ret = 0; 489 CFCalendarRef cfcal = CFCalendarCopyCurrent(); 490 491 if (cfcal != NULL) { 492 switch (type) { 493 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK: 494 ret = CFCalendarGetFirstWeekday(cfcal); 495 break; 496 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_MINIMALDAYSINFIRSTWEEK: 497 ret = CFCalendarGetMinimumDaysInFirstWeek(cfcal); 498 break; 499 default: 500 ret = 0; 501 } 502 503 CFRelease(cfcal); 504 } 505 506 return ret; 507 } 508 509 /* 510 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 511 * Method: getDisplayString 512 * Signature: (Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String; 513 */ 514 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDisplayString 515 (JNIEnv *env, jclass cls, jstring jlangtag, jint type, jstring value) { 516 jstring ret = NULL; 517 518 const char *clangtag = (*env)->GetStringUTFChars(env, jlangtag, 0); 519 if (clangtag != NULL) { 520 const char *cvalue = (*env)->GetStringUTFChars(env, value, 0); 521 if (cvalue != NULL) { 522 CFStringRef cflangtag = 523 CFStringCreateWithCString(kCFAllocatorDefault, clangtag, kCFStringEncodingUTF8); 524 if (cflangtag != NULL) { 525 CFLocaleRef cflocale = CFLocaleCreate(kCFAllocatorDefault, cflangtag); 526 if (cflocale != NULL) { 527 CFStringRef cfvalue = 528 CFStringCreateWithCString(kCFAllocatorDefault, cvalue, kCFStringEncodingUTF8); 529 if (cfvalue != NULL) { 530 CFStringRef str = NULL; 531 switch (type) { 532 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_LANGUAGE: 533 str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleLanguageCode, cfvalue); 534 break; 535 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_SCRIPT: 536 str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleScriptCode, cfvalue); 537 break; 538 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_REGION: 539 str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleCountryCode, cfvalue); 540 break; 541 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_VARIANT: 542 str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleVariantCode, cfvalue); 543 break; 544 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_CODE: 545 str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleCurrencyCode, cfvalue); 546 break; 547 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_SYMBOL: 548 str = CFLocaleCopyDisplayNameForPropertyValue(cflocale, kCFLocaleCurrencySymbol, cfvalue); 549 break; 550 } 551 if (str != NULL) { 552 char buf[BUFLEN]; 553 CFStringGetCString(str, buf, BUFLEN, kCFStringEncodingUTF8); 554 CFRelease(str); 555 ret = (*env)->NewStringUTF(env, buf); 556 } 557 CFRelease(cfvalue); 558 } 559 CFRelease(cflocale); 560 } 561 CFRelease(cflangtag); 562 } 563 (*env)->ReleaseStringUTFChars(env, value, cvalue); 564 } 565 (*env)->ReleaseStringUTFChars(env, jlangtag, clangtag); 566 } 567 568 return ret; 569 } 570 571 /* 572 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl 573 * Method: getTimeZoneDisplayString 574 * Signature: (Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String; 575 */ 576 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getTimeZoneDisplayString 577 (JNIEnv *env, jclass cls, jstring jlangtag, jint type, jstring tzid) { 578 jstring ret = NULL; 579 580 const char *clangtag = (*env)->GetStringUTFChars(env, jlangtag, 0); 581 if (clangtag != NULL) { 582 const char *ctzid = (*env)->GetStringUTFChars(env, tzid, 0); 583 if (ctzid != NULL) { 584 CFStringRef cflangtag = 585 CFStringCreateWithCString(kCFAllocatorDefault, clangtag, kCFStringEncodingUTF8); 586 if (cflangtag != NULL) { 587 CFLocaleRef cflocale = CFLocaleCreate(kCFAllocatorDefault, cflangtag); 588 if (cflocale != NULL) { 589 CFStringRef cftzid = 590 CFStringCreateWithCString(kCFAllocatorDefault, ctzid, kCFStringEncodingUTF8); 591 if (cftzid != NULL) { 592 CFTimeZoneRef cftz = CFTimeZoneCreateWithName(kCFAllocatorDefault, cftzid, false); 593 if (cftz != NULL) { 594 CFStringRef str = NULL; 595 switch (type) { 596 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_TZ_SHORT_STANDARD: 597 str = CFTimeZoneCopyLocalizedName(cftz, kCFTimeZoneNameStyleShortStandard, cflocale); 598 break; 599 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_TZ_SHORT_DST: 600 str = CFTimeZoneCopyLocalizedName(cftz, kCFTimeZoneNameStyleShortDaylightSaving, cflocale); 601 break; 602 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_TZ_LONG_STANDARD: 603 str = CFTimeZoneCopyLocalizedName(cftz, kCFTimeZoneNameStyleStandard, cflocale); 604 break; 605 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_TZ_LONG_DST: 606 str = CFTimeZoneCopyLocalizedName(cftz, kCFTimeZoneNameStyleDaylightSaving, cflocale); 607 break; 608 } 609 if (str != NULL) { 610 char buf[BUFLEN]; 611 CFStringGetCString(str, buf, BUFLEN, kCFStringEncodingUTF8); 612 CFRelease(str); 613 ret = (*env)->NewStringUTF(env, buf); 614 } 615 CFRelease(cftz); 616 } 617 CFRelease(cftzid); 618 } 619 CFRelease(cflocale); 620 } 621 CFRelease(cflangtag); 622 } 623 (*env)->ReleaseStringUTFChars(env, tzid, ctzid); 624 } 625 (*env)->ReleaseStringUTFChars(env, jlangtag, clangtag); 626 } 627 628 return ret; 629 } 630 631 static CFDateFormatterStyle convertDateFormatterStyle(jint javaStyle) { 632 switch (javaStyle) { 633 case 0: // FULL 634 return kCFDateFormatterFullStyle; 635 case 1: // LONG 636 return kCFDateFormatterLongStyle; 637 case 2: // MEDIUM 638 return kCFDateFormatterMediumStyle; 639 case 3: // LONG 640 return kCFDateFormatterShortStyle; 641 case -1: // No style 642 default: 643 return kCFDateFormatterNoStyle; 644 } 645 } 646 647 static CFNumberFormatterStyle convertNumberFormatterStyle(jint javaStyle) { 648 switch (javaStyle) { 649 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY: 650 return kCFNumberFormatterCurrencyStyle; 651 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER: 652 return kCFNumberFormatterDecimalStyle; 653 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER: 654 return kCFNumberFormatterDecimalStyle; 655 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT: 656 return kCFNumberFormatterPercentStyle; 657 default: 658 return kCFNumberFormatterNoStyle; 659 } 660 } 661 662 static void copyArrayElements(JNIEnv *env, CFArrayRef cfarray, jobjectArray jarray, CFIndex sindex, int dindex, int count) { 663 char buf[BUFLEN]; 664 jstring tmp_string; 665 666 for (; count > 0; sindex++, dindex++, count--) { 667 CFStringGetCString(CFArrayGetValueAtIndex(cfarray, sindex), buf, BUFLEN, kCFStringEncodingUTF8); 668 tmp_string = (*env)->NewStringUTF(env, buf); 669 if (tmp_string != NULL) { 670 (*env)->SetObjectArrayElement(env, jarray, dindex, tmp_string); 671 } else { 672 break; 673 } 674 } 675 } 676 677 static jstring getNumberSymbolString(JNIEnv *env, jstring jlangtag, jstring jdefault, CFStringRef type) { 678 char buf[BUFLEN]; 679 jstring ret = jdefault; 680 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 681 682 if (cflocale != NULL) { 683 CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault, 684 cflocale, 685 kCFNumberFormatterNoStyle); 686 if (nf != NULL) { 687 CFStringRef str = CFNumberFormatterCopyProperty(nf, type); 688 if (str != NULL) { 689 CFStringGetCString(str, buf, BUFLEN, kCFStringEncodingUTF8); 690 CFRelease(str); 691 ret = (*env)->NewStringUTF(env, buf); 692 } 693 694 CFRelease(nf); 695 } 696 697 CFRelease(cflocale); 698 } 699 700 return ret; 701 } 702 703 static jchar getNumberSymbolChar(JNIEnv *env, jstring jlangtag, jchar jdefault, CFStringRef type) { 704 jchar ret = jdefault; 705 CFLocaleRef cflocale = CFLocaleCopyCurrent(); 706 707 if (cflocale != NULL) { 708 CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorDefault, 709 cflocale, 710 kCFNumberFormatterNoStyle); 711 if (nf != NULL) { 712 CFStringRef str = CFNumberFormatterCopyProperty(nf, type); 713 if (str != NULL) { 714 if (CFStringGetLength(str) > 0) { 715 ret = CFStringGetCharacterAtIndex(str, 0); 716 } 717 CFRelease(str); 718 } 719 720 CFRelease(nf); 721 } 722 723 CFRelease(cflocale); 724 } 725 726 return ret; 727 }