@@ -38,16 +38,37 @@ include "jni.pxi"
38
38
from libc.stdlib cimport malloc, free
39
39
40
40
41
- cdef tuple parse_definition(definition):
42
- args, ret = definition[1 :].split(' )' )
43
- if args:
44
- args = args.split(' ;' )
45
- if args[- 1 ] == ' ' :
46
- args.pop(- 1 )
47
- else :
48
- args = []
49
- return ret, args
41
+ cdef parse_definition(definition):
42
+ # not a function, just a field
43
+ if definition[0 ] != ' (' :
44
+ return definition, None
45
+
46
+ # it's a function!
47
+ argdef, ret = definition[1 :].split(' )' )
48
+ args = []
49
+
50
+ while len (argdef):
51
+ c = argdef[0 ]
52
+
53
+ # read the array char
54
+ prefix = ' '
55
+ if c == ' [' :
56
+ prefix = c
57
+ argdef = argdef[1 :]
58
+ c = argdef[0 ]
59
+
60
+ # native type
61
+ if c in ' ZBCSIJFD' :
62
+ args.append(prefix + c)
63
+ argdef = argdef[1 :]
64
+ continue
65
+
66
+ # java class
67
+ if c == ' L' :
68
+ c, argdef = argdef.split(' ;' , 1 )
69
+ args.append(prefix + c + ' ;' )
50
70
71
+ return ret, args
51
72
52
73
class JavaException (Exception ):
53
74
''' Can be a real java exception, or just an exception from the wrapper.
@@ -164,15 +185,17 @@ cdef class JavaClass(object):
164
185
165
186
cdef void populate_args(self , list definition_args, jvalue * j_args, args):
166
187
# do the conversion from a Python object to Java from a Java definition
167
- cdef JavaObject j_object
188
+ cdef JavaObject jo
189
+ cdef JavaClass jc
190
+ cdef int index
168
191
for index, argtype in enumerate (definition_args):
169
192
py_arg = args[index]
170
193
if argtype == ' Z' :
171
194
j_args[index].z = py_arg
172
195
elif argtype == ' B' :
173
196
j_args[index].b = py_arg
174
197
elif argtype == ' C' :
175
- j_args[index].c = py_arg
198
+ j_args[index].c = ord ( py_arg)
176
199
elif argtype == ' S' :
177
200
j_args[index].s = py_arg
178
201
elif argtype == ' I' :
@@ -184,23 +207,150 @@ cdef class JavaClass(object):
184
207
elif argtype == ' D' :
185
208
j_args[index].d = py_arg
186
209
elif argtype[0 ] == ' L' :
187
- if argtype == ' Ljava/lang/String' :
188
- if isinstance (py_arg, basestring ):
189
- j_args[index].l = self .j_env[0 ].NewStringUTF(
190
- self .j_env, < char * >< bytes> py_arg)
191
- elif py_arg is None :
192
- j_args[index].l = NULL
193
- else :
194
- raise JavaException(' Not a correct type of string, '
195
- ' must be an instance of str or unicode' )
210
+ if py_arg is None :
211
+ j_args[index].l = NULL
212
+ elif isinstance (py_arg, basestring ) and \
213
+ argtype == ' Ljava/lang/String;' :
214
+ j_args[index].l = self .j_env[0 ].NewStringUTF(
215
+ self .j_env, < char * >< bytes> py_arg)
216
+ elif isinstance (py_arg, JavaClass):
217
+ jc = py_arg
218
+ if jc.__javaclass__ != argtype[1 :- 1 ]:
219
+ raise JavaException(' Invalid class argument, want '
220
+ ' {0!r}, got {1!r}' .format(
221
+ argtype[1 :- 1 ], jc.__javaclass__))
222
+ j_args[index].l = jc.j_self
223
+ elif isinstance (py_arg, JavaObject):
224
+ jo = py_arg
225
+ j_args[index].l = jo.obj
226
+ raise JavaException(' JavaObject needed for argument '
227
+ ' {0}' .format(index))
196
228
else :
197
- if not isinstance (py_arg, JavaObject):
198
- raise JavaException(' JavaObject needed for argument '
199
- ' {0}' .format(index))
200
- j_object = py_arg
201
- j_args[index].l = j_object.obj
229
+ raise JavaException(' Invalid python object for this '
230
+ ' argument. Want {0!r}, got {1!r}' .format(
231
+ argtype[1 :- 1 ], py_arg))
202
232
elif argtype[0 ] == ' [' :
203
- raise NotImplemented (' List arguments not accepted' )
233
+ if not isinstance (py_arg, list ) and \
234
+ not isinstance (py_arg, tuple ):
235
+ raise JavaException(' Expecting a python list/tuple, got '
236
+ ' {0!r}' .format(py_arg))
237
+
238
+ j_args[index].l = self .convert_pyarray_to_java(
239
+ argtype[1 :], py_arg)
240
+
241
+ cdef jobject convert_pyarray_to_java(self , definition, pyarray):
242
+ cdef jobject ret = NULL
243
+ cdef int array_size = len (pyarray)
244
+ cdef int i
245
+ cdef jboolean j_boolean
246
+ cdef jbyte j_byte
247
+ cdef jchar j_char
248
+ cdef jshort j_short
249
+ cdef jint j_int
250
+ cdef jlong j_long
251
+ cdef jfloat j_float
252
+ cdef jdouble j_double
253
+ cdef jstring j_string
254
+ cdef jclass j_class
255
+ cdef JavaObject jo
256
+ cdef JavaClass jc
257
+
258
+ if definition == ' Z' :
259
+ ret = self .j_env[0 ].NewBooleanArray(self .j_env, array_size)
260
+ for i in range (array_size):
261
+ j_boolean = 1 if pyarray[i] else 0
262
+ self .j_env[0 ].SetBooleanArrayRegion(self .j_env,
263
+ ret, i, 1 , & j_boolean)
264
+
265
+ elif definition == ' B' :
266
+ ret = self .j_env[0 ].NewByteArray(self .j_env, array_size)
267
+ for i in range (array_size):
268
+ j_byte = pyarray[i]
269
+ self .j_env[0 ].SetByteArrayRegion(self .j_env,
270
+ ret, i, 1 , & j_byte)
271
+
272
+ elif definition == ' C' :
273
+ ret = self .j_env[0 ].NewCharArray(self .j_env, array_size)
274
+ for i in range (array_size):
275
+ j_char = ord (pyarray[i])
276
+ self .j_env[0 ].SetCharArrayRegion(self .j_env,
277
+ ret, i, 1 , & j_char)
278
+
279
+ elif definition == ' S' :
280
+ ret = self .j_env[0 ].NewShortArray(self .j_env, array_size)
281
+ for i in range (array_size):
282
+ j_short = pyarray[i]
283
+ self .j_env[0 ].SetShortArrayRegion(self .j_env,
284
+ ret, i, 1 , & j_short)
285
+
286
+ elif definition == ' I' :
287
+ ret = self .j_env[0 ].NewIntArray(self .j_env, array_size)
288
+ for i in range (array_size):
289
+ j_int = pyarray[i]
290
+ self .j_env[0 ].SetIntArrayRegion(self .j_env,
291
+ ret, i, 1 , < const_jint * > & j_int)
292
+
293
+ elif definition == ' J' :
294
+ ret = self .j_env[0 ].NewLongArray(self .j_env, array_size)
295
+ for i in range (array_size):
296
+ j_long = pyarray[i]
297
+ self .j_env[0 ].SetLongArrayRegion(self .j_env,
298
+ ret, i, 1 , & j_long)
299
+
300
+ elif definition == ' F' :
301
+ ret = self .j_env[0 ].NewFloatArray(self .j_env, array_size)
302
+ for i in range (array_size):
303
+ j_float = pyarray[i]
304
+ self .j_env[0 ].SetFloatArrayRegion(self .j_env,
305
+ ret, i, 1 , & j_float)
306
+
307
+ elif definition == ' D' :
308
+ ret = self .j_env[0 ].NewDoubleArray(self .j_env, array_size)
309
+ for i in range (array_size):
310
+ j_double = pyarray[i]
311
+ self .j_env[0 ].SetDoubleArrayRegion(self .j_env,
312
+ ret, i, 1 , & j_double)
313
+
314
+ elif definition[0 ] == ' L' :
315
+ j_class = self .j_env[0 ].FindClass(
316
+ self .j_env, < bytes> definition[1 :- 1 ])
317
+ if j_class == NULL :
318
+ raise JavaException(' Cannot create array with a class not '
319
+ ' found {0!r}' .format(definition[1 :- 1 ]))
320
+ ret = self .j_env[0 ].NewObjectArray(
321
+ self .j_env, array_size, j_class, NULL )
322
+ for i in range (array_size):
323
+ arg = pyarray[i]
324
+ if arg is None :
325
+ self .j_env[0 ].SetObjectArrayElement(
326
+ self .j_env, < jobjectArray> ret, i, NULL )
327
+ elif isinstance (arg, basestring ) and \
328
+ definition == ' Ljava/lang/String;' :
329
+ j_string = self .j_env[0 ].NewStringUTF(
330
+ self .j_env, < bytes> arg)
331
+ self .j_env[0 ].SetObjectArrayElement(
332
+ self .j_env, < jobjectArray> ret, i, j_string)
333
+ elif isinstance (arg, JavaClass):
334
+ jc = arg
335
+ if jc.__javaclass__ != definition[1 :- 1 ]:
336
+ raise JavaException(' Invalid class argument, want '
337
+ ' {0!r}, got {1!r}' .format(
338
+ definition[1 :- 1 ],
339
+ jc.__javaclass__))
340
+ self .j_env[0 ].SetObjectArrayElement(
341
+ self .j_env, < jobjectArray> ret, i, jc.j_self)
342
+ elif isinstance (arg, JavaObject):
343
+ jo = arg
344
+ self .j_env[0 ].SetObjectArrayElement(
345
+ self .j_env, < jobjectArray> ret, i, jo.obj)
346
+ else :
347
+ raise JavaException(' Invalid variable used for L array' )
348
+
349
+ else :
350
+ raise JavaException(' Invalid array definition' )
351
+
352
+ return < jobject> ret
353
+
204
354
205
355
cdef convert_jarray_to_python(self , definition, jobject j_object):
206
356
cdef jboolean iscopy
@@ -210,8 +360,8 @@ cdef class JavaClass(object):
210
360
cdef jshort * j_shorts
211
361
cdef jint * j_ints
212
362
cdef jlong * j_longs
213
- cdef jfloat * j_float
214
- cdef jdouble * j_double
363
+ cdef jfloat * j_floats
364
+ cdef jdouble * j_doubles
215
365
cdef object ret = None
216
366
cdef jsize array_size
217
367
0 commit comments