mirror of https://github.com/kivy/pyjnius.git
refactor the conversion functions, move them into jnius_conversion.pxi, and factorize the jobject conversion.
This commit is contained in:
parent
a4af093aa1
commit
69fe77c403
415
jnius/jnius.pyx
415
jnius/jnius.pyx
|
@ -96,6 +96,7 @@ IF JNIUS_PLATFORM == "android":
|
||||||
include "jnius_jvm_android.pxi"
|
include "jnius_jvm_android.pxi"
|
||||||
ELSE:
|
ELSE:
|
||||||
include "jnius_jvm_desktop.pxi"
|
include "jnius_jvm_desktop.pxi"
|
||||||
|
include "jnius_conversion.pxi"
|
||||||
|
|
||||||
|
|
||||||
cdef parse_definition(definition):
|
cdef parse_definition(definition):
|
||||||
|
@ -130,320 +131,6 @@ cdef parse_definition(definition):
|
||||||
|
|
||||||
return ret, args
|
return ret, args
|
||||||
|
|
||||||
cdef convert_jarray_to_python(JNIEnv *j_env, definition, jobject j_object):
|
|
||||||
cdef jboolean iscopy
|
|
||||||
cdef jboolean *j_booleans
|
|
||||||
cdef jbyte *j_bytes
|
|
||||||
cdef jchar *j_chars
|
|
||||||
cdef jshort *j_shorts
|
|
||||||
cdef jint *j_ints
|
|
||||||
cdef jlong *j_longs
|
|
||||||
cdef jfloat *j_floats
|
|
||||||
cdef jdouble *j_doubles
|
|
||||||
cdef object ret = None
|
|
||||||
cdef jsize array_size
|
|
||||||
|
|
||||||
cdef int i
|
|
||||||
cdef jobject obj
|
|
||||||
cdef char *c_str
|
|
||||||
cdef bytes py_str
|
|
||||||
cdef JavaObject ret_jobject
|
|
||||||
cdef JavaClass ret_jc
|
|
||||||
|
|
||||||
if j_object == NULL:
|
|
||||||
return None
|
|
||||||
|
|
||||||
array_size = j_env[0].GetArrayLength(j_env, j_object)
|
|
||||||
|
|
||||||
r = definition[0]
|
|
||||||
if r == 'Z':
|
|
||||||
j_booleans = j_env[0].GetBooleanArrayElements(
|
|
||||||
j_env, j_object, &iscopy)
|
|
||||||
ret = [(True if j_booleans[i] else False)
|
|
||||||
for i in range(array_size)]
|
|
||||||
if iscopy:
|
|
||||||
j_env[0].ReleaseBooleanArrayElements(
|
|
||||||
j_env, j_object, j_booleans, 0)
|
|
||||||
|
|
||||||
elif r == 'B':
|
|
||||||
j_bytes = j_env[0].GetByteArrayElements(
|
|
||||||
j_env, j_object, &iscopy)
|
|
||||||
ret = [(<char>j_bytes[i]) for i in range(array_size)]
|
|
||||||
if iscopy:
|
|
||||||
j_env[0].ReleaseByteArrayElements(
|
|
||||||
j_env, j_object, j_bytes, 0)
|
|
||||||
|
|
||||||
elif r == 'C':
|
|
||||||
j_chars = j_env[0].GetCharArrayElements(
|
|
||||||
j_env, j_object, &iscopy)
|
|
||||||
ret = [(<char>j_chars[i]) for i in range(array_size)]
|
|
||||||
if iscopy:
|
|
||||||
j_env[0].ReleaseCharArrayElements(
|
|
||||||
j_env, j_object, j_chars, 0)
|
|
||||||
|
|
||||||
elif r == 'S':
|
|
||||||
j_shorts = j_env[0].GetShortArrayElements(
|
|
||||||
j_env, j_object, &iscopy)
|
|
||||||
ret = [(<short>j_shorts[i]) for i in range(array_size)]
|
|
||||||
if iscopy:
|
|
||||||
j_env[0].ReleaseShortArrayElements(
|
|
||||||
j_env, j_object, j_shorts, 0)
|
|
||||||
|
|
||||||
elif r == 'I':
|
|
||||||
j_ints = j_env[0].GetIntArrayElements(
|
|
||||||
j_env, j_object, &iscopy)
|
|
||||||
ret = [(<int>j_ints[i]) for i in range(array_size)]
|
|
||||||
if iscopy:
|
|
||||||
j_env[0].ReleaseIntArrayElements(
|
|
||||||
j_env, j_object, j_ints, 0)
|
|
||||||
|
|
||||||
elif r == 'J':
|
|
||||||
j_longs = j_env[0].GetLongArrayElements(
|
|
||||||
j_env, j_object, &iscopy)
|
|
||||||
ret = [(<long>j_longs[i]) for i in range(array_size)]
|
|
||||||
if iscopy:
|
|
||||||
j_env[0].ReleaseLongArrayElements(
|
|
||||||
j_env, j_object, j_longs, 0)
|
|
||||||
|
|
||||||
elif r == 'F':
|
|
||||||
j_floats = j_env[0].GetFloatArrayElements(
|
|
||||||
j_env, j_object, &iscopy)
|
|
||||||
ret = [(<float>j_floats[i]) for i in range(array_size)]
|
|
||||||
if iscopy:
|
|
||||||
j_env[0].ReleaseFloatArrayElements(
|
|
||||||
j_env, j_object, j_floats, 0)
|
|
||||||
|
|
||||||
elif r == 'D':
|
|
||||||
j_doubles = j_env[0].GetDoubleArrayElements(
|
|
||||||
j_env, j_object, &iscopy)
|
|
||||||
ret = [(<double>j_doubles[i]) for i in range(array_size)]
|
|
||||||
if iscopy:
|
|
||||||
j_env[0].ReleaseDoubleArrayElements(
|
|
||||||
j_env, j_object, j_doubles, 0)
|
|
||||||
|
|
||||||
elif r == 'L':
|
|
||||||
r = definition[1:-1]
|
|
||||||
ret = []
|
|
||||||
if r == 'java/lang/String':
|
|
||||||
for i in range(array_size):
|
|
||||||
obj = j_env[0].GetObjectArrayElement(
|
|
||||||
j_env, j_object, i)
|
|
||||||
if obj == NULL:
|
|
||||||
ret.append(None)
|
|
||||||
continue
|
|
||||||
c_str = <char *>j_env[0].GetStringUTFChars(
|
|
||||||
j_env, obj, NULL)
|
|
||||||
py_str = <bytes>c_str
|
|
||||||
j_env[0].ReleaseStringUTFChars(
|
|
||||||
j_env, j_object, c_str)
|
|
||||||
ret.append(py_str)
|
|
||||||
j_env[0].DeleteLocalRef(j_env, obj)
|
|
||||||
elif r in jclass_register:
|
|
||||||
for i in range(array_size):
|
|
||||||
obj = j_env[0].GetObjectArrayElement(
|
|
||||||
j_env, j_object, i)
|
|
||||||
ret_jc = jclass_register[r](noinstance=True)
|
|
||||||
ret_jc.instanciate_from(obj)
|
|
||||||
ret.append(ret_jc)
|
|
||||||
j_env[0].DeleteLocalRef(j_env, obj)
|
|
||||||
else:
|
|
||||||
for i in range(array_size):
|
|
||||||
obj = j_env[0].GetObjectArrayElement(
|
|
||||||
j_env, j_object, i)
|
|
||||||
if obj == NULL:
|
|
||||||
ret.append(None)
|
|
||||||
continue
|
|
||||||
ret_jobject = JavaObject()
|
|
||||||
ret_jobject.obj = obj
|
|
||||||
ret.append(ret_jobject)
|
|
||||||
else:
|
|
||||||
raise JavaException('Invalid return definition for array')
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
cdef void release_args(JNIEnv *j_env, list definition_args, jvalue *j_args, args) except *:
|
|
||||||
# do the conversion from a Python object to Java from a Java definition
|
|
||||||
cdef JavaObject jo
|
|
||||||
cdef JavaClass jc
|
|
||||||
cdef int index
|
|
||||||
for index, argtype in enumerate(definition_args):
|
|
||||||
py_arg = args[index]
|
|
||||||
if argtype[0] == 'L':
|
|
||||||
if py_arg is None:
|
|
||||||
j_args[index].l = NULL
|
|
||||||
if isinstance(py_arg, basestring) and \
|
|
||||||
argtype in ('Ljava/lang/String;', 'Ljava/lang/Object;'):
|
|
||||||
j_env[0].DeleteLocalRef(j_env, j_args[index].l)
|
|
||||||
elif argtype[0] == '[':
|
|
||||||
j_env[0].DeleteLocalRef(j_env, j_args[index].l)
|
|
||||||
|
|
||||||
cdef void populate_args(JNIEnv *j_env, list definition_args, jvalue *j_args, args) except *:
|
|
||||||
# do the conversion from a Python object to Java from a Java definition
|
|
||||||
cdef JavaObject jo
|
|
||||||
cdef JavaClass jc
|
|
||||||
cdef int index
|
|
||||||
for index, argtype in enumerate(definition_args):
|
|
||||||
py_arg = args[index]
|
|
||||||
if argtype == 'Z':
|
|
||||||
j_args[index].z = py_arg
|
|
||||||
elif argtype == 'B':
|
|
||||||
j_args[index].b = py_arg
|
|
||||||
elif argtype == 'C':
|
|
||||||
j_args[index].c = ord(py_arg)
|
|
||||||
elif argtype == 'S':
|
|
||||||
j_args[index].s = py_arg
|
|
||||||
elif argtype == 'I':
|
|
||||||
j_args[index].i = py_arg
|
|
||||||
elif argtype == 'J':
|
|
||||||
j_args[index].j = py_arg
|
|
||||||
elif argtype == 'F':
|
|
||||||
j_args[index].f = py_arg
|
|
||||||
elif argtype == 'D':
|
|
||||||
j_args[index].d = py_arg
|
|
||||||
elif argtype[0] == 'L':
|
|
||||||
if py_arg is None:
|
|
||||||
j_args[index].l = NULL
|
|
||||||
elif isinstance(py_arg, basestring) and \
|
|
||||||
argtype in ('Ljava/lang/String;', 'Ljava/lang/Object;'):
|
|
||||||
j_args[index].l = j_env[0].NewStringUTF(
|
|
||||||
j_env, <char *><bytes>py_arg)
|
|
||||||
elif isinstance(py_arg, JavaClass):
|
|
||||||
jc = py_arg
|
|
||||||
if argtype != 'Ljava/lang/Object;' and jc.__javaclass__ != argtype[1:-1]:
|
|
||||||
raise JavaException('Invalid class argument, want '
|
|
||||||
'{0!r}, got {1!r}'.format(
|
|
||||||
argtype[1:-1], jc.__javaclass__))
|
|
||||||
j_args[index].l = jc.j_self
|
|
||||||
elif isinstance(py_arg, JavaObject):
|
|
||||||
jo = py_arg
|
|
||||||
j_args[index].l = jo.obj
|
|
||||||
raise JavaException('JavaObject needed for argument '
|
|
||||||
'{0}'.format(index))
|
|
||||||
else:
|
|
||||||
raise JavaException('Invalid python object for this '
|
|
||||||
'argument. Want {0!r}, got {1!r}'.format(
|
|
||||||
argtype[1:-1], py_arg))
|
|
||||||
elif argtype[0] == '[':
|
|
||||||
if not isinstance(py_arg, list) and \
|
|
||||||
not isinstance(py_arg, tuple):
|
|
||||||
raise JavaException('Expecting a python list/tuple, got '
|
|
||||||
'{0!r}'.format(py_arg))
|
|
||||||
|
|
||||||
j_args[index].l = convert_pyarray_to_java(
|
|
||||||
j_env, argtype[1:], py_arg)
|
|
||||||
|
|
||||||
cdef jobject convert_pyarray_to_java(JNIEnv *j_env, definition, pyarray) except *:
|
|
||||||
cdef jobject ret = NULL
|
|
||||||
cdef int array_size = len(pyarray)
|
|
||||||
cdef int i
|
|
||||||
cdef jboolean j_boolean
|
|
||||||
cdef jbyte j_byte
|
|
||||||
cdef jchar j_char
|
|
||||||
cdef jshort j_short
|
|
||||||
cdef jint j_int
|
|
||||||
cdef jlong j_long
|
|
||||||
cdef jfloat j_float
|
|
||||||
cdef jdouble j_double
|
|
||||||
cdef jstring j_string
|
|
||||||
cdef jclass j_class
|
|
||||||
cdef JavaObject jo
|
|
||||||
cdef JavaClass jc
|
|
||||||
|
|
||||||
if definition == 'Z':
|
|
||||||
ret = j_env[0].NewBooleanArray(j_env, array_size)
|
|
||||||
for i in range(array_size):
|
|
||||||
j_boolean = 1 if pyarray[i] else 0
|
|
||||||
j_env[0].SetBooleanArrayRegion(j_env,
|
|
||||||
ret, i, 1, &j_boolean)
|
|
||||||
|
|
||||||
elif definition == 'B':
|
|
||||||
ret = j_env[0].NewByteArray(j_env, array_size)
|
|
||||||
for i in range(array_size):
|
|
||||||
j_byte = pyarray[i]
|
|
||||||
j_env[0].SetByteArrayRegion(j_env,
|
|
||||||
ret, i, 1, &j_byte)
|
|
||||||
|
|
||||||
elif definition == 'C':
|
|
||||||
ret = j_env[0].NewCharArray(j_env, array_size)
|
|
||||||
for i in range(array_size):
|
|
||||||
j_char = ord(pyarray[i])
|
|
||||||
j_env[0].SetCharArrayRegion(j_env,
|
|
||||||
ret, i, 1, &j_char)
|
|
||||||
|
|
||||||
elif definition == 'S':
|
|
||||||
ret = j_env[0].NewShortArray(j_env, array_size)
|
|
||||||
for i in range(array_size):
|
|
||||||
j_short = pyarray[i]
|
|
||||||
j_env[0].SetShortArrayRegion(j_env,
|
|
||||||
ret, i, 1, &j_short)
|
|
||||||
|
|
||||||
elif definition == 'I':
|
|
||||||
ret = j_env[0].NewIntArray(j_env, array_size)
|
|
||||||
for i in range(array_size):
|
|
||||||
j_int = pyarray[i]
|
|
||||||
j_env[0].SetIntArrayRegion(j_env,
|
|
||||||
ret, i, 1, <const_jint *>&j_int)
|
|
||||||
|
|
||||||
elif definition == 'J':
|
|
||||||
ret = j_env[0].NewLongArray(j_env, array_size)
|
|
||||||
for i in range(array_size):
|
|
||||||
j_long = pyarray[i]
|
|
||||||
j_env[0].SetLongArrayRegion(j_env,
|
|
||||||
ret, i, 1, &j_long)
|
|
||||||
|
|
||||||
elif definition == 'F':
|
|
||||||
ret = j_env[0].NewFloatArray(j_env, array_size)
|
|
||||||
for i in range(array_size):
|
|
||||||
j_float = pyarray[i]
|
|
||||||
j_env[0].SetFloatArrayRegion(j_env,
|
|
||||||
ret, i, 1, &j_float)
|
|
||||||
|
|
||||||
elif definition == 'D':
|
|
||||||
ret = j_env[0].NewDoubleArray(j_env, array_size)
|
|
||||||
for i in range(array_size):
|
|
||||||
j_double = pyarray[i]
|
|
||||||
j_env[0].SetDoubleArrayRegion(j_env,
|
|
||||||
ret, i, 1, &j_double)
|
|
||||||
|
|
||||||
elif definition[0] == 'L':
|
|
||||||
j_class = j_env[0].FindClass(
|
|
||||||
j_env, <bytes>definition[1:-1])
|
|
||||||
if j_class == NULL:
|
|
||||||
raise JavaException('Cannot create array with a class not '
|
|
||||||
'found {0!r}'.format(definition[1:-1]))
|
|
||||||
ret = j_env[0].NewObjectArray(
|
|
||||||
j_env, array_size, j_class, NULL)
|
|
||||||
for i in range(array_size):
|
|
||||||
arg = pyarray[i]
|
|
||||||
if arg is None:
|
|
||||||
j_env[0].SetObjectArrayElement(
|
|
||||||
j_env, <jobjectArray>ret, i, NULL)
|
|
||||||
elif isinstance(arg, basestring) and \
|
|
||||||
definition == 'Ljava/lang/String;':
|
|
||||||
j_string = j_env[0].NewStringUTF(
|
|
||||||
j_env, <bytes>arg)
|
|
||||||
j_env[0].SetObjectArrayElement(
|
|
||||||
j_env, <jobjectArray>ret, i, j_string)
|
|
||||||
elif isinstance(arg, JavaClass):
|
|
||||||
jc = arg
|
|
||||||
if jc.__javaclass__ != definition[1:-1]:
|
|
||||||
raise JavaException('Invalid class argument, want '
|
|
||||||
'{0!r}, got {1!r}'.format(
|
|
||||||
definition[1:-1],
|
|
||||||
jc.__javaclass__))
|
|
||||||
j_env[0].SetObjectArrayElement(
|
|
||||||
j_env, <jobjectArray>ret, i, jc.j_self)
|
|
||||||
elif isinstance(arg, JavaObject):
|
|
||||||
jo = arg
|
|
||||||
j_env[0].SetObjectArrayElement(
|
|
||||||
j_env, <jobjectArray>ret, i, jo.obj)
|
|
||||||
else:
|
|
||||||
raise JavaException('Invalid variable used for L array')
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise JavaException('Invalid array definition')
|
|
||||||
|
|
||||||
return <jobject>ret
|
|
||||||
|
|
||||||
cdef void check_exception(JNIEnv *j_env) except *:
|
cdef void check_exception(JNIEnv *j_env) except *:
|
||||||
cdef jthrowable exc = j_env[0].ExceptionOccurred(j_env)
|
cdef jthrowable exc = j_env[0].ExceptionOccurred(j_env)
|
||||||
|
@ -759,31 +446,15 @@ cdef class JavaField(object):
|
||||||
elif r == 'L':
|
elif r == 'L':
|
||||||
j_object = self.j_env[0].GetObjectField(
|
j_object = self.j_env[0].GetObjectField(
|
||||||
self.j_env, self.j_self, self.j_field)
|
self.j_env, self.j_self, self.j_field)
|
||||||
if j_object == NULL:
|
if j_object != NULL:
|
||||||
return None
|
ret = convert_jobject_to_python(
|
||||||
r = self.definition[1:-1]
|
self.j_env, self.definition, j_object)
|
||||||
if r == 'java/lang/Object':
|
|
||||||
r = lookup_java_object_name(self.j_env, j_object)
|
|
||||||
if r == 'java/lang/String':
|
|
||||||
c_str = <char *>self.j_env[0].GetStringUTFChars(
|
|
||||||
self.j_env, j_object, NULL)
|
|
||||||
py_str = <bytes>c_str
|
|
||||||
self.j_env[0].ReleaseStringUTFChars(
|
|
||||||
self.j_env, j_object, c_str)
|
|
||||||
ret = py_str
|
|
||||||
elif r in jclass_register:
|
|
||||||
ret_jc = jclass_register[r](noinstance=True)
|
|
||||||
ret_jc.instanciate_from(j_object)
|
|
||||||
ret = ret_jc
|
|
||||||
else:
|
|
||||||
ret_jobject = JavaObject()
|
|
||||||
ret_jobject.obj = self.j_env[0].NewLocalRef(self.j_env, j_object)
|
|
||||||
ret = ret_jobject
|
|
||||||
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
||||||
elif r == '[':
|
elif r == '[':
|
||||||
r = self.definition[1:]
|
r = self.definition[1:]
|
||||||
j_object = self.j_env[0].GetObjectField(
|
j_object = self.j_env[0].GetObjectField(
|
||||||
self.j_env, self.j_self, self.j_field)
|
self.j_env, self.j_self, self.j_field)
|
||||||
|
if j_object != NULL:
|
||||||
ret = convert_jarray_to_python(self.j_env, r, j_object)
|
ret = convert_jarray_to_python(self.j_env, r, j_object)
|
||||||
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
||||||
else:
|
else:
|
||||||
|
@ -802,11 +473,7 @@ cdef class JavaField(object):
|
||||||
cdef jfloat j_float
|
cdef jfloat j_float
|
||||||
cdef jdouble j_double
|
cdef jdouble j_double
|
||||||
cdef jobject j_object
|
cdef jobject j_object
|
||||||
cdef char *c_str
|
|
||||||
cdef bytes py_str
|
|
||||||
cdef object ret = None
|
cdef object ret = None
|
||||||
cdef JavaObject ret_jobject
|
|
||||||
cdef JavaClass ret_jc
|
|
||||||
|
|
||||||
# return type of the java method
|
# return type of the java method
|
||||||
r = self.definition[0]
|
r = self.definition[0]
|
||||||
|
@ -847,31 +514,15 @@ cdef class JavaField(object):
|
||||||
elif r == 'L':
|
elif r == 'L':
|
||||||
j_object = self.j_env[0].GetStaticObjectField(
|
j_object = self.j_env[0].GetStaticObjectField(
|
||||||
self.j_env, self.j_self, self.j_field)
|
self.j_env, self.j_self, self.j_field)
|
||||||
if j_object == NULL:
|
if j_object != NULL:
|
||||||
return None
|
ret = convert_jobject_to_python(
|
||||||
r = self.definition[1:-1]
|
self.j_env, self.definition, j_object)
|
||||||
if r == 'java/lang/Object':
|
|
||||||
r = lookup_java_object_name(self.j_env, j_object)
|
|
||||||
if r == 'java/lang/String':
|
|
||||||
c_str = <char *>self.j_env[0].GetStringUTFChars(
|
|
||||||
self.j_env, j_object, NULL)
|
|
||||||
py_str = <bytes>c_str
|
|
||||||
self.j_env[0].ReleaseStringUTFChars(
|
|
||||||
self.j_env, j_object, c_str)
|
|
||||||
ret = py_str
|
|
||||||
elif r in jclass_register:
|
|
||||||
ret_jc = jclass_register[r](noinstance=True)
|
|
||||||
ret_jc.instanciate_from(j_object)
|
|
||||||
ret = ret_jc
|
|
||||||
else:
|
|
||||||
ret_jobject = JavaObject()
|
|
||||||
ret_jobject.obj = self.j_env[0].NewLocalRef(self.j_env, j_object)
|
|
||||||
ret = ret_jobject
|
|
||||||
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
||||||
elif r == '[':
|
elif r == '[':
|
||||||
r = self.definition[1:]
|
r = self.definition[1:]
|
||||||
j_object = self.j_env[0].GetStaticObjectField(
|
j_object = self.j_env[0].GetStaticObjectField(
|
||||||
self.j_env, self.j_self, self.j_field)
|
self.j_env, self.j_self, self.j_field)
|
||||||
|
if j_object != NULL:
|
||||||
ret = convert_jarray_to_python(self.j_env, r, j_object)
|
ret = convert_jarray_to_python(self.j_env, r, j_object)
|
||||||
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
||||||
else:
|
else:
|
||||||
|
@ -1032,32 +683,15 @@ cdef class JavaMethod(object):
|
||||||
elif r == 'L':
|
elif r == 'L':
|
||||||
j_object = self.j_env[0].CallObjectMethodA(
|
j_object = self.j_env[0].CallObjectMethodA(
|
||||||
self.j_env, self.j_self, self.j_method, j_args)
|
self.j_env, self.j_self, self.j_method, j_args)
|
||||||
check_exception(self.j_env)
|
if j_object != NULL:
|
||||||
if j_object == NULL:
|
ret = convert_jobject_to_python(
|
||||||
return None
|
self.j_env, self.definition_return, j_object)
|
||||||
r = self.definition_return[1:-1]
|
|
||||||
if r == 'java/lang/Object':
|
|
||||||
r = lookup_java_object_name(self.j_env, j_object)
|
|
||||||
if r == 'java/lang/String':
|
|
||||||
c_str = <char *>self.j_env[0].GetStringUTFChars(
|
|
||||||
self.j_env, j_object, NULL)
|
|
||||||
py_str = <bytes>c_str
|
|
||||||
self.j_env[0].ReleaseStringUTFChars(
|
|
||||||
self.j_env, j_object, c_str)
|
|
||||||
ret = py_str
|
|
||||||
elif r in jclass_register:
|
|
||||||
ret_jc = jclass_register[r](noinstance=True)
|
|
||||||
ret_jc.instanciate_from(j_object)
|
|
||||||
ret = ret_jc
|
|
||||||
else:
|
|
||||||
ret_jobject = JavaObject()
|
|
||||||
ret_jobject.obj = self.j_env[0].NewLocalRef(self.j_env, j_object)
|
|
||||||
ret = ret_jobject
|
|
||||||
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
||||||
elif r == '[':
|
elif r == '[':
|
||||||
r = self.definition_return[1:]
|
r = self.definition_return[1:]
|
||||||
j_object = self.j_env[0].CallObjectMethodA(
|
j_object = self.j_env[0].CallObjectMethodA(
|
||||||
self.j_env, self.j_self, self.j_method, j_args)
|
self.j_env, self.j_self, self.j_method, j_args)
|
||||||
|
if j_object != NULL:
|
||||||
ret = convert_jarray_to_python(self.j_env, r, j_object)
|
ret = convert_jarray_to_python(self.j_env, r, j_object)
|
||||||
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
||||||
else:
|
else:
|
||||||
|
@ -1122,32 +756,17 @@ cdef class JavaMethod(object):
|
||||||
self.j_env, self.j_cls, self.j_method, j_args)
|
self.j_env, self.j_cls, self.j_method, j_args)
|
||||||
ret = <double>j_double
|
ret = <double>j_double
|
||||||
elif r == 'L':
|
elif r == 'L':
|
||||||
# accept only string for the moment
|
|
||||||
j_object = self.j_env[0].CallStaticObjectMethodA(
|
j_object = self.j_env[0].CallStaticObjectMethodA(
|
||||||
self.j_env, self.j_cls, self.j_method, j_args)
|
self.j_env, self.j_cls, self.j_method, j_args)
|
||||||
r = self.definition_return[1:-1]
|
if j_object != NULL:
|
||||||
if r == 'java/lang/Object':
|
ret = convert_jobject_to_python(
|
||||||
r = lookup_java_object_name(self.j_env, j_object)
|
self.j_env, self.definition_return, j_object)
|
||||||
if r == 'java/lang/String':
|
|
||||||
c_str = <char *>self.j_env[0].GetStringUTFChars(
|
|
||||||
self.j_env, j_object, NULL)
|
|
||||||
py_str = <bytes>c_str
|
|
||||||
self.j_env[0].ReleaseStringUTFChars(
|
|
||||||
self.j_env, j_object, c_str)
|
|
||||||
ret = py_str
|
|
||||||
elif r in jclass_register:
|
|
||||||
ret_jc = jclass_register[r](noinstance=True)
|
|
||||||
ret_jc.instanciate_from(j_object)
|
|
||||||
ret = ret_jc
|
|
||||||
else:
|
|
||||||
ret_jobject = JavaObject()
|
|
||||||
ret_jobject.obj = self.j_env[0].NewLocalRef(self.j_env, j_object)
|
|
||||||
ret = ret_jobject
|
|
||||||
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
||||||
elif r == '[':
|
elif r == '[':
|
||||||
r = self.definition_return[1:]
|
r = self.definition_return[1:]
|
||||||
j_object = self.j_env[0].CallStaticObjectMethodA(
|
j_object = self.j_env[0].CallStaticObjectMethodA(
|
||||||
self.j_env, self.j_cls, self.j_method, j_args)
|
self.j_env, self.j_cls, self.j_method, j_args)
|
||||||
|
if j_object != NULL:
|
||||||
ret = convert_jarray_to_python(self.j_env, r, j_object)
|
ret = convert_jarray_to_python(self.j_env, r, j_object)
|
||||||
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
self.j_env[0].DeleteLocalRef(self.j_env, j_object)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1,325 @@
|
||||||
|
|
||||||
|
cdef convert_jobject_to_python(JNIEnv *j_env, bytes definition, jobject j_object):
|
||||||
|
# Convert a Java Object to a Python object, according to the definition.
|
||||||
|
# If the definition is a java/lang/Object, then try to determine what is it
|
||||||
|
# exactly.
|
||||||
|
cdef char *c_str
|
||||||
|
cdef bytes py_str
|
||||||
|
cdef bytes r = definition[1:-1]
|
||||||
|
cdef JavaObject ret_jobject
|
||||||
|
cdef JavaClass ret_jc
|
||||||
|
|
||||||
|
# we got a generic object -> lookup for the real name instead.
|
||||||
|
if r == 'java/lang/Object':
|
||||||
|
r = lookup_java_object_name(j_env, j_object)
|
||||||
|
|
||||||
|
# if we got a string, just convert back to Python str.
|
||||||
|
if r == 'java/lang/String':
|
||||||
|
c_str = <char *>j_env[0].GetStringUTFChars(j_env, j_object, NULL)
|
||||||
|
py_str = <bytes>c_str
|
||||||
|
j_env[0].ReleaseStringUTFChars(j_env, j_object, c_str)
|
||||||
|
return py_str
|
||||||
|
|
||||||
|
# if the class is already in our register, use it
|
||||||
|
if r in jclass_register:
|
||||||
|
ret_jc = jclass_register[r](noinstance=True)
|
||||||
|
ret_jc.instanciate_from(j_object)
|
||||||
|
return ret_jc
|
||||||
|
|
||||||
|
# otherwise, return a generic object, without any reflection.
|
||||||
|
ret_jobject = JavaObject()
|
||||||
|
ret_jobject.obj = j_env[0].NewLocalRef(j_env, j_object)
|
||||||
|
return ret_jobject
|
||||||
|
|
||||||
|
|
||||||
|
cdef convert_jarray_to_python(JNIEnv *j_env, definition, jobject j_object):
|
||||||
|
cdef jboolean iscopy
|
||||||
|
cdef jboolean *j_booleans
|
||||||
|
cdef jbyte *j_bytes
|
||||||
|
cdef jchar *j_chars
|
||||||
|
cdef jshort *j_shorts
|
||||||
|
cdef jint *j_ints
|
||||||
|
cdef jlong *j_longs
|
||||||
|
cdef jfloat *j_floats
|
||||||
|
cdef jdouble *j_doubles
|
||||||
|
cdef object ret = None
|
||||||
|
cdef jsize array_size
|
||||||
|
|
||||||
|
cdef int i
|
||||||
|
cdef jobject j_object_item
|
||||||
|
cdef char *c_str
|
||||||
|
cdef bytes py_str
|
||||||
|
cdef JavaObject ret_jobject
|
||||||
|
cdef JavaClass ret_jc
|
||||||
|
|
||||||
|
if j_object == NULL:
|
||||||
|
return None
|
||||||
|
|
||||||
|
array_size = j_env[0].GetArrayLength(j_env, j_object)
|
||||||
|
|
||||||
|
r = definition[0]
|
||||||
|
if r == 'Z':
|
||||||
|
j_booleans = j_env[0].GetBooleanArrayElements(
|
||||||
|
j_env, j_object, &iscopy)
|
||||||
|
ret = [(True if j_booleans[i] else False)
|
||||||
|
for i in range(array_size)]
|
||||||
|
if iscopy:
|
||||||
|
j_env[0].ReleaseBooleanArrayElements(
|
||||||
|
j_env, j_object, j_booleans, 0)
|
||||||
|
|
||||||
|
elif r == 'B':
|
||||||
|
j_bytes = j_env[0].GetByteArrayElements(
|
||||||
|
j_env, j_object, &iscopy)
|
||||||
|
ret = [(<char>j_bytes[i]) for i in range(array_size)]
|
||||||
|
if iscopy:
|
||||||
|
j_env[0].ReleaseByteArrayElements(
|
||||||
|
j_env, j_object, j_bytes, 0)
|
||||||
|
|
||||||
|
elif r == 'C':
|
||||||
|
j_chars = j_env[0].GetCharArrayElements(
|
||||||
|
j_env, j_object, &iscopy)
|
||||||
|
ret = [(<char>j_chars[i]) for i in range(array_size)]
|
||||||
|
if iscopy:
|
||||||
|
j_env[0].ReleaseCharArrayElements(
|
||||||
|
j_env, j_object, j_chars, 0)
|
||||||
|
|
||||||
|
elif r == 'S':
|
||||||
|
j_shorts = j_env[0].GetShortArrayElements(
|
||||||
|
j_env, j_object, &iscopy)
|
||||||
|
ret = [(<short>j_shorts[i]) for i in range(array_size)]
|
||||||
|
if iscopy:
|
||||||
|
j_env[0].ReleaseShortArrayElements(
|
||||||
|
j_env, j_object, j_shorts, 0)
|
||||||
|
|
||||||
|
elif r == 'I':
|
||||||
|
j_ints = j_env[0].GetIntArrayElements(
|
||||||
|
j_env, j_object, &iscopy)
|
||||||
|
ret = [(<int>j_ints[i]) for i in range(array_size)]
|
||||||
|
if iscopy:
|
||||||
|
j_env[0].ReleaseIntArrayElements(
|
||||||
|
j_env, j_object, j_ints, 0)
|
||||||
|
|
||||||
|
elif r == 'J':
|
||||||
|
j_longs = j_env[0].GetLongArrayElements(
|
||||||
|
j_env, j_object, &iscopy)
|
||||||
|
ret = [(<long>j_longs[i]) for i in range(array_size)]
|
||||||
|
if iscopy:
|
||||||
|
j_env[0].ReleaseLongArrayElements(
|
||||||
|
j_env, j_object, j_longs, 0)
|
||||||
|
|
||||||
|
elif r == 'F':
|
||||||
|
j_floats = j_env[0].GetFloatArrayElements(
|
||||||
|
j_env, j_object, &iscopy)
|
||||||
|
ret = [(<float>j_floats[i]) for i in range(array_size)]
|
||||||
|
if iscopy:
|
||||||
|
j_env[0].ReleaseFloatArrayElements(
|
||||||
|
j_env, j_object, j_floats, 0)
|
||||||
|
|
||||||
|
elif r == 'D':
|
||||||
|
j_doubles = j_env[0].GetDoubleArrayElements(
|
||||||
|
j_env, j_object, &iscopy)
|
||||||
|
ret = [(<double>j_doubles[i]) for i in range(array_size)]
|
||||||
|
if iscopy:
|
||||||
|
j_env[0].ReleaseDoubleArrayElements(
|
||||||
|
j_env, j_object, j_doubles, 0)
|
||||||
|
|
||||||
|
elif r == 'L':
|
||||||
|
r = definition[1:-1]
|
||||||
|
ret = []
|
||||||
|
for i in range(array_size):
|
||||||
|
j_object_item = j_env[0].GetObjectArrayElement(
|
||||||
|
j_env, j_object, i)
|
||||||
|
if j_object_item == NULL:
|
||||||
|
ret.append(None)
|
||||||
|
continue
|
||||||
|
obj = convert_jobject_to_python(j_env, definition, j_object_item)
|
||||||
|
ret.append(obj)
|
||||||
|
j_env[0].DeleteLocalRef(j_env, j_object_item)
|
||||||
|
else:
|
||||||
|
raise JavaException('Invalid return definition for array')
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
cdef void release_args(JNIEnv *j_env, list definition_args, jvalue *j_args, args) except *:
|
||||||
|
# do the conversion from a Python object to Java from a Java definition
|
||||||
|
cdef JavaObject jo
|
||||||
|
cdef JavaClass jc
|
||||||
|
cdef int index
|
||||||
|
for index, argtype in enumerate(definition_args):
|
||||||
|
py_arg = args[index]
|
||||||
|
if argtype[0] == 'L':
|
||||||
|
if py_arg is None:
|
||||||
|
j_args[index].l = NULL
|
||||||
|
if isinstance(py_arg, basestring) and \
|
||||||
|
argtype in ('Ljava/lang/String;', 'Ljava/lang/Object;'):
|
||||||
|
j_env[0].DeleteLocalRef(j_env, j_args[index].l)
|
||||||
|
elif argtype[0] == '[':
|
||||||
|
j_env[0].DeleteLocalRef(j_env, j_args[index].l)
|
||||||
|
|
||||||
|
cdef void populate_args(JNIEnv *j_env, list definition_args, jvalue *j_args, args) except *:
|
||||||
|
# do the conversion from a Python object to Java from a Java definition
|
||||||
|
cdef JavaObject jo
|
||||||
|
cdef JavaClass jc
|
||||||
|
cdef int index
|
||||||
|
for index, argtype in enumerate(definition_args):
|
||||||
|
py_arg = args[index]
|
||||||
|
if argtype == 'Z':
|
||||||
|
j_args[index].z = py_arg
|
||||||
|
elif argtype == 'B':
|
||||||
|
j_args[index].b = py_arg
|
||||||
|
elif argtype == 'C':
|
||||||
|
j_args[index].c = ord(py_arg)
|
||||||
|
elif argtype == 'S':
|
||||||
|
j_args[index].s = py_arg
|
||||||
|
elif argtype == 'I':
|
||||||
|
j_args[index].i = py_arg
|
||||||
|
elif argtype == 'J':
|
||||||
|
j_args[index].j = py_arg
|
||||||
|
elif argtype == 'F':
|
||||||
|
j_args[index].f = py_arg
|
||||||
|
elif argtype == 'D':
|
||||||
|
j_args[index].d = py_arg
|
||||||
|
elif argtype[0] == 'L':
|
||||||
|
if py_arg is None:
|
||||||
|
j_args[index].l = NULL
|
||||||
|
elif isinstance(py_arg, basestring) and \
|
||||||
|
argtype in ('Ljava/lang/String;', 'Ljava/lang/Object;'):
|
||||||
|
j_args[index].l = j_env[0].NewStringUTF(
|
||||||
|
j_env, <char *><bytes>py_arg)
|
||||||
|
elif isinstance(py_arg, JavaClass):
|
||||||
|
jc = py_arg
|
||||||
|
if argtype != 'Ljava/lang/Object;' and jc.__javaclass__ != argtype[1:-1]:
|
||||||
|
raise JavaException('Invalid class argument, want '
|
||||||
|
'{0!r}, got {1!r}'.format(
|
||||||
|
argtype[1:-1], jc.__javaclass__))
|
||||||
|
j_args[index].l = jc.j_self
|
||||||
|
elif isinstance(py_arg, JavaObject):
|
||||||
|
jo = py_arg
|
||||||
|
j_args[index].l = jo.obj
|
||||||
|
raise JavaException('JavaObject needed for argument '
|
||||||
|
'{0}'.format(index))
|
||||||
|
else:
|
||||||
|
raise JavaException('Invalid python object for this '
|
||||||
|
'argument. Want {0!r}, got {1!r}'.format(
|
||||||
|
argtype[1:-1], py_arg))
|
||||||
|
elif argtype[0] == '[':
|
||||||
|
if not isinstance(py_arg, list) and \
|
||||||
|
not isinstance(py_arg, tuple):
|
||||||
|
raise JavaException('Expecting a python list/tuple, got '
|
||||||
|
'{0!r}'.format(py_arg))
|
||||||
|
|
||||||
|
j_args[index].l = convert_pyarray_to_java(
|
||||||
|
j_env, argtype[1:], py_arg)
|
||||||
|
|
||||||
|
cdef jobject convert_pyarray_to_java(JNIEnv *j_env, definition, pyarray) except *:
|
||||||
|
cdef jobject ret = NULL
|
||||||
|
cdef int array_size = len(pyarray)
|
||||||
|
cdef int i
|
||||||
|
cdef jboolean j_boolean
|
||||||
|
cdef jbyte j_byte
|
||||||
|
cdef jchar j_char
|
||||||
|
cdef jshort j_short
|
||||||
|
cdef jint j_int
|
||||||
|
cdef jlong j_long
|
||||||
|
cdef jfloat j_float
|
||||||
|
cdef jdouble j_double
|
||||||
|
cdef jstring j_string
|
||||||
|
cdef jclass j_class
|
||||||
|
cdef JavaObject jo
|
||||||
|
cdef JavaClass jc
|
||||||
|
|
||||||
|
if definition == 'Z':
|
||||||
|
ret = j_env[0].NewBooleanArray(j_env, array_size)
|
||||||
|
for i in range(array_size):
|
||||||
|
j_boolean = 1 if pyarray[i] else 0
|
||||||
|
j_env[0].SetBooleanArrayRegion(j_env,
|
||||||
|
ret, i, 1, &j_boolean)
|
||||||
|
|
||||||
|
elif definition == 'B':
|
||||||
|
ret = j_env[0].NewByteArray(j_env, array_size)
|
||||||
|
for i in range(array_size):
|
||||||
|
j_byte = pyarray[i]
|
||||||
|
j_env[0].SetByteArrayRegion(j_env,
|
||||||
|
ret, i, 1, &j_byte)
|
||||||
|
|
||||||
|
elif definition == 'C':
|
||||||
|
ret = j_env[0].NewCharArray(j_env, array_size)
|
||||||
|
for i in range(array_size):
|
||||||
|
j_char = ord(pyarray[i])
|
||||||
|
j_env[0].SetCharArrayRegion(j_env,
|
||||||
|
ret, i, 1, &j_char)
|
||||||
|
|
||||||
|
elif definition == 'S':
|
||||||
|
ret = j_env[0].NewShortArray(j_env, array_size)
|
||||||
|
for i in range(array_size):
|
||||||
|
j_short = pyarray[i]
|
||||||
|
j_env[0].SetShortArrayRegion(j_env,
|
||||||
|
ret, i, 1, &j_short)
|
||||||
|
|
||||||
|
elif definition == 'I':
|
||||||
|
ret = j_env[0].NewIntArray(j_env, array_size)
|
||||||
|
for i in range(array_size):
|
||||||
|
j_int = pyarray[i]
|
||||||
|
j_env[0].SetIntArrayRegion(j_env,
|
||||||
|
ret, i, 1, <const_jint *>&j_int)
|
||||||
|
|
||||||
|
elif definition == 'J':
|
||||||
|
ret = j_env[0].NewLongArray(j_env, array_size)
|
||||||
|
for i in range(array_size):
|
||||||
|
j_long = pyarray[i]
|
||||||
|
j_env[0].SetLongArrayRegion(j_env,
|
||||||
|
ret, i, 1, &j_long)
|
||||||
|
|
||||||
|
elif definition == 'F':
|
||||||
|
ret = j_env[0].NewFloatArray(j_env, array_size)
|
||||||
|
for i in range(array_size):
|
||||||
|
j_float = pyarray[i]
|
||||||
|
j_env[0].SetFloatArrayRegion(j_env,
|
||||||
|
ret, i, 1, &j_float)
|
||||||
|
|
||||||
|
elif definition == 'D':
|
||||||
|
ret = j_env[0].NewDoubleArray(j_env, array_size)
|
||||||
|
for i in range(array_size):
|
||||||
|
j_double = pyarray[i]
|
||||||
|
j_env[0].SetDoubleArrayRegion(j_env,
|
||||||
|
ret, i, 1, &j_double)
|
||||||
|
|
||||||
|
elif definition[0] == 'L':
|
||||||
|
j_class = j_env[0].FindClass(
|
||||||
|
j_env, <bytes>definition[1:-1])
|
||||||
|
if j_class == NULL:
|
||||||
|
raise JavaException('Cannot create array with a class not '
|
||||||
|
'found {0!r}'.format(definition[1:-1]))
|
||||||
|
ret = j_env[0].NewObjectArray(
|
||||||
|
j_env, array_size, j_class, NULL)
|
||||||
|
for i in range(array_size):
|
||||||
|
arg = pyarray[i]
|
||||||
|
if arg is None:
|
||||||
|
j_env[0].SetObjectArrayElement(
|
||||||
|
j_env, <jobjectArray>ret, i, NULL)
|
||||||
|
elif isinstance(arg, basestring) and \
|
||||||
|
definition == 'Ljava/lang/String;':
|
||||||
|
j_string = j_env[0].NewStringUTF(
|
||||||
|
j_env, <bytes>arg)
|
||||||
|
j_env[0].SetObjectArrayElement(
|
||||||
|
j_env, <jobjectArray>ret, i, j_string)
|
||||||
|
elif isinstance(arg, JavaClass):
|
||||||
|
jc = arg
|
||||||
|
if jc.__javaclass__ != definition[1:-1]:
|
||||||
|
raise JavaException('Invalid class argument, want '
|
||||||
|
'{0!r}, got {1!r}'.format(
|
||||||
|
definition[1:-1],
|
||||||
|
jc.__javaclass__))
|
||||||
|
j_env[0].SetObjectArrayElement(
|
||||||
|
j_env, <jobjectArray>ret, i, jc.j_self)
|
||||||
|
elif isinstance(arg, JavaObject):
|
||||||
|
jo = arg
|
||||||
|
j_env[0].SetObjectArrayElement(
|
||||||
|
j_env, <jobjectArray>ret, i, jo.obj)
|
||||||
|
else:
|
||||||
|
raise JavaException('Invalid variable used for L array')
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise JavaException('Invalid array definition')
|
||||||
|
|
||||||
|
return <jobject>ret
|
Loading…
Reference in New Issue