JNIUtilityPrivate.cpp [plain text]
#include "config.h"
#include "JNIUtilityPrivate.h"
#if ENABLE(JAVA_BRIDGE)
#include "JavaRuntimeObject.h"
#include "JNIBridgeJSC.h"
#include "jni_jsobject.h"
#include "runtime_array.h"
#include "runtime_object.h"
#include <runtime/JSArray.h>
#include <runtime/JSLock.h>
namespace JSC {
namespace Bindings {
static jobject convertArrayInstanceToJavaArray(ExecState* exec, JSArray* jsArray, const char* javaClassName)
{
JNIEnv* env = getJNIEnv();
unsigned length = jsArray->length();
jobjectArray jarray = 0;
switch (JNITypeFromPrimitiveType(javaClassName[1])) {
case object_type:
{
if (!strcmp("[Ljava.lang.String;", javaClassName)) {
jarray = (jobjectArray)env->NewObjectArray(length,
env->FindClass("java/lang/String"),
env->NewStringUTF(""));
for (unsigned i = 0; i < length; i++) {
JSValue item = jsArray->get(exec, i);
UString stringValue = item.toString(exec);
env->SetObjectArrayElement(jarray, i,
env->functions->NewString(env, (const jchar *)stringValue.data(), stringValue.size()));
}
}
break;
}
case boolean_type:
{
jarray = (jobjectArray)env->NewBooleanArray(length);
for (unsigned i = 0; i < length; i++) {
JSValue item = jsArray->get(exec, i);
jboolean value = (jboolean)item.toNumber(exec);
env->SetBooleanArrayRegion((jbooleanArray)jarray, (jsize)i, (jsize)1, &value);
}
break;
}
case byte_type:
{
jarray = (jobjectArray)env->NewByteArray(length);
for (unsigned i = 0; i < length; i++) {
JSValue item = jsArray->get(exec, i);
jbyte value = (jbyte)item.toNumber(exec);
env->SetByteArrayRegion((jbyteArray)jarray, (jsize)i, (jsize)1, &value);
}
break;
}
case char_type:
{
jarray = (jobjectArray)env->NewCharArray(length);
for (unsigned i = 0; i < length; i++) {
JSValue item = jsArray->get(exec, i);
UString stringValue = item.toString(exec);
jchar value = 0;
if (stringValue.size() > 0)
value = ((const jchar*)stringValue.data())[0];
env->SetCharArrayRegion((jcharArray)jarray, (jsize)i, (jsize)1, &value);
}
break;
}
case short_type:
{
jarray = (jobjectArray)env->NewShortArray(length);
for (unsigned i = 0; i < length; i++) {
JSValue item = jsArray->get(exec, i);
jshort value = (jshort)item.toNumber(exec);
env->SetShortArrayRegion((jshortArray)jarray, (jsize)i, (jsize)1, &value);
}
break;
}
case int_type:
{
jarray = (jobjectArray)env->NewIntArray(length);
for (unsigned i = 0; i < length; i++) {
JSValue item = jsArray->get(exec, i);
jint value = (jint)item.toNumber(exec);
env->SetIntArrayRegion((jintArray)jarray, (jsize)i, (jsize)1, &value);
}
break;
}
case long_type:
{
jarray = (jobjectArray)env->NewLongArray(length);
for (unsigned i = 0; i < length; i++) {
JSValue item = jsArray->get(exec, i);
jlong value = (jlong)item.toNumber(exec);
env->SetLongArrayRegion((jlongArray)jarray, (jsize)i, (jsize)1, &value);
}
break;
}
case float_type:
{
jarray = (jobjectArray)env->NewFloatArray(length);
for (unsigned i = 0; i < length; i++) {
JSValue item = jsArray->get(exec, i);
jfloat value = (jfloat)item.toNumber(exec);
env->SetFloatArrayRegion((jfloatArray)jarray, (jsize)i, (jsize)1, &value);
}
break;
}
case double_type:
{
jarray = (jobjectArray)env->NewDoubleArray(length);
for (unsigned i = 0; i < length; i++) {
JSValue item = jsArray->get(exec, i);
jdouble value = (jdouble)item.toNumber(exec);
env->SetDoubleArrayRegion((jdoubleArray)jarray, (jsize)i, (jsize)1, &value);
}
break;
}
case array_type: case void_type: case invalid_type: break;
}
return jarray;
}
jvalue convertValueToJValue(ExecState* exec, RootObject* rootObject, JSValue value, JNIType jniType, const char* javaClassName)
{
JSLock lock(SilenceAssertionsOnly);
jvalue result;
memset(&result, 0, sizeof(jvalue));
switch (jniType) {
case array_type:
case object_type:
{
if (value.isObject()) {
JSObject* object = asObject(value);
if (object->inherits(&JavaRuntimeObject::s_info)) {
JavaRuntimeObject* runtimeObject = static_cast<JavaRuntimeObject*>(object);
JavaInstance* instance = runtimeObject->getInternalJavaInstance();
if (instance)
result.l = instance->javaInstance();
} else if (object->classInfo() == &RuntimeArray::s_info) {
RuntimeArray* imp = static_cast<RuntimeArray*>(object);
JavaArray* array = static_cast<JavaArray*>(imp->getConcreteArray());
result.l = array->javaArray();
} else if (object->classInfo() == &JSArray::info) {
result.l = convertArrayInstanceToJavaArray(exec, asArray(value), javaClassName);
} else if (!result.l && (!strcmp(javaClassName, "java.lang.Object")) || (!strcmp(javaClassName, "netscape.javascript.JSObject"))) {
JNIEnv* env = getJNIEnv();
jclass jsObjectClass = env->FindClass("sun/plugin/javascript/webkit/JSObject");
jmethodID constructorID = env->GetMethodID(jsObjectClass, "<init>", "(J)V");
if (constructorID) {
jlong nativeHandle = ptr_to_jlong(object);
rootObject->gcProtect(object);
result.l = env->NewObject(jsObjectClass, constructorID, nativeHandle);
}
}
}
if (!result.l && !strcmp(javaClassName, "java.lang.Object")) {
if (value.isString()) {
UString stringValue = asString(value)->value(exec);
JNIEnv* env = getJNIEnv();
jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.data(), stringValue.size());
result.l = javaString;
} else if (value.isNumber()) {
double doubleValue = value.uncheckedGetNumber();
JNIEnv* env = getJNIEnv();
jclass clazz = env->FindClass("java/lang/Double");
jmethodID constructor = env->GetMethodID(clazz, "<init>", "(D)V");
jobject javaDouble = env->functions->NewObject(env, clazz, constructor, doubleValue);
result.l = javaDouble;
} else if (value.isBoolean()) {
bool boolValue = value.getBoolean();
JNIEnv* env = getJNIEnv();
jclass clazz = env->FindClass("java/lang/Boolean");
jmethodID constructor = env->GetMethodID(clazz, "<init>", "(Z)V");
jobject javaBoolean = env->functions->NewObject(env, clazz, constructor, boolValue);
result.l = javaBoolean;
} else if (value.isUndefined()) {
UString stringValue = "undefined";
JNIEnv* env = getJNIEnv();
jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.data(), stringValue.size());
result.l = javaString;
}
}
if (!result.l && !strcmp(javaClassName, "java.lang.String")) {
if (!value.isNull()) {
UString stringValue = value.toString(exec);
JNIEnv* env = getJNIEnv();
jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.data(), stringValue.size());
result.l = javaString;
}
}
}
break;
case boolean_type:
{
result.z = (jboolean)value.toNumber(exec);
}
break;
case byte_type:
{
result.b = (jbyte)value.toNumber(exec);
}
break;
case char_type:
{
result.c = (jchar)value.toNumber(exec);
}
break;
case short_type:
{
result.s = (jshort)value.toNumber(exec);
}
break;
case int_type:
{
result.i = (jint)value.toNumber(exec);
}
break;
case long_type:
{
result.j = (jlong)value.toNumber(exec);
}
break;
case float_type:
{
result.f = (jfloat)value.toNumber(exec);
}
break;
case double_type:
{
result.d = (jdouble)value.toNumber(exec);
}
break;
case invalid_type:
case void_type:
break;
}
return result;
}
}
}
#endif // ENABLE(JAVA_BRIDGE)