📄 jsj_utils.c
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * This Original Code has been modified by IBM Corporation. Modifications made * by IBM described herein are Copyright (c) International Business Machines * Corporation, 2000. * Modifications to Mozilla code or documentation identified per MPL Section 3.3 * * Date Modified by Description of modification * 04/20/2000 IBM Corp. OS/2 VisualAge build. * * ***** END LICENSE BLOCK ***** *//* * This file is part of the Java-vendor-neutral implementation of LiveConnect * * It contains low-level utility code. * */#include <stdlib.h>#include <string.h>#include "jsj_private.h" /* LiveConnect internals */#include "jsjava.h" /* External LiveConnect API *//* * This is a hash-table utility routine that computes the hash code of a Java * object by calling java.lang.System.identityHashCode() */JSJHashNumber JS_DLL_CALLBACKjsj_HashJavaObject(const void *key, void* env){ JSHashNumber hash_code; jobject java_obj; JNIEnv *jEnv; java_obj = (jobject)key; jEnv = (JNIEnv*) env; JS_ASSERT(!(*jEnv)->ExceptionOccurred(jEnv)); hash_code = (*jEnv)->CallStaticIntMethod(jEnv, jlSystem, jlSystem_identityHashCode, java_obj);#ifdef DEBUG if ((*jEnv)->ExceptionOccurred(jEnv)) { (*jEnv)->ExceptionDescribe(jEnv); JS_ASSERT(0); }#endif return hash_code;}/* * This is a hash-table utility routine for comparing two Java objects. * It's not possible to use the == operator to directly compare two jobject's, * since they're opaque references and aren't guaranteed to be simple pointers * or handles (though they may be in some JVM implementations). Instead, * use the JNI routine for comparing the two objects. */intN JS_DLL_CALLBACKjsj_JavaObjectComparator(const void *v1, const void *v2, void *arg){ jobject java_obj1, java_obj2; JNIEnv *jEnv; jEnv = (JNIEnv*)arg; java_obj1 = (jobject)v1; java_obj2 = (jobject)v2; if (java_obj1 == java_obj2) return 1; if (jEnv) return (*jEnv)->IsSameObject(jEnv, java_obj1, java_obj2); return 0;}/* * Return a UTF8, null-terminated encoding of a Java string. The string must * be free'ed by the caller. * * If an error occurs, returns NULL and calls the JS error reporter. */const char *jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr){ const char *str, *retval; str = (*jEnv)->GetStringUTFChars(jEnv, jstr, 0); if (!str) { jsj_UnexpectedJavaError(cx, jEnv, "Can't get UTF8 characters from " "Java string"); return NULL; } retval = JS_strdup(cx, str); (*jEnv)->ReleaseStringUTFChars(jEnv, jstr, str); return retval;}JSBoolJavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp){ const jschar *ucs2; JSString *jsstr; jsize ucs2_len; jsval val; ucs2 = (*jEnv)->GetStringChars(jEnv, jstr, 0); if (!ucs2) { jsj_UnexpectedJavaError(cx, jEnv, "Couldn't obtain Unicode characters" "from Java string"); return JS_FALSE; } ucs2_len = (*jEnv)->GetStringLength(jEnv, jstr); jsstr = JS_InternUCStringN(cx, ucs2, ucs2_len); (*jEnv)->ReleaseStringChars(jEnv, jstr, ucs2); if (!jsstr) return JS_FALSE; val = STRING_TO_JSVAL(jsstr); JS_ValueToId(cx, STRING_TO_JSVAL(jsstr), idp); return JS_TRUE;}/* * Return, as a C string, the error message associated with a Java exception * that occurred as a result of a JNI call, preceded by the class name of * the exception. As a special case, if the class of the exception is * netscape.javascript.JSException, the exception class name is omitted. * * NULL is returned if no Java exception is pending. The caller is * responsible for free'ing the returned string. On exit, the Java exception * is *not* cleared. */const char *jsj_GetJavaErrorMessage(JNIEnv *jEnv){ const char *java_error_msg; char *error_msg = NULL; jthrowable exception; jstring java_exception_jstring; exception = (*jEnv)->ExceptionOccurred(jEnv); if (exception && jlThrowable_toString) { java_exception_jstring = (*jEnv)->CallObjectMethod(jEnv, exception, jlThrowable_toString); if (!java_exception_jstring) goto done; java_error_msg = (*jEnv)->GetStringUTFChars(jEnv, java_exception_jstring, NULL); if (java_error_msg) { error_msg = strdup((char*)java_error_msg); (*jEnv)->ReleaseStringUTFChars(jEnv, java_exception_jstring, java_error_msg); } (*jEnv)->DeleteLocalRef(jEnv, java_exception_jstring);#ifdef DEBUG /* (*jEnv)->ExceptionDescribe(jEnv); */#endif }done: if (exception) (*jEnv)->DeleteLocalRef(jEnv, exception); return error_msg;} /* * Return, as a C string, the JVM stack trace associated with a Java * exception, as would be printed by java.lang.Throwable.printStackTrace(). * The caller is responsible for free'ing the returned string. * * Returns NULL if an error occurs. */static const char *get_java_stack_trace(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception){ const char *backtrace; jstring backtrace_jstr; backtrace = NULL; if (java_exception && njJSUtil_getStackTrace) { backtrace_jstr = (*jEnv)->CallStaticObjectMethod(jEnv, njJSUtil, njJSUtil_getStackTrace, java_exception); if (!backtrace_jstr) { jsj_UnexpectedJavaError(cx, jEnv, "Unable to get exception stack trace"); return NULL; } backtrace = jsj_DupJavaStringUTF(cx, jEnv, backtrace_jstr); (*jEnv)->DeleteLocalRef(jEnv, backtrace_jstr); } return backtrace;} /* Full Java backtrace when Java exceptions reported to JavaScript */#define REPORT_JAVA_EXCEPTION_STACK_TRACE/* * This is a wrapper around JS_ReportError(), useful when an error condition * is the result of a JVM failure or exception condition. It appends the * message associated with the pending Java exception to the passed in * printf-style format string and arguments. */static voidvreport_java_error(JSContext *cx, JNIEnv *jEnv, const char *format, va_list ap){ jobject java_obj; jclass java_class; JavaClassDescriptor *class_descriptor; jthrowable java_exception; JSType wrapped_exception_type; jsval js_exception; java_obj = NULL; class_descriptor = NULL; /* Get the exception out of the java environment. */ java_exception = (*jEnv)->ExceptionOccurred(jEnv); if (!java_exception) { JSString *err_jsstr; char *err = JS_vsmprintf(format, ap); if (!err)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -