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