コード例 #1
0
ファイル: pyjfield.c プロジェクト: bsteffensmeier/jep
int pyjfield_set(PyJfield_Object *self, PyObject *value) {
    JNIEnv   *env;
    jvalue    jarg;
    
    env = pyembed_get_env();
    
    if(!self) {
        PyErr_Format(PyExc_RuntimeError, "Invalid self object.");
        return -1;
    }
    
    if(!self->init) {
        if(!pyjfield_init(env, self) || PyErr_Occurred())
            return -1;
    }
    
    switch(self->fieldTypeId) {

    case JSTRING_ID:
        if(!pyarg_matches_jtype(env, value, JSTRING_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected string.");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JSTRING_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;
        
        if(self->isStatic)
            (*env)->SetStaticObjectField(env,
                                         self->pyjobject->clazz,
                                         self->fieldId,
                                         jarg.l);
        else
            (*env)->SetObjectField(env,
                                   self->pyjobject->object,
                                   self->fieldId,
                                   jarg.l);
        
        if(process_java_exception(env))
            return -1;
        
        return 0; // success
    
        
    case JCLASS_ID:
        if(!pyarg_matches_jtype(env, value, JCLASS_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected class.");
            return -1;
        }
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JCLASS_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;

        if(self->isStatic)
            (*env)->SetStaticObjectField(env,
                                         self->pyjobject->clazz,
                                         self->fieldId,
                                         jarg.l);
        else
            (*env)->SetObjectField(env,
                                   self->pyjobject->object,
                                   self->fieldId,
                                   jarg.l);
        
        if(process_java_exception(env))
            return -1;
        
        return 0; // success


    case JOBJECT_ID:
        if(!pyarg_matches_jtype(env, value, JOBJECT_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected object.");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JOBJECT_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;

        if(self->isStatic)
            (*env)->SetStaticObjectField(env,
                                         self->pyjobject->clazz,
                                         self->fieldId,
                                         jarg.l);
        else
            (*env)->SetObjectField(env,
                                   self->pyjobject->object,
                                   self->fieldId,
                                   jarg.l);
        
        if(process_java_exception(env))
            return -1;
        
        return 0; // success

        
    case JINT_ID:
        if(!pyarg_matches_jtype(env, value, JINT_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected int.");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JINT_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;
        
        if(self->isStatic)
            (*env)->SetStaticIntField(env,
                                      self->pyjobject->clazz,
                                      self->fieldId,
                                      jarg.i);
        else
            (*env)->SetIntField(env,
                                self->pyjobject->object,
                                self->fieldId,
                                jarg.i);

        if(process_java_exception(env))
            return -1;
        
        return 0; // success


    case JCHAR_ID:
        if(!pyarg_matches_jtype(env, value, JCHAR_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected char.");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JCHAR_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;
        
        if(self->isStatic)
            (*env)->SetStaticCharField(env,
                                      self->pyjobject->clazz,
                                      self->fieldId,
                                      jarg.c);
        else
            (*env)->SetCharField(env,
                                self->pyjobject->object,
                                self->fieldId,
                                jarg.c);

        if(process_java_exception(env))
            return -1;
        
        return 0; // success

        
    case JBYTE_ID:
        if(!pyarg_matches_jtype(env, value, JBYTE_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected byte.");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JBYTE_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;
        
        if(self->isStatic)
            (*env)->SetStaticByteField(env,
                                      self->pyjobject->clazz,
                                      self->fieldId,
                                      jarg.b);
        else
            (*env)->SetByteField(env,
                                self->pyjobject->object,
                                self->fieldId,
                                jarg.b);

        if(process_java_exception(env))
            return -1;
        
        return 0; // success
        
        
    case JSHORT_ID:
        if(!pyarg_matches_jtype(env, value, JSHORT_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected int.");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JSHORT_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;
        
        if(self->isStatic)
            (*env)->SetStaticShortField(env,
                                        self->pyjobject->clazz,
                                        self->fieldId,
                                        jarg.s);
        else
            (*env)->SetShortField(env,
                                  self->pyjobject->object,
                                  self->fieldId,
                                  jarg.s);

        if(process_java_exception(env))
            return -1;
        
        return 0; // success


    case JDOUBLE_ID:
        if(!pyarg_matches_jtype(env, value, JDOUBLE_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected float (jdouble).");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JDOUBLE_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;
        
        if(self->isStatic)
            (*env)->SetStaticDoubleField(env,
                                         self->pyjobject->clazz,
                                         self->fieldId,
                                         jarg.d);
        else
            (*env)->SetDoubleField(env,
                                   self->pyjobject->object,
                                   self->fieldId,
                                   jarg.d);
        
        if(process_java_exception(env))
            return -1;
        
        return 0; // success


    case JFLOAT_ID:
        if(!pyarg_matches_jtype(env, value, JFLOAT_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected float (jfloat).");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JFLOAT_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;
        
        if(self->isStatic)
            (*env)->SetStaticFloatField(env,
                                        self->pyjobject->clazz,
                                        self->fieldId,
                                        jarg.f);
        else
            (*env)->SetFloatField(env,
                                  self->pyjobject->object,
                                  self->fieldId,
                                  jarg.f);
        
        if(process_java_exception(env))
            return -1;
        
        return 0; // success


    case JLONG_ID:
        if(!pyarg_matches_jtype(env, value, JLONG_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected long.");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JLONG_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;
        
        if(self->isStatic)
            (*env)->SetStaticLongField(env,
                                       self->pyjobject->clazz,
                                       self->fieldId,
                                       jarg.j);
        else
            (*env)->SetLongField(env,
                                 self->pyjobject->object,
                                 self->fieldId,
                                 jarg.j);
        
        if(process_java_exception(env))
            return -1;
        
        return 0; // success


    case JBOOLEAN_ID:
        if(!pyarg_matches_jtype(env, value, JBOOLEAN_TYPE, self->fieldTypeId)) {
            PyErr_Format(PyExc_RuntimeError, "Expected boolean.");
            return -1;
        }
        
        jarg = convert_pyarg_jvalue(env,
                                    value,
                                    JBOOLEAN_TYPE,
                                    self->fieldTypeId,
                                    1);
        if(PyErr_Occurred())
            return -1;
        
        if(self->isStatic)
            (*env)->SetStaticBooleanField(env,
                                          self->pyjobject->clazz,
                                          self->fieldId,
                                          jarg.z);
        else
            (*env)->SetBooleanField(env,
                                    self->pyjobject->object,
                                    self->fieldId,
                                    jarg.z);

        if(process_java_exception(env))
            return -1;
        
        return 0; // success
    }
    

    PyErr_Format(PyExc_RuntimeError,
                 "Unknown field type %i.",
                 self->fieldTypeId);
    return -1;
}
コード例 #2
0
ファイル: pyjobject.c プロジェクト: Kroisse/jep
// find and call a method on this object that matches the python args.
// typically called by way of pyjmethod when python invokes __call__.
//
// steals reference to self, methodname and args.
PyObject* find_method(JNIEnv *env,
                      PyObject *methodName,
                      Py_ssize_t methodCount,
                      PyObject *attr,
                      PyObject *args) {
    // all possible method candidates
    PyJmethod_Object **cand = NULL;
    Py_ssize_t         pos, i, listSize, argsSize;
    
    pos = i = listSize = argsSize = 0;

    // not really likely if we were called from pyjmethod, but hey...
    if(methodCount < 1) {
        PyErr_Format(PyExc_RuntimeError, "I have no methods.");
        return NULL;
    }

    if(!attr || !PyList_CheckExact(attr)) {
        PyErr_Format(PyExc_RuntimeError, "Invalid attr list.");
        return NULL;
    }
    
    cand = (PyJmethod_Object **)
        PyMem_Malloc(sizeof(PyJmethod_Object*) * methodCount);
    
    // just for safety
    for(i = 0; i < methodCount; i++)
        cand[i] = NULL;
    
    listSize = PyList_GET_SIZE(attr);
    for(i = 0; i < listSize; i++) {
        PyObject *tuple = PyList_GetItem(attr, i);               /* borrowed */

        if(PyErr_Occurred())
            break;
        
        if(!tuple || tuple == Py_None || !PyTuple_CheckExact(tuple))
            continue;

        if(PyTuple_Size(tuple) == 2) {
            PyObject *key = PyTuple_GetItem(tuple, 0);           /* borrowed */
            
            if(PyErr_Occurred())
                break;
            
            if(!key || !PyString_Check(key))
                continue;
            
            if(PyObject_Compare(key, methodName) == 0) {
                PyObject *method = PyTuple_GetItem(tuple, 1);    /* borrowed */
                if(pyjmethod_check(method))
                    cand[pos++] = (PyJmethod_Object *) method;
            }
        }
    }
    
    if(PyErr_Occurred())
        goto EXIT_ERROR;
    
    // makes more sense to work with...
    pos--;
    
    if(pos < 0) {
        // didn't find a method by that name....
        // that shouldn't happen unless the search above is broken.
        PyErr_Format(PyExc_NameError, "No such method.");
        goto EXIT_ERROR;
    }
    if(pos == 0) {
        // we're done, call that one
        PyObject *ret = pyjmethod_call_internal(cand[0], args);
        PyMem_Free(cand);
        return ret;
    }

    // first, find out if there's only one method that
    // has the correct number of args
    argsSize = PyTuple_Size(args);
    {
        PyJmethod_Object *matching = NULL;
        int               count    = 0;
        
        for(i = 0; i <= pos && cand[i]; i++) {
            // make sure method is fully initialized
            if(!cand[i]->parameters) {
                if(!pyjmethod_init(env, cand[i])) {
                    // init failed, that's not good.
                    cand[i] = NULL;
                    PyErr_Warn(PyExc_Warning, "pyjmethod init failed.");
                    continue;
                }
            }

            if(cand[i]->lenParameters == argsSize) {
                matching = cand[i];
                count++;
            }
            else
                cand[i] = NULL; // eliminate non-matching
        }
        
        if(matching && count == 1) {
            PyMem_Free(cand);
            return pyjmethod_call_internal(matching, args);
        }
    } // local scope
    
    for(i = 0; i <= pos; i++) {
        int parmpos = 0;
        
        // already eliminated?
        if(!cand[i])
            continue;
        
        // check if argument types match
        (*env)->PushLocalFrame(env, 20);
        for(parmpos = 0; parmpos < cand[i]->lenParameters; parmpos++) {
            PyObject *param       = PyTuple_GetItem(args, parmpos);
            int       paramTypeId = -1;
            jclass    pclazz;
            jclass    paramType =
                (jclass) (*env)->GetObjectArrayElement(env,
                                                       cand[i]->parameters,
                                                       parmpos);

            if(process_java_exception(env) || !paramType)
                break;
            
            pclazz = (*env)->GetObjectClass(env, paramType);
            if(process_java_exception(env) || !pclazz)
                break;
            
            paramTypeId = get_jtype(env, paramType, pclazz);
            
            if(pyarg_matches_jtype(env, param, paramType, paramTypeId)) {
                if(PyErr_Occurred())
                    break;
                continue;
            }
            
            // args don't match
            break;
        }
        (*env)->PopLocalFrame(env, NULL);
        
        // this method matches?
        if(parmpos == cand[i]->lenParameters) {
            PyObject *ret = pyjmethod_call_internal(cand[i], args);
            PyMem_Free(cand);
            return ret;
        }
    }


EXIT_ERROR:
    PyMem_Free(cand);
    if(!PyErr_Occurred())
        PyErr_Format(PyExc_NameError,
                     "Matching overloaded method not found.");
    return NULL;
}