|
1 /* |
|
2 * Licensed under the Apache License, Version 2.0 (the "License"); |
|
3 * you may not use this file except in compliance with the License. |
|
4 * You may obtain a copy of the License at |
|
5 * |
|
6 * http://www.apache.org/licenses/LICENSE-2.0 |
|
7 * |
|
8 * Unless required by applicable law or agreed to in writing, software |
|
9 * distributed under the License is distributed on an "AS IS" BASIS, |
|
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
11 * See the License for the specific language governing permissions and |
|
12 * limitations under the License. |
|
13 */ |
|
14 |
|
15 #ifdef PYTHON |
|
16 |
|
17 #include <jni.h> |
|
18 #include <Python.h> |
|
19 #include "structmember.h" |
|
20 |
|
21 #include "JArray.h" |
|
22 #include "functions.h" |
|
23 #include "java/lang/Class.h" |
|
24 |
|
25 using namespace java::lang; |
|
26 |
|
27 |
|
28 template<typename T> class _t_jarray : public t_jarray<T> { |
|
29 public: |
|
30 static PyObject *format; |
|
31 }; |
|
32 |
|
33 template<typename U> |
|
34 static PyObject *get(U *self, int n) |
|
35 { |
|
36 return self->array.get(n); |
|
37 } |
|
38 |
|
39 template<typename U> |
|
40 static PyObject *toSequence(U *self) |
|
41 { |
|
42 return self->array.toSequence(); |
|
43 } |
|
44 |
|
45 template<typename U> |
|
46 static PyObject *toSequence(U *self, int lo, int hi) |
|
47 { |
|
48 return self->array.toSequence(lo, hi); |
|
49 } |
|
50 |
|
51 template<typename U> class _t_iterator { |
|
52 public: |
|
53 PyObject_HEAD |
|
54 U *obj; |
|
55 Py_ssize_t position; |
|
56 |
|
57 static void dealloc(_t_iterator *self) |
|
58 { |
|
59 Py_XDECREF(self->obj); |
|
60 self->ob_type->tp_free((PyObject *) self); |
|
61 } |
|
62 |
|
63 static PyObject *iternext(_t_iterator *self) |
|
64 { |
|
65 if (self->position < (Py_ssize_t) self->obj->array.length) |
|
66 return get<U>(self->obj, self->position++); |
|
67 |
|
68 PyErr_SetNone(PyExc_StopIteration); |
|
69 return NULL; |
|
70 } |
|
71 |
|
72 static PyTypeObject *JArrayIterator; |
|
73 }; |
|
74 |
|
75 template<typename T, typename U> |
|
76 static int init(U *self, PyObject *args, PyObject *kwds) |
|
77 { |
|
78 PyObject *obj; |
|
79 |
|
80 if (!PyArg_ParseTuple(args, "O", &obj)) |
|
81 return -1; |
|
82 |
|
83 if (PySequence_Check(obj)) |
|
84 { |
|
85 self->array = JArray<T>(obj); |
|
86 if (PyErr_Occurred()) |
|
87 return -1; |
|
88 } |
|
89 else if (PyGen_Check(obj)) |
|
90 { |
|
91 PyObject *tuple = |
|
92 PyObject_CallFunctionObjArgs((PyObject *) &PyTuple_Type, obj, NULL); |
|
93 |
|
94 if (!tuple) |
|
95 return -1; |
|
96 |
|
97 self->array = JArray<T>(tuple); |
|
98 Py_DECREF(tuple); |
|
99 if (PyErr_Occurred()) |
|
100 return -1; |
|
101 } |
|
102 else if (PyInt_Check(obj)) |
|
103 { |
|
104 int n = PyInt_AsLong(obj); |
|
105 |
|
106 if (n < 0) |
|
107 { |
|
108 PyErr_SetObject(PyExc_ValueError, obj); |
|
109 return -1; |
|
110 } |
|
111 |
|
112 self->array = JArray<T>(n); |
|
113 } |
|
114 else |
|
115 { |
|
116 PyErr_SetObject(PyExc_TypeError, obj); |
|
117 return -1; |
|
118 } |
|
119 |
|
120 return 0; |
|
121 } |
|
122 |
|
123 template<typename T, typename U> |
|
124 static void dealloc(U *self) |
|
125 { |
|
126 self->array = JArray<T>((jobject) NULL); |
|
127 self->ob_type->tp_free((PyObject *) self); |
|
128 } |
|
129 |
|
130 template<typename U> |
|
131 static PyObject *_format(U *self, PyObject *(*fn)(PyObject *)) |
|
132 { |
|
133 if (self->array.this$) |
|
134 { |
|
135 PyObject *list = toSequence<U>(self); |
|
136 |
|
137 if (list) |
|
138 { |
|
139 PyObject *result = (*fn)(list); |
|
140 |
|
141 Py_DECREF(list); |
|
142 if (result) |
|
143 { |
|
144 PyObject *args = PyTuple_New(1); |
|
145 |
|
146 PyTuple_SET_ITEM(args, 0, result); |
|
147 result = PyString_Format(U::format, args); |
|
148 Py_DECREF(args); |
|
149 |
|
150 return result; |
|
151 } |
|
152 } |
|
153 |
|
154 return NULL; |
|
155 } |
|
156 |
|
157 return PyString_FromString("<null>"); |
|
158 } |
|
159 |
|
160 template<typename U> |
|
161 static PyObject *repr(U *self) |
|
162 { |
|
163 return _format(self, (PyObject *(*)(PyObject *)) PyObject_Repr); |
|
164 } |
|
165 |
|
166 template<typename U> |
|
167 static PyObject *str(U *self) |
|
168 { |
|
169 return _format(self, (PyObject *(*)(PyObject *)) PyObject_Str); |
|
170 } |
|
171 |
|
172 template<typename U> |
|
173 static int _compare(U *self, PyObject *value, int i0, int i1, int op, int *cmp) |
|
174 { |
|
175 PyObject *v0 = get<U>(self, i0); |
|
176 PyObject *v1 = PySequence_Fast_GET_ITEM(value, i1); /* borrowed */ |
|
177 |
|
178 if (!v0) |
|
179 return -1; |
|
180 |
|
181 if (!v1) |
|
182 { |
|
183 Py_DECREF(v0); |
|
184 return -1; |
|
185 } |
|
186 |
|
187 *cmp = PyObject_RichCompareBool(v0, v1, op); |
|
188 Py_DECREF(v0); |
|
189 |
|
190 if (*cmp < 0) |
|
191 return -1; |
|
192 |
|
193 return 0; |
|
194 } |
|
195 |
|
196 template<typename U> |
|
197 static PyObject *richcompare(U *self, PyObject *value, int op) |
|
198 { |
|
199 PyObject *result = NULL; |
|
200 int s0, s1; |
|
201 |
|
202 if (!PySequence_Check(value)) |
|
203 { |
|
204 Py_INCREF(Py_NotImplemented); |
|
205 return Py_NotImplemented; |
|
206 } |
|
207 |
|
208 value = PySequence_Fast(value, "not a sequence"); |
|
209 if (!value) |
|
210 return NULL; |
|
211 |
|
212 s0 = PySequence_Fast_GET_SIZE(value); |
|
213 s1 = self->array.length; |
|
214 |
|
215 if (s1 < 0) |
|
216 { |
|
217 Py_DECREF(value); |
|
218 return NULL; |
|
219 } |
|
220 |
|
221 if (s0 != s1) |
|
222 { |
|
223 switch (op) { |
|
224 case Py_EQ: result = Py_False; break; |
|
225 case Py_NE: result = Py_True; break; |
|
226 } |
|
227 } |
|
228 |
|
229 if (!result) |
|
230 { |
|
231 int i0, i1, cmp = 1; |
|
232 |
|
233 for (i0 = 0, i1 = 0; i0 < s0 && i1 < s1 && cmp; i0++, i1++) { |
|
234 if (_compare(self, value, i0, i1, Py_EQ, &cmp) < 0) |
|
235 { |
|
236 Py_DECREF(value); |
|
237 return NULL; |
|
238 } |
|
239 } |
|
240 |
|
241 if (cmp) |
|
242 { |
|
243 switch (op) { |
|
244 case Py_LT: cmp = s0 < s1; break; |
|
245 case Py_LE: cmp = s0 <= s1; break; |
|
246 case Py_EQ: cmp = s0 == s1; break; |
|
247 case Py_NE: cmp = s0 != s1; break; |
|
248 case Py_GT: cmp = s0 > s1; break; |
|
249 case Py_GE: cmp = s0 >= s1; break; |
|
250 default: cmp = 0; |
|
251 } |
|
252 |
|
253 result = cmp ? Py_True : Py_False; |
|
254 } |
|
255 else if (op == Py_EQ) |
|
256 result = Py_False; |
|
257 else if (op == Py_NE) |
|
258 result = Py_True; |
|
259 else if (_compare(self, value, i0, i1, op, &cmp) < 0) |
|
260 { |
|
261 Py_DECREF(value); |
|
262 return NULL; |
|
263 } |
|
264 else |
|
265 result = cmp ? Py_True : Py_False; |
|
266 } |
|
267 Py_DECREF(value); |
|
268 |
|
269 Py_INCREF(result); |
|
270 return result; |
|
271 } |
|
272 |
|
273 template<typename U> |
|
274 static PyObject *iter(U *self) |
|
275 { |
|
276 _t_iterator<U> *it = |
|
277 PyObject_New(_t_iterator<U>, _t_iterator<U>::JArrayIterator); |
|
278 |
|
279 if (it) |
|
280 { |
|
281 it->position = 0; |
|
282 it->obj = self; Py_INCREF((PyObject *) self); |
|
283 } |
|
284 |
|
285 return (PyObject *) it; |
|
286 } |
|
287 |
|
288 template<typename U> |
|
289 static Py_ssize_t seq_length(U *self) |
|
290 { |
|
291 if (self->array.this$) |
|
292 return self->array.length; |
|
293 |
|
294 return 0; |
|
295 } |
|
296 |
|
297 template<typename U> |
|
298 static PyObject *seq_get(U *self, Py_ssize_t n) |
|
299 { |
|
300 return get<U>(self, n); |
|
301 } |
|
302 |
|
303 template<typename U> |
|
304 static int seq_contains(U *self, PyObject *value) |
|
305 { |
|
306 return 0; |
|
307 } |
|
308 |
|
309 template<typename U> |
|
310 static PyObject *seq_concat(U *self, PyObject *arg) |
|
311 { |
|
312 PyObject *list = toSequence<U>(self); |
|
313 |
|
314 if (list != NULL && |
|
315 PyList_Type.tp_as_sequence->sq_inplace_concat(list, arg) < 0) |
|
316 { |
|
317 Py_DECREF(list); |
|
318 return NULL; |
|
319 } |
|
320 |
|
321 return list; |
|
322 } |
|
323 |
|
324 template<typename U> |
|
325 static PyObject *seq_repeat(U *self, Py_ssize_t n) |
|
326 { |
|
327 PyObject *list = toSequence<U>(self); |
|
328 |
|
329 if (list != NULL && |
|
330 PyList_Type.tp_as_sequence->sq_inplace_repeat(list, n) < 0) |
|
331 { |
|
332 Py_DECREF(list); |
|
333 return NULL; |
|
334 } |
|
335 |
|
336 return list; |
|
337 } |
|
338 |
|
339 template<typename U> |
|
340 static PyObject *seq_getslice(U *self, Py_ssize_t lo, Py_ssize_t hi) |
|
341 { |
|
342 return toSequence<U>(self, lo, hi); |
|
343 } |
|
344 |
|
345 template<typename U> |
|
346 static int seq_set(U *self, Py_ssize_t n, PyObject *value) |
|
347 { |
|
348 return self->array.set(n, value); |
|
349 } |
|
350 |
|
351 template<typename U> |
|
352 static int seq_setslice(U *self, Py_ssize_t lo, Py_ssize_t hi, PyObject *values) |
|
353 { |
|
354 int length = self->array.length; |
|
355 |
|
356 if (values == NULL) |
|
357 { |
|
358 PyErr_SetString(PyExc_ValueError, "array size cannot change"); |
|
359 return -1; |
|
360 } |
|
361 |
|
362 if (lo < 0) lo = length + lo; |
|
363 if (lo < 0) lo = 0; |
|
364 else if (lo > length) lo = length; |
|
365 if (hi < 0) hi = length + hi; |
|
366 if (hi < 0) hi = 0; |
|
367 else if (hi > length) hi = length; |
|
368 if (lo > hi) lo = hi; |
|
369 |
|
370 PyObject *sequence = PySequence_Fast(values, "not a sequence"); |
|
371 if (!sequence) |
|
372 return -1; |
|
373 |
|
374 int size = PySequence_Fast_GET_SIZE(sequence); |
|
375 if (size < 0) |
|
376 goto error; |
|
377 |
|
378 if (size != hi - lo) |
|
379 { |
|
380 PyErr_SetString(PyExc_ValueError, "array size cannot change"); |
|
381 goto error; |
|
382 } |
|
383 |
|
384 for (int i = lo; i < hi; i++) { |
|
385 PyObject *value = PySequence_Fast_GET_ITEM(sequence, i - lo); |
|
386 |
|
387 if (value == NULL) |
|
388 goto error; |
|
389 |
|
390 if (self->array.set(i, value) < 0) |
|
391 goto error; |
|
392 } |
|
393 |
|
394 Py_DECREF(sequence); |
|
395 return 0; |
|
396 |
|
397 error: |
|
398 Py_DECREF(sequence); |
|
399 return -1; |
|
400 } |
|
401 |
|
402 template<typename T> |
|
403 static jclass initializeClass(void) |
|
404 { |
|
405 return env->get_vm_env()->GetObjectClass(JArray<T>(0).this$); |
|
406 } |
|
407 |
|
408 template<typename T> |
|
409 static PyObject *cast_(PyTypeObject *type, PyObject *args, PyObject *kwds) |
|
410 { |
|
411 PyObject *arg, *clsObj; |
|
412 |
|
413 if (!PyArg_ParseTuple(args, "O", &arg)) |
|
414 return NULL; |
|
415 |
|
416 if (!PyObject_TypeCheck(arg, &Object$$Type)) |
|
417 { |
|
418 PyErr_SetObject(PyExc_TypeError, arg); |
|
419 return NULL; |
|
420 } |
|
421 |
|
422 Class argCls = ((t_Object *) arg)->object.getClass(); |
|
423 |
|
424 if (!argCls.isArray()) |
|
425 { |
|
426 PyErr_SetObject(PyExc_TypeError, arg); |
|
427 return NULL; |
|
428 } |
|
429 |
|
430 clsObj = PyObject_GetAttrString((PyObject *) type, "class_"); |
|
431 if (!clsObj) |
|
432 return NULL; |
|
433 |
|
434 Class arrayCls = ((t_Class *) clsObj)->object; |
|
435 |
|
436 if (!arrayCls.isAssignableFrom(argCls)) |
|
437 { |
|
438 PyErr_SetObject(PyExc_TypeError, arg); |
|
439 return NULL; |
|
440 } |
|
441 |
|
442 return JArray<T>(((t_JObject *) arg)->object.this$).wrap(); |
|
443 } |
|
444 |
|
445 template<typename T> |
|
446 static PyObject *instance_(PyTypeObject *type, PyObject *args, PyObject *kwds) |
|
447 { |
|
448 PyObject *arg, *clsObj; |
|
449 |
|
450 if (!PyArg_ParseTuple(args, "O", &arg)) |
|
451 return NULL; |
|
452 |
|
453 if (!PyObject_TypeCheck(arg, &Object$$Type)) |
|
454 Py_RETURN_FALSE; |
|
455 |
|
456 Class argCls = ((t_Object *) arg)->object.getClass(); |
|
457 |
|
458 if (!argCls.isArray()) |
|
459 Py_RETURN_FALSE; |
|
460 |
|
461 clsObj = PyObject_GetAttrString((PyObject *) type, "class_"); |
|
462 if (!clsObj) |
|
463 return NULL; |
|
464 |
|
465 Class arrayCls = ((t_Class *) clsObj)->object; |
|
466 |
|
467 if (!arrayCls.isAssignableFrom(argCls)) |
|
468 Py_RETURN_FALSE; |
|
469 |
|
470 Py_RETURN_TRUE; |
|
471 } |
|
472 |
|
473 template<typename T> |
|
474 static PyObject *assignable_(PyTypeObject *type, PyObject *args, PyObject *kwds) |
|
475 { |
|
476 return instance_<T>(type, args, kwds); |
|
477 } |
|
478 |
|
479 template< typename T, typename U = _t_jarray<T> > class jarray_type { |
|
480 public: |
|
481 PySequenceMethods seq_methods; |
|
482 PyTypeObject type_object; |
|
483 |
|
484 class iterator_type { |
|
485 public: |
|
486 PyTypeObject type_object; |
|
487 |
|
488 void install(char *name, PyObject *module) |
|
489 { |
|
490 type_object.tp_name = name; |
|
491 |
|
492 if (PyType_Ready(&type_object) == 0) |
|
493 { |
|
494 Py_INCREF((PyObject *) &type_object); |
|
495 PyModule_AddObject(module, name, (PyObject *) &type_object); |
|
496 } |
|
497 |
|
498 _t_iterator<U>::JArrayIterator = &type_object; |
|
499 } |
|
500 |
|
501 iterator_type() |
|
502 { |
|
503 memset(&type_object, 0, sizeof(type_object)); |
|
504 |
|
505 type_object.ob_refcnt = 1; |
|
506 type_object.ob_type = NULL; |
|
507 type_object.tp_basicsize = sizeof(_t_iterator<U>); |
|
508 type_object.tp_dealloc = (destructor) _t_iterator<U>::dealloc; |
|
509 type_object.tp_flags = Py_TPFLAGS_DEFAULT; |
|
510 type_object.tp_doc = "JArrayIterator<T> wrapper type"; |
|
511 type_object.tp_iter = (getiterfunc) PyObject_SelfIter; |
|
512 type_object.tp_iternext = (iternextfunc) _t_iterator<U>::iternext; |
|
513 } |
|
514 }; |
|
515 |
|
516 iterator_type iterator_type_object; |
|
517 |
|
518 void install(char *name, char *type_name, char *iterator_name, |
|
519 PyObject *module) |
|
520 { |
|
521 type_object.tp_name = name; |
|
522 |
|
523 if (PyType_Ready(&type_object) == 0) |
|
524 { |
|
525 Py_INCREF((PyObject *) &type_object); |
|
526 PyDict_SetItemString(type_object.tp_dict, "class_", |
|
527 make_descriptor(initializeClass<T>)); |
|
528 |
|
529 PyModule_AddObject(module, name, (PyObject *) &type_object); |
|
530 } |
|
531 |
|
532 U::format = PyString_FromFormat("JArray<%s>%%s", type_name); |
|
533 iterator_type_object.install(iterator_name, module); |
|
534 } |
|
535 |
|
536 static PyObject *_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
|
537 { |
|
538 U *self = (U *) type->tp_alloc(type, 0); |
|
539 |
|
540 if (self) |
|
541 self->array = JArray<T>((jobject) NULL); |
|
542 |
|
543 return (PyObject *) self; |
|
544 } |
|
545 |
|
546 jarray_type() |
|
547 { |
|
548 memset(&seq_methods, 0, sizeof(seq_methods)); |
|
549 memset(&type_object, 0, sizeof(type_object)); |
|
550 |
|
551 static PyMethodDef methods[] = { |
|
552 { "cast_", |
|
553 (PyCFunction) (PyObject *(*)(PyTypeObject *, |
|
554 PyObject *, PyObject *)) |
|
555 cast_<T>, |
|
556 METH_VARARGS | METH_CLASS, NULL }, |
|
557 { "instance_", |
|
558 (PyCFunction) (PyObject *(*)(PyTypeObject *, |
|
559 PyObject *, PyObject *)) |
|
560 instance_<T>, |
|
561 METH_VARARGS | METH_CLASS, NULL }, |
|
562 { "assignable_", |
|
563 (PyCFunction) (PyObject *(*)(PyTypeObject *, |
|
564 PyObject *, PyObject *)) |
|
565 assignable_<T>, |
|
566 METH_VARARGS | METH_CLASS, NULL }, |
|
567 { NULL, NULL, 0, NULL } |
|
568 }; |
|
569 |
|
570 seq_methods.sq_length = |
|
571 (lenfunc) (Py_ssize_t (*)(U *)) seq_length<U>; |
|
572 seq_methods.sq_concat = |
|
573 (binaryfunc) (PyObject *(*)(U *, PyObject *)) seq_concat<U>; |
|
574 seq_methods.sq_repeat = |
|
575 (ssizeargfunc) (PyObject *(*)(U *, Py_ssize_t)) seq_repeat<U>; |
|
576 seq_methods.sq_item = |
|
577 (ssizeargfunc) (PyObject *(*)(U *, Py_ssize_t)) seq_get<U>; |
|
578 seq_methods.sq_slice = |
|
579 (ssizessizeargfunc) (PyObject *(*)(U *, Py_ssize_t, Py_ssize_t)) |
|
580 seq_getslice<U>; |
|
581 seq_methods.sq_ass_item = |
|
582 (ssizeobjargproc) (int (*)(U *, Py_ssize_t, PyObject *)) seq_set<U>; |
|
583 seq_methods.sq_ass_slice = |
|
584 (ssizessizeobjargproc) (int (*)(U *, Py_ssize_t, Py_ssize_t, |
|
585 PyObject *)) seq_setslice<U>; |
|
586 seq_methods.sq_contains = |
|
587 (objobjproc) (int (*)(U *, PyObject *)) seq_contains<U>; |
|
588 seq_methods.sq_inplace_concat = NULL; |
|
589 seq_methods.sq_inplace_repeat = NULL; |
|
590 |
|
591 type_object.ob_refcnt = 1; |
|
592 type_object.tp_basicsize = sizeof(U); |
|
593 type_object.tp_dealloc = (destructor) (void (*)(U *)) dealloc<T,U>; |
|
594 type_object.tp_repr = (reprfunc) (PyObject *(*)(U *)) repr<U>; |
|
595 type_object.tp_as_sequence = &seq_methods; |
|
596 type_object.tp_str = (reprfunc) (PyObject *(*)(U *)) str<U>; |
|
597 type_object.tp_flags = Py_TPFLAGS_DEFAULT; |
|
598 type_object.tp_doc = "JArray<T> wrapper type"; |
|
599 type_object.tp_richcompare = |
|
600 (richcmpfunc) (PyObject *(*)(U *, PyObject *, int)) richcompare<U>; |
|
601 type_object.tp_iter = (getiterfunc) (PyObject *(*)(U *)) iter<U>; |
|
602 type_object.tp_methods = methods; |
|
603 type_object.tp_base = &Object$$Type; |
|
604 type_object.tp_init = |
|
605 (initproc) (int (*)(U *, PyObject *, PyObject *)) init<T,U>; |
|
606 type_object.tp_new = (newfunc) _new; |
|
607 } |
|
608 }; |
|
609 |
|
610 template<typename T> class _t_jobjectarray : public _t_jarray<T> { |
|
611 public: |
|
612 PyObject *(*wrapfn)(const T&); |
|
613 }; |
|
614 |
|
615 template<> PyObject *get(_t_jobjectarray<jobject> *self, int n) |
|
616 { |
|
617 return self->array.get(n, self->wrapfn); |
|
618 } |
|
619 |
|
620 template<> PyObject *toSequence(_t_jobjectarray<jobject> *self) |
|
621 { |
|
622 return self->array.toSequence(self->wrapfn); |
|
623 } |
|
624 |
|
625 template<> PyObject *toSequence(_t_jobjectarray<jobject> *self, int lo, int hi) |
|
626 { |
|
627 return self->array.toSequence(lo, hi, self->wrapfn); |
|
628 } |
|
629 |
|
630 template<> int init< jobject,_t_jobjectarray<jobject> >(_t_jobjectarray<jobject> *self, PyObject *args, PyObject *kwds) |
|
631 { |
|
632 PyObject *obj, *clsObj = NULL; |
|
633 PyObject *(*wrapfn)(const jobject &) = NULL; |
|
634 jclass cls; |
|
635 |
|
636 if (!PyArg_ParseTuple(args, "O|O", &obj, &clsObj)) |
|
637 return -1; |
|
638 |
|
639 if (clsObj == NULL) |
|
640 cls = env->findClass("java/lang/Object"); |
|
641 else if (PyObject_TypeCheck(clsObj, &Class$$Type)) |
|
642 cls = (jclass) ((t_Class *) clsObj)->object.this$; |
|
643 else if (PyType_Check(clsObj)) |
|
644 { |
|
645 if (PyType_IsSubtype((PyTypeObject *) clsObj, &JObject$$Type)) |
|
646 { |
|
647 PyObject *cobj = PyObject_GetAttrString(clsObj, "wrapfn_"); |
|
648 |
|
649 if (cobj == NULL) |
|
650 PyErr_Clear(); |
|
651 else |
|
652 { |
|
653 wrapfn = (PyObject *(*)(const jobject &)) |
|
654 PyCObject_AsVoidPtr(cobj); |
|
655 Py_DECREF(cobj); |
|
656 } |
|
657 |
|
658 clsObj = PyObject_GetAttrString(clsObj, "class_"); |
|
659 if (clsObj == NULL) |
|
660 return -1; |
|
661 |
|
662 cls = (jclass) ((t_Class *) clsObj)->object.this$; |
|
663 Py_DECREF(clsObj); |
|
664 } |
|
665 else |
|
666 { |
|
667 PyErr_SetObject(PyExc_ValueError, clsObj); |
|
668 return -1; |
|
669 } |
|
670 } |
|
671 else |
|
672 { |
|
673 PyErr_SetObject(PyExc_TypeError, clsObj); |
|
674 return -1; |
|
675 } |
|
676 |
|
677 if (PySequence_Check(obj)) |
|
678 { |
|
679 self->array = JArray<jobject>(cls, obj); |
|
680 if (PyErr_Occurred()) |
|
681 return -1; |
|
682 } |
|
683 else if (PyGen_Check(obj)) |
|
684 { |
|
685 PyObject *tuple = |
|
686 PyObject_CallFunctionObjArgs((PyObject *) &PyTuple_Type, obj, NULL); |
|
687 |
|
688 if (!tuple) |
|
689 return -1; |
|
690 |
|
691 self->array = JArray<jobject>(cls, tuple); |
|
692 Py_DECREF(tuple); |
|
693 if (PyErr_Occurred()) |
|
694 return -1; |
|
695 } |
|
696 else if (PyInt_Check(obj)) |
|
697 { |
|
698 int n = PyInt_AsLong(obj); |
|
699 |
|
700 if (n < 0) |
|
701 { |
|
702 PyErr_SetObject(PyExc_ValueError, obj); |
|
703 return -1; |
|
704 } |
|
705 |
|
706 self->array = JArray<jobject>(cls, n); |
|
707 } |
|
708 else |
|
709 { |
|
710 PyErr_SetObject(PyExc_TypeError, obj); |
|
711 return -1; |
|
712 } |
|
713 |
|
714 self->wrapfn = wrapfn; |
|
715 |
|
716 return 0; |
|
717 } |
|
718 |
|
719 template<> jclass initializeClass<jobject>(void) |
|
720 { |
|
721 jclass cls = env->findClass("java/lang/Object"); |
|
722 return env->get_vm_env()->GetObjectClass(JArray<jobject>(cls, 0).this$); |
|
723 } |
|
724 |
|
725 template<> PyObject *cast_<jobject>(PyTypeObject *type, |
|
726 PyObject *args, PyObject *kwds) |
|
727 { |
|
728 PyObject *arg, *clsArg = NULL; |
|
729 PyObject *(*wrapfn)(const jobject&) = NULL; |
|
730 jclass elementCls; |
|
731 |
|
732 if (!PyArg_ParseTuple(args, "O|O", &arg, &clsArg)) |
|
733 return NULL; |
|
734 |
|
735 if (!PyObject_TypeCheck(arg, &Object$$Type)) |
|
736 { |
|
737 PyErr_SetObject(PyExc_TypeError, arg); |
|
738 return NULL; |
|
739 } |
|
740 |
|
741 Class argCls = ((t_Object *) arg)->object.getClass(); |
|
742 |
|
743 if (!argCls.isArray()) |
|
744 { |
|
745 PyErr_SetObject(PyExc_TypeError, arg); |
|
746 return NULL; |
|
747 } |
|
748 |
|
749 if (clsArg != NULL) |
|
750 { |
|
751 if (!PyType_Check(clsArg)) |
|
752 { |
|
753 PyErr_SetObject(PyExc_TypeError, clsArg); |
|
754 return NULL; |
|
755 } |
|
756 else if (!PyType_IsSubtype((PyTypeObject *) clsArg, &JObject$$Type)) |
|
757 { |
|
758 PyErr_SetObject(PyExc_ValueError, clsArg); |
|
759 return NULL; |
|
760 } |
|
761 |
|
762 PyObject *cobj = PyObject_GetAttrString(clsArg, "wrapfn_"); |
|
763 |
|
764 if (cobj == NULL) |
|
765 PyErr_Clear(); |
|
766 else |
|
767 { |
|
768 wrapfn = (PyObject *(*)(const jobject &)) PyCObject_AsVoidPtr(cobj); |
|
769 Py_DECREF(cobj); |
|
770 } |
|
771 |
|
772 clsArg = PyObject_GetAttrString(clsArg, "class_"); |
|
773 if (clsArg == NULL) |
|
774 return NULL; |
|
775 |
|
776 elementCls = (jclass) ((t_Class *) clsArg)->object.this$; |
|
777 Py_DECREF(clsArg); |
|
778 } |
|
779 else |
|
780 elementCls = env->findClass("java/lang/Object"); |
|
781 |
|
782 JNIEnv *vm_env = env->get_vm_env(); |
|
783 jobjectArray array = vm_env->NewObjectArray(0, elementCls, NULL); |
|
784 Class arrayCls(vm_env->GetObjectClass((jobject) array)); |
|
785 |
|
786 if (!arrayCls.isAssignableFrom(argCls)) |
|
787 { |
|
788 PyErr_SetObject(PyExc_TypeError, arg); |
|
789 return NULL; |
|
790 } |
|
791 |
|
792 return JArray<jobject>(((t_JObject *) arg)->object.this$).wrap(wrapfn); |
|
793 } |
|
794 |
|
795 template<> PyObject *instance_<jobject>(PyTypeObject *type, |
|
796 PyObject *args, PyObject *kwds) |
|
797 { |
|
798 PyObject *arg, *clsArg = NULL; |
|
799 jclass elementCls; |
|
800 |
|
801 if (!PyArg_ParseTuple(args, "O|O", &arg, &clsArg)) |
|
802 return NULL; |
|
803 |
|
804 if (!PyObject_TypeCheck(arg, &Object$$Type)) |
|
805 Py_RETURN_FALSE; |
|
806 |
|
807 Class argCls = ((t_Object *) arg)->object.getClass(); |
|
808 |
|
809 if (!argCls.isArray()) |
|
810 Py_RETURN_FALSE; |
|
811 |
|
812 if (clsArg != NULL) |
|
813 { |
|
814 if (!PyType_Check(clsArg)) |
|
815 { |
|
816 PyErr_SetObject(PyExc_TypeError, clsArg); |
|
817 return NULL; |
|
818 } |
|
819 else if (!PyType_IsSubtype((PyTypeObject *) clsArg, &JObject$$Type)) |
|
820 { |
|
821 PyErr_SetObject(PyExc_ValueError, clsArg); |
|
822 return NULL; |
|
823 } |
|
824 |
|
825 clsArg = PyObject_GetAttrString(clsArg, "class_"); |
|
826 if (clsArg == NULL) |
|
827 return NULL; |
|
828 |
|
829 elementCls = (jclass) ((t_Class *) clsArg)->object.this$; |
|
830 Py_DECREF(clsArg); |
|
831 } |
|
832 else |
|
833 elementCls = env->findClass("java/lang/Object"); |
|
834 |
|
835 JNIEnv *vm_env = env->get_vm_env(); |
|
836 jobjectArray array = vm_env->NewObjectArray(0, elementCls, NULL); |
|
837 Class arrayCls(vm_env->GetObjectClass((jobject) array)); |
|
838 |
|
839 if (!arrayCls.isAssignableFrom(argCls)) |
|
840 Py_RETURN_FALSE; |
|
841 |
|
842 Py_RETURN_TRUE; |
|
843 } |
|
844 |
|
845 template<> PyObject *assignable_<jobject>(PyTypeObject *type, |
|
846 PyObject *args, PyObject *kwds) |
|
847 { |
|
848 PyObject *arg, *clsArg = NULL; |
|
849 jclass elementCls; |
|
850 |
|
851 if (!PyArg_ParseTuple(args, "O|O", &arg, &clsArg)) |
|
852 return NULL; |
|
853 |
|
854 if (!PyObject_TypeCheck(arg, &Object$$Type)) |
|
855 Py_RETURN_FALSE; |
|
856 |
|
857 Class argCls = ((t_Object *) arg)->object.getClass(); |
|
858 |
|
859 if (!argCls.isArray()) |
|
860 Py_RETURN_FALSE; |
|
861 |
|
862 if (clsArg != NULL) |
|
863 { |
|
864 if (!PyType_Check(clsArg)) |
|
865 { |
|
866 PyErr_SetObject(PyExc_TypeError, clsArg); |
|
867 return NULL; |
|
868 } |
|
869 else if (!PyType_IsSubtype((PyTypeObject *) clsArg, &JObject$$Type)) |
|
870 { |
|
871 PyErr_SetObject(PyExc_ValueError, clsArg); |
|
872 return NULL; |
|
873 } |
|
874 |
|
875 clsArg = PyObject_GetAttrString(clsArg, "class_"); |
|
876 if (clsArg == NULL) |
|
877 return NULL; |
|
878 |
|
879 elementCls = (jclass) ((t_Class *) clsArg)->object.this$; |
|
880 Py_DECREF(clsArg); |
|
881 } |
|
882 else |
|
883 elementCls = env->findClass("java/lang/Object"); |
|
884 |
|
885 JNIEnv *vm_env = env->get_vm_env(); |
|
886 jobjectArray array = vm_env->NewObjectArray(0, elementCls, NULL); |
|
887 Class arrayCls(vm_env->GetObjectClass((jobject) array)); |
|
888 |
|
889 if (!argCls.isAssignableFrom(arrayCls)) |
|
890 Py_RETURN_FALSE; |
|
891 |
|
892 Py_RETURN_TRUE; |
|
893 } |
|
894 |
|
895 |
|
896 template<typename T> PyTypeObject *_t_iterator<T>::JArrayIterator; |
|
897 template<typename T> PyObject *_t_jarray<T>::format; |
|
898 |
|
899 static jarray_type< jobject, _t_jobjectarray<jobject> > jarray_jobject; |
|
900 |
|
901 static jarray_type<jstring> jarray_jstring; |
|
902 static jarray_type<jboolean> jarray_jboolean; |
|
903 static jarray_type<jbyte> jarray_jbyte; |
|
904 static jarray_type<jchar> jarray_jchar; |
|
905 static jarray_type<jdouble> jarray_jdouble; |
|
906 static jarray_type<jfloat> jarray_jfloat; |
|
907 static jarray_type<jint> jarray_jint; |
|
908 static jarray_type<jlong> jarray_jlong; |
|
909 static jarray_type<jshort> jarray_jshort; |
|
910 |
|
911 |
|
912 PyObject *JArray<jobject>::wrap(PyObject *(*wrapfn)(const jobject&)) |
|
913 { |
|
914 if (this$ != NULL) |
|
915 { |
|
916 _t_jobjectarray<jobject> *obj = |
|
917 PyObject_New(_t_jobjectarray<jobject>, &jarray_jobject.type_object); |
|
918 |
|
919 memset(&(obj->array), 0, sizeof(JArray<jobject>)); |
|
920 obj->array = *this; |
|
921 obj->wrapfn = wrapfn; |
|
922 |
|
923 return (PyObject *) obj; |
|
924 } |
|
925 |
|
926 Py_RETURN_NONE; |
|
927 } |
|
928 |
|
929 PyObject *JArray<jstring>::wrap() |
|
930 { |
|
931 if (this$ != NULL) |
|
932 { |
|
933 _t_jarray<jstring> *obj = |
|
934 PyObject_New(_t_jarray<jstring>, &jarray_jstring.type_object); |
|
935 |
|
936 memset(&(obj->array), 0, sizeof(JArray<jstring>)); |
|
937 obj->array = *this; |
|
938 |
|
939 return (PyObject *) obj; |
|
940 } |
|
941 |
|
942 Py_RETURN_NONE; |
|
943 } |
|
944 |
|
945 PyObject *JArray<jboolean>::wrap() |
|
946 { |
|
947 if (this$ != NULL) |
|
948 { |
|
949 _t_jarray<jboolean> *obj = |
|
950 PyObject_New(_t_jarray<jboolean>, &jarray_jboolean.type_object); |
|
951 |
|
952 memset(&(obj->array), 0, sizeof(JArray<jboolean>)); |
|
953 obj->array = *this; |
|
954 |
|
955 return (PyObject *) obj; |
|
956 } |
|
957 |
|
958 Py_RETURN_NONE; |
|
959 } |
|
960 |
|
961 PyObject *JArray<jbyte>::wrap() |
|
962 { |
|
963 if (this$ != NULL) |
|
964 { |
|
965 _t_jarray<jbyte> *obj = |
|
966 PyObject_New(_t_jarray<jbyte>, &jarray_jbyte.type_object); |
|
967 |
|
968 memset(&(obj->array), 0, sizeof(JArray<jbyte>)); |
|
969 obj->array = *this; |
|
970 |
|
971 return (PyObject *) obj; |
|
972 } |
|
973 |
|
974 Py_RETURN_NONE; |
|
975 } |
|
976 |
|
977 PyObject *JArray<jchar>::wrap() |
|
978 { |
|
979 if (this$ != NULL) |
|
980 { |
|
981 _t_jarray<jchar> *obj = |
|
982 PyObject_New(_t_jarray<jchar>, &jarray_jchar.type_object); |
|
983 |
|
984 memset(&(obj->array), 0, sizeof(JArray<jchar>)); |
|
985 obj->array = *this; |
|
986 |
|
987 return (PyObject *) obj; |
|
988 } |
|
989 |
|
990 Py_RETURN_NONE; |
|
991 } |
|
992 |
|
993 PyObject *JArray<jdouble>::wrap() |
|
994 { |
|
995 if (this$ != NULL) |
|
996 { |
|
997 _t_jarray<jdouble> *obj = |
|
998 PyObject_New(_t_jarray<jdouble>, &jarray_jdouble.type_object); |
|
999 |
|
1000 memset(&(obj->array), 0, sizeof(JArray<jdouble>)); |
|
1001 obj->array = *this; |
|
1002 |
|
1003 return (PyObject *) obj; |
|
1004 } |
|
1005 |
|
1006 Py_RETURN_NONE; |
|
1007 } |
|
1008 |
|
1009 PyObject *JArray<jfloat>::wrap() |
|
1010 { |
|
1011 if (this$ != NULL) |
|
1012 { |
|
1013 _t_jarray<jfloat> *obj = |
|
1014 PyObject_New(_t_jarray<jfloat>, &jarray_jfloat.type_object); |
|
1015 |
|
1016 memset(&(obj->array), 0, sizeof(JArray<jfloat>)); |
|
1017 obj->array = *this; |
|
1018 |
|
1019 return (PyObject *) obj; |
|
1020 } |
|
1021 |
|
1022 Py_RETURN_NONE; |
|
1023 } |
|
1024 |
|
1025 PyObject *JArray<jint>::wrap() |
|
1026 { |
|
1027 if (this$ != NULL) |
|
1028 { |
|
1029 _t_jarray<jint> *obj = |
|
1030 PyObject_New(_t_jarray<jint>, &jarray_jint.type_object); |
|
1031 |
|
1032 memset(&(obj->array), 0, sizeof(JArray<jint>)); |
|
1033 obj->array = *this; |
|
1034 |
|
1035 return (PyObject *) obj; |
|
1036 } |
|
1037 |
|
1038 Py_RETURN_NONE; |
|
1039 } |
|
1040 |
|
1041 PyObject *JArray<jlong>::wrap() |
|
1042 { |
|
1043 if (this$ != NULL) |
|
1044 { |
|
1045 _t_jarray<jlong> *obj = |
|
1046 PyObject_New(_t_jarray<jlong>, &jarray_jlong.type_object); |
|
1047 |
|
1048 memset(&(obj->array), 0, sizeof(JArray<jlong>)); |
|
1049 obj->array = *this; |
|
1050 |
|
1051 return (PyObject *) obj; |
|
1052 } |
|
1053 |
|
1054 Py_RETURN_NONE; |
|
1055 } |
|
1056 |
|
1057 PyObject *JArray<jshort>::wrap() |
|
1058 { |
|
1059 if (this$ != NULL) |
|
1060 { |
|
1061 _t_jarray<jshort> *obj = |
|
1062 PyObject_New(_t_jarray<jshort>, &jarray_jshort.type_object); |
|
1063 |
|
1064 memset(&(obj->array), 0, sizeof(JArray<jshort>)); |
|
1065 obj->array = *this; |
|
1066 |
|
1067 return (PyObject *) obj; |
|
1068 } |
|
1069 |
|
1070 Py_RETURN_NONE; |
|
1071 } |
|
1072 |
|
1073 PyObject *JArray_Type(PyObject *self, PyObject *arg) |
|
1074 { |
|
1075 PyObject *type_name = NULL, *type; |
|
1076 char const *name = NULL; |
|
1077 |
|
1078 if (PyType_Check(arg)) |
|
1079 { |
|
1080 type_name = PyObject_GetAttrString(arg, "__name__"); |
|
1081 if (!type_name) |
|
1082 return NULL; |
|
1083 } |
|
1084 else if (PyString_Check(arg)) |
|
1085 { |
|
1086 type_name = arg; |
|
1087 Py_INCREF(type_name); |
|
1088 } |
|
1089 else if (PyFloat_Check(arg)) |
|
1090 { |
|
1091 type_name = NULL; |
|
1092 name = "double"; |
|
1093 } |
|
1094 else |
|
1095 { |
|
1096 PyObject *arg_type = (PyObject *) arg->ob_type; |
|
1097 |
|
1098 type_name = PyObject_GetAttrString(arg_type, "__name__"); |
|
1099 if (!type_name) |
|
1100 return NULL; |
|
1101 } |
|
1102 |
|
1103 if (type_name != NULL) |
|
1104 { |
|
1105 name = PyString_AsString(type_name); |
|
1106 Py_DECREF(type_name); |
|
1107 |
|
1108 if (!name) |
|
1109 return NULL; |
|
1110 } |
|
1111 |
|
1112 if (!strcmp(name, "object")) |
|
1113 type = (PyObject *) &jarray_jobject.type_object; |
|
1114 else if (!strcmp(name, "string")) |
|
1115 type = (PyObject *) &jarray_jstring.type_object; |
|
1116 else if (!strcmp(name, "bool")) |
|
1117 type = (PyObject *) &jarray_jboolean.type_object; |
|
1118 else if (!strcmp(name, "byte")) |
|
1119 type = (PyObject *) &jarray_jbyte.type_object; |
|
1120 else if (!strcmp(name, "char")) |
|
1121 type = (PyObject *) &jarray_jchar.type_object; |
|
1122 else if (!strcmp(name, "double")) |
|
1123 type = (PyObject *) &jarray_jdouble.type_object; |
|
1124 else if (!strcmp(name, "float")) |
|
1125 type = (PyObject *) &jarray_jfloat.type_object; |
|
1126 else if (!strcmp(name, "int")) |
|
1127 type = (PyObject *) &jarray_jint.type_object; |
|
1128 else if (!strcmp(name, "long")) |
|
1129 type = (PyObject *) &jarray_jlong.type_object; |
|
1130 else if (!strcmp(name, "short")) |
|
1131 type = (PyObject *) &jarray_jshort.type_object; |
|
1132 else |
|
1133 { |
|
1134 PyErr_SetObject(PyExc_ValueError, arg); |
|
1135 return NULL; |
|
1136 } |
|
1137 |
|
1138 Py_INCREF(type); |
|
1139 return type; |
|
1140 } |
|
1141 |
|
1142 static PyObject *t_jarray_jbyte__get_string_(t_jarray<jbyte> *self, void *data) |
|
1143 { |
|
1144 return self->array.to_string_(); |
|
1145 } |
|
1146 |
|
1147 static PyGetSetDef t_jarray_jbyte__fields[] = { |
|
1148 { "string_", (getter) t_jarray_jbyte__get_string_, NULL, "", NULL }, |
|
1149 { NULL, NULL, NULL, NULL, NULL } |
|
1150 }; |
|
1151 |
|
1152 |
|
1153 PyTypeObject *JArrayObject$$Type; |
|
1154 PyTypeObject *JArrayString$$Type; |
|
1155 PyTypeObject *JArrayBool$$Type; |
|
1156 PyTypeObject *JArrayByte$$Type; |
|
1157 PyTypeObject *JArrayChar$$Type; |
|
1158 PyTypeObject *JArrayDouble$$Type; |
|
1159 PyTypeObject *JArrayFloat$$Type; |
|
1160 PyTypeObject *JArrayInt$$Type; |
|
1161 PyTypeObject *JArrayLong$$Type; |
|
1162 PyTypeObject *JArrayShort$$Type; |
|
1163 |
|
1164 |
|
1165 void _install_jarray(PyObject *module) |
|
1166 { |
|
1167 jarray_jobject.install("JArray_object", "object", |
|
1168 "__JArray_object_iterator", module); |
|
1169 JArrayObject$$Type = &jarray_jobject.type_object; |
|
1170 |
|
1171 jarray_jstring.install("JArray_string", "string", |
|
1172 "__JArray_string_iterator", module); |
|
1173 JArrayString$$Type = &jarray_jstring.type_object; |
|
1174 |
|
1175 jarray_jboolean.install("JArray_bool", "bool", |
|
1176 "__JArray_bool_iterator", module); |
|
1177 JArrayBool$$Type = &jarray_jboolean.type_object; |
|
1178 |
|
1179 jarray_jbyte.type_object.tp_getset = t_jarray_jbyte__fields; |
|
1180 jarray_jbyte.install("JArray_byte", "byte", |
|
1181 "__JArray_byte_iterator", module); |
|
1182 JArrayByte$$Type = &jarray_jbyte.type_object; |
|
1183 |
|
1184 jarray_jchar.install("JArray_char", "char", |
|
1185 "__JArray_char_iterator", module); |
|
1186 JArrayChar$$Type = &jarray_jchar.type_object; |
|
1187 |
|
1188 jarray_jdouble.install("JArray_double", "double", |
|
1189 "__JArray_double_iterator", module); |
|
1190 JArrayDouble$$Type = &jarray_jdouble.type_object; |
|
1191 |
|
1192 jarray_jfloat.install("JArray_float", "float", |
|
1193 "__JArray_float_iterator", module); |
|
1194 JArrayFloat$$Type = &jarray_jfloat.type_object; |
|
1195 |
|
1196 jarray_jint.install("JArray_int", "int", |
|
1197 "__JArray_int_iterator", module); |
|
1198 JArrayInt$$Type = &jarray_jint.type_object; |
|
1199 |
|
1200 jarray_jlong.install("JArray_long", "long", |
|
1201 "__JArray_long_iterator", module); |
|
1202 JArrayLong$$Type = &jarray_jlong.type_object; |
|
1203 |
|
1204 jarray_jshort.install("JArray_short", "short", |
|
1205 "__JArray_short_iterator", module); |
|
1206 JArrayShort$$Type = &jarray_jshort.type_object; |
|
1207 } |
|
1208 |
|
1209 #endif /* PYTHON */ |