~james-page/ubuntu/oneiric/jcc/fix-library-linking

« back to all changes in this revision

Viewing changes to jcc/sources/JArray.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ludovico Cavedon
  • Date: 2010-01-31 18:00:47 UTC
  • mfrom: (3.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20100131180047-jryq701kg5wq4943
Tags: 2.5-3
* Merge patch from Ubuntu by Onkar Shinde:
  - When CPU type is i686, use the JRE lib directory corresponding to i386.
    Fixes FTBFS on lpia.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 */