Skip to content

Commit dd56373

Browse files
committed
implement array for return definition (except a return of a String array...
1 parent 35bc5b8 commit dd56373

File tree

1 file changed

+122
-16
lines changed

1 file changed

+122
-16
lines changed

recipes/android/src/java.pyx

Lines changed: 122 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ cdef class JavaClass(object):
8787
# the goal is to found the class constructor, and call it with the
8888
# correct arguments.
8989
cdef jvalue *j_args = NULL
90+
cdef jmethodID constructor = NULL
9091

9192
# get the constructor definition if exist
9293
definition = '()V'
@@ -107,7 +108,7 @@ cdef class JavaClass(object):
107108
self.populate_args(d_args, j_args, args)
108109

109110
# get the java constructor
110-
cdef jmethodID constructor = self.j_env[0].GetMethodID(
111+
constructor = self.j_env[0].GetMethodID(
111112
self.j_env, self.j_cls, '<init>', <char *><bytes>definition)
112113
if constructor == NULL:
113114
raise JavaException('Unable to found the constructor'
@@ -195,7 +196,7 @@ cdef class JavaMethod(object):
195196
cdef JNIEnv *j_env
196197
cdef jclass j_cls
197198
cdef jobject j_self
198-
cdef char *definition
199+
cdef bytes definition
199200
cdef object is_static
200201
cdef object definition_return
201202
cdef object definition_args
@@ -207,8 +208,9 @@ cdef class JavaMethod(object):
207208

208209
def __init__(self, definition, **kwargs):
209210
super(JavaMethod, self).__init__()
210-
self.definition = <char *><bytes>definition
211-
self.definition_return, self.definition_args = parse_definition(definition)
211+
self.definition = <bytes>definition
212+
self.definition_return, self.definition_args = \
213+
parse_definition(definition)
212214
self.is_static = kwargs.get('static', False)
213215

214216
cdef resolve_method(self, JavaClass jc, bytes name):
@@ -219,11 +221,16 @@ cdef class JavaMethod(object):
219221
self.j_self = jc.j_self
220222
if self.is_static:
221223
self.j_method = self.j_env[0].GetStaticMethodID(
222-
self.j_env, self.j_cls, <char *>name, self.definition)
224+
self.j_env, self.j_cls, <char *>name,
225+
<char *>self.definition)
223226
else:
224227
self.j_method = self.j_env[0].GetMethodID(
225-
self.j_env, self.j_cls, <char *>name, self.definition)
226-
assert(self.j_method != NULL)
228+
self.j_env, self.j_cls, <char *>name,
229+
<char *>self.definition)
230+
231+
if self.j_method == NULL:
232+
raise JavaException('Unable to found the method'
233+
' {0} in {1}'.format(name, jc.__javaclass__))
227234

228235
def __call__(self, *args):
229236
# argument array to pass to the method
@@ -304,9 +311,10 @@ cdef class JavaMethod(object):
304311
self.j_env, self.j_self, self.j_method, j_args)
305312
ret = <double>j_double
306313
elif r == 'L':
307-
# accept only string for the moment
308314
j_object = self.j_env[0].CallObjectMethodA(
309315
self.j_env, self.j_self, self.j_method, j_args)
316+
if j_object == NULL:
317+
return None
310318
if r == 'Ljava/lang/String;':
311319
c_str = <char *>self.j_env[0].GetStringUTFChars(
312320
self.j_env, j_object, NULL)
@@ -319,8 +327,10 @@ cdef class JavaMethod(object):
319327
ret_jobject.obj = j_object
320328
ret = ret_jobject
321329
elif r == '[':
322-
# TODO array support
323-
raise NotImplementedError("Array arguments not implemented")
330+
r = self.definition_return[1:]
331+
j_object = self.j_env[0].CallObjectMethodA(
332+
self.j_env, self.j_self, self.j_method, j_args)
333+
ret = self.convert_return_array(j_object)
324334
else:
325335
raise Exception('Invalid return definition?')
326336

@@ -361,8 +371,8 @@ cdef class JavaMethod(object):
361371
self.j_env, self.j_cls, self.j_method, j_args)
362372
ret = True if j_boolean else False
363373
elif r == 'B':
364-
j_byte = self.j_env[0].CallStaticByteMethodA
365-
(self.j_env, self.j_cls, self.j_method, j_args)
374+
j_byte = self.j_env[0].CallStaticByteMethodA(
375+
self.j_env, self.j_cls, self.j_method, j_args)
366376
ret = <char>j_byte
367377
elif r == 'C':
368378
j_char = self.j_env[0].CallStaticCharMethodA(
@@ -381,8 +391,8 @@ cdef class JavaMethod(object):
381391
self.j_env, self.j_cls, self.j_method, j_args)
382392
ret = <long>j_long
383393
elif r == 'F':
384-
j_float = self.j_env[0].CallStaticFloatMethodA
385-
(self.j_env, self.j_cls, self.j_method, j_args)
394+
j_float = self.j_env[0].CallStaticFloatMethodA(
395+
self.j_env, self.j_cls, self.j_method, j_args)
386396
ret = <float>j_float
387397
elif r == 'D':
388398
j_double = self.j_env[0].CallStaticDoubleMethodA(
@@ -404,13 +414,109 @@ cdef class JavaMethod(object):
404414
ret_jobject.obj = j_object
405415
ret = ret_jobject
406416
elif r == '[':
407-
# TODO array support
408-
raise NotImplementedError("Array arguments not implemented")
417+
r = self.definition_return[1:]
418+
j_object = self.j_env[0].CallStaticObjectMethodA(
419+
self.j_env, self.j_cls, self.j_method, j_args)
420+
ret = self.convert_return_array(j_object)
409421
else:
410422
raise Exception('Invalid return definition?')
411423

412424
return ret
413425

426+
cdef convert_return_array(self, jobject j_object):
427+
cdef jboolean iscopy
428+
cdef jboolean *j_booleans
429+
cdef jbyte *j_bytes
430+
cdef jchar *j_chars
431+
cdef jshort *j_shorts
432+
cdef jint *j_ints
433+
cdef jlong *j_longs
434+
cdef jfloat *j_float
435+
cdef jdouble *j_double
436+
cdef object ret = None
437+
cdef jsize array_size
438+
cdef int i
439+
440+
if j_object == NULL:
441+
return None
442+
443+
array_size = self.j_env[0].GetArrayLength(self.j_env, j_object)
444+
445+
r = self.definition_return[1]
446+
if r == 'Z':
447+
j_booleans = self.j_env[0].GetBooleanArrayElements(
448+
self.j_env, j_object, &iscopy)
449+
ret = [(True if j_booleans[i] else False)
450+
for i in range(array_size)]
451+
if iscopy:
452+
self.j_env[0].ReleaseBooleanArrayElements(
453+
self.j_env, j_object, j_booleans, 0)
454+
455+
elif r == 'B':
456+
j_bytes = self.j_env[0].GetByteArrayElements(
457+
self.j_env, j_object, &iscopy)
458+
ret = [(<char>j_bytes[i]) for i in range(array_size)]
459+
if iscopy:
460+
self.j_env[0].ReleaseByteArrayElements(
461+
self.j_env, j_object, j_bytes, 0)
462+
463+
elif r == 'C':
464+
j_chars = self.j_env[0].GetCharArrayElements(
465+
self.j_env, j_object, &iscopy)
466+
ret = [(<char>j_chars[i]) for i in range(array_size)]
467+
if iscopy:
468+
self.j_env[0].ReleaseCharArrayElements(
469+
self.j_env, j_object, j_chars, 0)
470+
471+
elif r == 'S':
472+
j_shorts = self.j_env[0].GetShortArrayElements(
473+
self.j_env, j_object, &iscopy)
474+
ret = [(<short>j_shorts[i]) for i in range(array_size)]
475+
if iscopy:
476+
self.j_env[0].ReleaseShortArrayElements(
477+
self.j_env, j_object, j_shorts, 0)
478+
479+
elif r == 'I':
480+
j_ints = self.j_env[0].GetIntArrayElements(
481+
self.j_env, j_object, &iscopy)
482+
ret = [(<int>j_ints[i]) for i in range(array_size)]
483+
if iscopy:
484+
self.j_env[0].ReleaseIntArrayElements(
485+
self.j_env, j_object, j_ints, 0)
486+
487+
elif r == 'J':
488+
j_longs = self.j_env[0].GetLongArrayElements(
489+
self.j_env, j_object, &iscopy)
490+
ret = [(<long>j_longs[i]) for i in range(array_size)]
491+
if iscopy:
492+
self.j_env[0].ReleaseLongArrayElements(
493+
self.j_env, j_object, j_longs, 0)
494+
495+
elif r == 'F':
496+
j_floats = self.j_env[0].GetFloatArrayElements(
497+
self.j_env, j_object, &iscopy)
498+
ret = [(<float>j_floats[i]) for i in range(array_size)]
499+
if iscopy:
500+
self.j_env[0].ReleaseFloatArrayElements(
501+
self.j_env, j_object, j_floats, 0)
502+
503+
elif r == 'D':
504+
j_doubles = self.j_env[0].GetDoubleArrayElements(
505+
self.j_env, j_object, &iscopy)
506+
ret = [(<double>j_doubles[i]) for i in range(array_size)]
507+
if iscopy:
508+
self.j_env[0].ReleaseDoubleArrayElements(
509+
self.j_env, j_object, j_doubles, 0)
510+
511+
elif r == 'L':
512+
# TODO support list of strings etc...
513+
raise NotImplementedError('Array of Java object not done yet')
514+
515+
else:
516+
raise JavaException('Invalid return definition for array')
517+
518+
return ret
519+
414520
class JavaStaticMethod(JavaMethod):
415521
def __init__(self, definition, **kwargs):
416522
kwargs['static'] = True

0 commit comments

Comments
 (0)