Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 73 additions & 8 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,24 @@ jvalueType javaGetArrayComponentType(JNIEnv *env, jobjectArray array) {
return arrayComponentType;
}

#if (NODE_VERSION_AT_LEAST(4, 0, 0))
v8::Local<v8::ArrayBuffer> newArrayBuffer(void* elems, size_t length) {
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), length);
memcpy(ab->GetContents().Data(), elems, length);
return ab;
}
#endif

v8::Local<v8::String> javaCharToV8String(jchar c) {
#if ((NODE_MAJOR_VERSION == 0) && (NODE_MINOR_VERSION <= 10))
return v8::String::New(&c, 1);
#elif ((NODE_MAJOR_VERSION == 0) && (NODE_MINOR_VERSION <= 12))
return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), &c, v8::String::kNormalString, 1);
#else
return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), &c, v8::NewStringType::kNormal, 1).ToLocalChecked();
#endif
}

v8::Local<v8::Value> javaArrayToV8(Java* java, JNIEnv* env, jobjectArray objArray) {
if(objArray == NULL) {
return Nan::Null();
Expand All @@ -489,77 +507,126 @@ v8::Local<v8::Value> javaArrayToV8(Java* java, JNIEnv* env, jobjectArray objArra
//printf("array size: %d\n", arraySize);

v8::Local<v8::Array> result = Nan::New<v8::Array>(arraySize);
// http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html
switch(arrayComponentType) {
case TYPE_CHAR:
{
jchar* elems = env->GetCharArrayElements((jcharArray)objArray, 0);
char str[2];
str[1] = '\0';
#if (NODE_VERSION_AT_LEAST(4, 0, 0))
size_t byteLength = arraySize * 2;
v8::Local<v8::ArrayBuffer> ab = newArrayBuffer(elems, byteLength);
env->ReleaseCharArrayElements((jcharArray)objArray, elems, 0);
return v8::Uint16Array::New(ab, 0, arraySize);
#else
jchar str;
for(jsize i=0; i<arraySize; i++) {
str[0] = elems[i];
result->Set(i, Nan::New<v8::String>(str).ToLocalChecked());
str = elems[i];
result->Set(i, javaCharToV8String(str));
}
env->ReleaseCharArrayElements((jcharArray)objArray, elems, 0);
#endif
}
break;

case TYPE_INT:
{
jint* elems = env->GetIntArrayElements((jintArray)objArray, 0);
#if (NODE_VERSION_AT_LEAST(4, 0, 0))
size_t byteLength = arraySize * 4;
v8::Local<v8::ArrayBuffer> ab = newArrayBuffer(elems, byteLength);
env->ReleaseIntArrayElements((jintArray)objArray, elems, 0);
return v8::Int32Array::New(ab, 0, arraySize);
#else
for(jsize i=0; i<arraySize; i++) {
result->Set(i, Nan::New<v8::Integer>(elems[i]));
}
env->ReleaseIntArrayElements((jintArray)objArray, elems, 0);
#endif
}
break;

case TYPE_BYTE:
{
jbyte* elems = env->GetByteArrayElements((jbyteArray)objArray, 0);
#if (NODE_VERSION_AT_LEAST(4, 0, 0))
size_t byteLength = arraySize;
v8::Local<v8::ArrayBuffer> ab = newArrayBuffer(elems, byteLength);
env->ReleaseByteArrayElements((jbyteArray)objArray, elems, 0);
return v8::Int8Array::New(ab, 0, arraySize);
#else
for(jsize i=0; i<arraySize; i++) {
result->Set(i, Nan::New<v8::Number>(elems[i]));
}
env->ReleaseByteArrayElements((jbyteArray)objArray, elems, 0);
#endif
}
break;

case TYPE_BOOLEAN:
{
jboolean* elems = env->GetBooleanArrayElements((jbooleanArray)objArray, 0);
#if (NODE_VERSION_AT_LEAST(4, 0, 0))
size_t byteLength = arraySize;
v8::Local<v8::ArrayBuffer> ab = newArrayBuffer(elems, byteLength);
env->ReleaseBooleanArrayElements((jbooleanArray)objArray, elems, 0);
return v8::Uint8Array::New(ab, 0, arraySize);
#else
for(jsize i=0; i<arraySize; i++) {
result->Set(i, Nan::New<v8::Boolean>(elems[i]));
}
env->ReleaseBooleanArrayElements((jbooleanArray)objArray, elems, 0);
#endif
}
break;

case TYPE_SHORT:
{
jshort* elems = env->GetShortArrayElements((jshortArray)objArray, 0);
#if (NODE_VERSION_AT_LEAST(4, 0, 0))
size_t byteLength = arraySize * 2;
v8::Local<v8::ArrayBuffer> ab = newArrayBuffer(elems, byteLength);
env->ReleaseShortArrayElements((jshortArray)objArray, elems, 0);
return v8::Int16Array::New(ab, 0, arraySize);
#else
for(jsize i=0; i<arraySize; i++) {
result->Set(i, Nan::New<v8::Number>(elems[i]));
}
env->ReleaseShortArrayElements((jshortArray)objArray, elems, 0);
#endif
}
break;

case TYPE_DOUBLE:
{
jdouble* elems = env->GetDoubleArrayElements((jdoubleArray)objArray, 0);
#if (NODE_VERSION_AT_LEAST(4, 0, 0))
size_t byteLength = arraySize * 8;
v8::Local<v8::ArrayBuffer> ab = newArrayBuffer(elems, byteLength);
env->ReleaseDoubleArrayElements((jdoubleArray)objArray, elems, 0);
return v8::Float64Array::New(ab, 0, arraySize);
#else
for(jsize i=0; i<arraySize; i++) {
result->Set(i, Nan::New<v8::Number>(elems[i]));
}
env->ReleaseDoubleArrayElements((jdoubleArray)objArray, elems, 0);
#endif
}
break;

case TYPE_FLOAT:
{
jfloat* elems = env->GetFloatArrayElements((jfloatArray)objArray, 0);
#if (NODE_VERSION_AT_LEAST(4, 0, 0))
size_t byteLength = arraySize * 4;
v8::Local<v8::ArrayBuffer> ab = newArrayBuffer(elems, byteLength);
env->ReleaseFloatArrayElements((jfloatArray)objArray, elems, 0);
return v8::Float32Array::New(ab, 0, arraySize);
#else
for(jsize i=0; i<arraySize; i++) {
result->Set(i, Nan::New<v8::Number>(elems[i]));
}
env->ReleaseFloatArrayElements((jfloatArray)objArray, elems, 0);
#endif
}
break;

Expand Down Expand Up @@ -612,11 +679,9 @@ v8::Local<v8::Value> javaToV8(Java* java, JNIEnv* env, jobject obj, DynamicProxy
{
jclass charClazz = env->FindClass("java/lang/Character");
jmethodID char_charValue = env->GetMethodID(charClazz, "charValue", "()C");
char str[2];
str[0] = env->CallCharMethod(obj, char_charValue);
str[1] = '\0';
jchar c = env->CallCharMethod(obj, char_charValue);
checkJavaException(env);
return Nan::New<v8::String>(str).ToLocalChecked();
return javaCharToV8String(c);
}
case TYPE_BOOLEAN:
{
Expand Down
11 changes: 8 additions & 3 deletions test/utils-types-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,20 @@ exports['Utils - Types'] = nodeunit.testCase({
},

"Char array": function(test) {
var originalArray = "hello world\n".split('');
var originalArray = "hello 世界\n".split('');
var Arrays = java.import("java.util.Arrays");
var arr1 = java.newArray("char", originalArray);
var list = Arrays.asListSync(arr1);
var arr2 = list.toArraySync();
test.equal(arr2.length, 1);
test.equal(arr2[0].length, 12);
test.equal(arr2[0].length, 9);
var isTypedArrayReturn = !(typeof arr2[0][0] === 'string');
for(var i=0; i<originalArray.length; i++) {
test.equal(arr2[0][i], originalArray[i]);
if (isTypedArrayReturn) {
test.equal(arr2[0][i], originalArray[i].charCodeAt(0));
} else {
test.equal(arr2[0][i], originalArray[i]);
}
}
test.done();
}
Expand Down