1 /* 2 * Copyright (c) 1997, 2010, 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 <stdlib.h> 27 #include <string.h> 28 #include <stdio.h> 29 30 #include "jvm.h" 31 #include "jni.h" 32 #include "jni_util.h" 33 34 /* Due to a bug in the win32 C runtime library strings 35 * such as "z:" need to be appended with a "." so we 36 * must allocate at least 4 bytes to allow room for 37 * this expansion. See 4235353 for details. 38 */ 39 #define MALLOC_MIN4(len) ((char *)malloc((len) + 1 < 4 ? 4 : (len) + 1)) 40 41 /** 42 * Throw a Java exception by name. Similar to SignalError. 43 */ 44 JNIEXPORT void JNICALL 45 JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg) 46 { 47 jclass cls = (*env)->FindClass(env, name); 48 49 if (cls != 0) /* Otherwise an exception has already been thrown */ 50 (*env)->ThrowNew(env, cls, msg); 51 } 52 53 /* JNU_Throw common exceptions */ 54 55 JNIEXPORT void JNICALL 56 JNU_ThrowNullPointerException(JNIEnv *env, const char *msg) 57 { 58 JNU_ThrowByName(env, "java/lang/NullPointerException", msg); 59 } 60 61 JNIEXPORT void JNICALL 62 JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv *env, const char *msg) 63 { 64 JNU_ThrowByName(env, "java/lang/ArrayIndexOutOfBoundsException", msg); 65 } 66 67 JNIEXPORT void JNICALL 68 JNU_ThrowOutOfMemoryError(JNIEnv *env, const char *msg) 69 { 70 JNU_ThrowByName(env, "java/lang/OutOfMemoryError", msg); 71 } 72 73 JNIEXPORT void JNICALL 74 JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg) 75 { 76 JNU_ThrowByName(env, "java/lang/IllegalArgumentException", msg); 77 } 78 79 JNIEXPORT void JNICALL 80 JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg) 81 { 82 JNU_ThrowByName(env, "java/lang/IllegalAccessError", msg); 83 } 84 85 JNIEXPORT void JNICALL 86 JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg) 87 { 88 JNU_ThrowByName(env, "java/lang/IllegalAccessException", msg); 89 } 90 91 JNIEXPORT void JNICALL 92 JNU_ThrowInternalError(JNIEnv *env, const char *msg) 93 { 94 JNU_ThrowByName(env, "java/lang/InternalError", msg); 95 } 96 97 JNIEXPORT void JNICALL 98 JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg) 99 { 100 JNU_ThrowByName(env, "java/lang/NoSuchFieldException", msg); 101 } 102 103 JNIEXPORT void JNICALL 104 JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg) 105 { 106 JNU_ThrowByName(env, "java/lang/NoSuchMethodException", msg); 107 } 108 109 JNIEXPORT void JNICALL 110 JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg) 111 { 112 JNU_ThrowByName(env, "java/lang/ClassNotFoundException", msg); 113 } 114 115 JNIEXPORT void JNICALL 116 JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg) 117 { 118 JNU_ThrowByName(env, "java/lang/NumberFormatException", msg); 119 } 120 121 JNIEXPORT void JNICALL 122 JNU_ThrowIOException(JNIEnv *env, const char *msg) 123 { 124 JNU_ThrowByName(env, "java/io/IOException", msg); 125 } 126 127 JNIEXPORT void JNICALL 128 JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg) 129 { 130 JNU_ThrowByName(env, "java/lang/NoSuchFieldError", msg); 131 } 132 133 JNIEXPORT void JNICALL 134 JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg) 135 { 136 JNU_ThrowByName(env, "java/lang/NoSuchMethodError", msg); 137 } 138 139 JNIEXPORT void JNICALL 140 JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg) 141 { 142 JNU_ThrowByName(env, "java/lang/StringIndexOutOfBoundsException", msg); 143 } 144 145 JNIEXPORT void JNICALL 146 JNU_ThrowInstantiationException(JNIEnv *env, const char *msg) 147 { 148 JNU_ThrowByName(env, "java/lang/InstantiationException", msg); 149 } 150 151 152 /* Throw an exception by name, using the string returned by 153 * JVM_LastErrorString for the detail string. If the last-error 154 * string is NULL, use the given default detail string. 155 */ 156 JNIEXPORT void JNICALL 157 JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name, 158 const char *defaultDetail) 159 { 160 char buf[256]; 161 int n = JVM_GetLastErrorString(buf, sizeof(buf)); 162 163 if (n > 0) { 164 jstring s = JNU_NewStringPlatform(env, buf); 165 if (s != NULL) { 166 jobject x = JNU_NewObjectByName(env, name, 167 "(Ljava/lang/String;)V", s); 168 if (x != NULL) { 169 (*env)->Throw(env, x); 170 } 171 } 172 } 173 if (!(*env)->ExceptionOccurred(env)) { 174 JNU_ThrowByName(env, name, defaultDetail); 175 } 176 } 177 178 /* Throw an IOException, using the last-error string for the detail 179 * string. If the last-error string is NULL, use the given default 180 * detail string. 181 */ 182 JNIEXPORT void JNICALL 183 JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail) 184 { 185 JNU_ThrowByNameWithLastError(env, "java/io/IOException", defaultDetail); 186 } 187 188 189 JNIEXPORT jvalue JNICALL 190 JNU_CallStaticMethodByName(JNIEnv *env, 191 jboolean *hasException, 192 const char *class_name, 193 const char *name, 194 const char *signature, 195 ...) 196 { 197 jclass clazz; 198 jmethodID mid; 199 va_list args; 200 jvalue result; 201 const char *p = signature; 202 203 /* find out the return type */ 204 while (*p && *p != ')') 205 p++; 206 p++; 207 208 result.i = 0; 209 210 if ((*env)->EnsureLocalCapacity(env, 3) < 0) 211 goto done2; 212 213 clazz = (*env)->FindClass(env, class_name); 214 if (clazz == 0) 215 goto done2; 216 mid = (*env)->GetStaticMethodID(env, clazz, name, signature); 217 if (mid == 0) 218 goto done1; 219 va_start(args, signature); 220 switch (*p) { 221 case 'V': 222 (*env)->CallStaticVoidMethodV(env, clazz, mid, args); 223 break; 224 case '[': 225 case 'L': 226 result.l = (*env)->CallStaticObjectMethodV(env, clazz, mid, args); 227 break; 228 case 'Z': 229 result.z = (*env)->CallStaticBooleanMethodV(env, clazz, mid, args); 230 break; 231 case 'B': 232 result.b = (*env)->CallStaticByteMethodV(env, clazz, mid, args); 233 break; 234 case 'C': 235 result.c = (*env)->CallStaticCharMethodV(env, clazz, mid, args); 236 break; 237 case 'S': 238 result.s = (*env)->CallStaticShortMethodV(env, clazz, mid, args); 239 break; 240 case 'I': 241 result.i = (*env)->CallStaticIntMethodV(env, clazz, mid, args); 242 break; 243 case 'J': 244 result.j = (*env)->CallStaticLongMethodV(env, clazz, mid, args); 245 break; 246 case 'F': 247 result.f = (*env)->CallStaticFloatMethodV(env, clazz, mid, args); 248 break; 249 case 'D': 250 result.d = (*env)->CallStaticDoubleMethodV(env, clazz, mid, args); 251 break; 252 default: 253 (*env)->FatalError(env, "JNU_CallStaticMethodByName: illegal signature"); 254 } 255 va_end(args); 256 257 done1: 258 (*env)->DeleteLocalRef(env, clazz); 259 done2: 260 if (hasException) { 261 *hasException = (*env)->ExceptionCheck(env); 262 } 263 return result; 264 } 265 266 JNIEXPORT jvalue JNICALL 267 JNU_CallMethodByName(JNIEnv *env, 268 jboolean *hasException, 269 jobject obj, 270 const char *name, 271 const char *signature, 272 ...) 273 { 274 jvalue result; 275 va_list args; 276 277 va_start(args, signature); 278 result = JNU_CallMethodByNameV(env, hasException, obj, name, signature, 279 args); 280 va_end(args); 281 282 return result; 283 } 284 285 286 JNIEXPORT jvalue JNICALL 287 JNU_CallMethodByNameV(JNIEnv *env, 288 jboolean *hasException, 289 jobject obj, 290 const char *name, 291 const char *signature, 292 va_list args) 293 { 294 jclass clazz; 295 jmethodID mid; 296 jvalue result; 297 const char *p = signature; 298 299 /* find out the return type */ 300 while (*p && *p != ')') 301 p++; 302 p++; 303 304 result.i = 0; 305 306 if ((*env)->EnsureLocalCapacity(env, 3) < 0) 307 goto done2; 308 309 clazz = (*env)->GetObjectClass(env, obj); 310 mid = (*env)->GetMethodID(env, clazz, name, signature); 311 if (mid == 0) 312 goto done1; 313 314 switch (*p) { 315 case 'V': 316 (*env)->CallVoidMethodV(env, obj, mid, args); 317 break; 318 case '[': 319 case 'L': 320 result.l = (*env)->CallObjectMethodV(env, obj, mid, args); 321 break; 322 case 'Z': 323 result.z = (*env)->CallBooleanMethodV(env, obj, mid, args); 324 break; 325 case 'B': 326 result.b = (*env)->CallByteMethodV(env, obj, mid, args); 327 break; 328 case 'C': 329 result.c = (*env)->CallCharMethodV(env, obj, mid, args); 330 break; 331 case 'S': 332 result.s = (*env)->CallShortMethodV(env, obj, mid, args); 333 break; 334 case 'I': 335 result.i = (*env)->CallIntMethodV(env, obj, mid, args); 336 break; 337 case 'J': 338 result.j = (*env)->CallLongMethodV(env, obj, mid, args); 339 break; 340 case 'F': 341 result.f = (*env)->CallFloatMethodV(env, obj, mid, args); 342 break; 343 case 'D': 344 result.d = (*env)->CallDoubleMethodV(env, obj, mid, args); 345 break; 346 default: 347 (*env)->FatalError(env, "JNU_CallMethodByNameV: illegal signature"); 348 } 349 done1: 350 (*env)->DeleteLocalRef(env, clazz); 351 done2: 352 if (hasException) { 353 *hasException = (*env)->ExceptionCheck(env); 354 } 355 return result; 356 } 357 358 JNIEXPORT jobject JNICALL 359 JNU_NewObjectByName(JNIEnv *env, const char *class_name, 360 const char *constructor_sig, ...) 361 { 362 jobject obj = NULL; 363 364 jclass cls = 0; 365 jmethodID cls_initMID; 366 va_list args; 367 368 if ((*env)->EnsureLocalCapacity(env, 2) < 0) 369 goto done; 370 371 cls = (*env)->FindClass(env, class_name); 372 if (cls == 0) { 373 goto done; 374 } 375 cls_initMID = (*env)->GetMethodID(env, cls, 376 "<init>", constructor_sig); 377 if (cls_initMID == NULL) { 378 goto done; 379 } 380 va_start(args, constructor_sig); 381 obj = (*env)->NewObjectV(env, cls, cls_initMID, args); 382 va_end(args); 383 384 done: 385 (*env)->DeleteLocalRef(env, cls); 386 return obj; 387 } 388 389 // Android removed: Deal solely in UTF-8 390 // 391 // /* Optimized for char set ISO_8559_1 */ 392 // static jstring 393 // newString8859_1(JNIEnv *env, const char *str) 394 // { 395 // int len = (int)strlen(str); 396 // jchar buf[512]; 397 // jchar *str1; 398 // jstring result; 399 // int i; 400 // 401 // if (len > 512) { 402 // str1 = (jchar *)malloc(len * sizeof(jchar)); 403 // if (str1 == 0) { 404 // JNU_ThrowOutOfMemoryError(env, 0); 405 // return 0; 406 // } 407 // } else 408 // str1 = buf; 409 // 410 // for (i=0;i<len;i++) 411 // str1[i] = (unsigned char)str[i]; 412 // result = (*env)->NewString(env, str1, len); 413 // if (str1 != buf) 414 // free(str1); 415 // return result; 416 // } 417 // 418 // static const char* 419 // getString8859_1Chars(JNIEnv *env, jstring jstr) 420 // { 421 // int i; 422 // char *result; 423 // jint len = (*env)->GetStringLength(env, jstr); 424 // const jchar *str = (*env)->GetStringCritical(env, jstr, 0); 425 // if (str == 0) { 426 // return 0; 427 // } 428 // 429 // result = MALLOC_MIN4(len); 430 // if (result == 0) { 431 // (*env)->ReleaseStringCritical(env, jstr, str); 432 // JNU_ThrowOutOfMemoryError(env, 0); 433 // return 0; 434 // } 435 // 436 // for (i=0; i<len; i++) { 437 // jchar unicode = str[i]; 438 // if (unicode <= 0x00ff) 439 // result[i] = (char)unicode; 440 // else 441 // result[i] = '?'; 442 // } 443 // 444 // result[len] = 0; 445 // (*env)->ReleaseStringCritical(env, jstr, str); 446 // return result; 447 // } 448 // 449 // 450 // /* Optimized for char set ISO646-US (us-ascii) */ 451 // static jstring 452 // newString646_US(JNIEnv *env, const char *str) 453 // { 454 // int len = strlen(str); 455 // jchar buf[512]; 456 // jchar *str1; 457 // jstring result; 458 // int i; 459 // 460 // if (len > 512) { 461 // str1 = (jchar *)malloc(len * sizeof(jchar)); 462 // if (str1 == 0) { 463 // JNU_ThrowOutOfMemoryError(env, 0); 464 // return 0; 465 // } 466 // } else 467 // str1 = buf; 468 // 469 // for (i=0; i<len; i++) { 470 // unsigned char c = (unsigned char)str[i]; 471 // if (c <= 0x7f) 472 // str1[i] = c; 473 // else 474 // str1[i] = '?'; 475 // } 476 // 477 // result = (*env)->NewString(env, str1, len); 478 // if (str1 != buf) 479 // free(str1); 480 // return result; 481 // } 482 // 483 // static const char* 484 // getString646_USChars(JNIEnv *env, jstring jstr) 485 // { 486 // int i; 487 // char *result; 488 // jint len = (*env)->GetStringLength(env, jstr); 489 // const jchar *str = (*env)->GetStringCritical(env, jstr, 0); 490 // if (str == 0) { 491 // return 0; 492 // } 493 // 494 // result = MALLOC_MIN4(len); 495 // if (result == 0) { 496 // (*env)->ReleaseStringCritical(env, jstr, str); 497 // JNU_ThrowOutOfMemoryError(env, 0); 498 // return 0; 499 // } 500 // 501 // for (i=0; i<len; i++) { 502 // jchar unicode = str[i]; 503 // if (unicode <= 0x007f ) 504 // result[i] = (char)unicode; 505 // else 506 // result[i] = '?'; 507 // } 508 // 509 // result[len] = 0; 510 // (*env)->ReleaseStringCritical(env, jstr, str); 511 // return result; 512 // } 513 // 514 // /* enumeration of c1 row from Cp1252 */ 515 // static int cp1252c1chars[32] = { 516 // 0x20AC,0xFFFD,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021, 517 // 0x02C6,0x2030,0x0160,0x2039,0x0152,0xFFFD,0x017D,0xFFFD, 518 // 0xFFFD,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 519 // 0x02Dc,0x2122,0x0161,0x203A,0x0153,0xFFFD,0x017E,0x0178 520 // }; 521 // 522 // /* Optimized for char set Cp1252 */ 523 // static jstring 524 // newStringCp1252(JNIEnv *env, const char *str) 525 // { 526 // int len = (int) strlen(str); 527 // jchar buf[512]; 528 // jchar *str1; 529 // jstring result; 530 // int i; 531 // if (len > 512) { 532 // str1 = (jchar *)malloc(len * sizeof(jchar)); 533 // if (str1 == 0) { 534 // JNU_ThrowOutOfMemoryError(env, 0); 535 // return 0; 536 // } 537 // } else 538 // str1 = buf; 539 // 540 // for (i=0; i<len; i++) { 541 // unsigned char c = (unsigned char)str[i]; 542 // if ((c >= 0x80) && (c <= 0x9f)) 543 // str1[i] = cp1252c1chars[c-128]; 544 // else 545 // str1[i] = c; 546 // } 547 // 548 // result = (*env)->NewString(env, str1, len); 549 // if (str1 != buf) 550 // free(str1); 551 // return result; 552 // } 553 // 554 // static const char* 555 // getStringCp1252Chars(JNIEnv *env, jstring jstr) 556 // { 557 // int i; 558 // char *result; 559 // jint len = (*env)->GetStringLength(env, jstr); 560 // const jchar *str = (*env)->GetStringCritical(env, jstr, 0); 561 // if (str == 0) { 562 // return 0; 563 // } 564 // 565 // result = MALLOC_MIN4(len); 566 // if (result == 0) { 567 // (*env)->ReleaseStringCritical(env, jstr, str); 568 // JNU_ThrowOutOfMemoryError(env, 0); 569 // return 0; 570 // } 571 // 572 // for (i=0; i<len; i++) { 573 // jchar c = str[i]; 574 // if (c < 256) 575 // result[i] = (char)c; 576 // else switch(c) { 577 // case 0x20AC: result[i] = (char)0x80; break; 578 // case 0x201A: result[i] = (char)0x82; break; 579 // case 0x0192: result[i] = (char)0x83; break; 580 // case 0x201E: result[i] = (char)0x84; break; 581 // case 0x2026: result[i] = (char)0x85; break; 582 // case 0x2020: result[i] = (char)0x86; break; 583 // case 0x2021: result[i] = (char)0x87; break; 584 // case 0x02C6: result[i] = (char)0x88; break; 585 // case 0x2030: result[i] = (char)0x89; break; 586 // case 0x0160: result[i] = (char)0x8A; break; 587 // case 0x2039: result[i] = (char)0x8B; break; 588 // case 0x0152: result[i] = (char)0x8C; break; 589 // case 0x017D: result[i] = (char)0x8E; break; 590 // case 0x2018: result[i] = (char)0x91; break; 591 // case 0x2019: result[i] = (char)0x92; break; 592 // case 0x201C: result[i] = (char)0x93; break; 593 // case 0x201D: result[i] = (char)0x94; break; 594 // case 0x2022: result[i] = (char)0x95; break; 595 // case 0x2013: result[i] = (char)0x96; break; 596 // case 0x2014: result[i] = (char)0x97; break; 597 // case 0x02DC: result[i] = (char)0x98; break; 598 // case 0x2122: result[i] = (char)0x99; break; 599 // case 0x0161: result[i] = (char)0x9A; break; 600 // case 0x203A: result[i] = (char)0x9B; break; 601 // case 0x0153: result[i] = (char)0x9C; break; 602 // case 0x017E: result[i] = (char)0x9E; break; 603 // case 0x0178: result[i] = (char)0x9F; break; 604 // default: result[i] = '?'; break; 605 // } 606 // } 607 // 608 // result[len] = 0; 609 // (*env)->ReleaseStringCritical(env, jstr, str); 610 // return result; 611 // } 612 // 613 // static int fastEncoding = NO_ENCODING_YET; 614 // static jstring jnuEncoding = NULL; 615 // 616 // /* Cached method IDs */ 617 // static jmethodID String_init_ID; /* String(byte[], enc) */ 618 // static jmethodID String_getBytes_ID; /* String.getBytes(enc) */ 619 // 620 // int getFastEncoding() { 621 // return fastEncoding; 622 // } 623 // 624 // /* Initialize the fast encoding. If the "sun.jnu.encoding" property 625 // * has not yet been set, we leave fastEncoding == NO_ENCODING_YET. 626 // */ 627 // void 628 // initializeEncoding(JNIEnv *env) 629 // { 630 // jstring propname = 0; 631 // jstring enc = 0; 632 // 633 // if ((*env)->EnsureLocalCapacity(env, 3) < 0) 634 // return; 635 // 636 // propname = (*env)->NewStringUTF(env, "sun.jnu.encoding"); 637 // if (propname) { 638 // jboolean exc; 639 // enc = JNU_CallStaticMethodByName 640 // (env, 641 // &exc, 642 // "java/lang/System", 643 // "getProperty", 644 // "(Ljava/lang/String;)Ljava/lang/String;", 645 // propname).l; 646 // if (!exc) { 647 // if (enc) { 648 // const char* encname = (*env)->GetStringUTFChars(env, enc, 0); 649 // if (encname) { 650 // /* 651 // * On Solaris with nl_langinfo() called in GetJavaProperties(): 652 // * 653 // * locale undefined -> NULL -> hardcoded default 654 // * "C" locale -> "" -> hardcoded default (on 2.6) 655 // * "C" locale -> "ISO646-US" (on Sol 7/8) 656 // * "en_US" locale -> "ISO8859-1" 657 // * "en_GB" locale -> "ISO8859-1" (on Sol 7/8) 658 // * "en_UK" locale -> "ISO8859-1" (on 2.6) 659 // */ 660 // if ((strcmp(encname, "8859_1") == 0) || 661 // (strcmp(encname, "ISO8859-1") == 0) || 662 // (strcmp(encname, "ISO8859_1") == 0)) 663 // fastEncoding = FAST_8859_1; 664 // else if (strcmp(encname, "ISO646-US") == 0) 665 // fastEncoding = FAST_646_US; 666 // else if (strcmp(encname, "Cp1252") == 0 || 667 // /* This is a temporary fix until we move */ 668 // /* to wide character versions of all Windows */ 669 // /* calls. */ 670 // strcmp(encname, "utf-16le") == 0) 671 // fastEncoding = FAST_CP1252; 672 // else { 673 // fastEncoding = NO_FAST_ENCODING; 674 // jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); 675 // } 676 // (*env)->ReleaseStringUTFChars(env, enc, encname); 677 // } 678 // } 679 // } else { 680 // (*env)->ExceptionClear(env); 681 // } 682 // } else { 683 // (*env)->ExceptionClear(env); 684 // } 685 // (*env)->DeleteLocalRef(env, propname); 686 // (*env)->DeleteLocalRef(env, enc); 687 // 688 // /* Initialize method-id cache */ 689 // String_getBytes_ID = (*env)->GetMethodID(env, JNU_ClassString(env), 690 // "getBytes", "(Ljava/lang/String;)[B"); 691 // String_init_ID = (*env)->GetMethodID(env, JNU_ClassString(env), 692 // "<init>", "([BLjava/lang/String;)V"); 693 // } 694 // 695 // static jboolean isJNUEncodingSupported = JNI_FALSE; 696 // static jboolean jnuEncodingSupported(JNIEnv *env) { 697 // jboolean exe; 698 // if (isJNUEncodingSupported == JNI_TRUE) { 699 // return JNI_TRUE; 700 // } 701 // isJNUEncodingSupported = (jboolean) JNU_CallStaticMethodByName ( 702 // env, &exe, 703 // "java/nio/charset/Charset", 704 // "isSupported", 705 // "(Ljava/lang/String;)Z", 706 // jnuEncoding).z; 707 // return isJNUEncodingSupported; 708 // } 709 710 711 JNIEXPORT jstring 712 JNU_NewStringPlatform(JNIEnv *env, const char *str) 713 { 714 // Android-changed: Always use nativeNewStringPlatform. 715 // return JNU_NewStringPlatform(env, str); 716 return nativeNewStringPlatform(env, str); 717 } 718 719 JNIEXPORT const char * 720 JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) 721 { 722 // Android-changed: Always use nativeGetStringPlatformChars. 723 // return JNU_GetStringPlatformChars(env, jstr, isCopy); 724 return nativeGetStringPlatformChars(env, jstr, isCopy); 725 } 726 727 JNIEXPORT void JNICALL 728 JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str) 729 { 730 // Android changed : Use the "native" code from the platform a chance 731 // to handle this first. 732 // 733 // free((void *)str); 734 nativeReleaseStringPlatformChars(env, jstr, str); 735 } 736 737 // Android removed: Deal solely in UTF-8 738 // 739 // JNIEXPORT jstring JNICALL 740 // JNU_NewStringPlatform(JNIEnv *env, const char *str) 741 // { 742 // jstring result; 743 // result = nativeNewStringPlatform(env, str); 744 // if (result == NULL) { 745 // jbyteArray hab = 0; 746 // int len; 747 // 748 // if (fastEncoding == NO_ENCODING_YET) 749 // initializeEncoding(env); 750 // 751 // if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET)) 752 // return newString8859_1(env, str); 753 // if (fastEncoding == FAST_646_US) 754 // return newString646_US(env, str); 755 // if (fastEncoding == FAST_CP1252) 756 // return newStringCp1252(env, str); 757 // 758 // if ((*env)->EnsureLocalCapacity(env, 2) < 0) 759 // return NULL; 760 // 761 // len = (int)strlen(str); 762 // hab = (*env)->NewByteArray(env, len); 763 // if (hab != 0) { 764 // (*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str); 765 // if (jnuEncodingSupported(env)) { 766 // result = (*env)->NewObject(env, JNU_ClassString(env), 767 // String_init_ID, hab, jnuEncoding); 768 // } else { 769 // /*If the encoding specified in sun.jnu.encoding is not endorsed 770 // by "Charset.isSupported" we have to fall back to use String(byte[]) 771 // explicitly here without specifying the encoding name, in which the 772 // StringCoding class will pickup the iso-8859-1 as the fallback 773 // converter for us. 774 // */ 775 // jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env), 776 // "<init>", "([B)V"); 777 // result = (*env)->NewObject(env, JNU_ClassString(env), mid, hab); 778 // } 779 // (*env)->DeleteLocalRef(env, hab); 780 // return result; 781 // } 782 // } 783 // return NULL; 784 //} 785 // 786 // 787 //JNIEXPORT const char * JNICALL 788 //JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) 789 //{ 790 // char *result = nativeGetStringPlatformChars(env, jstr, isCopy); 791 // if (result == NULL) { 792 // 793 // jbyteArray hab = 0; 794 // 795 // if (isCopy) 796 // *isCopy = JNI_TRUE; 797 // 798 // if (fastEncoding == NO_ENCODING_YET) 799 // initializeEncoding(env); 800 // 801 // if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET)) 802 // return getString8859_1Chars(env, jstr); 803 // if (fastEncoding == FAST_646_US) 804 // return getString646_USChars(env, jstr); 805 // if (fastEncoding == FAST_CP1252) 806 // return getStringCp1252Chars(env, jstr); 807 // 808 // if ((*env)->EnsureLocalCapacity(env, 2) < 0) 809 // return 0; 810 // 811 // if (jnuEncodingSupported(env)) { 812 // hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding); 813 // } else { 814 // jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env), 815 // "getBytes", "()[B"); 816 // hab = (*env)->CallObjectMethod(env, jstr, mid); 817 // } 818 // 819 // if (!(*env)->ExceptionCheck(env)) { 820 // jint len = (*env)->GetArrayLength(env, hab); 821 // result = MALLOC_MIN4(len); 822 // if (result == 0) { 823 // JNU_ThrowOutOfMemoryError(env, 0); 824 // (*env)->DeleteLocalRef(env, hab); 825 // return 0; 826 // } 827 // (*env)->GetByteArrayRegion(env, hab, 0, len, (jbyte *)result); 828 // result[len] = 0; /* NULL-terminate */ 829 // } 830 // 831 // (*env)->DeleteLocalRef(env, hab); 832 // } 833 // return result; 834 //} 835 836 837 /* 838 * Export the platform dependent path canonicalization so that 839 * VM can find it when loading system classes. 840 * 841 */ 842 extern int canonicalize(char *path, const char *out, int len); 843 844 JNIEXPORT int 845 Canonicalize(JNIEnv *env, char *orig, char *out, int len) 846 { 847 /* canonicalize an already natived path */ 848 return canonicalize(orig, out, len); 849 } 850 851 JNIEXPORT jclass JNICALL 852 JNU_ClassString(JNIEnv *env) 853 { 854 static jclass cls = 0; 855 if (cls == 0) { 856 jclass c; 857 if ((*env)->EnsureLocalCapacity(env, 1) < 0) 858 return 0; 859 c = (*env)->FindClass(env, "java/lang/String"); 860 cls = (*env)->NewGlobalRef(env, c); 861 (*env)->DeleteLocalRef(env, c); 862 } 863 return cls; 864 } 865 866 JNIEXPORT jclass JNICALL 867 JNU_ClassClass(JNIEnv *env) 868 { 869 static jclass cls = 0; 870 if (cls == 0) { 871 jclass c; 872 if ((*env)->EnsureLocalCapacity(env, 1) < 0) 873 return 0; 874 c = (*env)->FindClass(env, "java/lang/Class"); 875 cls = (*env)->NewGlobalRef(env, c); 876 (*env)->DeleteLocalRef(env, c); 877 } 878 return cls; 879 } 880 881 JNIEXPORT jclass JNICALL 882 JNU_ClassObject(JNIEnv *env) 883 { 884 static jclass cls = 0; 885 if (cls == 0) { 886 jclass c; 887 if ((*env)->EnsureLocalCapacity(env, 1) < 0) 888 return 0; 889 c = (*env)->FindClass(env, "java/lang/Object"); 890 cls = (*env)->NewGlobalRef(env, c); 891 (*env)->DeleteLocalRef(env, c); 892 } 893 return cls; 894 } 895 896 JNIEXPORT jclass JNICALL 897 JNU_ClassThrowable(JNIEnv *env) 898 { 899 static jclass cls = 0; 900 if (cls == 0) { 901 jclass c; 902 if ((*env)->EnsureLocalCapacity(env, 1) < 0) 903 return 0; 904 c = (*env)->FindClass(env, "java/lang/Throwable"); 905 cls = (*env)->NewGlobalRef(env, c); 906 (*env)->DeleteLocalRef(env, c); 907 } 908 return cls; 909 } 910 911 JNIEXPORT jint JNICALL 912 JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src, 913 jint count) 914 { 915 int i; 916 if ((*env)->EnsureLocalCapacity(env, 1) < 0) 917 return -1; 918 for (i=0; i<count; i++) { 919 jstring p = (*env)->GetObjectArrayElement(env, src, i); 920 (*env)->SetObjectArrayElement(env, dst, i, p); 921 (*env)->DeleteLocalRef(env, p); 922 } 923 return 0; 924 } 925 926 JNIEXPORT void * JNICALL 927 JNU_GetEnv(JavaVM *vm, jint version) 928 { 929 void *env; 930 (*vm)->GetEnv(vm, &env, version); 931 return env; 932 } 933 934 JNIEXPORT jint JNICALL 935 JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char* classname) 936 { 937 jclass cls; 938 if ((*env)->EnsureLocalCapacity(env, 1) < 0) 939 return JNI_ERR; 940 cls = (*env)->FindClass(env, classname); 941 if (cls != NULL) { 942 jint result = (*env)->IsInstanceOf(env, object, cls); 943 (*env)->DeleteLocalRef(env, cls); 944 return result; 945 } 946 return JNI_ERR; 947 } 948 949 JNIEXPORT jboolean JNICALL 950 JNU_Equals(JNIEnv *env, jobject object1, jobject object2) 951 { 952 static jmethodID mid = NULL; 953 if (mid == NULL) { 954 mid = (*env)->GetMethodID(env, JNU_ClassObject(env), "equals", 955 "(Ljava/lang/Object;)Z"); 956 } 957 return (*env)->CallBooleanMethod(env, object1, mid, object2); 958 } 959 960 961 /************************************************************************ 962 * Thread calls 963 */ 964 965 static jmethodID Object_waitMID; 966 static jmethodID Object_notifyMID; 967 static jmethodID Object_notifyAllMID; 968 969 JNIEXPORT void JNICALL 970 JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout) 971 { 972 if (object == NULL) { 973 JNU_ThrowNullPointerException(env, "JNU_MonitorWait argument"); 974 return; 975 } 976 if (Object_waitMID == NULL) { 977 jclass cls = JNU_ClassObject(env); 978 if (cls == NULL) { 979 return; 980 } 981 Object_waitMID = (*env)->GetMethodID(env, cls, "wait", "(J)V"); 982 if (Object_waitMID == NULL) { 983 return; 984 } 985 } 986 (*env)->CallVoidMethod(env, object, Object_waitMID, timeout); 987 } 988 989 JNIEXPORT void JNICALL 990 JNU_Notify(JNIEnv *env, jobject object) 991 { 992 if (object == NULL) { 993 JNU_ThrowNullPointerException(env, "JNU_Notify argument"); 994 return; 995 } 996 if (Object_notifyMID == NULL) { 997 jclass cls = JNU_ClassObject(env); 998 if (cls == NULL) { 999 return; 1000 } 1001 Object_notifyMID = (*env)->GetMethodID(env, cls, "notify", "()V"); 1002 if (Object_notifyMID == NULL) { 1003 return; 1004 } 1005 } 1006 (*env)->CallVoidMethod(env, object, Object_notifyMID); 1007 } 1008 1009 JNIEXPORT void JNICALL 1010 JNU_NotifyAll(JNIEnv *env, jobject object) 1011 { 1012 if (object == NULL) { 1013 JNU_ThrowNullPointerException(env, "JNU_NotifyAll argument"); 1014 return; 1015 } 1016 if (Object_notifyAllMID == NULL) { 1017 jclass cls = JNU_ClassObject(env); 1018 if (cls == NULL) { 1019 return; 1020 } 1021 Object_notifyAllMID = (*env)->GetMethodID(env, cls,"notifyAll", "()V"); 1022 if (Object_notifyAllMID == NULL) { 1023 return; 1024 } 1025 } 1026 (*env)->CallVoidMethod(env, object, Object_notifyAllMID); 1027 } 1028 1029 1030 /************************************************************************ 1031 * Debugging utilities 1032 */ 1033 1034 JNIEXPORT void JNICALL 1035 JNU_PrintString(JNIEnv *env, char *hdr, jstring string) 1036 { 1037 if (string == NULL) { 1038 fprintf(stderr, "%s: is NULL\n", hdr); 1039 } else { 1040 const char *stringPtr = JNU_GetStringPlatformChars(env, string, 0); 1041 if (stringPtr == 0) 1042 return; 1043 fprintf(stderr, "%s: %s\n", hdr, stringPtr); 1044 JNU_ReleaseStringPlatformChars(env, string, stringPtr); 1045 } 1046 } 1047 1048 JNIEXPORT void JNICALL 1049 JNU_PrintClass(JNIEnv *env, char* hdr, jobject object) 1050 { 1051 if (object == NULL) { 1052 fprintf(stderr, "%s: object is NULL\n", hdr); 1053 return; 1054 } else { 1055 jclass cls = (*env)->GetObjectClass(env, object); 1056 jstring clsName = JNU_ToString(env, cls); 1057 JNU_PrintString(env, hdr, clsName); 1058 (*env)->DeleteLocalRef(env, cls); 1059 (*env)->DeleteLocalRef(env, clsName); 1060 } 1061 } 1062 1063 JNIEXPORT jstring JNICALL 1064 JNU_ToString(JNIEnv *env, jobject object) 1065 { 1066 if (object == NULL) { 1067 return (*env)->NewStringUTF(env, "NULL"); 1068 } else { 1069 return (jstring)JNU_CallMethodByName(env, 1070 NULL, 1071 object, 1072 "toString", 1073 "()Ljava/lang/String;").l; 1074 } 1075 } 1076 1077 JNIEXPORT jvalue JNICALL 1078 JNU_GetFieldByName(JNIEnv *env, 1079 jboolean *hasException, 1080 jobject obj, 1081 const char *name, 1082 const char *signature) 1083 { 1084 jclass cls; 1085 jfieldID fid; 1086 jvalue result; 1087 1088 result.i = 0; 1089 1090 if ((*env)->EnsureLocalCapacity(env, 3) < 0) 1091 goto done2; 1092 1093 cls = (*env)->GetObjectClass(env, obj); 1094 fid = (*env)->GetFieldID(env, cls, name, signature); 1095 if (fid == 0) 1096 goto done1; 1097 1098 switch (*signature) { 1099 case '[': 1100 case 'L': 1101 result.l = (*env)->GetObjectField(env, obj, fid); 1102 break; 1103 case 'Z': 1104 result.z = (*env)->GetBooleanField(env, obj, fid); 1105 break; 1106 case 'B': 1107 result.b = (*env)->GetByteField(env, obj, fid); 1108 break; 1109 case 'C': 1110 result.c = (*env)->GetCharField(env, obj, fid); 1111 break; 1112 case 'S': 1113 result.s = (*env)->GetShortField(env, obj, fid); 1114 break; 1115 case 'I': 1116 result.i = (*env)->GetIntField(env, obj, fid); 1117 break; 1118 case 'J': 1119 result.j = (*env)->GetLongField(env, obj, fid); 1120 break; 1121 case 'F': 1122 result.f = (*env)->GetFloatField(env, obj, fid); 1123 break; 1124 case 'D': 1125 result.d = (*env)->GetDoubleField(env, obj, fid); 1126 break; 1127 1128 default: 1129 (*env)->FatalError(env, "JNU_GetFieldByName: illegal signature"); 1130 } 1131 1132 done1: 1133 (*env)->DeleteLocalRef(env, cls); 1134 done2: 1135 if (hasException) { 1136 *hasException = (*env)->ExceptionCheck(env); 1137 } 1138 return result; 1139 } 1140 1141 JNIEXPORT void JNICALL 1142 JNU_SetFieldByName(JNIEnv *env, 1143 jboolean *hasException, 1144 jobject obj, 1145 const char *name, 1146 const char *signature, 1147 ...) 1148 { 1149 jclass cls; 1150 jfieldID fid; 1151 va_list args; 1152 1153 if ((*env)->EnsureLocalCapacity(env, 3) < 0) 1154 goto done2; 1155 1156 cls = (*env)->GetObjectClass(env, obj); 1157 fid = (*env)->GetFieldID(env, cls, name, signature); 1158 if (fid == 0) 1159 goto done1; 1160 1161 va_start(args, signature); 1162 switch (*signature) { 1163 case '[': 1164 case 'L': 1165 (*env)->SetObjectField(env, obj, fid, va_arg(args, jobject)); 1166 break; 1167 case 'Z': 1168 (*env)->SetBooleanField(env, obj, fid, (jboolean)va_arg(args, int)); 1169 break; 1170 case 'B': 1171 (*env)->SetByteField(env, obj, fid, (jbyte)va_arg(args, int)); 1172 break; 1173 case 'C': 1174 (*env)->SetCharField(env, obj, fid, (jchar)va_arg(args, int)); 1175 break; 1176 case 'S': 1177 (*env)->SetShortField(env, obj, fid, (jshort)va_arg(args, int)); 1178 break; 1179 case 'I': 1180 (*env)->SetIntField(env, obj, fid, va_arg(args, jint)); 1181 break; 1182 case 'J': 1183 (*env)->SetLongField(env, obj, fid, va_arg(args, jlong)); 1184 break; 1185 case 'F': 1186 (*env)->SetFloatField(env, obj, fid, (jfloat)va_arg(args, jdouble)); 1187 break; 1188 case 'D': 1189 (*env)->SetDoubleField(env, obj, fid, va_arg(args, jdouble)); 1190 break; 1191 1192 default: 1193 (*env)->FatalError(env, "JNU_SetFieldByName: illegal signature"); 1194 } 1195 va_end(args); 1196 1197 done1: 1198 (*env)->DeleteLocalRef(env, cls); 1199 done2: 1200 if (hasException) { 1201 *hasException = (*env)->ExceptionCheck(env); 1202 } 1203 } 1204 1205 JNIEXPORT jvalue JNICALL 1206 JNU_GetStaticFieldByName(JNIEnv *env, 1207 jboolean *hasException, 1208 const char *classname, 1209 const char *name, 1210 const char *signature) 1211 { 1212 jclass cls; 1213 jfieldID fid; 1214 jvalue result; 1215 1216 result.i = 0; 1217 1218 if ((*env)->EnsureLocalCapacity(env, 3) < 0) 1219 goto done2; 1220 1221 cls = (*env)->FindClass(env, classname); 1222 if (cls == 0) 1223 goto done2; 1224 1225 fid = (*env)->GetStaticFieldID(env, cls, name, signature); 1226 if (fid == 0) 1227 goto done1; 1228 1229 switch (*signature) { 1230 case '[': 1231 case 'L': 1232 result.l = (*env)->GetStaticObjectField(env, cls, fid); 1233 break; 1234 case 'Z': 1235 result.z = (*env)->GetStaticBooleanField(env, cls, fid); 1236 break; 1237 case 'B': 1238 result.b = (*env)->GetStaticByteField(env, cls, fid); 1239 break; 1240 case 'C': 1241 result.c = (*env)->GetStaticCharField(env, cls, fid); 1242 break; 1243 case 'S': 1244 result.s = (*env)->GetStaticShortField(env, cls, fid); 1245 break; 1246 case 'I': 1247 result.i = (*env)->GetStaticIntField(env, cls, fid); 1248 break; 1249 case 'J': 1250 result.j = (*env)->GetStaticLongField(env, cls, fid); 1251 break; 1252 case 'F': 1253 result.f = (*env)->GetStaticFloatField(env, cls, fid); 1254 break; 1255 case 'D': 1256 result.d = (*env)->GetStaticDoubleField(env, cls, fid); 1257 break; 1258 1259 default: 1260 (*env)->FatalError(env, "JNU_GetStaticFieldByName: illegal signature"); 1261 } 1262 1263 done1: 1264 (*env)->DeleteLocalRef(env, cls); 1265 done2: 1266 if (hasException) { 1267 *hasException = (*env)->ExceptionCheck(env); 1268 } 1269 return result; 1270 } 1271 1272 JNIEXPORT void JNICALL 1273 JNU_SetStaticFieldByName(JNIEnv *env, 1274 jboolean *hasException, 1275 const char *classname, 1276 const char *name, 1277 const char *signature, 1278 ...) 1279 { 1280 jclass cls; 1281 jfieldID fid; 1282 va_list args; 1283 1284 if ((*env)->EnsureLocalCapacity(env, 3) < 0) 1285 goto done2; 1286 1287 cls = (*env)->FindClass(env, classname); 1288 if (cls == 0) 1289 goto done2; 1290 1291 fid = (*env)->GetStaticFieldID(env, cls, name, signature); 1292 if (fid == 0) 1293 goto done1; 1294 1295 va_start(args, signature); 1296 switch (*signature) { 1297 case '[': 1298 case 'L': 1299 (*env)->SetStaticObjectField(env, cls, fid, va_arg(args, jobject)); 1300 break; 1301 case 'Z': 1302 (*env)->SetStaticBooleanField(env, cls, fid, (jboolean)va_arg(args, int)); 1303 break; 1304 case 'B': 1305 (*env)->SetStaticByteField(env, cls, fid, (jbyte)va_arg(args, int)); 1306 break; 1307 case 'C': 1308 (*env)->SetStaticCharField(env, cls, fid, (jchar)va_arg(args, int)); 1309 break; 1310 case 'S': 1311 (*env)->SetStaticShortField(env, cls, fid, (jshort)va_arg(args, int)); 1312 break; 1313 case 'I': 1314 (*env)->SetStaticIntField(env, cls, fid, va_arg(args, jint)); 1315 break; 1316 case 'J': 1317 (*env)->SetStaticLongField(env, cls, fid, va_arg(args, jlong)); 1318 break; 1319 case 'F': 1320 (*env)->SetStaticFloatField(env, cls, fid, (jfloat)va_arg(args, jdouble)); 1321 break; 1322 case 'D': 1323 (*env)->SetStaticDoubleField(env, cls, fid, va_arg(args, jdouble)); 1324 break; 1325 1326 default: 1327 (*env)->FatalError(env, "JNU_SetStaticFieldByName: illegal signature"); 1328 } 1329 va_end(args); 1330 1331 done1: 1332 (*env)->DeleteLocalRef(env, cls); 1333 done2: 1334 if (hasException) { 1335 *hasException = (*env)->ExceptionCheck(env); 1336 } 1337 } 1338