web/lib/arch/osx/jcc/sources/JArray.cpp
changeset 29 cc9b7e14412b
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
       
     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 */