diff options
Diffstat (limited to 'WebCore/bridge/jni/JNIUtility.cpp')
| -rw-r--r-- | WebCore/bridge/jni/JNIUtility.cpp | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/WebCore/bridge/jni/JNIUtility.cpp b/WebCore/bridge/jni/JNIUtility.cpp new file mode 100644 index 0000000..d2ac475 --- /dev/null +++ b/WebCore/bridge/jni/JNIUtility.cpp @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JNIUtility.h" + +#if ENABLE(MAC_JAVA_BRIDGE) + +#include <dlfcn.h> + +namespace JSC { + +namespace Bindings { + +static jint KJS_GetCreatedJavaVMs(JavaVM** vmBuf, jsize bufLen, jsize* nVMs) +{ + static void* javaVMFramework = 0; + if (!javaVMFramework) + javaVMFramework = dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM", RTLD_LAZY); + if (!javaVMFramework) + return JNI_ERR; + + static jint(*functionPointer)(JavaVM**, jsize, jsize *) = 0; + if (!functionPointer) + functionPointer = (jint(*)(JavaVM**, jsize, jsize *))dlsym(javaVMFramework, "JNI_GetCreatedJavaVMs"); + if (!functionPointer) + return JNI_ERR; + return functionPointer(vmBuf, bufLen, nVMs); +} + +static JavaVM *jvm = 0; + +// Provide the ability for an outside component to specify the JavaVM to use +// If the jvm value is set, the getJavaVM function below will just return. +// In getJNIEnv(), if AttachCurrentThread is called to a VM that is already +// attached, the result is a no-op. +void setJavaVM(JavaVM *javaVM) +{ + jvm = javaVM; +} + +JavaVM *getJavaVM() +{ + if (jvm) + return jvm; + + JavaVM *jvmArray[1]; + jsize bufLen = 1; + jsize nJVMs = 0; + jint jniError = 0; + + // Assumes JVM is already running ..., one per process + jniError = KJS_GetCreatedJavaVMs(jvmArray, bufLen, &nJVMs); + if ( jniError == JNI_OK && nJVMs > 0 ) { + jvm = jvmArray[0]; + } + else + fprintf(stderr, "%s: JNI_GetCreatedJavaVMs failed, returned %ld\n", __PRETTY_FUNCTION__, (long)jniError); + + return jvm; +} + +JNIEnv* getJNIEnv() +{ + union { + JNIEnv* env; + void* dummy; + } u; + jint jniError = 0; + + jniError = (getJavaVM())->AttachCurrentThread(&u.dummy, NULL); + if (jniError == JNI_OK) + return u.env; + else + fprintf(stderr, "%s: AttachCurrentThread failed, returned %ld\n", __PRETTY_FUNCTION__, (long)jniError); + return NULL; +} + +jmethodID getMethodID (jobject obj, const char *name, const char *sig) +{ + JNIEnv *env = getJNIEnv(); + jmethodID mid = 0; + + if ( env != NULL) { + jclass cls = env->GetObjectClass(obj); + if ( cls != NULL ) { + mid = env->GetMethodID(cls, name, sig); + if (!mid) { + env->ExceptionClear(); + mid = env->GetStaticMethodID(cls, name, sig); + if (!mid) { + env->ExceptionClear(); + } + } + } + env->DeleteLocalRef(cls); + } + return mid; +} + +const char *getCharactersFromJString (jstring aJString) +{ + return getCharactersFromJStringInEnv (getJNIEnv(), aJString); +} + +void releaseCharactersForJString (jstring aJString, const char *s) +{ + releaseCharactersForJStringInEnv (getJNIEnv(), aJString, s); +} + +const char *getCharactersFromJStringInEnv (JNIEnv *env, jstring aJString) +{ + jboolean isCopy; + const char *s = env->GetStringUTFChars((jstring)aJString, &isCopy); + if (!s) { + env->ExceptionDescribe(); + env->ExceptionClear(); + fprintf (stderr, "\n"); + } + return s; +} + +void releaseCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const char *s) +{ + env->ReleaseStringUTFChars (aJString, s); +} + +const jchar *getUCharactersFromJStringInEnv (JNIEnv *env, jstring aJString) +{ + jboolean isCopy; + const jchar *s = env->GetStringChars((jstring)aJString, &isCopy); + if (!s) { + env->ExceptionDescribe(); + env->ExceptionClear(); + fprintf (stderr, "\n"); + } + return s; +} + +void releaseUCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const jchar *s) +{ + env->ReleaseStringChars (aJString, s); +} + +JNIType JNITypeFromClassName(const char *name) +{ + JNIType type; + + if (strcmp("byte",name) == 0) + type = byte_type; + else if (strcmp("short",name) == 0) + type = short_type; + else if (strcmp("int",name) == 0) + type = int_type; + else if (strcmp("long",name) == 0) + type = long_type; + else if (strcmp("float",name) == 0) + type = float_type; + else if (strcmp("double",name) == 0) + type = double_type; + else if (strcmp("char",name) == 0) + type = char_type; + else if (strcmp("boolean",name) == 0) + type = boolean_type; + else if (strcmp("void",name) == 0) + type = void_type; + else if ('[' == name[0]) + type = array_type; + else + type = object_type; + + return type; +} + +const char *signatureFromPrimitiveType(JNIType type) +{ + switch (type){ + case void_type: + return "V"; + + case array_type: + return "["; + + case object_type: + return "L"; + + case boolean_type: + return "Z"; + + case byte_type: + return "B"; + + case char_type: + return "C"; + + case short_type: + return "S"; + + case int_type: + return "I"; + + case long_type: + return "J"; + + case float_type: + return "F"; + + case double_type: + return "D"; + + case invalid_type: + default: + break; + } + return ""; +} + +JNIType JNITypeFromPrimitiveType(char type) +{ + switch (type){ + case 'V': + return void_type; + + case 'L': + return object_type; + + case '[': + return array_type; + + case 'Z': + return boolean_type; + + case 'B': + return byte_type; + + case 'C': + return char_type; + + case 'S': + return short_type; + + case 'I': + return int_type; + + case 'J': + return long_type; + + case 'F': + return float_type; + + case 'D': + return double_type; + + default: + break; + } + return invalid_type; +} + +jvalue getJNIField( jobject obj, JNIType type, const char *name, const char *signature) +{ + JavaVM *jvm = getJavaVM(); + JNIEnv *env = getJNIEnv(); + jvalue result; + + bzero (&result, sizeof(jvalue)); + if ( obj != NULL && jvm != NULL && env != NULL) { + jclass cls = env->GetObjectClass(obj); + if ( cls != NULL ) { + jfieldID field = env->GetFieldID(cls, name, signature); + if ( field != NULL ) { + switch (type) { + case array_type: + case object_type: + result.l = env->functions->GetObjectField(env, obj, field); + break; + case boolean_type: + result.z = env->functions->GetBooleanField(env, obj, field); + break; + case byte_type: + result.b = env->functions->GetByteField(env, obj, field); + break; + case char_type: + result.c = env->functions->GetCharField(env, obj, field); + break; + case short_type: + result.s = env->functions->GetShortField(env, obj, field); + break; + case int_type: + result.i = env->functions->GetIntField(env, obj, field); + break; + case long_type: + result.j = env->functions->GetLongField(env, obj, field); + break; + case float_type: + result.f = env->functions->GetFloatField(env, obj, field); + break; + case double_type: + result.d = env->functions->GetDoubleField(env, obj, field); + break; + default: + fprintf(stderr, "%s: invalid field type (%d)\n", __PRETTY_FUNCTION__, (int)type); + } + } + else + { + fprintf(stderr, "%s: Could not find field: %s\n", __PRETTY_FUNCTION__, name); + env->ExceptionDescribe(); + env->ExceptionClear(); + fprintf (stderr, "\n"); + } + + env->DeleteLocalRef(cls); + } + else { + fprintf(stderr, "%s: Could not find class for object\n", __PRETTY_FUNCTION__); + } + } + + return result; +} + +} // end of namespace Bindings + +} // end of namespace JSC + +#endif // ENABLE(MAC_JAVA_BRIDGE) |
