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