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