Omaha #4259 native java.util.List support in JEP
Change-Id: If0706318fd409884933433a8edf279e1f6659621 Former-commit-id: 4921ee47a87af497fdc2be53f6bde67b857587b8
This commit is contained in:
parent
963f457d65
commit
99b5d09d9d
2 changed files with 608 additions and 0 deletions
549
nativeLib/rary.cots.jepp/jepp-2.3/src/jep/pyjlist.c
Normal file
549
nativeLib/rary.cots.jepp/jepp-2.3/src/jep/pyjlist.c
Normal file
|
@ -0,0 +1,549 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 c-style: "K&R" -*- */
|
||||
/*
|
||||
jep - Java Embedded Python
|
||||
|
||||
Copyright (c) 2004 - 2011 Mike Johnson.
|
||||
@author Nate Jensen
|
||||
|
||||
This file is licenced under the the zlib/libpng License.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
# include "winconfig.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
// shut up the compiler
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
# undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
#ifdef _FILE_OFFSET_BITS
|
||||
# undef _FILE_OFFSET_BITS
|
||||
#endif
|
||||
#include <jni.h>
|
||||
|
||||
// shut up the compiler
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
# undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
#include "Python.h"
|
||||
|
||||
#include "pyjlist.h"
|
||||
#include "pyjobject.h"
|
||||
#include "pyembed.h"
|
||||
|
||||
staticforward PyTypeObject PyJlist_Type;
|
||||
|
||||
static Py_ssize_t pyjlist_len(PyObject*);
|
||||
static PyObject* pyjlist_add(PyObject*, PyObject*);
|
||||
static PyObject* pyjlist_fill(PyObject*, Py_ssize_t);
|
||||
static PyObject* pyjlist_getitem(PyObject*, Py_ssize_t);
|
||||
static PyObject* pyjlist_getslice(PyObject*, Py_ssize_t, Py_ssize_t);
|
||||
static int pyjlist_setitem(PyObject*, Py_ssize_t, PyObject*);
|
||||
static int pyjlist_setslice(PyObject*, Py_ssize_t, Py_ssize_t, PyObject*);
|
||||
static int pyjlist_contains(PyObject*, PyObject*);
|
||||
static PyObject* pyjlist_inplace_add(PyObject*, PyObject*);
|
||||
static PyObject* pyjlist_inplace_fill(PyObject*, Py_ssize_t);
|
||||
|
||||
/*
|
||||
* News up a pyjlist, which is just a pyjobject with some sequence methods
|
||||
* attached to it. This should only be called from pyjobject_new().
|
||||
*/
|
||||
PyJlist_Object* pyjlist_new() {
|
||||
/*
|
||||
* some sample code sets this, something about not necessarily being set
|
||||
* at compile time with some compilers, seems to work ok with it commented
|
||||
* out
|
||||
*/
|
||||
// PyJlist_Type.tp_base = &PyJobject_Type;
|
||||
|
||||
if(PyType_Ready(&PyJlist_Type) < 0)
|
||||
return NULL;
|
||||
|
||||
return PyObject_NEW(PyJlist_Object, &PyJlist_Type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience method to copy a list's items into a new java.util.List of the
|
||||
* same type.
|
||||
*/
|
||||
PyObject* pyjlist_new_copy(PyObject *toCopy) {
|
||||
jmethodID newInstance = NULL;
|
||||
jobject newList = NULL;
|
||||
jmethodID addAll = NULL;
|
||||
jclass clazz = NULL;
|
||||
PyJobject_Object *obj = (PyJobject_Object*) toCopy;
|
||||
JNIEnv *env = pyembed_get_env();
|
||||
|
||||
|
||||
if(!pyjlist_check(toCopy)) {
|
||||
PyErr_Format(PyExc_RuntimeError, "pyjlist_new_copy() must receive a pyjlist");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clazz = (*env)->FindClass(env, "java/lang/Class");
|
||||
if(process_java_exception(env) || !clazz){
|
||||
return NULL;
|
||||
}
|
||||
newInstance = (*env)->GetMethodID(env, clazz, "newInstance", "()Ljava/lang/Object;");
|
||||
if(process_java_exception(env) || !newInstance) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newList = (*env)->CallObjectMethod(env, obj->clazz, newInstance);
|
||||
if(process_java_exception(env) || !newList) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addAll = (*env)->GetMethodID(env, obj->clazz, "addAll", "(Ljava/util/Collection;)Z");
|
||||
if(process_java_exception(env) || !addAll) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(*env)->CallBooleanMethod(env, newList, addAll, obj->object);
|
||||
if(process_java_exception(env)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pyjobject_new(env, newList);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the object is a pyjlist.
|
||||
*/
|
||||
int pyjlist_check(PyObject *obj) {
|
||||
if(PyObject_TypeCheck(obj, &PyJlist_Type))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the size of the list.
|
||||
*/
|
||||
static Py_ssize_t pyjlist_len(PyObject* self) {
|
||||
jmethodID size = NULL;
|
||||
Py_ssize_t len = 0;
|
||||
PyJobject_Object *pyjob = (PyJobject_Object*) self;
|
||||
JNIEnv *env = pyembed_get_env();
|
||||
|
||||
size = (*env)->GetMethodID(env, pyjob->clazz, "size", "()I");
|
||||
if(process_java_exception(env) || !size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = (*env)->CallIntMethod(env, pyjob->object, size);
|
||||
if(process_java_exception(env)) {
|
||||
return -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for the + operator on pyjlist. For example, result = o1 + o2, where
|
||||
* o1 is a pyjlist and result is a new pyjlist.
|
||||
*/
|
||||
static PyObject* pyjlist_add(PyObject *o1, PyObject *o2) {
|
||||
PyObject *result = NULL;
|
||||
PyObject *copy = NULL;
|
||||
|
||||
copy = pyjlist_new_copy(o1);
|
||||
if(copy == NULL) {
|
||||
// error indicators already set
|
||||
return NULL;
|
||||
}
|
||||
result = pyjlist_inplace_add(copy, o2);
|
||||
if(result) {
|
||||
// both pyjlist_new_copy() and pyjlist_inplace_add() increfed it
|
||||
Py_DECREF(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for * operator on pyjlist. For example, result = o * 5, where o is
|
||||
* a pyjlist and result is a new pyjlist.
|
||||
*/
|
||||
static PyObject* pyjlist_fill(PyObject *o, Py_ssize_t count) {
|
||||
PyObject *result = NULL;
|
||||
PyObject *copy = NULL;
|
||||
|
||||
copy = pyjlist_new_copy(o);
|
||||
if(copy == NULL) {
|
||||
// error indicators already set
|
||||
return NULL;
|
||||
}
|
||||
result = pyjlist_inplace_fill(copy, count);
|
||||
if(result) {
|
||||
// both pyjlist_new_copy() and pyjlist_inplace_fill() increfed it
|
||||
Py_DECREF(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for the getting items with the [int] operator on pyjlist. For
|
||||
* example, result = o[i]
|
||||
*/
|
||||
static PyObject* pyjlist_getitem(PyObject *o, Py_ssize_t i) {
|
||||
jmethodID get = NULL;
|
||||
jobject val = NULL;
|
||||
int size = 0;
|
||||
PyJobject_Object *obj = (PyJobject_Object*) o;
|
||||
JNIEnv *env = pyembed_get_env();
|
||||
|
||||
get = (*env)->GetMethodID(env, obj->clazz, "get", "(I)Ljava/lang/Object;");
|
||||
if(process_java_exception(env) || !get){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = pyjlist_len(o);
|
||||
if((i > size-1) || (i < 0)) {
|
||||
PyErr_Format(PyExc_IndexError, "list index %i out of range, size %i", (int) i, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
val = (*env)->CallObjectMethod(env, obj->object, get, (jint) i);
|
||||
if(process_java_exception(env)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(val == NULL){
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
} else {
|
||||
return pyjobject_new(env, val);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for getting slices with the [int:int] operator on pyjlist. For
|
||||
* example, result = o[i1:i2]
|
||||
*/
|
||||
static PyObject* pyjlist_getslice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) {
|
||||
jmethodID sublist = NULL;
|
||||
jobject result = NULL;
|
||||
PyJobject_Object *obj = (PyJobject_Object*) o;
|
||||
JNIEnv *env = pyembed_get_env();
|
||||
|
||||
sublist = (*env)->GetMethodID(env, obj->clazz, "subList", "(II)Ljava/util/List;");
|
||||
if(process_java_exception(env) || !sublist) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = (*env)->CallObjectMethod(env, obj->object, sublist, (jint) i1, (jint) i2);
|
||||
if(process_java_exception(env)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pyjobject_new(env, result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for the setting items with the [int] operator on pyjlist. For example,
|
||||
* o[i] = v
|
||||
*/
|
||||
static int pyjlist_setitem(PyObject *o, Py_ssize_t i, PyObject *v) {
|
||||
jmethodID set = NULL;
|
||||
PyJobject_Object *obj = (PyJobject_Object*) o;
|
||||
JNIEnv *env = pyembed_get_env();
|
||||
jobject value = NULL;
|
||||
|
||||
if(v == Py_None) {
|
||||
value = NULL;
|
||||
} else {
|
||||
value = pyembed_box_py(env, v);
|
||||
if(process_java_exception(env)) {
|
||||
return -1;
|
||||
} else if(!value) {
|
||||
/*
|
||||
* with the way pyembed_box_py is currently implemented, shouldn't
|
||||
* be able to get here
|
||||
*/
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"__setitem__ received an incompatible type: %s",
|
||||
PyString_AsString(PyObject_Str((PyObject*) Py_TYPE(v))));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
set = (*env)->GetMethodID(env, obj->clazz, "set", "(ILjava/lang/Object;)Ljava/lang/Object;");
|
||||
if(process_java_exception(env) || !set) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*env)->CallObjectMethod(env, obj->object, set, (jint) i, value);
|
||||
if(process_java_exception(env)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// have to return 0 on success even though it's not documented
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for setting slices with the [int:int] operator on pyjlist. For
|
||||
* example, o[i1:i2] = v. Note this is not fully supported yet.
|
||||
*/
|
||||
static int pyjlist_setslice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v) {
|
||||
if(pyjlist_check(v) || PyList_Check(v) || PyTuple_Check(v)) {
|
||||
/*
|
||||
* TODO Implement, good luck.
|
||||
*
|
||||
* If v is a list, tuple, or pyjlist, then this gets infinitely more complex.
|
||||
*/
|
||||
PyErr_Format(PyExc_NotImplementedError,
|
||||
"pyjlist.__setslice__ does not support assigning lists yet");
|
||||
return -1;
|
||||
} else {
|
||||
Py_ssize_t i;
|
||||
for(i = i1; i < i2 + 1; i++) {
|
||||
if(pyjlist_setitem(o, i, v) == -1) {
|
||||
/*
|
||||
* TODO This is not transactional if it fails partially through.
|
||||
* Not sure how to make that safe short of making a copy of o
|
||||
* and then replacing o's underlying jobject on success. That
|
||||
* would slow it down though....
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// have to return 0 on success even though it's not documented
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for the __contains__() method on pyjlist, frequently used by the
|
||||
* in operator. For example, if v in o:
|
||||
*/
|
||||
static int pyjlist_contains(PyObject *o, PyObject *v) {
|
||||
jmethodID contains = NULL;
|
||||
jboolean result = JNI_FALSE;
|
||||
PyJobject_Object *obj = (PyJobject_Object*) o;
|
||||
JNIEnv *env = pyembed_get_env();
|
||||
jobject value = NULL;
|
||||
|
||||
if(v == Py_None) {
|
||||
value = NULL;
|
||||
} else {
|
||||
value = pyembed_box_py(env, v);
|
||||
if(process_java_exception(env)) {
|
||||
return -1;
|
||||
} else if(!value) {
|
||||
/*
|
||||
* with the way pyembed_box_py is currently implemented, shouldn't
|
||||
* be able to get here
|
||||
*/
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"__contains__ received an incompatible type: %s",
|
||||
PyString_AsString(PyObject_Str((PyObject*) Py_TYPE(v))));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
contains = (*env)->GetMethodID(env, obj->clazz, "contains", "(Ljava/lang/Object;)Z");
|
||||
if(process_java_exception(env) || !contains) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = (*env)->CallBooleanMethod(env, obj->object, contains, value);
|
||||
if(process_java_exception(env)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(result) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for the += operator on pyjlist. For example, o1 += o2, where
|
||||
* o1 is a pyjlist.
|
||||
*/
|
||||
static PyObject* pyjlist_inplace_add(PyObject *o1, PyObject *o2) {
|
||||
jobject value = NULL;
|
||||
jclass collection = NULL;
|
||||
JNIEnv *env = pyembed_get_env();
|
||||
PyJobject_Object *self = (PyJobject_Object*) o1;
|
||||
|
||||
if(pyjlist_check(o2)) {
|
||||
value = ((PyJobject_Object*) o2)->object;
|
||||
} else {
|
||||
value = pyembed_box_py(env, o2);
|
||||
}
|
||||
|
||||
collection = (*env)->FindClass(env, "java/util/Collection");
|
||||
if(process_java_exception(env) || !collection) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((*env)->IsInstanceOf(env, value, collection)) {
|
||||
/*
|
||||
* it's a Collection so we need to simulate a python + and combine the
|
||||
* two collections
|
||||
*/
|
||||
jmethodID addAll = (*env)->GetMethodID(env, self->clazz, "addAll", "(Ljava/util/Collection;)Z");
|
||||
if(process_java_exception(env) || !addAll) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(*env)->CallBooleanMethod(env, self->object, addAll, value);
|
||||
if(process_java_exception(env)) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
// not a collection, add it as a single object
|
||||
jmethodID add = (*env)->GetMethodID(env, self->clazz, "add", "(Ljava/lang/Object;)Z");
|
||||
if(process_java_exception(env) || !add) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(*env)->CallBooleanMethod(env, self->object, add, value);
|
||||
if(process_java_exception(env)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Py_INCREF(o1);
|
||||
|
||||
return o1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for *= operator on pyjlist. For example, o *= 5, where o is
|
||||
* a pyjlist.
|
||||
*/
|
||||
static PyObject* pyjlist_inplace_fill(PyObject *o, Py_ssize_t count) {
|
||||
PyJobject_Object *self = (PyJobject_Object*) o;
|
||||
JNIEnv *env = pyembed_get_env();
|
||||
|
||||
if(count < 1) {
|
||||
jmethodID clear = (*env)->GetMethodID(env, self->clazz, "clear", "()V");
|
||||
if(process_java_exception(env) || !clear) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(*env)->CallVoidMethod(env, self->object, clear);
|
||||
if(process_java_exception(env)) {
|
||||
return NULL;
|
||||
}
|
||||
} else if (count > 1){
|
||||
int i = 0;
|
||||
PyObject *copy = pyjlist_new_copy(o);
|
||||
if(copy == NULL) {
|
||||
// error indicators already set
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO there's probably a better way to do this
|
||||
for(i = 1; i < count; i++) {
|
||||
PyObject *result = pyjlist_inplace_add(o, copy);
|
||||
if(!result) {
|
||||
// error indicators already set
|
||||
return NULL;
|
||||
} else {
|
||||
// result and o are the same object, pyjlist_inplace_add increfed it
|
||||
Py_DECREF(result);
|
||||
}
|
||||
}
|
||||
Py_DECREF(copy);
|
||||
}
|
||||
|
||||
Py_INCREF(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
static PyMethodDef pyjlist_methods[] = {
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static PySequenceMethods pyjlist_seq_methods = {
|
||||
pyjlist_len, /* sq_length */
|
||||
pyjlist_add, /* sq_concat */
|
||||
pyjlist_fill, /* sq_repeat */
|
||||
pyjlist_getitem, /* sq_item */
|
||||
pyjlist_getslice, /* sq_slice */
|
||||
pyjlist_setitem, /* sq_ass_item */
|
||||
pyjlist_setslice, /* sq_ass_slice */
|
||||
pyjlist_contains, /* sq_contains */
|
||||
pyjlist_inplace_add, /* sq_inplace_concat */
|
||||
pyjlist_inplace_fill, /* sq_inplace_repeat */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* I set tp_base to PyJobject_Type so it has inheritance, but for the life
|
||||
* of me I couldn't get it to inherit the methods, so I set the relevant
|
||||
* methods directly.
|
||||
*/
|
||||
static PyTypeObject PyJlist_Type = {
|
||||
PyObject_HEAD_INIT(0)
|
||||
0,
|
||||
"jep.PyJlist",
|
||||
sizeof(PyJlist_Object),
|
||||
0,
|
||||
(destructor) pyjobject_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
(getattrfunc) pyjobject_getattr, /* tp_getattr */
|
||||
(setattrfunc) pyjobject_setattr, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
&pyjlist_seq_methods, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
(reprfunc) pyjobject_str, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||
"jlist", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
pyjlist_methods, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
&PyJobject_Type, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
NULL, /* tp_new */
|
||||
};
|
59
nativeLib/rary.cots.jepp/jepp-2.3/src/jep/pyjlist.h
Normal file
59
nativeLib/rary.cots.jepp/jepp-2.3/src/jep/pyjlist.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 c-style: "K&R" -*- */
|
||||
/*
|
||||
jep - Java Embedded Python
|
||||
|
||||
Copyright (c) 2004 - 2011 Mike Johnson.
|
||||
@author Nate Jensen.
|
||||
|
||||
This file is licenced under the the zlib/libpng License.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// shut up the compiler
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
# undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
#include <jni.h>
|
||||
#include <Python.h>
|
||||
#include "pyjobject.h"
|
||||
|
||||
|
||||
#ifndef _Included_pyjlist
|
||||
#define _Included_pyjlist
|
||||
|
||||
/*
|
||||
* A pyjlist is just a pyjobject with some extra methods attached to it to meet
|
||||
* the python Sequence protocol (interface). It should only be used where
|
||||
* the underlying jobject of the pyjobject is an implementation of java.util.List.
|
||||
*/
|
||||
typedef struct {
|
||||
PyJobject_Object obj; /* magic inheritance */
|
||||
} PyJlist_Object;
|
||||
|
||||
|
||||
PyJlist_Object* pyjlist_new(void);
|
||||
PyObject* pyjlist_new_copy(PyObject*);
|
||||
int pyjlist_check(PyObject *obj);
|
||||
|
||||
|
||||
#endif // ndef pyjlist
|
Loading…
Add table
Reference in a new issue