425 goto done;
426
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
523 for (i=0; i<len; i++) {
524 unsigned char c = (unsigned char)str[i];
556 jchar unicode = str[i];
557 if (unicode <= 0x007f )
558 result[i] = (char)unicode;
559 else
560 result[i] = '?';
561 }
562
563 result[len] = 0;
564 (*env)->ReleaseStringCritical(env, jstr, str);
565 return result;
566 }
567
568 /* enumeration of c1 row from Cp1252 */
569 static int cp1252c1chars[32] = {
570 0x20AC,0xFFFD,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
571 0x02C6,0x2030,0x0160,0x2039,0x0152,0xFFFD,0x017D,0xFFFD,
572 0xFFFD,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
573 0x02Dc,0x2122,0x0161,0x203A,0x0153,0xFFFD,0x017E,0x0178
574 };
575
576 /* Optimized for char set Cp1252 */
577 static jstring
578 newStringCp1252(JNIEnv *env, const char *str)
579 {
580 int len = (int) strlen(str);
581 jchar buf[512];
582 jchar *str1;
583 jstring result;
584 int i;
585 if (len > 512) {
586 str1 = (jchar *)malloc(len * sizeof(jchar));
587 if (str1 == 0) {
588 JNU_ThrowOutOfMemoryError(env, 0);
589 return 0;
590 }
591 } else
592 str1 = buf;
593
594 for (i=0; i<len; i++) {
595 unsigned char c = (unsigned char)str[i];
596 if ((c >= 0x80) && (c <= 0x9f))
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) {
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)
773 {
774 return JNU_NewStringPlatform(env, 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 */
815 jmethodID mid = (*env)->GetMethodID(env, strClazz,
816 "<init>", "([B)V");
817 if (mid != NULL) {
818 result = (*env)->NewObject(env, strClazz, mid, hab);
819 }
820 }
821 (*env)->DeleteLocalRef(env, hab);
822 return result;
823 }
824 return NULL;
825 }
826
827 JNIEXPORT const char *
828 GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
829 {
830 return JNU_GetStringPlatformChars(env, jstr, isCopy);
831 }
832
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);
873 if (result == 0) {
874 JNU_ThrowOutOfMemoryError(env, 0);
875 (*env)->DeleteLocalRef(env, hab);
876 return 0;
877 }
878 (*env)->GetByteArrayRegion(env, hab, 0, len, (jbyte *)result);
879 result[len] = 0; /* NULL-terminate */
880 }
881
882 (*env)->DeleteLocalRef(env, hab);
883 return result;
884 }
885
886 JNIEXPORT void JNICALL
887 JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str)
888 {
889 free((void *)str);
890 }
891
892 /*
893 * Export the platform dependent path canonicalization so that
894 * VM can find it when loading system classes.
895 * This function is also used by the instrumentation agent.
896 */
897 extern int canonicalize(char *path, const char *out, int len);
898
899 JNIEXPORT int
900 Canonicalize(JNIEnv *unused, char *orig, char *out, int len)
901 {
902 /* canonicalize an already natived path */
903 return canonicalize(orig, out, len);
904 }
905
|
425 goto done;
426
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 charset ISO_8559_1 */
446 static jstring
447 newSizedString8859_1(JNIEnv *env, const char *str, const 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 jbyte LATIN1 = 0;
479 static const jbyte UTF16 = 1;
480
481 static const char*
482 getString8859_1Chars(JNIEnv *env, jstring jstr)
483 {
484 int i;
485 char *result;
486 jint len = (*env)->GetStringLength(env, jstr);
487 const jchar *str = (*env)->GetStringCritical(env, jstr, 0);
488 if (str == 0) {
489 return 0;
490 }
491
492 result = MALLOC_MIN4(len);
493 if (result == 0) {
494 (*env)->ReleaseStringCritical(env, jstr, str);
495 JNU_ThrowOutOfMemoryError(env, 0);
496 return 0;
497 }
498
499 for (i=0; i<len; i++) {
500 jchar unicode = str[i];
501 if (unicode <= 0x00ff)
502 result[i] = (char)unicode;
503 else
504 result[i] = '?';
505 }
506
507 result[len] = 0;
508 (*env)->ReleaseStringCritical(env, jstr, str);
509 return result;
510 }
511
512
513 /* Optimized for charset ISO646-US (us-ascii) */
514 static jstring
515 newString646_US(JNIEnv *env, const char *str)
516 {
517 int len = (int)strlen(str);
518 jchar buf[512];
519 jchar *str1;
520 jstring result;
521 int i;
522
523 if (len > 512) {
524 str1 = (jchar *)malloc(len * sizeof(jchar));
525 if (str1 == 0) {
526 JNU_ThrowOutOfMemoryError(env, 0);
527 return 0;
528 }
529 } else
530 str1 = buf;
531
532 for (i=0; i<len; i++) {
533 unsigned char c = (unsigned char)str[i];
565 jchar unicode = str[i];
566 if (unicode <= 0x007f )
567 result[i] = (char)unicode;
568 else
569 result[i] = '?';
570 }
571
572 result[len] = 0;
573 (*env)->ReleaseStringCritical(env, jstr, str);
574 return result;
575 }
576
577 /* enumeration of c1 row from Cp1252 */
578 static int cp1252c1chars[32] = {
579 0x20AC,0xFFFD,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
580 0x02C6,0x2030,0x0160,0x2039,0x0152,0xFFFD,0x017D,0xFFFD,
581 0xFFFD,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
582 0x02Dc,0x2122,0x0161,0x203A,0x0153,0xFFFD,0x017E,0x0178
583 };
584
585 /* Optimized for charset Cp1252 */
586 static jstring
587 newStringCp1252(JNIEnv *env, const char *str)
588 {
589 int len = (int) strlen(str);
590 jchar buf[512];
591 jchar *str1;
592 jstring result;
593 int i;
594 if (len > 512) {
595 str1 = (jchar *)malloc(len * sizeof(jchar));
596 if (str1 == 0) {
597 JNU_ThrowOutOfMemoryError(env, 0);
598 return 0;
599 }
600 } else
601 str1 = buf;
602
603 for (i=0; i<len; i++) {
604 unsigned char c = (unsigned char)str[i];
605 if ((c >= 0x80) && (c <= 0x9f))
663 case 0x203A: result[i] = (char)0x9B; break;
664 case 0x0153: result[i] = (char)0x9C; break;
665 case 0x017E: result[i] = (char)0x9E; break;
666 case 0x0178: result[i] = (char)0x9F; break;
667 default: result[i] = '?'; break;
668 }
669 }
670
671 result[len] = 0;
672 (*env)->ReleaseStringCritical(env, jstr, str);
673 return result;
674 }
675
676 static int fastEncoding = NO_ENCODING_YET;
677 static jstring jnuEncoding = NULL;
678
679 /* Cached method IDs */
680 static jmethodID String_init_ID; /* String(byte[], enc) */
681 static jmethodID String_getBytes_ID; /* String.getBytes(enc) */
682
683 /* Cached field IDs */
684 static jfieldID String_coder_ID; /* String.coder */
685 static jfieldID String_value_ID; /* String.value */
686
687 static jboolean isJNUEncodingSupported = JNI_FALSE;
688 static jboolean jnuEncodingSupported(JNIEnv *env) {
689 jboolean exe;
690 if (isJNUEncodingSupported == JNI_TRUE) {
691 return JNI_TRUE;
692 }
693 isJNUEncodingSupported = (jboolean) JNU_CallStaticMethodByName (
694 env, &exe,
695 "java/nio/charset/Charset",
696 "isSupported",
697 "(Ljava/lang/String;)Z",
698 jnuEncoding).z;
699 return isJNUEncodingSupported;
700 }
701
702 /* Create a new string by converting str to a heap-allocated byte array and
703 * calling the appropriate String constructor.
704 */
705 static jstring
706 newSizedStringJava(JNIEnv *env, const char *str, const int len)
707 {
708 jstring result = NULL;
709 jbyteArray bytes = 0;
710
711 if ((*env)->EnsureLocalCapacity(env, 2) < 0)
712 return NULL;
713
714 bytes = (*env)->NewByteArray(env, len);
715 if (bytes != NULL) {
716 jclass strClazz = JNU_ClassString(env);
717 CHECK_NULL_RETURN(strClazz, 0);
718 (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *)str);
719 if (jnuEncodingSupported(env)) {
720 result = (*env)->NewObject(env, strClazz,
721 String_init_ID, bytes, jnuEncoding);
722 } else {
723 /*If the encoding specified in sun.jnu.encoding is not endorsed
724 by "Charset.isSupported" we have to fall back to use String(byte[])
725 explicitly here without specifying the encoding name, in which the
726 StringCoding class will pickup the iso-8859-1 as the fallback
727 converter for us.
728 */
729 jmethodID mid = (*env)->GetMethodID(env, strClazz,
730 "<init>", "([B)V");
731 if (mid != NULL) {
732 result = (*env)->NewObject(env, strClazz, mid, bytes);
733 }
734 }
735 (*env)->DeleteLocalRef(env, bytes);
736 return result;
737 }
738 return NULL;
739 }
740
741 static jstring
742 newStringJava(JNIEnv *env, const char *str)
743 {
744 int len = (int)strlen(str);
745 return newSizedStringJava(env, str, len);
746 }
747
748 /* Optimized for charset UTF-8 */
749 static jstring
750 newStringUTF8(JNIEnv *env, const char *str)
751 {
752 int len;
753 const unsigned char *p;
754 unsigned char asciiCheck;
755 for (asciiCheck = 0, p = (const unsigned char*)str; *p != '\0'; p++) {
756 asciiCheck |= *p;
757 }
758 len = (int)((const char*)p - str);
759
760 if (asciiCheck < 0x80) {
761 // ascii fast-path
762 return newSizedString8859_1(env, str, len);
763 }
764
765 return newSizedStringJava(env, str, len);
766 }
767
768 /* Initialize the fast encoding. If the "sun.jnu.encoding" property
769 * has not yet been set, we leave fastEncoding == NO_ENCODING_YET.
770 */
771 void
772 initializeEncoding(JNIEnv *env)
773 {
774 jstring propname = 0;
775 jstring enc = 0;
776 jclass strClazz = NULL;
777
778 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
779 return;
780
781 strClazz = JNU_ClassString(env);
782 CHECK_NULL(strClazz);
783
784 propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
785 if (propname) {
791 "getProperty",
792 "(Ljava/lang/String;)Ljava/lang/String;",
793 propname).l;
794 if (!exc) {
795 if (enc) {
796 const char* encname = (*env)->GetStringUTFChars(env, enc, 0);
797 if (encname) {
798 /*
799 * On Solaris with nl_langinfo() called in GetJavaProperties():
800 *
801 * locale undefined -> NULL -> hardcoded default
802 * "C" locale -> "" -> hardcoded default (on 2.6)
803 * "C" locale -> "ISO646-US" (on Sol 7/8)
804 * "en_US" locale -> "ISO8859-1"
805 * "en_GB" locale -> "ISO8859-1" (on Sol 7/8)
806 * "en_UK" locale -> "ISO8859-1" (on 2.6)
807 */
808 if ((strcmp(encname, "8859_1") == 0) ||
809 (strcmp(encname, "ISO8859-1") == 0) ||
810 (strcmp(encname, "ISO8859_1") == 0) ||
811 (strcmp(encname, "ISO-8859-1") == 0)) {
812 fastEncoding = FAST_8859_1;
813 } else if (strcmp(encname, "UTF-8") == 0) {
814 fastEncoding = FAST_UTF_8;
815 jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc);
816 } else if (strcmp(encname, "ISO646-US") == 0) {
817 fastEncoding = FAST_646_US;
818 } else if (strcmp(encname, "Cp1252") == 0 ||
819 /* This is a temporary fix until we move */
820 /* to wide character versions of all Windows */
821 /* calls. */
822 strcmp(encname, "utf-16le") == 0) {
823 fastEncoding = FAST_CP1252;
824 } else {
825 fastEncoding = NO_FAST_ENCODING;
826 jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc);
827 }
828 (*env)->ReleaseStringUTFChars(env, enc, encname);
829 }
830 }
831 } else {
832 (*env)->ExceptionClear(env);
833 }
834 } else {
835 (*env)->ExceptionClear(env);
836 }
837 (*env)->DeleteLocalRef(env, propname);
838 (*env)->DeleteLocalRef(env, enc);
839
840 /* Initialize method-id cache */
841 String_getBytes_ID = (*env)->GetMethodID(env, strClazz,
842 "getBytes", "(Ljava/lang/String;)[B");
843 CHECK_NULL(String_getBytes_ID);
844 String_init_ID = (*env)->GetMethodID(env, strClazz,
845 "<init>", "([BLjava/lang/String;)V");
846 String_coder_ID = (*env)->GetFieldID(env, strClazz, "coder", "B");
847 String_value_ID = (*env)->GetFieldID(env, strClazz, "value", "[B");
848 }
849
850 JNIEXPORT jstring
851 NewStringPlatform(JNIEnv *env, const char *str)
852 {
853 return JNU_NewStringPlatform(env, str);
854 }
855
856 JNIEXPORT jstring JNICALL
857 JNU_NewStringPlatform(JNIEnv *env, const char *str)
858 {
859 if (fastEncoding == NO_ENCODING_YET) {
860 initializeEncoding(env);
861 JNU_CHECK_EXCEPTION_RETURN(env, NULL);
862 }
863
864 if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
865 return newString8859_1(env, str);
866 if (fastEncoding == FAST_646_US)
867 return newString646_US(env, str);
868 if (fastEncoding == FAST_CP1252)
869 return newStringCp1252(env, str);
870 if (fastEncoding == FAST_UTF_8)
871 return newStringUTF8(env, str);
872 return newStringJava(env, str);
873 }
874
875 JNIEXPORT const char *
876 GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
877 {
878 return JNU_GetStringPlatformChars(env, jstr, isCopy);
879 }
880
881 static const char* getStringBytes(JNIEnv *env, jstring jstr) {
882 char *result = NULL;
883 jbyteArray hab = 0;
884
885 if ((*env)->EnsureLocalCapacity(env, 2) < 0)
886 return 0;
887
888 if (jnuEncodingSupported(env)) {
889 hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding);
890 } else {
891 jmethodID mid;
892 jclass strClazz = JNU_ClassString(env);
893 CHECK_NULL_RETURN(strClazz, 0);
894 mid = (*env)->GetMethodID(env, strClazz,
895 "getBytes", "()[B");
896 if (mid != NULL) {
897 hab = (*env)->CallObjectMethod(env, jstr, mid);
898 }
899 }
900
901 if (!(*env)->ExceptionCheck(env)) {
902 jint len = (*env)->GetArrayLength(env, hab);
903 result = MALLOC_MIN4(len);
904 if (result == 0) {
905 JNU_ThrowOutOfMemoryError(env, 0);
906 (*env)->DeleteLocalRef(env, hab);
907 return 0;
908 }
909 (*env)->GetByteArrayRegion(env, hab, 0, len, (jbyte *)result);
910 result[len] = 0; /* NULL-terminate */
911 }
912
913 (*env)->DeleteLocalRef(env, hab);
914 return result;
915 }
916
917 static const char*
918 getStringUTF8(JNIEnv *env, jstring jstr)
919 {
920 int i;
921 char *result;
922 jarray value;
923 jint len;
924 const jbyte *str;
925 jint rlen;
926 int ri;
927 jbyte coder = (*env)->GetByteField(env, jstr, String_coder_ID);
928 if (coder != LATIN1) {
929 return getStringBytes(env, jstr);
930 }
931 value = (jarray)(*env)->GetObjectField(env, jstr, String_value_ID);
932 len = (*env)->GetArrayLength(env, value);
933 str = (jbyte*)(*env)->GetPrimitiveArrayCritical(env, value, NULL);
934
935 if (str == NULL) {
936 return NULL;
937 }
938
939 rlen = len;
940 // we need two bytes for each latin-1 char above 127 (negative jbytes)
941 for (i = 0; i < len; i++) {
942 if (str[i] < 0) {
943 rlen++;
944 }
945 }
946
947 result = MALLOC_MIN4(rlen);
948 if (result == NULL) {
949 (*env)->ReleasePrimitiveArrayCritical(env, jstr, (void *)str, 0);
950 JNU_ThrowOutOfMemoryError(env, 0);
951 return NULL;
952 }
953
954 for (ri = 0, i = 0; i < len; i++) {
955 jbyte c = str[i];
956 if (c < 0) {
957 result[ri++] = (char)(0xc0 | ((c & 0xff) >> 6));
958 result[ri++] = (char)(0x80 | (c & 0x3f));
959 } else {
960 result[ri++] = c;
961 }
962 }
963 result[rlen] = '\0';
964 (*env)->ReleasePrimitiveArrayCritical(env, jstr, (void *)str, 0);
965 return result;
966 }
967
968 JNIEXPORT const char * JNICALL
969 JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
970 {
971
972 if (isCopy)
973 *isCopy = JNI_TRUE;
974
975 if (fastEncoding == NO_ENCODING_YET) {
976 initializeEncoding(env);
977 JNU_CHECK_EXCEPTION_RETURN(env, 0);
978 }
979
980 if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
981 return getString8859_1Chars(env, jstr);
982 if (fastEncoding == FAST_646_US)
983 return getString646_USChars(env, jstr);
984 if (fastEncoding == FAST_CP1252)
985 return getStringCp1252Chars(env, jstr);
986 if (fastEncoding == FAST_UTF_8)
987 return getStringUTF8(env, jstr);
988 else
989 return getStringBytes(env, jstr);
990 }
991 JNIEXPORT void JNICALL
992 JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str)
993 {
994 free((void *)str);
995 }
996
997 /*
998 * Export the platform dependent path canonicalization so that
999 * VM can find it when loading system classes.
1000 * This function is also used by the instrumentation agent.
1001 */
1002 extern int canonicalize(char *path, const char *out, int len);
1003
1004 JNIEXPORT int
1005 Canonicalize(JNIEnv *unused, char *orig, char *out, int len)
1006 {
1007 /* canonicalize an already natived path */
1008 return canonicalize(orig, out, len);
1009 }
1010
|