util.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 2,125 行 · 第 1/5 页
C
2,125 行
/* * @(#)util.c 1.79 06/10/25 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */#include <ctype.h>#include "util.h"#include "transport.h"#include "eventHandler.h"#include "threadControl.h"#include "outStream.h"#include "inStream.h"#include "invoker.h"/* Global data area */BackendGlobalData *gdata = NULL;/* Forward declarations */static jboolean isInterface(jclass clazz);static jboolean isArrayClass(jclass clazz);static char * getPropertyUTF8(JNIEnv *env, char *propertyName);/* Save an object reference for use later (create a NewGlobalRef) */void saveGlobalRef(JNIEnv *env, jobject obj, jobject *pobj){ jobject newobj; if ( pobj == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef pobj"); } if ( *pobj != NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef *pobj"); } if ( env == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef env"); } if ( obj == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef obj"); } newobj = JNI_FUNC_PTR(env,NewGlobalRef)(env, obj); if ( newobj == NULL ) { EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"NewGlobalRef"); } *pobj = newobj;}/* Toss a previously saved object reference */void tossGlobalRef(JNIEnv *env, jobject *pobj){ jobject obj; if ( pobj == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"tossGlobalRef pobj"); } obj = *pobj; if ( env == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"tossGlobalRef env"); } if ( obj == NULL ) { EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"tossGlobalRef obj"); } JNI_FUNC_PTR(env,DeleteGlobalRef)(env, obj); *pobj = NULL;}static jclassfindClass(JNIEnv *env, const char * name){ jclass x; if ( env == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"findClass env"); } if ( name == NULL || name[0] == 0 ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"findClass name"); } x = JNI_FUNC_PTR(env,FindClass)(env, name); if (x == NULL) { ERROR_MESSAGE(("JDWP Can't find class %s", name)); EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL); } if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) { ERROR_MESSAGE(("JDWP Exception occurred finding class %s", name)); EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL); } return x;}static jmethodIDgetMethod(JNIEnv *env, jclass clazz, const char * name, const char *signature){ jmethodID method; if ( env == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod env"); } if ( clazz == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod clazz"); } if ( name == NULL || name[0] == 0 ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod name"); } if ( signature == NULL || signature[0] == 0 ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod signature"); } method = JNI_FUNC_PTR(env,GetMethodID)(env, clazz, name, signature); if (method == NULL) { ERROR_MESSAGE(("JDWP Can't find method %s with signature %s", name, signature)); EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL); } if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) { ERROR_MESSAGE(("JDWP Exception occurred finding method %s with signature %s", name, signature)); EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL); } return method;}static jmethodIDgetStaticMethod(JNIEnv *env, jclass clazz, const char * name, const char *signature){ jmethodID method; if ( env == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod env"); } if ( clazz == NULL ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod clazz"); } if ( name == NULL || name[0] == 0 ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod name"); } if ( signature == NULL || signature[0] == 0 ) { EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod signature"); } method = JNI_FUNC_PTR(env,GetStaticMethodID)(env, clazz, name, signature); if (method == NULL) { ERROR_MESSAGE(("JDWP Can't find method %s with signature %s", name, signature)); EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL); } if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) { ERROR_MESSAGE(("JDWP Exception occurred finding method %s with signature %s", name, signature)); EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL); } return method;}void util_initialize(JNIEnv *env){ WITH_LOCAL_REFS(env, 7) { jvmtiError error; jclass localClassClass; jclass localThreadClass; jclass localThreadGroupClass; jclass localClassLoaderClass; jclass localStringClass; jclass localSystemClass; jclass localPropertiesClass; jint groupCount; jthreadGroup *groups; jthreadGroup localSystemThreadGroup; /* Find some standard classes */ localClassClass = findClass(env,"java/lang/Class"); localThreadClass = findClass(env,"java/lang/Thread"); localThreadGroupClass = findClass(env,"java/lang/ThreadGroup"); localClassLoaderClass = findClass(env,"java/lang/ClassLoader"); localStringClass = findClass(env,"java/lang/String"); localSystemClass = findClass(env,"java/lang/System"); localPropertiesClass = findClass(env,"java/util/Properties"); /* Save references */ saveGlobalRef(env, localClassClass, &(gdata->classClass)); saveGlobalRef(env, localThreadClass, &(gdata->threadClass)); saveGlobalRef(env, localThreadGroupClass, &(gdata->threadGroupClass)); saveGlobalRef(env, localClassLoaderClass, &(gdata->classLoaderClass)); saveGlobalRef(env, localStringClass, &(gdata->stringClass)); saveGlobalRef(env, localSystemClass, &(gdata->systemClass)); /* Find some standard methods */ gdata->threadConstructor = getMethod(env, gdata->threadClass, "<init>", "(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"); gdata->threadCurrentThread = getStaticMethod(env, gdata->threadClass, "currentThread", "()Ljava/lang/Thread;"); gdata->threadSetDaemon = getMethod(env, gdata->threadClass, "setDaemon", "(Z)V"); gdata->systemGetProperty = getStaticMethod(env, gdata->systemClass, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"); /* Find the system thread group */ groups = NULL; groupCount = 0; error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups) (gdata->jvmti, &groupCount, &groups); if (error != JVMTI_ERROR_NONE ) { EXIT_ERROR(error, "Can't get system thread group"); } if ( groupCount == 0 ) { EXIT_ERROR(AGENT_ERROR_NULL_POINTER, "Can't get system thread group"); } localSystemThreadGroup = groups[0]; saveGlobalRef(env, localSystemThreadGroup, &(gdata->systemThreadGroup)); /* Get some basic Java property values we will need at some point */ gdata->property_java_version = getPropertyUTF8(env, "java.version"); gdata->property_java_vm_name = getPropertyUTF8(env, "java.vm.name"); gdata->property_java_vm_info = getPropertyUTF8(env, "java.vm.info"); gdata->property_java_class_path = getPropertyUTF8(env, "java.class.path"); gdata->property_sun_boot_class_path = getPropertyUTF8(env, "sun.boot.class.path"); gdata->property_sun_boot_library_path = getPropertyUTF8(env, "sun.boot.library.path"); gdata->property_java_library_path = getPropertyUTF8(env, "java.library.path"); gdata->property_path_separator = getPropertyUTF8(env, "path.separator"); gdata->property_user_dir = getPropertyUTF8(env, "user.dir"); gdata->agent_properties = NULL; } END_WITH_LOCAL_REFS(env);}voidutil_reset(void){}jboolean isObjectTag(jbyte tag) { return (tag == JDWP_TAG(OBJECT)) || (tag == JDWP_TAG(STRING)) || (tag == JDWP_TAG(THREAD)) || (tag == JDWP_TAG(THREAD_GROUP)) || (tag == JDWP_TAG(CLASS_LOADER)) || (tag == JDWP_TAG(CLASS_OBJECT)) || (tag == JDWP_TAG(ARRAY));}jbyte specificTypeKey(JNIEnv *env, jobject object) { if (object == NULL) { return JDWP_TAG(OBJECT); } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->stringClass)) { return JDWP_TAG(STRING); } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadClass)) { return JDWP_TAG(THREAD); } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadGroupClass)) { return JDWP_TAG(THREAD_GROUP); } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classLoaderClass)) { return JDWP_TAG(CLASS_LOADER); } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classClass)) { return JDWP_TAG(CLASS_OBJECT); } else { jboolean classIsArray; WITH_LOCAL_REFS(env, 1) { jclass clazz; clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object); classIsArray = isArrayClass(clazz); } END_WITH_LOCAL_REFS(env); return (classIsArray ? JDWP_TAG(ARRAY) : JDWP_TAG(OBJECT)); }}static void writeFieldValue(JNIEnv *env, PacketOutputStream *out, jobject object, jfieldID field){ jclass clazz; char *signature = NULL; jvmtiError error; jbyte typeKey; clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object); error = fieldSignature(clazz, field, NULL, &signature, NULL); if (error != JVMTI_ERROR_NONE) { outStream_setError(out, map2jdwpError(error)); return; } typeKey = signature[0]; jvmtiDeallocate(signature); /* * For primitive types, the type key is bounced back as is. Objects * are handled in the switch statement below. */ if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) { (void)outStream_writeByte(out, typeKey); } switch (typeKey) { case JDWP_TAG(OBJECT): case JDWP_TAG(ARRAY): { jobject value = JNI_FUNC_PTR(env,GetObjectField)(env, object, field); (void)outStream_writeByte(out, specificTypeKey(env, value)); (void)outStream_writeObjectRef(env, out, value); break; } case JDWP_TAG(BYTE): (void)outStream_writeByte(out, JNI_FUNC_PTR(env,GetByteField)(env, object, field)); break; case JDWP_TAG(CHAR): (void)outStream_writeChar(out, JNI_FUNC_PTR(env,GetCharField)(env, object, field)); break; case JDWP_TAG(FLOAT): (void)outStream_writeFloat(out, JNI_FUNC_PTR(env,GetFloatField)(env, object, field)); break; case JDWP_TAG(DOUBLE): (void)outStream_writeDouble(out, JNI_FUNC_PTR(env,GetDoubleField)(env, object, field)); break; case JDWP_TAG(INT): (void)outStream_writeInt(out, JNI_FUNC_PTR(env,GetIntField)(env, object, field)); break; case JDWP_TAG(LONG): (void)outStream_writeLong(out, JNI_FUNC_PTR(env,GetLongField)(env, object, field)); break; case JDWP_TAG(SHORT): (void)outStream_writeShort(out, JNI_FUNC_PTR(env,GetShortField)(env, object, field)); break; case JDWP_TAG(BOOLEAN): (void)outStream_writeBoolean(out, JNI_FUNC_PTR(env,GetBooleanField)(env, object, field)); break; }}static void writeStaticFieldValue(JNIEnv *env, PacketOutputStream *out, jclass clazz, jfieldID field){ jvmtiError error; char *signature = NULL; jbyte typeKey; error = fieldSignature(clazz, field, NULL, &signature, NULL); if (error != JVMTI_ERROR_NONE) { outStream_setError(out, map2jdwpError(error)); return; } typeKey = signature[0]; jvmtiDeallocate(signature); /* * For primitive types, the type key is bounced back as is. Objects * are handled in the switch statement below. */ if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) { (void)outStream_writeByte(out, typeKey); } switch (typeKey) { case JDWP_TAG(OBJECT): case JDWP_TAG(ARRAY): { jobject value = JNI_FUNC_PTR(env,GetStaticObjectField)(env, clazz, field); (void)outStream_writeByte(out, specificTypeKey(env, value)); (void)outStream_writeObjectRef(env, out, value); break; } case JDWP_TAG(BYTE): (void)outStream_writeByte(out, JNI_FUNC_PTR(env,GetStaticByteField)(env, clazz, field)); break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?