PyLucene 3.4.0-1 import
[pylucene.git] / jcc / jcc / sources / types.cpp
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 #include <jni.h>
16 #include <Python.h>
17 #include "structmember.h"
18
19 #include "java/lang/Object.h"
20 #include "java/lang/Class.h"
21 #include "functions.h"
22
23 using namespace java::lang;
24
25
26 /* FinalizerProxy */
27
28 static PyObject *t_fc_call(PyObject *self, PyObject *args, PyObject *kwds);
29
30 static void t_fp_dealloc(t_fp *self);
31 static PyObject *t_fp_getattro(t_fp *self, PyObject *name);
32 static int t_fp_setattro(t_fp *self, PyObject *name, PyObject *value);
33 static int t_fp_traverse(t_fp *self, visitproc visit, void *arg);
34 static int t_fp_clear(t_fp *self);
35 static PyObject *t_fp_repr(t_fp *self);
36 static PyObject *t_fp_iter(t_fp *self);
37
38 static Py_ssize_t t_fp_map_length(t_fp *self);
39 static PyObject *t_fp_map_get(t_fp *self, PyObject *key);
40 static int t_fp_map_set(t_fp *self, PyObject *key, PyObject *value);
41
42 static Py_ssize_t t_fp_seq_length(t_fp *self);
43 static PyObject *t_fp_seq_get(t_fp *self, Py_ssize_t n);
44 static int t_fp_seq_contains(t_fp *self, PyObject *value);
45 static PyObject *t_fp_seq_concat(t_fp *self, PyObject *arg);
46 static PyObject *t_fp_seq_repeat(t_fp *self, Py_ssize_t n);
47 static PyObject *t_fp_seq_getslice(t_fp *self, Py_ssize_t low, Py_ssize_t high);
48 static int t_fp_seq_set(t_fp *self, Py_ssize_t i, PyObject *value);
49 static int t_fp_seq_setslice(t_fp *self, Py_ssize_t low,
50                              Py_ssize_t high, PyObject *arg);
51 static PyObject *t_fp_seq_inplace_concat(t_fp *self, PyObject *arg);
52 static PyObject *t_fp_seq_inplace_repeat(t_fp *self, Py_ssize_t n);
53
54
55 PyTypeObject PY_TYPE(FinalizerClass) = {
56     PyObject_HEAD_INIT(NULL)
57     0,                                   /* ob_size */
58     "jcc.FinalizerClass",                /* tp_name */
59     PyType_Type.tp_basicsize,            /* tp_basicsize */
60     0,                                   /* tp_itemsize */
61     0,                                   /* tp_dealloc */
62     0,                                   /* tp_print */
63     0,                                   /* tp_getattr */
64     0,                                   /* tp_setattr */
65     0,                                   /* tp_compare */
66     0,                                   /* tp_repr */
67     0,                                   /* tp_as_number */
68     0,                                   /* tp_as_sequence */
69     0,                                   /* tp_as_mapping */
70     0,                                   /* tp_hash  */
71     (ternaryfunc) t_fc_call,             /* tp_call */
72     0,                                   /* tp_str */
73     0,                                   /* tp_getattro */
74     0,                                   /* tp_setattro */
75     0,                                   /* tp_as_buffer */
76     Py_TPFLAGS_DEFAULT,                  /* tp_flags */
77     "FinalizerClass",                    /* tp_doc */
78     0,                                   /* tp_traverse */
79     0,                                   /* tp_clear */
80     0,                                   /* tp_richcompare */
81     0,                                   /* tp_weaklistoffset */
82     0,                                   /* tp_iter */
83     0,                                   /* tp_iternext */
84     0,                                   /* tp_methods */
85     0,                                   /* tp_members */
86     0,                                   /* tp_getset */
87     &PyType_Type,                        /* tp_base */
88     0,                                   /* tp_dict */
89     0,                                   /* tp_descr_get */
90     0,                                   /* tp_descr_set */
91     0,                                   /* tp_dictoffset */
92     0,                                   /* tp_init */
93     0,                                   /* tp_alloc */
94     0,                                   /* tp_new */
95 };
96
97 static PyMappingMethods t_fp_as_mapping = {
98     (lenfunc)t_fp_map_length,            /* mp_length          */
99     (binaryfunc)t_fp_map_get,            /* mp_subscript       */
100     (objobjargproc)t_fp_map_set,         /* mp_ass_subscript   */
101 };
102
103 static PySequenceMethods t_fp_as_sequence = {
104     (lenfunc)t_fp_seq_length,                 /* sq_length */
105     (binaryfunc)t_fp_seq_concat,              /* sq_concat */
106     (ssizeargfunc)t_fp_seq_repeat,            /* sq_repeat */
107     (ssizeargfunc)t_fp_seq_get,               /* sq_item */
108     (ssizessizeargfunc)t_fp_seq_getslice,     /* sq_slice */
109     (ssizeobjargproc)t_fp_seq_set,            /* sq_ass_item */
110     (ssizessizeobjargproc)t_fp_seq_setslice,  /* sq_ass_slice */
111     (objobjproc)t_fp_seq_contains,            /* sq_contains */
112     (binaryfunc)t_fp_seq_inplace_concat,      /* sq_inplace_concat */
113     (ssizeargfunc)t_fp_seq_inplace_repeat,    /* sq_inplace_repeat */
114 };
115
116 PyTypeObject PY_TYPE(FinalizerProxy) = {
117     PyObject_HEAD_INIT(NULL)
118     0,                                   /* ob_size */
119     "jcc.FinalizerProxy",                /* tp_name */
120     sizeof(t_fp),                        /* tp_basicsize */
121     0,                                   /* tp_itemsize */
122     (destructor)t_fp_dealloc,            /* tp_dealloc */
123     0,                                   /* tp_print */
124     0,                                   /* tp_getattr */
125     0,                                   /* tp_setattr */
126     0,                                   /* tp_compare */
127     (reprfunc)t_fp_repr,                 /* tp_repr */
128     0,                                   /* tp_as_number */
129     &t_fp_as_sequence,                   /* tp_as_sequence */
130     &t_fp_as_mapping,                    /* tp_as_mapping */
131     0,                                   /* tp_hash  */
132     0,                                   /* tp_call */
133     0,                                   /* tp_str */
134     (getattrofunc)t_fp_getattro,         /* tp_getattro */
135     (setattrofunc)t_fp_setattro,         /* tp_setattro */
136     0,                                   /* tp_as_buffer */
137     (Py_TPFLAGS_DEFAULT |
138      Py_TPFLAGS_HAVE_GC),                /* tp_flags */
139     "FinalizerProxy",                    /* tp_doc */
140     (traverseproc)t_fp_traverse,         /* tp_traverse */
141     (inquiry)t_fp_clear,                 /* tp_clear */
142     0,                                   /* tp_richcompare */
143     0,                                   /* tp_weaklistoffset */
144     (getiterfunc)t_fp_iter,              /* tp_iter */
145     0,                                   /* tp_iternext */
146     0,                                   /* tp_methods */
147     0,                                   /* tp_members */
148     0,                                   /* tp_getset */
149     0,                                   /* tp_base */
150     0,                                   /* tp_dict */
151     0,                                   /* tp_descr_get */
152     0,                                   /* tp_descr_set */
153     0,                                   /* tp_dictoffset */
154     0,                                   /* tp_init */
155     0,                                   /* tp_alloc */
156     0,                                   /* tp_new */
157 };
158
159 static PyObject *t_fc_call(PyObject *self, PyObject *args, PyObject *kwds)
160 {
161     PyObject *obj = PyType_Type.tp_call(self, args, kwds);
162
163     if (obj)
164     {
165         t_fp *fp = (t_fp *) PY_TYPE(FinalizerProxy).tp_alloc(&PY_TYPE(FinalizerProxy), 0);
166
167         fp->object = obj;      /* released by t_fp_clear() */
168         obj = (PyObject *) fp;
169     }
170
171     return obj;
172 }
173
174 static void t_fp_dealloc(t_fp *self)
175 {
176     if (self->object)
177         ((t_JObject *) self->object)->object.weaken$();
178
179     t_fp_clear(self);
180     self->ob_type->tp_free((PyObject *) self);
181 }
182
183 static int t_fp_traverse(t_fp *self, visitproc visit, void *arg)
184 {
185     Py_VISIT(self->object);
186     return 0;
187 }
188
189 static int t_fp_clear(t_fp *self)
190 {
191     Py_CLEAR(self->object);
192     return 0;
193 }
194
195 static PyObject *t_fp_repr(t_fp *self)
196 {
197     return PyObject_Repr(self->object);
198 }
199
200 static PyObject *t_fp_iter(t_fp *self)
201 {
202     return PyObject_GetIter(self->object);
203 }
204
205 static PyObject *t_fp_getattro(t_fp *self, PyObject *name)
206 {
207     return PyObject_GetAttr(self->object, name);
208 }
209
210 static int t_fp_setattro(t_fp *self, PyObject *name, PyObject *value)
211 {
212     return PyObject_SetAttr(self->object, name, value);
213 }
214
215 static Py_ssize_t t_fp_map_length(t_fp *self)
216 {
217     return PyMapping_Size(self->object);
218 }
219
220 static PyObject *t_fp_map_get(t_fp *self, PyObject *key)
221 {
222     return PyObject_GetItem(self->object, key);
223 }
224
225 static int t_fp_map_set(t_fp *self, PyObject *key, PyObject *value)
226 {
227     if (value == NULL)
228         return PyObject_DelItem(self->object, key);
229
230     return PyObject_SetItem(self->object, key, value);
231 }
232
233 static Py_ssize_t t_fp_seq_length(t_fp *self)
234 {
235     return PySequence_Length(self->object);
236 }
237
238 static PyObject *t_fp_seq_get(t_fp *self, Py_ssize_t n)
239 {
240     return PySequence_GetItem(self->object, n);
241 }
242
243 static int t_fp_seq_contains(t_fp *self, PyObject *value)
244 {
245     return PySequence_Contains(self->object, value);
246 }
247
248 static PyObject *t_fp_seq_concat(t_fp *self, PyObject *arg)
249 {
250     return PySequence_Concat(self->object, arg);
251 }
252
253 static PyObject *t_fp_seq_repeat(t_fp *self, Py_ssize_t n)
254 {
255     return PySequence_Repeat(self->object, n);
256 }
257
258 static PyObject *t_fp_seq_getslice(t_fp *self, Py_ssize_t low, Py_ssize_t high)
259 {
260     return PySequence_GetSlice(self->object, low, high);
261 }
262
263 static int t_fp_seq_set(t_fp *self, Py_ssize_t i, PyObject *value)
264 {
265     return PySequence_SetItem(self->object, i, value);
266 }
267
268 static int t_fp_seq_setslice(t_fp *self, Py_ssize_t low,
269                              Py_ssize_t high, PyObject *arg)
270 {
271     return PySequence_SetSlice(self->object, low, high, arg);
272 }
273
274 static PyObject *t_fp_seq_inplace_concat(t_fp *self, PyObject *arg)
275 {
276     return PySequence_InPlaceConcat(self->object, arg);
277 }
278
279 static PyObject *t_fp_seq_inplace_repeat(t_fp *self, Py_ssize_t n)
280 {
281     return PySequence_InPlaceRepeat(self->object, n);
282 }
283
284
285 /* const variable descriptor */
286
287 class t_descriptor {
288 public:
289     PyObject_HEAD
290     int flags;
291     union {
292         PyObject *value;
293         getclassfn initializeClass;
294     } access;
295 };
296     
297 #define DESCRIPTOR_VALUE   0x0001
298 #define DESCRIPTOR_CLASS   0x0002
299 #define DESCRIPTOR_GETFN   0x0004
300 #define DESCRIPTOR_GENERIC 0x0008
301
302 static void t_descriptor_dealloc(t_descriptor *self);
303 static PyObject *t_descriptor___get__(t_descriptor *self,
304                                       PyObject *obj, PyObject *type);
305
306 static PyMethodDef t_descriptor_methods[] = {
307     { NULL, NULL, 0, NULL }
308 };
309
310
311 PyTypeObject PY_TYPE(ConstVariableDescriptor) = {
312     PyObject_HEAD_INIT(NULL)
313     0,                                   /* ob_size */
314     "jcc.ConstVariableDescriptor",       /* tp_name */
315     sizeof(t_descriptor),                /* tp_basicsize */
316     0,                                   /* tp_itemsize */
317     (destructor)t_descriptor_dealloc,    /* tp_dealloc */
318     0,                                   /* tp_print */
319     0,                                   /* tp_getattr */
320     0,                                   /* tp_setattr */
321     0,                                   /* tp_compare */
322     0,                                   /* tp_repr */
323     0,                                   /* tp_as_number */
324     0,                                   /* tp_as_sequence */
325     0,                                   /* tp_as_mapping */
326     0,                                   /* tp_hash  */
327     0,                                   /* tp_call */
328     0,                                   /* tp_str */
329     0,                                   /* tp_getattro */
330     0,                                   /* tp_setattro */
331     0,                                   /* tp_as_buffer */
332     Py_TPFLAGS_DEFAULT,                  /* tp_flags */
333     "const variable descriptor",         /* tp_doc */
334     0,                                   /* tp_traverse */
335     0,                                   /* tp_clear */
336     0,                                   /* tp_richcompare */
337     0,                                   /* tp_weaklistoffset */
338     0,                                   /* tp_iter */
339     0,                                   /* tp_iternext */
340     t_descriptor_methods,                /* tp_methods */
341     0,                                   /* tp_members */
342     0,                                   /* tp_getset */
343     0,                                   /* tp_base */
344     0,                                   /* tp_dict */
345     (descrgetfunc)t_descriptor___get__,  /* tp_descr_get */
346     0,                                   /* tp_descr_set */
347     0,                                   /* tp_dictoffset */
348     0,                                   /* tp_init */
349     0,                                   /* tp_alloc */
350     0,                                   /* tp_new */
351 };
352
353 static void t_descriptor_dealloc(t_descriptor *self)
354 {
355     if (self->flags & DESCRIPTOR_VALUE)
356     {
357         Py_DECREF(self->access.value);
358     }
359     self->ob_type->tp_free((PyObject *) self);
360 }
361
362 PyObject *make_descriptor(PyTypeObject *value)
363 {
364     t_descriptor *self = (t_descriptor *)
365         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
366
367     if (self)
368     {
369         Py_INCREF(value);
370         self->access.value = (PyObject *) value;
371         self->flags = DESCRIPTOR_VALUE;
372     }
373
374     return (PyObject *) self;
375 }
376
377 PyObject *make_descriptor(getclassfn initializeClass)
378 {
379     t_descriptor *self = (t_descriptor *)
380         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
381
382     if (self)
383     {
384         self->access.initializeClass = initializeClass;
385         self->flags = DESCRIPTOR_CLASS;
386     }
387
388     return (PyObject *) self;
389 }
390
391 PyObject *make_descriptor(getclassfn initializeClass, int generics)
392 {
393     t_descriptor *self = (t_descriptor *) make_descriptor(initializeClass);
394
395     if (self && generics)
396         self->flags |= DESCRIPTOR_GENERIC;
397
398     return (PyObject *) self;
399 }
400
401 PyObject *make_descriptor(PyObject *value)
402 {
403     t_descriptor *self = (t_descriptor *)
404         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
405
406     if (self)
407     {
408         self->access.value = value;
409         self->flags = DESCRIPTOR_VALUE;
410     }
411     else
412         Py_DECREF(value);
413
414     return (PyObject *) self;
415 }
416
417 PyObject *make_descriptor(PyObject *(*wrapfn)(const jobject &))
418 {
419     return make_descriptor(PyCObject_FromVoidPtr((void *) wrapfn, NULL));
420 }
421
422 PyObject *make_descriptor(boxfn fn)
423 {
424     return make_descriptor(PyCObject_FromVoidPtr((void *) fn, NULL));
425 }
426
427 PyObject *make_descriptor(jboolean b)
428 {
429     t_descriptor *self = (t_descriptor *)
430         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
431
432     if (self)
433     {
434         PyObject *value = b ? Py_True : Py_False;
435         self->access.value = (PyObject *) value; Py_INCREF(value);
436         self->flags = DESCRIPTOR_VALUE;
437     }
438
439     return (PyObject *) self;
440 }
441
442 PyObject *make_descriptor(jbyte value)
443 {
444     t_descriptor *self = (t_descriptor *)
445         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
446
447     if (self)
448     {
449         self->access.value = PyInt_FromLong(value);
450         self->flags = DESCRIPTOR_VALUE;
451     }
452
453     return (PyObject *) self;
454 }
455
456 PyObject *make_descriptor(jchar value)
457 {
458     t_descriptor *self = (t_descriptor *)
459         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
460
461     if (self)
462     {
463         Py_UNICODE pchar = (Py_UNICODE) value;
464
465         self->access.value = PyUnicode_FromUnicode(&pchar, 1);
466         self->flags = DESCRIPTOR_VALUE;
467     }
468
469     return (PyObject *) self;
470 }
471
472 PyObject *make_descriptor(jdouble value)
473 {
474     t_descriptor *self = (t_descriptor *)
475         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
476
477     if (self)
478     {
479         self->access.value = PyFloat_FromDouble(value);
480         self->flags = DESCRIPTOR_VALUE;
481     }
482
483     return (PyObject *) self;
484 }
485
486 PyObject *make_descriptor(jfloat value)
487 {
488     t_descriptor *self = (t_descriptor *)
489         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
490
491     if (self)
492     {
493         self->access.value = PyFloat_FromDouble((double) value);
494         self->flags = DESCRIPTOR_VALUE;
495     }
496
497     return (PyObject *) self;
498 }
499
500 PyObject *make_descriptor(jint value)
501 {
502     t_descriptor *self = (t_descriptor *)
503         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
504
505     if (self)
506     {
507         self->access.value = PyInt_FromLong(value);
508         self->flags = DESCRIPTOR_VALUE;
509     }
510
511     return (PyObject *) self;
512 }
513
514 PyObject *make_descriptor(jlong value)
515 {
516     t_descriptor *self = (t_descriptor *)
517         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
518
519     if (self)
520     {
521         self->access.value = PyLong_FromLongLong((long long) value);
522         self->flags = DESCRIPTOR_VALUE;
523     }
524
525     return (PyObject *) self;
526 }
527
528 PyObject *make_descriptor(jshort value)
529 {
530     t_descriptor *self = (t_descriptor *)
531         PY_TYPE(ConstVariableDescriptor).tp_alloc(&PY_TYPE(ConstVariableDescriptor), 0);
532
533     if (self)
534     {
535         self->access.value = PyInt_FromLong((short) value);
536         self->flags = DESCRIPTOR_VALUE;
537     }
538
539     return (PyObject *) self;
540 }
541
542 static PyObject *t_descriptor___get__(t_descriptor *self,
543                                       PyObject *obj, PyObject *type)
544 {
545     if (self->flags & DESCRIPTOR_VALUE)
546     {
547         Py_INCREF(self->access.value);
548         return self->access.value;
549     }
550
551     if (self->flags & DESCRIPTOR_CLASS)
552     {
553 #ifdef _java_generics
554         if (self->flags & DESCRIPTOR_GENERIC)
555             return t_Class::wrap_Object(Class((*self->access.initializeClass)()), (PyTypeObject *) type);
556         else
557 #endif
558             return t_Class::wrap_Object(Class((*self->access.initializeClass)()));
559     }
560
561     Py_RETURN_NONE;
562 }
563