@@ -630,11 +630,11 @@ getStringCp1252Chars(JNIEnv *env, jstring jstr)
630
630
}
631
631
632
632
static int fastEncoding = NO_ENCODING_YET ;
633
- static jstring jnuEncoding = NULL ;
633
+ static jobject jnuCharset = NULL ;
634
634
635
635
/* Cached method IDs */
636
- static jmethodID String_init_ID ; /* String(byte[], enc ) */
637
- static jmethodID String_getBytes_ID ; /* String.getBytes(enc ) */
636
+ static jmethodID String_init_ID ; /* String(byte[], Charset ) */
637
+ static jmethodID String_getBytes_ID ; /* String.getBytes(Charset ) */
638
638
639
639
/* Cached field IDs */
640
640
static jfieldID String_coder_ID ; /* String.coder */
@@ -658,7 +658,7 @@ newSizedStringJava(JNIEnv *env, const char *str, const int len)
658
658
CHECK_NULL_RETURN (strClazz , 0 );
659
659
(* env )-> SetByteArrayRegion (env , bytes , 0 , len , (jbyte * )str );
660
660
result = (* env )-> NewObject (env , strClazz ,
661
- String_init_ID , bytes , jnuEncoding );
661
+ String_init_ID , bytes , jnuCharset );
662
662
(* env )-> DeleteLocalRef (env , bytes );
663
663
return result ;
664
664
}
@@ -717,18 +717,15 @@ InitializeEncoding(JNIEnv *env, const char *encname)
717
717
* "en_GB" locale -> "ISO8859-1" (on Sol 7/8)
718
718
* "en_UK" locale -> "ISO8859-1" (on 2.6)
719
719
*/
720
+ const char * charsetname = NULL ;
720
721
if ((strcmp (encname , "8859_1" ) == 0 ) ||
721
722
(strcmp (encname , "ISO8859-1" ) == 0 ) ||
722
723
(strcmp (encname , "ISO8859_1" ) == 0 ) ||
723
724
(strcmp (encname , "ISO-8859-1" ) == 0 )) {
724
725
fastEncoding = FAST_8859_1 ;
725
726
} else if (strcmp (encname , "UTF-8" ) == 0 ) {
726
- jstring enc = (* env )-> NewStringUTF (env , encname );
727
- if (enc == NULL )
728
- return ;
727
+ charsetname = encname ;
729
728
fastEncoding = FAST_UTF_8 ;
730
- jnuEncoding = (jstring )(* env )-> NewGlobalRef (env , enc );
731
- (* env )-> DeleteLocalRef (env , enc );
732
729
} else if (strcmp (encname , "ISO646-US" ) == 0 ) {
733
730
fastEncoding = FAST_646_US ;
734
731
} else if (strcmp (encname , "Cp1252" ) == 0 ||
@@ -738,31 +735,38 @@ InitializeEncoding(JNIEnv *env, const char *encname)
738
735
strcmp (encname , "utf-16le" ) == 0 ) {
739
736
fastEncoding = FAST_CP1252 ;
740
737
} else {
741
- jboolean exe ;
742
- jstring enc = (* env )-> NewStringUTF (env , encname );
743
- if (enc == NULL )
738
+ charsetname = encname ;
739
+ fastEncoding = NO_FAST_ENCODING ;
740
+ }
741
+ while (charsetname != NULL ) {
742
+ jstring enc = (* env )-> NewStringUTF (env , charsetname );
743
+ if (enc == NULL ) {
744
+ fastEncoding = NO_ENCODING_YET ;
744
745
return ;
746
+ }
747
+ jboolean exc ;
748
+ jvalue charset = JNU_CallStaticMethodByName (
749
+ env , & exc ,
750
+ "java/nio/charset/Charset" ,
751
+ "forName" ,
752
+ "(Ljava/lang/String;)Ljava/nio/charset/Charset;" ,
753
+ enc );
754
+ if (exc ) {
755
+ (* env )-> ExceptionClear (env );
756
+ }
757
+ (* env )-> DeleteLocalRef (env , enc );
745
758
746
- if ((jboolean ) JNU_CallStaticMethodByName (
747
- env , & exe ,
748
- "java/nio/charset/Charset" ,
749
- "isSupported" ,
750
- "(Ljava/lang/String;)Z" ,
751
- enc ).z == JNI_TRUE ) {
752
- fastEncoding = NO_FAST_ENCODING ;
753
- jnuEncoding = (jstring )(* env )-> NewGlobalRef (env , enc );
754
- } else {
755
- // jnuEncoding falls back to UTF-8
756
- jstring utf8 = (* env )-> NewStringUTF (env , "UTF-8" );
757
- if (utf8 == NULL ) {
758
- (* env )-> DeleteLocalRef (env , enc );
759
- return ;
760
- }
759
+ if (!exc && charset .l != NULL ) {
760
+ jnuCharset = (* env )-> NewGlobalRef (env , charset .l );
761
+ (* env )-> DeleteLocalRef (env , charset .l );
762
+ break ; // success, continue below
763
+ } else if (strcmp (charsetname , "UTF-8" ) != 0 ) { // fall back
764
+ charsetname = "UTF-8" ;
761
765
fastEncoding = FAST_UTF_8 ;
762
- jnuEncoding = (jstring )(* env )-> NewGlobalRef (env , utf8 );
763
- (* env )-> DeleteLocalRef (env , utf8 );
766
+ } else { // give up
767
+ fastEncoding = NO_ENCODING_YET ;
768
+ return ;
764
769
}
765
- (* env )-> DeleteLocalRef (env , enc );
766
770
}
767
771
} else {
768
772
JNU_ThrowInternalError (env , "platform encoding undefined" );
@@ -771,10 +775,10 @@ InitializeEncoding(JNIEnv *env, const char *encname)
771
775
772
776
/* Initialize method-id cache */
773
777
String_getBytes_ID = (* env )-> GetMethodID (env , strClazz ,
774
- "getBytes" , "(Ljava/lang/String ;)[B" );
778
+ "getBytes" , "(Ljava/nio/charset/Charset ;)[B" );
775
779
CHECK_NULL (String_getBytes_ID );
776
780
String_init_ID = (* env )-> GetMethodID (env , strClazz ,
777
- "<init>" , "([BLjava/lang/String ;)V" );
781
+ "<init>" , "([BLjava/nio/charset/Charset ;)V" );
778
782
CHECK_NULL (String_init_ID );
779
783
String_coder_ID = (* env )-> GetFieldID (env , strClazz , "coder" , "B" );
780
784
CHECK_NULL (String_coder_ID );
@@ -813,7 +817,7 @@ static const char* getStringBytes(JNIEnv *env, jstring jstr) {
813
817
if ((* env )-> EnsureLocalCapacity (env , 2 ) < 0 )
814
818
return 0 ;
815
819
816
- hab = (* env )-> CallObjectMethod (env , jstr , String_getBytes_ID , jnuEncoding );
820
+ hab = (* env )-> CallObjectMethod (env , jstr , String_getBytes_ID , jnuCharset );
817
821
if (hab != 0 ) {
818
822
if (!(* env )-> ExceptionCheck (env )) {
819
823
jint len = (* env )-> GetArrayLength (env , hab );
0 commit comments