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 + -
显示快捷键?