/* * Method for the setting items with the [key] operator on pyjmap. For example, * o[key] = v */ static int pyjmap_setitem(PyObject *o, PyObject *key, PyObject *v) { jobject jkey = NULL; jobject value = NULL; PyJObject *obj = (PyJObject*) o; JNIEnv *env = pyembed_get_env(); if (v == Py_None) { value = NULL; } else { value = pyembed_box_py(env, v); if (process_java_exception(env)) { return -1; } else if (!value) { /* * with the way pyembed_box_py is currently implemented, shouldn't * be able to get here */ PyObject *pystring = PyObject_Str((PyObject*) Py_TYPE(v)); PyErr_Format(PyExc_TypeError, "__setitem__ received an incompatible type: %s", PyString_AsString(pystring)); Py_XDECREF(pystring); return -1; } } if (pyjobject_check(key)) { jkey = ((PyJObject*) key)->object; } else { jvalue jvkey = convert_pyarg_jvalue(env, key, JOBJECT_TYPE, JOBJECT_ID, 1); jkey = jvkey.l; if (process_java_exception(env) || !jkey) { return -1; } } if (mapPut == 0) { mapPut = (*env)->GetMethodID(env, JMAP_TYPE, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); if (process_java_exception(env) || !mapPut) { return -1; } } (*env)->CallObjectMethod(env, obj->object, mapPut, jkey, value); if (process_java_exception(env)) { return -1; } // have to return 0 on success even though it's not documented return 0; }
/* * Method for the getting items with the [key] operator on pyjmap. For * example, result = o[key] */ static PyObject* pyjmap_getitem(PyObject *o, PyObject *key) { jobject jkey = NULL; jobject val = NULL; PyJObject *obj = (PyJObject*) o; JNIEnv *env = pyembed_get_env(); if (mapGet == 0) { mapGet = (*env)->GetMethodID(env, JMAP_TYPE, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); if (process_java_exception(env) || !mapGet) { return NULL; } } if (pyjobject_check(key)) { jkey = ((PyJObject*) key)->object; } else { /* * convert_pyarg_jvalue will leave jkey as NULL and set PyExc_TypeError * if we can't handle the key type, which matches python's guidelines */ jvalue jvkey = convert_pyarg_jvalue(env, key, JOBJECT_TYPE, JOBJECT_ID, 1); jkey = jvkey.l; if (process_java_exception(env) || !jkey) { return NULL; } } val = (*env)->CallObjectMethod(env, obj->object, mapGet, jkey); if (process_java_exception(env)) { return NULL; } if (!val) { /* * Python docs indicate KeyError should be set if the key is not in the * container, but some Maps allow null values. So we have to check. */ if (!pyjmap_contains_key(o, key)) { PyObject *pystr = PyObject_Str(key); PyErr_Format(PyExc_KeyError, "KeyError: %s", PyString_AsString(pystr)); Py_XDECREF(pystr); return NULL; } } return convert_jobject_pyobject(env, val); }
static PyObject* pyjconstructor_call(PyJMethodObject *self, PyObject *args, PyObject *keywords) { PyObject *firstArg = NULL; PyJObject *clazz = NULL; JNIEnv *env = NULL; int pos = 0; jvalue *jargs = NULL; int foundArray = 0; /* if params includes pyjarray instance */ PyThreadState *_save = NULL; jobject obj = NULL; PyObject *pobj = NULL; if (keywords != NULL) { PyErr_Format(PyExc_TypeError, "Keywords are not supported."); return NULL; } if (self->lenParameters != PyTuple_GET_SIZE(args) - 1) { PyErr_Format(PyExc_RuntimeError, "Invalid number of arguments: %i, expected %i.", (int) PyTuple_GET_SIZE(args), self->lenParameters + 1); return NULL; } firstArg = PyTuple_GetItem(args, 0); if (!pyjclass_check(firstArg)) { PyErr_SetString(PyExc_RuntimeError, "First argument to a java constructor must be a java class."); return NULL; } clazz = (PyJObject*) firstArg; // ------------------------------ build jargs off python values env = pyembed_get_env(); if ((*env)->PushLocalFrame(env, JLOCAL_REFS + self->lenParameters) != 0) { process_java_exception(env); return NULL; } jargs = (jvalue *) PyMem_Malloc(sizeof(jvalue) * self->lenParameters); for (pos = 0; pos < self->lenParameters; pos++) { PyObject *param = NULL; int paramTypeId = -1; jclass paramType = (jclass) (*env)->GetObjectArrayElement(env, self->parameters, pos); param = PyTuple_GetItem(args, pos + 1); /* borrowed */ if (PyErr_Occurred()) { goto EXIT_ERROR; } paramTypeId = get_jtype(env, paramType); if (paramTypeId == JARRAY_ID) { foundArray = 1; } jargs[pos] = convert_pyarg_jvalue(env, param, paramType, paramTypeId, pos); if (PyErr_Occurred()) { goto EXIT_ERROR; } (*env)->DeleteLocalRef(env, paramType); } Py_UNBLOCK_THREADS; obj = (*env)->NewObjectA(env, clazz->clazz, self->methodId, jargs); Py_BLOCK_THREADS; if (process_java_exception(env) || !obj) { goto EXIT_ERROR; } // finally, make pyjobject and return pobj = pyjobject_new(env, obj); // we already closed the local frame, so make // sure to delete this local ref. PyMem_Free(jargs); // re pin array if needed if (foundArray) { for (pos = 0; pos < self->lenParameters; pos++) { PyObject *param = PyTuple_GetItem(args, pos); if (param && pyjarray_check(param)) { pyjarray_pin((PyJArrayObject *) param); } } } (*env)->PopLocalFrame(env, NULL); return pobj; EXIT_ERROR: PyMem_Free(jargs); (*env)->PopLocalFrame(env, NULL); return NULL; }
// pyjmethod_call_internal. where the magic happens. // // okay, some of the magic -- we already the methodId, so we don't have // to reflect. we just have to parse the arguments from python, // check them against the java args, and call the java function. // // easy. :-) PyObject* pyjmethod_call_internal(PyJmethod_Object *self, PyJobject_Object *instance, PyObject *args) { PyObject *result = NULL; const char *str = NULL; JNIEnv *env = NULL; int pos = 0; jvalue *jargs = NULL; int foundArray = 0; /* if params includes pyjarray instance */ PyThreadState *_save; env = pyembed_get_env(); if(!self->parameters) { if(!pyjmethod_init(env, self) || PyErr_Occurred()) return NULL; return pyjmethod_call_internal(self, instance, args); } // validate we can call this method if(!instance->object && self->isStatic != JNI_TRUE) { PyErr_Format(PyExc_RuntimeError, "Instantiate this class before " "calling an object method."); return NULL; } // shouldn't happen if(self->lenParameters != PyTuple_GET_SIZE(args)) { PyErr_Format(PyExc_RuntimeError, "Invalid number of arguments: %i, expected %i.", (int) PyTuple_GET_SIZE(args), self->lenParameters); return NULL; } jargs = (jvalue *) PyMem_Malloc(sizeof(jvalue) * self->lenParameters); // ------------------------------ build jargs off python values // hopefully 40 local references are enough per method call (*env)->PushLocalFrame(env, 40); for(pos = 0; pos < self->lenParameters; pos++) { PyObject *param = NULL; int paramTypeId = -1; jclass paramType = (jclass) (*env)->GetObjectArrayElement(env, self->parameters, pos); param = PyTuple_GetItem(args, pos); /* borrowed */ if(PyErr_Occurred()) { /* borrowed */ goto EXIT_ERROR; } paramTypeId = get_jtype(env, paramType); if(paramTypeId == JARRAY_ID) foundArray = 1; jargs[pos] = convert_pyarg_jvalue(env, param, paramType, paramTypeId, pos); if(PyErr_Occurred()) { /* borrowed */ goto EXIT_ERROR; } (*env)->DeleteLocalRef(env, paramType); } // for parameters // ------------------------------ call based off return type switch(self->returnTypeId) { case JSTRING_ID: { jstring jstr; Py_UNBLOCK_THREADS; if(self->isStatic) jstr = (jstring) (*env)->CallStaticObjectMethodA( env, instance->clazz, self->methodId, jargs); else { // not static, a method on class then. if(!instance->object) jstr = (jstring) (*env)->CallObjectMethodA( env, instance->clazz, self->methodId, jargs); else jstr = (jstring) (*env)->CallObjectMethodA( env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env) && jstr != NULL) { str = (*env)->GetStringUTFChars(env, jstr, 0); result = PyString_FromString(str); (*env)->ReleaseStringUTFChars(env, jstr, str); (*env)->DeleteLocalRef(env, jstr); } break; } case JARRAY_ID: { jobjectArray obj; Py_UNBLOCK_THREADS; if(self->isStatic) obj = (jobjectArray) (*env)->CallStaticObjectMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) obj = (jobjectArray) (*env)->CallObjectMethodA( env, instance->clazz, self->methodId, jargs); else obj = (jobjectArray) (*env)->CallObjectMethodA( env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env) && obj != NULL) result = pyjarray_new(env, obj); break; } case JCLASS_ID: { jobject obj; Py_UNBLOCK_THREADS; if(self->isStatic) obj = (*env)->CallStaticObjectMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) obj = (*env)->CallObjectMethodA(env, instance->clazz, self->methodId, jargs); else obj = (*env)->CallObjectMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env) && obj != NULL) result = pyjobject_new_class(env, obj); break; } case JOBJECT_ID: { jobject obj; Py_UNBLOCK_THREADS; if(self->isStatic) obj = (*env)->CallStaticObjectMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) obj = (*env)->CallObjectMethodA(env, instance->clazz, self->methodId, jargs); else obj = (*env)->CallObjectMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env) && obj != NULL) { result = pyjobject_new(env, obj); } break; } case JINT_ID: { jint ret; Py_UNBLOCK_THREADS; if(self->isStatic) ret = (*env)->CallStaticIntMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) ret = (*env)->CallIntMethodA(env, instance->clazz, self->methodId, jargs); else ret = (*env)->CallIntMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env)) result = Py_BuildValue("i", ret); break; } case JBYTE_ID: { jbyte ret; Py_UNBLOCK_THREADS; if(self->isStatic) ret = (*env)->CallStaticByteMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) ret = (*env)->CallByteMethodA(env, instance->clazz, self->methodId, jargs); else ret = (*env)->CallByteMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env)) result = Py_BuildValue("i", ret); break; } case JCHAR_ID: { jchar ret; char val[2]; Py_UNBLOCK_THREADS; if(self->isStatic) ret = (*env)->CallStaticCharMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) ret = (*env)->CallCharMethodA(env, instance->clazz, self->methodId, jargs); else ret = (*env)->CallCharMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env)) { val[0] = (char) ret; val[1] = '\0'; result = PyString_FromString(val); } break; } case JSHORT_ID: { jshort ret; Py_UNBLOCK_THREADS; if(self->isStatic) ret = (*env)->CallStaticShortMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) ret = (*env)->CallShortMethodA(env, instance->clazz, self->methodId, jargs); else ret = (*env)->CallShortMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env)) result = Py_BuildValue("i", (int) ret); break; } case JDOUBLE_ID: { jdouble ret; Py_UNBLOCK_THREADS; if(self->isStatic) ret = (*env)->CallStaticDoubleMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) ret = (*env)->CallDoubleMethodA(env, instance->clazz, self->methodId, jargs); else ret = (*env)->CallDoubleMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env)) result = PyFloat_FromDouble(ret); break; } case JFLOAT_ID: { jfloat ret; Py_UNBLOCK_THREADS; if(self->isStatic) ret = (*env)->CallStaticFloatMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) ret = (*env)->CallFloatMethodA(env, instance->clazz, self->methodId, jargs); else ret = (*env)->CallFloatMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env)) result = PyFloat_FromDouble((double) ret); break; } case JLONG_ID: { jlong ret; Py_UNBLOCK_THREADS; if(self->isStatic) ret = (*env)->CallStaticLongMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) ret = (*env)->CallLongMethodA(env, instance->clazz, self->methodId, jargs); else ret = (*env)->CallLongMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env)) result = PyLong_FromLongLong(ret); break; } case JBOOLEAN_ID: { jboolean ret; Py_UNBLOCK_THREADS; if(self->isStatic) ret = (*env)->CallStaticBooleanMethodA( env, instance->clazz, self->methodId, jargs); else { if(!instance->object) ret = (*env)->CallBooleanMethodA(env, instance->clazz, self->methodId, jargs); else ret = (*env)->CallBooleanMethodA(env, instance->object, self->methodId, jargs); } Py_BLOCK_THREADS; if(!process_java_exception(env)) result = Py_BuildValue("i", ret); break; } default: Py_UNBLOCK_THREADS; // i hereby anoint thee a void method if(self->isStatic) (*env)->CallStaticVoidMethodA(env, instance->clazz, self->methodId, jargs); else (*env)->CallVoidMethodA(env, instance->object, self->methodId, jargs); Py_BLOCK_THREADS; process_java_exception(env); break; } PyMem_Free(jargs); (*env)->PopLocalFrame(env, NULL); if(PyErr_Occurred()) return NULL; // re pin array objects if needed if(foundArray) { for(pos = 0; pos < self->lenParameters; pos++) { PyObject *param = PyTuple_GetItem(args, pos); /* borrowed */ if(param && pyjarray_check(param)) pyjarray_pin((PyJarray_Object *) param); } } if(result == NULL) { Py_RETURN_NONE; } return result; EXIT_ERROR: PyMem_Free(jargs); (*env)->PopLocalFrame(env, NULL); return NULL; }
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; }