< prev index next >

src/java.base/share/native/libjava/jni_util.c

Print this page
rev 17266 : 8181147: JNI_GetStringPlatformChars should have a fast path for UTF-8
Reviewed-by: shade, chegar, erikj


 427     cls = (*env)->FindClass(env, class_name);
 428     if (cls == 0) {
 429         goto done;
 430     }
 431     cls_initMID  = (*env)->GetMethodID(env, cls,
 432                                        "<init>", constructor_sig);
 433     if (cls_initMID == NULL) {
 434         goto done;
 435     }
 436     va_start(args, constructor_sig);
 437     obj = (*env)->NewObjectV(env, cls, cls_initMID, args);
 438     va_end(args);
 439 
 440  done:
 441     (*env)->DeleteLocalRef(env, cls);
 442     return obj;
 443 }
 444 
 445 /* Optimized for char set ISO_8559_1 */
 446 static jstring
 447 newString8859_1(JNIEnv *env, const char *str)
 448 {
 449     int len = (int)strlen(str);
 450     jchar buf[512];
 451     jchar *str1;
 452     jstring result;
 453     int i;
 454 
 455     if (len > 512) {
 456         str1 = (jchar *)malloc(len * sizeof(jchar));
 457         if (str1 == 0) {
 458             JNU_ThrowOutOfMemoryError(env, 0);
 459             return 0;
 460         }
 461     } else
 462         str1 = buf;
 463 
 464     for (i=0;i<len;i++)
 465         str1[i] = (unsigned char)str[i];
 466     result = (*env)->NewString(env, str1, len);
 467     if (str1 != buf)
 468         free(str1);
 469     return result;
 470 }
 471 







 472 static const char*
 473 getString8859_1Chars(JNIEnv *env, jstring jstr)
 474 {
 475     int i;
 476     char *result;
 477     jint len = (*env)->GetStringLength(env, jstr);
 478     const jchar *str = (*env)->GetStringCritical(env, jstr, 0);
 479     if (str == 0) {
 480         return 0;
 481     }
 482 
 483     result = MALLOC_MIN4(len);
 484     if (result == 0) {
 485         (*env)->ReleaseStringCritical(env, jstr, str);
 486         JNU_ThrowOutOfMemoryError(env, 0);
 487         return 0;
 488     }
 489 
 490     for (i=0; i<len; i++) {
 491         jchar unicode = str[i];
 492         if (unicode <= 0x00ff)
 493             result[i] = (char)unicode;
 494         else
 495             result[i] = '?';
 496     }
 497 
 498     result[len] = 0;
 499     (*env)->ReleaseStringCritical(env, jstr, str);
 500     return result;
 501 }
 502 






















































































































 503 
 504 /* Optimized for char set ISO646-US (us-ascii) */
 505 static jstring
 506 newString646_US(JNIEnv *env, const char *str)
 507 {
 508     int len = (int)strlen(str);
 509     jchar buf[512];
 510     jchar *str1;
 511     jstring result;
 512     int i;
 513 
 514     if (len > 512) {
 515         str1 = (jchar *)malloc(len * sizeof(jchar));
 516         if (str1 == 0) {
 517             JNU_ThrowOutOfMemoryError(env, 0);
 518             return 0;
 519         }
 520     } else
 521         str1 = buf;
 522 


 652             case 0x2122: result[i] = (char)0x99; break;
 653             case 0x0161: result[i] = (char)0x9A; break;
 654             case 0x203A: result[i] = (char)0x9B; break;
 655             case 0x0153: result[i] = (char)0x9C; break;
 656             case 0x017E: result[i] = (char)0x9E; break;
 657             case 0x0178: result[i] = (char)0x9F; break;
 658             default:     result[i] = '?';  break;
 659         }
 660     }
 661 
 662     result[len] = 0;
 663     (*env)->ReleaseStringCritical(env, jstr, str);
 664     return result;
 665 }
 666 
 667 static int fastEncoding = NO_ENCODING_YET;
 668 static jstring jnuEncoding = NULL;
 669 
 670 /* Cached method IDs */
 671 static jmethodID String_init_ID;        /* String(byte[], enc) */

 672 static jmethodID String_getBytes_ID;    /* String.getBytes(enc) */
 673 
 674 int getFastEncoding() {
 675     return fastEncoding;




























 676 }
 677 

 678 /* Initialize the fast encoding.  If the "sun.jnu.encoding" property
 679  * has not yet been set, we leave fastEncoding == NO_ENCODING_YET.
 680  */
 681 void
 682 initializeEncoding(JNIEnv *env)
 683 {
 684     jstring propname = 0;
 685     jstring enc = 0;
 686     jclass strClazz = NULL;
 687 
 688     if ((*env)->EnsureLocalCapacity(env, 3) < 0)
 689         return;
 690 
 691     strClazz = JNU_ClassString(env);
 692     CHECK_NULL(strClazz);
 693 
 694     propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
 695     if (propname) {
 696         jboolean exc;
 697         enc = JNU_CallStaticMethodByName


 701                         "getProperty",
 702                         "(Ljava/lang/String;)Ljava/lang/String;",
 703                         propname).l;
 704         if (!exc) {
 705             if (enc) {
 706                 const char* encname = (*env)->GetStringUTFChars(env, enc, 0);
 707                 if (encname) {
 708            /*
 709             * On Solaris with nl_langinfo() called in GetJavaProperties():
 710             *
 711             *   locale undefined -> NULL -> hardcoded default
 712             *   "C" locale       -> "" -> hardcoded default     (on 2.6)
 713             *   "C" locale       -> "ISO646-US"                 (on Sol 7/8)
 714             *   "en_US" locale -> "ISO8859-1"
 715             *   "en_GB" locale -> "ISO8859-1"                   (on Sol 7/8)
 716             *   "en_UK" locale -> "ISO8859-1"                   (on 2.6)
 717             */
 718                     if ((strcmp(encname, "8859_1") == 0) ||
 719                         (strcmp(encname, "ISO8859-1") == 0) ||
 720                         (strcmp(encname, "ISO8859_1") == 0) ||
 721                         (strcmp(encname, "ISO-8859-1") == 0))
 722                         fastEncoding = FAST_8859_1;
 723                     else if (strcmp(encname, "ISO646-US") == 0)



 724                         fastEncoding = FAST_646_US;
 725                     else if (strcmp(encname, "Cp1252") == 0 ||
 726                              /* This is a temporary fix until we move */
 727                              /* to wide character versions of all Windows */
 728                              /* calls. */
 729                              strcmp(encname, "utf-16le") == 0)
 730                         fastEncoding = FAST_CP1252;
 731                     else {
 732                         fastEncoding = NO_FAST_ENCODING;
 733                         jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc);
 734                     }
 735                     (*env)->ReleaseStringUTFChars(env, enc, encname);
 736                 }
 737             }
 738         } else {
 739             (*env)->ExceptionClear(env);
 740         }
 741     } else {
 742         (*env)->ExceptionClear(env);
 743     }
 744     (*env)->DeleteLocalRef(env, propname);
 745     (*env)->DeleteLocalRef(env, enc);
 746 
 747     /* Initialize method-id cache */
 748     String_getBytes_ID = (*env)->GetMethodID(env, strClazz,
 749                                              "getBytes", "(Ljava/lang/String;)[B");
 750     CHECK_NULL(String_getBytes_ID);
 751     String_init_ID = (*env)->GetMethodID(env, strClazz,
 752                                          "<init>", "([BLjava/lang/String;)V");


 753 }
 754 
 755 static jboolean isJNUEncodingSupported = JNI_FALSE;
 756 static jboolean jnuEncodingSupported(JNIEnv *env) {
 757     jboolean exe;
 758     if (isJNUEncodingSupported == JNI_TRUE) {
 759         return JNI_TRUE;
 760     }
 761     isJNUEncodingSupported = (jboolean) JNU_CallStaticMethodByName (
 762                                     env, &exe,
 763                                     "java/nio/charset/Charset",
 764                                     "isSupported",
 765                                     "(Ljava/lang/String;)Z",
 766                                     jnuEncoding).z;
 767     return isJNUEncodingSupported;
 768 }
 769 
 770 
 771 JNIEXPORT jstring
 772 NewStringPlatform(JNIEnv *env, const char *str)


 775 }
 776 
 777 JNIEXPORT jstring JNICALL
 778 JNU_NewStringPlatform(JNIEnv *env, const char *str)
 779 {
 780     jstring result = NULL;
 781     jbyteArray hab = 0;
 782     int len;
 783 
 784     if (fastEncoding == NO_ENCODING_YET) {
 785         initializeEncoding(env);
 786         JNU_CHECK_EXCEPTION_RETURN(env, NULL);
 787     }
 788 
 789     if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
 790         return newString8859_1(env, str);
 791     if (fastEncoding == FAST_646_US)
 792         return newString646_US(env, str);
 793     if (fastEncoding == FAST_CP1252)
 794         return newStringCp1252(env, str);


 795 
 796     if ((*env)->EnsureLocalCapacity(env, 2) < 0)
 797         return NULL;
 798 
 799     len = (int)strlen(str);
 800     hab = (*env)->NewByteArray(env, len);
 801     if (hab != 0) {
 802         jclass strClazz = JNU_ClassString(env);
 803         CHECK_NULL_RETURN(strClazz, 0);
 804         (*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
 805         if (jnuEncodingSupported(env)) {
 806             result = (*env)->NewObject(env, strClazz,
 807                                        String_init_ID, hab, jnuEncoding);
 808         } else {
 809             /*If the encoding specified in sun.jnu.encoding is not endorsed
 810               by "Charset.isSupported" we have to fall back to use String(byte[])
 811               explicitly here without specifying the encoding name, in which the
 812               StringCoding class will pickup the iso-8859-1 as the fallback
 813               converter for us.
 814              */


 833 JNIEXPORT const char * JNICALL
 834 JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
 835 {
 836     char *result = NULL;
 837     jbyteArray hab = 0;
 838 
 839     if (isCopy)
 840         *isCopy = JNI_TRUE;
 841 
 842     if (fastEncoding == NO_ENCODING_YET) {
 843         initializeEncoding(env);
 844         JNU_CHECK_EXCEPTION_RETURN(env, 0);
 845     }
 846 
 847     if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
 848         return getString8859_1Chars(env, jstr);
 849     if (fastEncoding == FAST_646_US)
 850         return getString646_USChars(env, jstr);
 851     if (fastEncoding == FAST_CP1252)
 852         return getStringCp1252Chars(env, jstr);


 853 
 854     if ((*env)->EnsureLocalCapacity(env, 2) < 0)
 855         return 0;
 856 
 857     if (jnuEncodingSupported(env)) {
 858         hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding);
 859     } else {
 860         jmethodID mid;
 861         jclass strClazz = JNU_ClassString(env);
 862         CHECK_NULL_RETURN(strClazz, 0);
 863         mid = (*env)->GetMethodID(env, strClazz,
 864                                        "getBytes", "()[B");
 865         if (mid != NULL) {
 866             hab = (*env)->CallObjectMethod(env, jstr, mid);
 867         }
 868     }
 869 
 870     if (!(*env)->ExceptionCheck(env)) {
 871         jint len = (*env)->GetArrayLength(env, hab);
 872         result = MALLOC_MIN4(len);




 427     cls = (*env)->FindClass(env, class_name);
 428     if (cls == 0) {
 429         goto done;
 430     }
 431     cls_initMID  = (*env)->GetMethodID(env, cls,
 432                                        "<init>", constructor_sig);
 433     if (cls_initMID == NULL) {
 434         goto done;
 435     }
 436     va_start(args, constructor_sig);
 437     obj = (*env)->NewObjectV(env, cls, cls_initMID, args);
 438     va_end(args);
 439 
 440  done:
 441     (*env)->DeleteLocalRef(env, cls);
 442     return obj;
 443 }
 444 
 445 /* Optimized for char set ISO_8559_1 */
 446 static jstring
 447 newSizedString8859_1(JNIEnv *env, const char *str, int len)
 448 {

 449     jchar buf[512];
 450     jchar *str1;
 451     jstring result;
 452     int i;
 453 
 454     if (len > 512) {
 455         str1 = (jchar *)malloc(len * sizeof(jchar));
 456         if (str1 == 0) {
 457             JNU_ThrowOutOfMemoryError(env, 0);
 458             return 0;
 459         }
 460     } else
 461         str1 = buf;
 462 
 463     for (i=0;i<len;i++)
 464         str1[i] = (unsigned char)str[i];
 465     result = (*env)->NewString(env, str1, len);
 466     if (str1 != buf)
 467         free(str1);
 468     return result;
 469 }
 470 
 471 static jstring
 472 newString8859_1(JNIEnv *env, const char *str)
 473 {
 474     int len = (int)strlen(str);
 475     return newSizedString8859_1(env, str, len);
 476 }
 477 
 478 static const char*
 479 getString8859_1Chars(JNIEnv *env, jstring jstr)
 480 {
 481     int i;
 482     char *result;
 483     jint len = (*env)->GetStringLength(env, jstr);
 484     const jchar *str = (*env)->GetStringCritical(env, jstr, 0);
 485     if (str == 0) {
 486         return 0;
 487     }
 488 
 489     result = MALLOC_MIN4(len);
 490     if (result == 0) {
 491         (*env)->ReleaseStringCritical(env, jstr, str);
 492         JNU_ThrowOutOfMemoryError(env, 0);
 493         return 0;
 494     }
 495 
 496     for (i=0; i<len; i++) {
 497         jchar unicode = str[i];
 498         if (unicode <= 0x00ff)
 499             result[i] = (char)unicode;
 500         else
 501             result[i] = '?';
 502     }
 503 
 504     result[len] = 0;
 505     (*env)->ReleaseStringCritical(env, jstr, str);
 506     return result;
 507 }
 508 
 509 /* Real UTF-8, adapted from java.lang.StringCoding.encodeUTF8 */
 510 #define MIN_HIGH_SURROGATE 0xD800
 511 #define MAX_HIGH_SURROGATE 0xDBFF
 512 #define MIN_LOW_SURROGATE 0xDC00
 513 #define MAX_LOW_SURROGATE 0xDFFF
 514 #define MAX_SURROGATE MAX_LOW_SURROGATE
 515 #define MIN_SURROGATE MIN_HIGH_SURROGATE
 516 #define MIN_SUPPLEMENTARY_CODE_POINT 0x010000
 517 
 518 static jboolean isSurrogate(jchar unicode) {
 519     return unicode >= MIN_SURROGATE && unicode < (MAX_SURROGATE + 1);
 520 }
 521 
 522 static jboolean isLowSurrogate(jchar unicode) {
 523     return unicode >= MIN_LOW_SURROGATE && unicode < (MAX_LOW_SURROGATE + 1);
 524 }
 525 
 526 static jboolean isHighSurrogate(jchar unicode) {
 527     return unicode >= MIN_HIGH_SURROGATE && unicode < (MAX_HIGH_SURROGATE + 1);
 528 }
 529 static int toCodePoint(jchar high, jchar low) {
 530     // Optimized form of:
 531     // return ((high - MIN_HIGH_SURROGATE) << 10)
 532     //         + (low - MIN_LOW_SURROGATE)
 533     //         + MIN_SUPPLEMENTARY_CODE_POINT;
 534     return ((high << 10) + low) + (MIN_SUPPLEMENTARY_CODE_POINT
 535                                    - (MIN_HIGH_SURROGATE << 10)
 536                                    - MIN_LOW_SURROGATE);
 537 }
 538 
 539 static const char*
 540 getStringUTF8(JNIEnv *env, jstring jstr)
 541 {
 542     jsize i;
 543     int dp = 0;
 544     char *result;
 545     jsize len = (*env)->GetStringLength(env, jstr);
 546     jsize size = 0;
 547 
 548     const jchar *str = (*env)->GetStringChars(env, jstr, NULL);
 549     if (str == NULL) {
 550         return NULL;
 551     }
 552 
 553     for (i = 0; i < len;) {
 554         jchar c = str[i++];
 555         if (c <= 0x0080) {
 556             size++;
 557         } else if (c <= 0x0800) {
 558             size += 2;
 559         } else if (isSurrogate(c)) { // isSurrogate
 560             int uc = -1;
 561             if (isHighSurrogate(c) && i < len &&
 562                 isLowSurrogate(str[i])) {
 563                 uc = toCodePoint(c, str[i]);
 564             }
 565             if (uc < 0) {
 566                 size++;
 567             } else {
 568                 size += 4;
 569                 i++;  // 2 chars
 570             }
 571         } else {
 572             // 3 bytes, 16 bits
 573             size += 3;
 574         }
 575     }
 576 
 577     result = MALLOC_MIN4(size);
 578 
 579     if (result == NULL) {
 580         (*env)->ReleaseStringChars(env, jstr, str);
 581         JNU_ThrowOutOfMemoryError(env, NULL);
 582         return 0;
 583     }
 584 
 585     if (size == len) {
 586         // ASCII fast path
 587         for (i = 0; i < len;) {
 588             result[dp++] = (char)str[i++];
 589         }
 590     } else {
 591         for (i = 0; i < len;) {
 592             jchar c = str[i++];
 593             if (c <= 0x0080) {
 594                 result[dp++] = (char)c;
 595             } else if (c <= 0x0800) {
 596                 result[dp++] = (char)(0xc0 | (c >> 6));
 597                 result[dp++] = (char)(0x80 | (c & 0x3f));
 598             } else if (isSurrogate(c)) { // isSurrogate
 599                 int uc = -1;
 600                 if (isHighSurrogate(c) && i < len &&
 601                     isLowSurrogate(str[i])) {
 602                     uc = toCodePoint(c, str[i]);
 603                 }
 604                 if (uc < 0) {
 605                     result[dp++] = '?';
 606                 } else {
 607                     result[dp++] = (char)(0xf0 | ((uc >> 18)));
 608                     result[dp++] = (char)(0x80 | ((uc >> 12) & 0x3f));
 609                     result[dp++] = (char)(0x80 | ((uc >>  6) & 0x3f));
 610                     result[dp++] = (char)(0x80 | (uc & 0x3f));
 611                     i++;  // 2 chars
 612                 }
 613             } else {
 614                 // 3 bytes, 16 bits
 615                 result[dp++] = (char)(0xe0 | ((c >> 12)));
 616                 result[dp++] = (char)(0x80 | ((c >>  6) & 0x3f));
 617                 result[dp++] = (char)(0x80 | (c & 0x3f));
 618             }
 619         }
 620     }
 621 
 622     result[size] = 0;
 623     (*env)->ReleaseStringChars(env, jstr, str);
 624     return result;
 625 }
 626 
 627 
 628 /* Optimized for char set ISO646-US (us-ascii) */
 629 static jstring
 630 newString646_US(JNIEnv *env, const char *str)
 631 {
 632     int len = (int)strlen(str);
 633     jchar buf[512];
 634     jchar *str1;
 635     jstring result;
 636     int i;
 637 
 638     if (len > 512) {
 639         str1 = (jchar *)malloc(len * sizeof(jchar));
 640         if (str1 == 0) {
 641             JNU_ThrowOutOfMemoryError(env, 0);
 642             return 0;
 643         }
 644     } else
 645         str1 = buf;
 646 


 776             case 0x2122: result[i] = (char)0x99; break;
 777             case 0x0161: result[i] = (char)0x9A; break;
 778             case 0x203A: result[i] = (char)0x9B; break;
 779             case 0x0153: result[i] = (char)0x9C; break;
 780             case 0x017E: result[i] = (char)0x9E; break;
 781             case 0x0178: result[i] = (char)0x9F; break;
 782             default:     result[i] = '?';  break;
 783         }
 784     }
 785 
 786     result[len] = 0;
 787     (*env)->ReleaseStringCritical(env, jstr, str);
 788     return result;
 789 }
 790 
 791 static int fastEncoding = NO_ENCODING_YET;
 792 static jstring jnuEncoding = NULL;
 793 
 794 /* Cached method IDs */
 795 static jmethodID String_init_ID;        /* String(byte[], enc) */
 796 static jmethodID String_init_coder_ID;  /* String(byte[], byte) */
 797 static jmethodID String_getBytes_ID;    /* String.getBytes(enc) */
 798 
 799 /* Optimized for char set UTF-8 */
 800 static jstring
 801 newStringUTF8(JNIEnv *env, const char *str)
 802 {
 803     jboolean isAscii = JNI_TRUE;
 804     jstring result;
 805     jbyteArray hab = NULL;
 806     int len = 0;
 807     char b;
 808     for (b = str[len]; b != '\0'; len++, b = str[len]) {
 809         if (isAscii && b & 0x80) {
 810             isAscii = JNI_FALSE;
 811         }
 812     }
 813 
 814     if (isAscii) {
 815         return newSizedString8859_1(env, str, len);
 816     }
 817 
 818     hab = (*env)->NewByteArray(env, len);
 819     if (hab != 0) {
 820         jclass strClazz = JNU_ClassString(env);
 821         CHECK_NULL_RETURN(strClazz, 0);
 822         (*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
 823         result = (*env)->NewObject(env, strClazz,
 824                                        String_init_ID, hab, jnuEncoding);
 825         (*env)->DeleteLocalRef(env, hab);
 826         return result;
 827     }
 828     return NULL;
 829 }
 830 
 831 
 832 /* Initialize the fast encoding.  If the "sun.jnu.encoding" property
 833  * has not yet been set, we leave fastEncoding == NO_ENCODING_YET.
 834  */
 835 void
 836 initializeEncoding(JNIEnv *env)
 837 {
 838     jstring propname = 0;
 839     jstring enc = 0;
 840     jclass strClazz = NULL;
 841 
 842     if ((*env)->EnsureLocalCapacity(env, 3) < 0)
 843         return;
 844 
 845     strClazz = JNU_ClassString(env);
 846     CHECK_NULL(strClazz);
 847 
 848     propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
 849     if (propname) {
 850         jboolean exc;
 851         enc = JNU_CallStaticMethodByName


 855                         "getProperty",
 856                         "(Ljava/lang/String;)Ljava/lang/String;",
 857                         propname).l;
 858         if (!exc) {
 859             if (enc) {
 860                 const char* encname = (*env)->GetStringUTFChars(env, enc, 0);
 861                 if (encname) {
 862            /*
 863             * On Solaris with nl_langinfo() called in GetJavaProperties():
 864             *
 865             *   locale undefined -> NULL -> hardcoded default
 866             *   "C" locale       -> "" -> hardcoded default     (on 2.6)
 867             *   "C" locale       -> "ISO646-US"                 (on Sol 7/8)
 868             *   "en_US" locale -> "ISO8859-1"
 869             *   "en_GB" locale -> "ISO8859-1"                   (on Sol 7/8)
 870             *   "en_UK" locale -> "ISO8859-1"                   (on 2.6)
 871             */
 872                     if ((strcmp(encname, "8859_1") == 0) ||
 873                         (strcmp(encname, "ISO8859-1") == 0) ||
 874                         (strcmp(encname, "ISO8859_1") == 0) ||
 875                         (strcmp(encname, "ISO-8859-1") == 0)) {
 876                         fastEncoding = FAST_8859_1;
 877                     } else if (strcmp(encname, "UTF-8") == 0) {
 878                         fastEncoding = FAST_UTF_8;
 879                         jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc);
 880                     } else if (strcmp(encname, "ISO646-US") == 0) {
 881                         fastEncoding = FAST_646_US;
 882                     } else if (strcmp(encname, "Cp1252") == 0 ||
 883                              /* This is a temporary fix until we move */
 884                              /* to wide character versions of all Windows */
 885                              /* calls. */
 886                              strcmp(encname, "utf-16le") == 0) {
 887                         fastEncoding = FAST_CP1252;
 888                     } else {
 889                         fastEncoding = NO_FAST_ENCODING;
 890                         jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc);
 891                     }
 892                     (*env)->ReleaseStringUTFChars(env, enc, encname);
 893                 }
 894             }
 895         } else {
 896             (*env)->ExceptionClear(env);
 897         }
 898     } else {
 899         (*env)->ExceptionClear(env);
 900     }
 901     (*env)->DeleteLocalRef(env, propname);
 902     (*env)->DeleteLocalRef(env, enc);
 903 
 904     /* Initialize method-id cache */
 905     String_getBytes_ID = (*env)->GetMethodID(env, strClazz,
 906                                              "getBytes", "(Ljava/lang/String;)[B");
 907     CHECK_NULL(String_getBytes_ID);
 908     String_init_ID = (*env)->GetMethodID(env, strClazz,
 909                                          "<init>", "([BLjava/lang/String;)V");
 910     String_init_coder_ID = (*env)->GetMethodID(env, strClazz,
 911                                          "<init>", "([BB)V");
 912 }
 913 
 914 static jboolean isJNUEncodingSupported = JNI_FALSE;
 915 static jboolean jnuEncodingSupported(JNIEnv *env) {
 916     jboolean exe;
 917     if (isJNUEncodingSupported == JNI_TRUE) {
 918         return JNI_TRUE;
 919     }
 920     isJNUEncodingSupported = (jboolean) JNU_CallStaticMethodByName (
 921                                     env, &exe,
 922                                     "java/nio/charset/Charset",
 923                                     "isSupported",
 924                                     "(Ljava/lang/String;)Z",
 925                                     jnuEncoding).z;
 926     return isJNUEncodingSupported;
 927 }
 928 
 929 
 930 JNIEXPORT jstring
 931 NewStringPlatform(JNIEnv *env, const char *str)


 934 }
 935 
 936 JNIEXPORT jstring JNICALL
 937 JNU_NewStringPlatform(JNIEnv *env, const char *str)
 938 {
 939     jstring result = NULL;
 940     jbyteArray hab = 0;
 941     int len;
 942 
 943     if (fastEncoding == NO_ENCODING_YET) {
 944         initializeEncoding(env);
 945         JNU_CHECK_EXCEPTION_RETURN(env, NULL);
 946     }
 947 
 948     if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
 949         return newString8859_1(env, str);
 950     if (fastEncoding == FAST_646_US)
 951         return newString646_US(env, str);
 952     if (fastEncoding == FAST_CP1252)
 953         return newStringCp1252(env, str);
 954     if (fastEncoding == FAST_UTF_8)
 955         return newStringUTF8(env, str);
 956 
 957     if ((*env)->EnsureLocalCapacity(env, 2) < 0)
 958         return NULL;
 959 
 960     len = (int)strlen(str);
 961     hab = (*env)->NewByteArray(env, len);
 962     if (hab != 0) {
 963         jclass strClazz = JNU_ClassString(env);
 964         CHECK_NULL_RETURN(strClazz, 0);
 965         (*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
 966         if (jnuEncodingSupported(env)) {
 967             result = (*env)->NewObject(env, strClazz,
 968                                        String_init_ID, hab, jnuEncoding);
 969         } else {
 970             /*If the encoding specified in sun.jnu.encoding is not endorsed
 971               by "Charset.isSupported" we have to fall back to use String(byte[])
 972               explicitly here without specifying the encoding name, in which the
 973               StringCoding class will pickup the iso-8859-1 as the fallback
 974               converter for us.
 975              */


 994 JNIEXPORT const char * JNICALL
 995 JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
 996 {
 997     char *result = NULL;
 998     jbyteArray hab = 0;
 999 
1000     if (isCopy)
1001         *isCopy = JNI_TRUE;
1002 
1003     if (fastEncoding == NO_ENCODING_YET) {
1004         initializeEncoding(env);
1005         JNU_CHECK_EXCEPTION_RETURN(env, 0);
1006     }
1007 
1008     if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
1009         return getString8859_1Chars(env, jstr);
1010     if (fastEncoding == FAST_646_US)
1011         return getString646_USChars(env, jstr);
1012     if (fastEncoding == FAST_CP1252)
1013         return getStringCp1252Chars(env, jstr);
1014     if (fastEncoding == FAST_UTF_8)
1015         return getStringUTF8(env, jstr);
1016 
1017     if ((*env)->EnsureLocalCapacity(env, 2) < 0)
1018         return 0;
1019 
1020     if (jnuEncodingSupported(env)) {
1021         hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding);
1022     } else {
1023         jmethodID mid;
1024         jclass strClazz = JNU_ClassString(env);
1025         CHECK_NULL_RETURN(strClazz, 0);
1026         mid = (*env)->GetMethodID(env, strClazz,
1027                                        "getBytes", "()[B");
1028         if (mid != NULL) {
1029             hab = (*env)->CallObjectMethod(env, jstr, mid);
1030         }
1031     }
1032 
1033     if (!(*env)->ExceptionCheck(env)) {
1034         jint len = (*env)->GetArrayLength(env, hab);
1035         result = MALLOC_MIN4(len);


< prev index next >