/* * Method for checking if a key is in the dictionary. For example, * if key in o: */ static int pyjmap_contains_key(PyObject *self, PyObject *key) { jboolean jresult = JNI_FALSE; PyJObject *obj = (PyJObject*) self; JNIEnv *env = pyembed_get_env(); jobject jkey = NULL; int result = -1; if ((*env)->PushLocalFrame(env, JLOCAL_REFS) != 0) { process_java_exception(env); return -1; } jkey = PyObject_As_jobject(env, key, JOBJECT_TYPE); if (!jkey && PyErr_Occurred()) { goto FINALLY; } jresult = java_util_Map_containsKey(env, obj->object, jkey); if (process_java_exception(env)) { goto FINALLY; } if (jresult) { result = 1; } else { result = 0; } FINALLY: (*env)->PopLocalFrame(env, NULL); return result; }
PyObject* pyjiterator_next(PyObject* self) { jmethodID hasNext = NULL; jboolean nextAvail = JNI_FALSE; PyJobject_Object *pyjob = (PyJobject_Object*) self; JNIEnv *env = pyembed_get_env(); hasNext = (*env)->GetMethodID(env, pyjob->clazz, "hasNext", "()Z"); if(process_java_exception(env)) { return NULL; } nextAvail = (*env)->CallBooleanMethod(env, pyjob->object, hasNext); if(process_java_exception(env)) { return NULL; } if(nextAvail) { jobject nextItem; jmethodID next; next = (*env)->GetMethodID(env, pyjob->clazz, "next", "()Ljava/lang/Object;"); if(process_java_exception(env) || !next) { return NULL; } nextItem = (*env)->CallObjectMethod(env, pyjob->object, next); if(process_java_exception(env)) { return NULL; } return convert_jobject_pyobject(env, nextItem); } return NULL; }
/* * Method for iterating over the keys of the dictionary. For example, * for key in o: */ PyObject* pyjmap_getiter(PyObject* obj) { jobject set = NULL; jobject iter = NULL; PyJObject *pyjob = (PyJObject*) obj; JNIEnv *env = pyembed_get_env(); if (mapKeySet == 0) { mapKeySet = (*env)->GetMethodID(env, JMAP_TYPE, "keySet", "()Ljava/util/Set;"); if (process_java_exception(env) || !mapKeySet) { return NULL; } } set = (*env)->CallObjectMethod(env, pyjob->object, mapKeySet); if (process_java_exception(env) || !set) { return NULL; } if (mapKeyItr == 0) { mapKeyItr = (*env)->GetMethodID(env, JCOLLECTION_TYPE, "iterator", "()Ljava/util/Iterator;"); if (process_java_exception(env) || !mapKeyItr) { return NULL; } } iter = (*env)->CallObjectMethod(env, set, mapKeyItr); if (process_java_exception(env) || !iter) { return NULL; } return pyjobject_new(env, iter); }
/* * Method for iterating over the keys of the dictionary. For example, * for key in o: */ static PyObject* pyjmap_getiter(PyObject* obj) { jobject set = NULL; jobject iter = NULL; PyJObject *pyjob = (PyJObject*) obj; PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); if ((*env)->PushLocalFrame(env, JLOCAL_REFS) != 0) { process_java_exception(env); return NULL; } set = java_util_Map_keySet(env, pyjob->object); if (process_java_exception(env) || !set) { goto FINALLY; } iter = java_lang_Iterable_iterator(env, set); if (process_java_exception(env) || !iter) { goto FINALLY; } result = PyJObject_New(env, iter); FINALLY: (*env)->PopLocalFrame(env, NULL); return result; }
/* * Method for the getting items with the [int] operator on pyjlist. For * example, result = o[i] */ static PyObject* pyjlist_getitem(PyObject *o, Py_ssize_t i) { jobject val = NULL; Py_ssize_t size = 0; PyJObject *obj = (PyJObject*) o; JNIEnv *env = pyembed_get_env(); size = PyObject_Size(o); if ((i > size - 1) || (i < 0)) { PyErr_Format(PyExc_IndexError, "list index %i out of range, size %i", (int) i, (int) size); return NULL; } if ((*env)->PushLocalFrame(env, JLOCAL_REFS) != 0) { process_java_exception(env); return NULL; } val = java_util_List_get(env, obj->object, (jint) i); if (process_java_exception(env)) { (*env)->PopLocalFrame(env, NULL); return NULL; } if (val == NULL) { (*env)->PopLocalFrame(env, NULL); Py_RETURN_NONE; } else { PyObject *result = jobject_As_PyObject(env, val); (*env)->PopLocalFrame(env, NULL); return result; } }
/* * Method for the getting items with the [int] operator on pyjlist. For * example, result = o[i] */ static PyObject* pyjlist_getitem(PyObject *o, Py_ssize_t i) { jmethodID get = NULL; jobject val = NULL; Py_ssize_t size = 0; PyJobject_Object *obj = (PyJobject_Object*) o; JNIEnv *env = pyembed_get_env(); get = (*env)->GetMethodID(env, obj->clazz, "get", "(I)Ljava/lang/Object;"); if(process_java_exception(env) || !get) { return NULL; } size = PyObject_Size(o); if((i > size-1) || (i < 0)) { PyErr_Format(PyExc_IndexError, "list index %i out of range, size %i", (int) i, (int) size); return NULL; } val = (*env)->CallObjectMethod(env, obj->object, get, (jint) i); if(process_java_exception(env)) { return NULL; } if(val == NULL) { Py_RETURN_NONE; } else { return pyjobject_new(env, val); } }
/* * Convenience method to copy a list's items into a new java.util.List of the * same type. */ PyObject* pyjlist_new_copy(PyObject *toCopy) { jmethodID newInstance = NULL; jobject newList = NULL; jmethodID addAll = NULL; PyJobject_Object *obj = (PyJobject_Object*) toCopy; JNIEnv *env = pyembed_get_env(); if(!pyjlist_check(toCopy)) { PyErr_Format(PyExc_RuntimeError, "pyjlist_new_copy() must receive a pyjlist"); return NULL; } newInstance = (*env)->GetMethodID(env, JCLASS_TYPE, "newInstance", "()Ljava/lang/Object;"); if(process_java_exception(env) || !newInstance) { return NULL; } newList = (*env)->CallObjectMethod(env, obj->clazz, newInstance); if(process_java_exception(env) || !newList) { return NULL; } addAll = (*env)->GetMethodID(env, obj->clazz, "addAll", "(Ljava/util/Collection;)Z"); if(process_java_exception(env) || !addAll) { return NULL; } (*env)->CallBooleanMethod(env, newList, addAll, obj->object); if(process_java_exception(env)) { return NULL; } return pyjobject_new(env, newList); }
static long pyjobject_hash(PyJObject *self) { JNIEnv *env = pyembed_get_env(); int hash = -1; if (objectHashCode == 0) { objectHashCode = (*env)->GetMethodID(env, self->clazz, "hashCode", "()I"); if (process_java_exception(env) || !objectHashCode) { return -1; } } if (self->object) { hash = (*env)->CallIntMethod(env, self->object, objectHashCode); } else { hash = (*env)->CallIntMethod(env, self->clazz, objectHashCode); } if (process_java_exception(env)) { return -1; } /* * this seems odd but python expects -1 for error occurred and other * built-in types then return -2 if the actual hash is -1 */ if (hash == -1) { hash = -2; } return hash; }
/* * Convenience method to copy a list's items into a new java.util.List of the * same type. */ static PyObject* pyjlist_new_copy(PyObject *toCopy) { jobject newList = NULL; PyJObject *obj = (PyJObject*) toCopy; JNIEnv *env = pyembed_get_env(); PyObject *result = NULL; if (!PyJList_Check(toCopy)) { PyErr_Format(PyExc_RuntimeError, "pyjlist_new_copy() must receive a PyJList"); return NULL; } if ((*env)->PushLocalFrame(env, JLOCAL_REFS) != 0) { process_java_exception(env); return NULL; } newList = java_lang_Class_newInstance(env, obj->clazz); if (process_java_exception(env) || !newList) { goto FINALLY; } java_util_List_addAll(env, newList, obj->object); if (process_java_exception(env)) { goto FINALLY; } result = PyJList_Wrap(env, newList, obj->clazz); FINALLY: (*env)->PopLocalFrame(env, NULL); return result; }
static PyObject* pyjnumber_absolute(PyObject *x) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); CALL_UNARY(env, PyNumber_Absolute, x); return result; }
static PyObject* pyjnumber_subtract(PyObject *x, PyObject *y) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); CALL_BINARY(env, PyNumber_Subtract, x, y); return result; }
static PyObject* pyjnumber_positive(PyObject *x) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); CALL_UNARY(env, PyNumber_Positive, x); return result; }
static PyObject* pyjnumber_divmod(PyObject *x, PyObject *y) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); CALL_BINARY(env, PyNumber_Divmod, x, y); return result; }
static PyObject* pyjnumber_truedivide(PyObject *x, PyObject *y) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); CALL_BINARY(env, PyNumber_TrueDivide, x, y); return result; }
static PyObject* pyjnumber_remainder(PyObject *x, PyObject *y) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); CALL_BINARY(env, PyNumber_Remainder, x, y); return result; }
static PyObject* pyjnumber_multiply(PyObject *x, PyObject *y) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); CALL_BINARY(env, PyNumber_Multiply, x, y); return result; }
// find and call a method on this object that matches the python args. // typically called from pyjmethod when python invokes __call__. // // steals reference to self, methodname and args. PyObject* pyjobject_find_method(PyJobject_Object *self, PyObject *methodName, PyObject *args) { // util method does this for us return find_method(pyembed_get_env(), methodName, PyList_Size(self->methods), self->attr, args); }
/* * Method for the setting items with the [key] operator on pyjmap. For example, * o[key] = v. Also supports del o[key] */ 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(); int result = -1; if ((*env)->PushLocalFrame(env, JLOCAL_REFS) != 0) { process_java_exception(env); return -1; } if (v == NULL) { // this is a del PyJMap[key] statement if (!pyjmap_contains_key(o, key)) { PyObject *pystr = PyObject_Str(key); PyErr_Format(PyExc_KeyError, "KeyError: %s", PyString_AsString(pystr)); Py_XDECREF(pystr); goto FINALLY; } jkey = PyObject_As_jobject(env, key, JOBJECT_TYPE); if (!jkey && PyErr_Occurred()) { goto FINALLY; } java_util_Map_remove(env, obj->object, jkey); if (process_java_exception(env)) { goto FINALLY; } } else { value = PyObject_As_jobject(env, v, JOBJECT_TYPE); if (!value && PyErr_Occurred()) { goto FINALLY; } jkey = PyObject_As_jobject(env, key, JOBJECT_TYPE); if (!jkey && PyErr_Occurred()) { return -1; } java_util_Map_put(env, obj->object, jkey, value); if (process_java_exception(env)) { goto FINALLY; } } // have to return 0 on success even though it's not documented result = 0; FINALLY: (*env)->PopLocalFrame(env, NULL); return result; }
/* * Gets the size of the map. */ static Py_ssize_t pyjmap_len(PyObject *self) { Py_ssize_t len = 0; PyJObject *pyjob = (PyJObject*) self; JNIEnv *env = pyembed_get_env(); len = java_util_Map_size(env, pyjob->object); if (process_java_exception(env)) { return -1; } return len; }
/* * 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; }
/* * Exits the Python ContextManager and calls java.lang.AutoCloseable.close(). */ static PyObject* pyjautocloseable_exit(PyObject* self, PyObject* args) { PyJObject *pyjob = (PyJObject*) self; JNIEnv *env = pyembed_get_env(); java_lang_AutoCloseable_close(env, pyjob->object); if (process_java_exception(env)) { return NULL; } Py_RETURN_NONE; }
static int pyjnumber_nonzero(PyObject *x) { JNIEnv *env = pyembed_get_env(); int result = -1; if (pyjnumber_check(x)) { x = java_number_to_python(env, x); } result = PyObject_IsTrue(x); Py_DECREF(x); return result; }
static PyObject* pyjnumber_long(PyObject *x) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); result = java_number_to_pythonintlong(env, x); if (PyInt_Check(result)) { PyObject *longResult = PyLong_FromLong(PyInt_AS_LONG(result)); Py_DECREF(result); return longResult; } return result; }
/* * 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 void pyjmethod_dealloc(PyJmethod_Object *self) { #if USE_DEALLOC JNIEnv *env = pyembed_get_env(); if(env) { if(self->parameters) (*env)->DeleteGlobalRef(env, self->parameters); if(self->rmethod) (*env)->DeleteGlobalRef(env, self->rmethod); } Py_CLEAR(self->pyMethodName); PyObject_Del(self); #endif }
static void pyjfield_dealloc(PyJfield_Object *self) { #if USE_DEALLOC JNIEnv *env = pyembed_get_env(); if(env) { if(self->rfield) (*env)->DeleteGlobalRef(env, self->rfield); } if(self->pyFieldName) { Py_DECREF(self->pyFieldName); } PyObject_Del(self); #endif }
/* * Method for the += operator on pyjlist. For example, o1 += o2, where * o1 is a pyjlist. */ static PyObject* pyjlist_inplace_add(PyObject *o1, PyObject *o2) { jobject value = NULL; jclass collection = NULL; JNIEnv *env = pyembed_get_env(); PyJobject_Object *self = (PyJobject_Object*) o1; if(pyjlist_check(o2)) { value = ((PyJobject_Object*) o2)->object; } else { value = pyembed_box_py(env, o2); } collection = (*env)->FindClass(env, "java/util/Collection"); if(process_java_exception(env) || !collection) { return NULL; } if((*env)->IsInstanceOf(env, value, collection)) { /* * it's a Collection so we need to simulate a python + and combine the * two collections */ jmethodID addAll = (*env)->GetMethodID(env, self->clazz, "addAll", "(Ljava/util/Collection;)Z"); if(process_java_exception(env) || !addAll) { return NULL; } (*env)->CallBooleanMethod(env, self->object, addAll, value); if(process_java_exception(env)) { return NULL; } } else { // not a collection, add it as a single object jmethodID add = (*env)->GetMethodID(env, self->clazz, "add", "(Ljava/lang/Object;)Z"); if(process_java_exception(env) || !add) { return NULL; } (*env)->CallBooleanMethod(env, self->object, add, value); if(process_java_exception(env)) { return NULL; } } Py_INCREF(o1); return o1; }
// call toString() on jobject. returns null on error. // excpected to return new reference. static PyObject* pyjobject_str(PyJobject_Object *self) { PyObject *pyres = NULL; JNIEnv *env; env = pyembed_get_env(); pyres = jobject_topystring(env, self->object, self->clazz); if(process_java_exception(env)) return NULL; // python doesn't like Py_None here... if(pyres == NULL) return Py_BuildValue("s", ""); return pyres; }
/* * Method for checking if a key is in the dictionary. For example, * if key in o: */ static int pyjmap_contains_key(PyObject *self, PyObject *key) { jboolean result = JNI_FALSE; PyJObject *obj = (PyJObject*) self; JNIEnv *env = pyembed_get_env(); jobject jkey = NULL; if (key == Py_None) { jkey = NULL; } else { jkey = pyembed_box_py(env, key); if (process_java_exception(env)) { return -1; } else if (!jkey) { /* * with the way pyembed_box_py is currently implemented, shouldn't * be able to get here */ PyObject *pystring = PyObject_Str((PyObject*) Py_TYPE(key)); PyErr_Format(PyExc_TypeError, "__contains__ received an incompatible type: %s", PyString_AsString(pystring)); Py_XDECREF(pystring); return -1; } } if (mapContainsKey == 0) { mapContainsKey = (*env)->GetMethodID(env, JMAP_TYPE, "containsKey", "(Ljava/lang/Object;)Z"); if (process_java_exception(env) || !mapContainsKey) { return -1; } } result = (*env)->CallBooleanMethod(env, obj->object, mapContainsKey, jkey); if (process_java_exception(env)) { return -1; } if (result) { return 1; } else { return 0; } }
static PyObject* pyjnumber_power(PyObject *x, PyObject *y, PyObject *z) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); TO_PYTHON_NUMBER(env, x); TO_PYTHON_NUMBER(env, y); if (z != Py_None) { TO_PYTHON_NUMBER(env, z); } result = PyNumber_Power(x, y, z); Py_DECREF(x); Py_DECREF(y); Py_DECREF(z); return result; }