Skip to content

Commit a2a40f7

Browse files
committed
handle primitive array return types
1 parent 6e7709e commit a2a40f7

5 files changed

Lines changed: 190 additions & 8 deletions

File tree

src/utils.cpp

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -373,23 +373,103 @@ v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, const std::string& alternat
373373
return scope.Close(javaExceptionToV8(env, ex, alternateMessage));
374374
}
375375

376+
jvalueType javaGetArrayComponentType(JNIEnv *env, jobjectArray array) {
377+
jclass objectClazz = env->FindClass("java/lang/Object");
378+
jclass clazzclazz = env->FindClass("java/lang/Class");
379+
380+
jmethodID object_getClass = env->GetMethodID(objectClazz, "getClass", "()Ljava/lang/Class;");
381+
jobject arrayClass = env->CallObjectMethod(array, object_getClass);
382+
383+
jmethodID class_getComponentType = env->GetMethodID(clazzclazz, "getComponentType", "()Ljava/lang/Class;");
384+
jobject arrayComponentTypeClass = env->CallObjectMethod(arrayClass, class_getComponentType);
385+
386+
jvalueType arrayComponentType = javaGetType(env, (jclass)arrayComponentTypeClass);
387+
return arrayComponentType;
388+
}
389+
376390
v8::Handle<v8::Value> javaArrayToV8(Java* java, JNIEnv* env, jobjectArray objArray) {
377391
v8::HandleScope scope;
378392

379393
if(objArray == NULL) {
380394
return v8::Null();
381395
}
382396

383-
//printf("javaArrayToV8: %d %s\n", javaObjectToString(env, objArray).c_str());
397+
jvalueType arrayComponentType = javaGetArrayComponentType(env, objArray);
398+
//printf("javaArrayToV8: %d %s\n", arrayComponentType, javaObjectToString(env, objArray).c_str());
384399

385400
jsize arraySize = env->GetArrayLength(objArray);
386401
//printf("array size: %d\n", arraySize);
387402

388403
v8::Handle<v8::Array> result = v8::Array::New(arraySize);
389-
for(jsize i=0; i<arraySize; i++) {
390-
jobject obj = env->GetObjectArrayElement(objArray, i);
391-
v8::Handle<v8::Value> item = javaToV8(java, env, obj);
392-
result->Set(i, item);
404+
switch(arrayComponentType) {
405+
case TYPE_INT:
406+
{
407+
jint* elems = env->GetIntArrayElements((jintArray)objArray, 0);
408+
for(jsize i=0; i<arraySize; i++) {
409+
result->Set(i, v8::Integer::New(elems[i]));
410+
}
411+
env->ReleaseIntArrayElements((jintArray)objArray, elems, 0);
412+
}
413+
break;
414+
415+
case TYPE_BYTE:
416+
{
417+
jbyte* elems = env->GetByteArrayElements((jbyteArray)objArray, 0);
418+
for(jsize i=0; i<arraySize; i++) {
419+
result->Set(i, v8::Number::New(elems[i]));
420+
}
421+
env->ReleaseByteArrayElements((jbyteArray)objArray, elems, 0);
422+
}
423+
break;
424+
425+
case TYPE_BOOLEAN:
426+
{
427+
jboolean* elems = env->GetBooleanArrayElements((jbooleanArray)objArray, 0);
428+
for(jsize i=0; i<arraySize; i++) {
429+
result->Set(i, v8::Boolean::New(elems[i]));
430+
}
431+
env->ReleaseBooleanArrayElements((jbooleanArray)objArray, elems, 0);
432+
}
433+
break;
434+
435+
case TYPE_DOUBLE:
436+
{
437+
jdouble* elems = env->GetDoubleArrayElements((jdoubleArray)objArray, 0);
438+
for(jsize i=0; i<arraySize; i++) {
439+
result->Set(i, v8::Number::New(elems[i]));
440+
}
441+
env->ReleaseDoubleArrayElements((jdoubleArray)objArray, elems, 0);
442+
}
443+
break;
444+
445+
case TYPE_FLOAT:
446+
{
447+
jfloat* elems = env->GetFloatArrayElements((jfloatArray)objArray, 0);
448+
for(jsize i=0; i<arraySize; i++) {
449+
result->Set(i, v8::Number::New(elems[i]));
450+
}
451+
env->ReleaseFloatArrayElements((jfloatArray)objArray, elems, 0);
452+
}
453+
break;
454+
455+
case TYPE_LONG:
456+
{
457+
jlong* elems = env->GetLongArrayElements((jlongArray)objArray, 0);
458+
for(jsize i=0; i<arraySize; i++) {
459+
jobject obj = longToJavaLongObj(env, elems[i]);
460+
result->Set(i, JavaObject::New(java, obj));
461+
}
462+
env->ReleaseLongArrayElements((jlongArray)objArray, elems, 0);
463+
}
464+
break;
465+
466+
default:
467+
for(jsize i=0; i<arraySize; i++) {
468+
jobject obj = env->GetObjectArrayElement(objArray, i);
469+
v8::Handle<v8::Value> item = javaToV8(java, env, obj);
470+
result->Set(i, item);
471+
}
472+
break;
393473
}
394474

395475
return scope.Close(result);
@@ -506,10 +586,11 @@ jobject javaFindConstructor(JNIEnv *env, jclass clazz, jobjectArray methodArgs)
506586
return method;
507587
}
508588

509-
jobject longToJavaLongObj(JNIEnv *env, long val) {
589+
jobject longToJavaLongObj(JNIEnv *env, jlong val) {
510590
jclass longClass = env->FindClass("java/lang/Long");
511591
jmethodID constructor = env->GetMethodID(longClass, "<init>", "(J)V");
512-
return env->NewObject(longClass, constructor, val);
592+
jobject result = env->NewObject(longClass, constructor, val);
593+
return result;
513594
}
514595

515596
int dynamicProxyDataVerify(DynamicProxyData* data) {

src/utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ std::string javaMethodCallToString(JNIEnv *env, jobject obj, jmethodID methodId,
5454
JNIEnv* javaAttachCurrentThread(JavaVM* jvm, jobject classLoader);
5555
void javaDetachCurrentThread(JavaVM* jvm);
5656
jobject getSystemClassLoader(JNIEnv *env);
57+
jvalueType javaGetArrayComponentType(JNIEnv *env, jobjectArray array);
5758
jvalueType javaGetType(JNIEnv *env, jclass type);
5859
jobjectArray v8ToJava(JNIEnv* env, const v8::Arguments& args, int start, int end);
5960
jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg);
@@ -62,7 +63,7 @@ v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, jthrowable ex, const std::s
6263
v8::Handle<v8::Value> javaArrayToV8(Java* java, JNIEnv* env, jobjectArray objArray);
6364
v8::Handle<v8::Value> javaToV8(Java* java, JNIEnv* env, jobject obj);
6465
jobjectArray javaObjectArrayToClasses(JNIEnv *env, jobjectArray objs);
65-
jobject longToJavaLongObj(JNIEnv *env, long l);
66+
jobject longToJavaLongObj(JNIEnv *env, jlong l);
6667

6768
jclass javaFindClass(JNIEnv* env, std::string& className);
6869
jobject javaFindField(JNIEnv* env, jclass clazz, std::string& fieldName);

test/Test.class

788 Bytes
Binary file not shown.

test/Test.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,64 @@ public static class SuperClass {
3535
public static class SubClass extends SuperClass {
3636
public int getVal() { return 4; }
3737
}
38+
39+
public static int[] getArrayOfInts() {
40+
int arr[] = new int[5];
41+
arr[0] = 1;
42+
arr[1] = 2;
43+
arr[2] = 3;
44+
arr[3] = 4;
45+
arr[4] = 5;
46+
return arr;
47+
}
48+
49+
public static byte[] getArrayOfBytes() {
50+
byte arr[] = new byte[5];
51+
arr[0] = 1;
52+
arr[1] = 2;
53+
arr[2] = 3;
54+
arr[3] = 4;
55+
arr[4] = 5;
56+
return arr;
57+
}
58+
59+
public static boolean[] getArrayOfBools() {
60+
boolean arr[] = new boolean[5];
61+
arr[0] = true;
62+
arr[1] = true;
63+
arr[2] = false;
64+
arr[3] = true;
65+
arr[4] = false;
66+
return arr;
67+
}
68+
69+
public static double[] getArrayOfDoubles() {
70+
double arr[] = new double[5];
71+
arr[0] = 1;
72+
arr[1] = 2;
73+
arr[2] = 3;
74+
arr[3] = 4;
75+
arr[4] = 5;
76+
return arr;
77+
}
78+
79+
public static float[] getArrayOfFloats() {
80+
float arr[] = new float[5];
81+
arr[0] = 1;
82+
arr[1] = 2;
83+
arr[2] = 3;
84+
arr[3] = 4;
85+
arr[4] = 5;
86+
return arr;
87+
}
88+
89+
public static long[] getArrayOfLongs() {
90+
long arr[] = new long[5];
91+
arr[0] = Long.MAX_VALUE;
92+
arr[1] = Long.MIN_VALUE;
93+
arr[2] = 3;
94+
arr[3] = 4;
95+
arr[4] = 5;
96+
return arr;
97+
}
3898
}

test/simple-test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,46 @@ exports['Simple'] = nodeunit.testCase({
9999
console.log("bufferedReader.readLineSync", str);
100100
test.equal(str, "hello world");
101101
test.done();
102+
},
103+
104+
"method returning an array of ints sync": function(test) {
105+
var arr = java.callStaticMethodSync("Test", "getArrayOfInts");
106+
console.log(arr);
107+
test.done();
108+
},
109+
110+
"method returning an array of bytes sync": function(test) {
111+
var arr = java.callStaticMethodSync("Test", "getArrayOfBytes");
112+
console.log(arr);
113+
test.done();
114+
},
115+
116+
"method returning an array of bools sync": function(test) {
117+
var arr = java.callStaticMethodSync("Test", "getArrayOfBools");
118+
console.log(arr);
119+
test.done();
120+
},
121+
122+
"method returning an array of doubles sync": function(test) {
123+
var arr = java.callStaticMethodSync("Test", "getArrayOfDoubles");
124+
console.log(arr);
125+
test.done();
126+
},
127+
128+
"method returning an array of floats sync": function(test) {
129+
var arr = java.callStaticMethodSync("Test", "getArrayOfFloats");
130+
console.log(arr);
131+
test.done();
132+
},
133+
134+
"method returning an array of longs sync": function(test) {
135+
var arr = java.callStaticMethodSync("Test", "getArrayOfLongs");
136+
arr = arr.map(function(l) {
137+
return l.toStringSync();
138+
});
139+
console.log(arr);
140+
test.done();
102141
}
142+
103143
});
104144

0 commit comments

Comments
 (0)