annotate src/share/native/common/jni_util.c @ 4338:9b8c96f96a0f

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