Repository URL to install this package:
|
Version:
3.5 ▾
|
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <stdarg.h>
#ifdef _MSC_VER
#include <Winsock2.h>
#else
#include <arpa/inet.h>
#endif
#include "java/lang/Object.h"
#include "java/lang/Class.h"
#include "java/lang/String.h"
#include "java/lang/Throwable.h"
#include "java/lang/Boolean.h"
#include "java/lang/Byte.h"
#include "java/lang/Character.h"
#include "java/lang/Double.h"
#include "java/lang/Float.h"
#include "java/lang/Integer.h"
#include "java/lang/Long.h"
#include "java/lang/Short.h"
#include "java/util/Iterator.h"
#include "JArray.h"
#include "functions.h"
#include "macros.h"
using namespace java::lang;
using namespace java::util;
PyObject *PyExc_JavaError = PyExc_ValueError;
PyObject *PyExc_InvalidArgsError = PyExc_ValueError;
PyObject *_set_exception_types(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, "OO",
&PyExc_JavaError, &PyExc_InvalidArgsError))
return NULL;
Py_RETURN_NONE;
}
PyObject *_set_function_self(PyObject *self, PyObject *args)
{
PyObject *object, *module;
if (!PyArg_ParseTuple(args, "OO", &object, &module))
return NULL;
if (!PyCFunction_Check(object))
{
PyErr_SetObject(PyExc_TypeError, object);
return NULL;
}
PyCFunctionObject *cfn = (PyCFunctionObject *) object;
Py_INCREF(module);
Py_XDECREF(cfn->m_self);
cfn->m_self = module;
Py_RETURN_NONE;
}
PyObject *findClass(PyObject *self, PyObject *args)
{
char *className;
if (!PyArg_ParseTuple(args, "s", &className))
return NULL;
try {
jclass cls = env->findClass(className);
if (cls)
return t_Class::wrap_Object(Class(cls));
} catch (int e) {
switch (e) {
case _EXC_PYTHON:
return NULL;
case _EXC_JAVA:
return PyErr_SetJavaError();
default:
throw;
}
}
Py_RETURN_NONE;
}
static const char interface_bytes[] = {
'\xca', '\xfe', '\xba', '\xbe', // magic number: 0xcafebabe
'\x00', '\x00', '\x00', '\x32', // version 50.0
'\x00', '\x07', // constant pool max index: 6
'\x07', '\x00', '\x04', // 1: class name at 4
'\x07', '\x00', '\x05', // 2: class name at 5
'\x07', '\x00', '\x06', // 3: class name at 6
'\x01', '\x00', '\x00', // 4: empty string
'\x01', '\x00', '\x10', // 5: 16-byte string: java/lang/Object
'j', 'a', 'v', 'a', '/', 'l', 'a', 'n', 'g', '/',
'O', 'b', 'j', 'e', 'c', 't',
'\x01', '\x00', '\x00', // 6: empty string
'\x06', '\x01', // public abstract interface
'\x00', '\x01', // this class at 1
'\x00', '\x02', // superclass at 2
'\x00', '\x01', // 1 interface
'\x00', '\x03', // interface at 3
'\x00', '\x00', // 0 fields
'\x00', '\x00', // 0 methods
'\x00', '\x00' // 0 attributes
};
/* make an empty interface that extends an interface */
PyObject *makeInterface(PyObject *self, PyObject *args)
{
char *name, *extName;
int name_len, extName_len;
if (!PyArg_ParseTuple(args, "s#s#",
&name, &name_len, &extName, &extName_len))
return NULL;
JNIEnv *vm_env = env->get_vm_env();
jclass _ucl = (jclass) vm_env->FindClass("java/net/URLClassLoader");
jmethodID mid = vm_env->GetStaticMethodID(_ucl, "getSystemClassLoader",
"()Ljava/lang/ClassLoader;");
jobject classLoader = vm_env->CallStaticObjectMethod(_ucl, mid);
const int bytes_len = sizeof(interface_bytes);
const int len = bytes_len + name_len + extName_len;
char *buf = (char *) malloc(len);
if (buf == NULL)
return PyErr_NoMemory();
int name_pos = 22;
int extName_pos = 44;
jclass cls;
memcpy(buf, interface_bytes, name_pos);
memcpy(buf + name_pos + name_len, interface_bytes + name_pos,
extName_pos - name_pos);
memcpy(buf + extName_pos + name_len + extName_len,
interface_bytes + extName_pos, bytes_len - extName_pos);
extName_pos += name_len;
*((unsigned short *) (buf + name_pos - 2)) = htons(name_len);
memcpy(buf + name_pos, name, name_len);
*((unsigned short *) (buf + extName_pos - 2)) = htons(extName_len);
memcpy(buf + extName_pos, extName, extName_len);
cls = vm_env->DefineClass(name, classLoader, (const jbyte *) buf, len);
free(buf);
if (cls)
return t_Class::wrap_Object(Class(cls));
return PyErr_SetJavaError();
}
static const char class_bytes[] = {
'\xca', '\xfe', '\xba', '\xbe', // magic number: 0xcafebabe
'\x00', '\x00', '\x00', '\x32', // version 50.0
'\x00', '\x0c', // constant pool max index: 11
'\x0a', '\x00', '\x03', '\x00', '\x08', // 1: method for class 3 at 8
'\x07', '\x00', '\x09', // 2: class name at 9
'\x07', '\x00', '\x0a', // 3: class name at 10
'\x07', '\x00', '\x0b', // 4: class name at 11
'\x01', '\x00', '\x06', // 5: 6-byte string: <init>
'<', 'i', 'n', 'i', 't', '>',
'\x01', '\x00', '\x03', '(', ')', 'V', // 6: 3-byte string: ()V
'\x01', '\x00', '\x04', // 7: 4-byte string: Code
'C', 'o', 'd', 'e',
'\x0c', '\x00', '\x05', '\x00', '\x06', // 8: name at 5, signature at 6
'\x01', '\x00', '\x00', // 9: empty string
'\x01', '\x00', '\x00', // 10: empty string
'\x01', '\x00', '\x00', // 11: empty string
'\x00', '\x21', // super public
'\x00', '\x02', // this class at 2
'\x00', '\x03', // superclass at 3
'\x00', '\x01', // 1 interface
'\x00', '\x04', // interface at 4
'\x00', '\x00', // 0 fields
'\x00', '\x01', // 1 method
'\x00', '\x01', '\x00', '\x05', // public, name at 5
'\x00', '\x06', '\x00', '\x01', // signature at 6, 1 attribute
'\x00', '\x07', // attribute name at 7: Code
'\x00', '\x00', '\x00', '\x11', // 17 bytes past 6 attribute bytes
'\x00', '\x01', // max stack: 1
'\x00', '\x01', // max locals: 1
'\x00', '\x00', '\x00', '\x05', // code length: 5
'\x2a', '\xb7', '\x00', '\x01', '\xb1', // actual code bytes
'\x00', '\x00', // 0 method exceptions
'\x00', '\x00', // 0 method attributes
'\x00', '\x00', // 0 attributes
};
/* make an empty class that extends a class and implements an interface */
PyObject *makeClass(PyObject *self, PyObject *args)
{
char *name, *extName, *implName;
int name_len, extName_len, implName_len;
if (!PyArg_ParseTuple(args, "s#s#s#",
&name, &name_len, &extName, &extName_len,
&implName, &implName_len))
return NULL;
JNIEnv *vm_env = env->get_vm_env();
jclass _ucl = (jclass) vm_env->FindClass("java/net/URLClassLoader");
jmethodID mid = vm_env->GetStaticMethodID(_ucl, "getSystemClassLoader",
"()Ljava/lang/ClassLoader;");
jobject classLoader = vm_env->CallStaticObjectMethod(_ucl, mid);
const int bytes_len = sizeof(class_bytes);
const int len = bytes_len + name_len + extName_len + implName_len;
char *buf = (char *) malloc(len);
if (buf == NULL)
return PyErr_NoMemory();
int name_pos = 54;
int extName_pos = 57;
int implName_pos = 60;
jclass cls;
memcpy(buf, class_bytes, name_pos);
memcpy(buf + name_pos + name_len, class_bytes + name_pos,
extName_pos - name_pos);
memcpy(buf + extName_pos + name_len + extName_len,
class_bytes + extName_pos, bytes_len - extName_pos);
memcpy(buf + implName_pos + name_len + extName_len + implName_len,
class_bytes + implName_pos, bytes_len - implName_pos);
extName_pos += name_len;
implName_pos += name_len + extName_len;
*((unsigned short *) (buf + name_pos - 2)) = htons(name_len);
memcpy(buf + name_pos, name, name_len);
*((unsigned short *) (buf + extName_pos - 2)) = htons(extName_len);
memcpy(buf + extName_pos, extName, extName_len);
*((unsigned short *) (buf + implName_pos - 2)) = htons(implName_len);
memcpy(buf + implName_pos, implName, implName_len);
cls = vm_env->DefineClass(name, classLoader, (const jbyte *) buf, len);
free(buf);
if (cls)
return t_Class::wrap_Object(Class(cls));
return PyErr_SetJavaError();
}
static boxfn get_boxfn(PyTypeObject *type)
{
static PyObject *boxfn_ = PyUnicode_FromString("boxfn_");
PyObject *cobj = PyObject_GetAttr((PyObject *) type, boxfn_);
boxfn fn;
if (cobj == NULL)
return NULL;
fn = (boxfn) PyCapsule_GetPointer(cobj, "boxfn");
Py_DECREF(cobj);
return fn;
}
static int is_instance_of(PyObject *arg, PyTypeObject *type)
{
static PyObject *class_ = PyUnicode_FromString("class_");
PyObject *clsObj = PyObject_GetAttr((PyObject *) type, class_);
int result;
if (clsObj == NULL)
return -1;
result = env->get_vm_env()->
IsInstanceOf(((t_Object *) arg)->object.this$,
(jclass) ((t_Object *) clsObj)->object.this$);
Py_DECREF(clsObj);
return result;
}
#if defined(_MSC_VER) || defined(__SUNPRO_CC)
int __parseArgs(PyObject *args, char *types, ...)
{
int count = Py_SIZE((PyTupleObject *) args);
va_list list, check;
va_start(list, types);
va_start(check, types);
return _parseArgs(((PyTupleObject *) args)->ob_item, count, types,
list, check);
}
int __parseArg(PyObject *arg, char *types, ...)
{
va_list list, check;
va_start(list, types);
va_start(check, types);
return _parseArgs(&arg, 1, types, list, check);
}
int _parseArgs(PyObject **args, unsigned int count, char *types,
va_list list, va_list check)
{
unsigned int typeCount = strlen(types);
if (count > typeCount)
return -1;
#else
int _parseArgs(PyObject **args, unsigned int count, char *types, ...)
{
unsigned int typeCount = strlen(types);
va_list list, check;
va_start(list, types);
va_start(check, types);
#endif
if (!env->vm)
{
PyErr_SetString(PyExc_RuntimeError, "initVM() must be called first");
return -1;
}
JNIEnv *vm_env = env->get_vm_env();
if (!vm_env)
{
PyErr_SetString(PyExc_RuntimeError, "attachCurrentThread() must be called first");
return -1;
}
bool last = false; /* true if last expected parameter */
bool varargs = false; /* true if in varargs mode */
bool empty = false; /* true if in varargs mode and no params passed */
int array = 0; /* > 0 if expecting an array, its nesting level */
unsigned int pos = 0;
for (unsigned int a = 0; a < count; a++, pos++) {
PyObject *arg = args[a];
char tc = types[pos];
last = last || types[pos + 1] == '\0';
if (array > 1 && tc != '[')
tc = 'o';
switch (tc) {
case '[':
{
if (++array > 1 &&
!PyObject_TypeCheck(arg, PY_TYPE(JArrayObject)))
return -1;
a -= 1;
break;
}
case 'j': /* Java object, with class$ */
case 'k': /* Java object, with initializeClass */
case 'K': /* Java object, with initializeClass and params */
{
jclass cls = NULL;
switch (tc) {
case 'j':
cls = (jclass) va_arg(list, Class *)->this$;
break;
case 'k':
case 'K':
try {
getclassfn initializeClass = va_arg(list, getclassfn);
cls = env->getClass(initializeClass);
} catch (int e) {
switch (e) {
case _EXC_PYTHON:
return -1;
case _EXC_JAVA:
PyErr_SetJavaError();
return -1;
default:
throw;
}
}
break;
}
if (arg == Py_None)
break;
/* ensure that class Class is initialized (which may not be the
* case because of earlier recursion avoidance (JObject(cls)).
*/
if (!Class::class$)
env->getClass(Class::initializeClass);
if (array)
{
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayObject)))
break;
if (PySequence_Check(arg) &&
!PyBytes_Check(arg) && !PyUnicode_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = 0;
if (obj == Py_None)
ok = 1;
else if (PyObject_TypeCheck(obj, PY_TYPE(Object)) &&
vm_env->IsInstanceOf(((t_Object *) obj)->object.this$, cls))
ok = 1;
else if (PyObject_TypeCheck(obj, PY_TYPE(FinalizerProxy)))
{
PyObject *o = ((t_fp *) obj)->object;
if (PyObject_TypeCheck(o, PY_TYPE(Object)) &&
vm_env->IsInstanceOf(((t_Object *) o)->object.this$, cls))
ok = 1;
}
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
if (last)
{
int ok = 0;
if (arg == Py_None)
ok = 1;
else if (PyObject_TypeCheck(arg, PY_TYPE(Object)) &&
vm_env->IsInstanceOf(((t_Object *) arg)->object.this$, cls))
ok = 1;
else if (PyObject_TypeCheck(arg, PY_TYPE(FinalizerProxy)))
{
PyObject *o = ((t_fp *) arg)->object;
if (PyObject_TypeCheck(o, PY_TYPE(Object)) &&
vm_env->IsInstanceOf(((t_Object *) o)->object.this$, cls))
ok = 1;
}
if (ok)
{
varargs = true;
break;
}
}
}
else if (PyObject_TypeCheck(arg, PY_TYPE(Object)) &&
vm_env->IsInstanceOf(((t_Object *) arg)->object.this$, cls))
break;
else if (PyObject_TypeCheck(arg, PY_TYPE(FinalizerProxy)))
{
arg = ((t_fp *) arg)->object;
if (PyObject_TypeCheck(arg, PY_TYPE(Object)) &&
vm_env->IsInstanceOf(((t_Object *) arg)->object.this$, cls))
break;
}
return -1;
}
case 'Z': /* boolean, strict */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayBool)))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = obj == Py_True || obj == Py_False;
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
if (last && (arg == Py_True || arg == Py_False))
{
varargs = true;
break;
}
}
else if (arg == Py_True || arg == Py_False)
break;
return -1;
}
case 'B': /* byte */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayByte)))
break;
if (last)
{
if ((PyBytes_Check(arg) && (PyBytes_Size(arg) == 1)) ||
PyLong_CheckExact(arg))
{
varargs = true;
break;
}
}
}
else if (PyBytes_Check(arg) && (PyBytes_Size(arg) == 1))
break;
else if (PyLong_CheckExact(arg))
break;
return -1;
}
case 'C': /* char */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayChar)))
break;
if (last)
{
if ((PyBytes_Check(arg) && PyBytes_Size(arg) == 1) ||
(PyUnicode_Check(arg) &&
PyUnicode_GetLength(arg) == 1 &&
PyUnicode_READ_CHAR(arg, 0) < 0x10000))
{
varargs = true;
break;
}
}
}
else if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1)
break;
else if (PyUnicode_Check(arg) && PyUnicode_GetLength(arg) == 1 &&
PyUnicode_READ_CHAR(arg, 0) < 0x10000)
break;
return -1;
}
case 'I': /* int */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayInt)))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyLong_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
if (last && PyLong_CheckExact(arg))
{
varargs = true;
break;
}
}
else if (PyLong_CheckExact(arg))
break;
return -1;
}
case 'S': /* short */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayShort)))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyLong_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
if (last && PyLong_CheckExact(arg))
{
varargs = true;
break;
}
}
else if (PyLong_CheckExact(arg))
break;
return -1;
}
case 'D': /* double */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayDouble)))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyFloat_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
if (last && PyFloat_CheckExact(arg))
{
varargs = true;
break;
}
}
else if (PyFloat_CheckExact(arg))
break;
return -1;
}
case 'F': /* float */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayFloat)))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyFloat_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
if (last && PyFloat_CheckExact(arg))
{
varargs = true;
break;
}
}
else if (PyFloat_CheckExact(arg))
break;
return -1;
}
case 'J': /* long long */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayLong)))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyLong_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
if (last && PyLong_CheckExact(arg))
{
varargs = true;
break;
}
}
else if (PyLong_CheckExact(arg))
break;
return -1;
}
case 's': /* string */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, PY_TYPE(JArrayString)))
break;
if (PySequence_Check(arg) &&
!PyBytes_Check(arg) && !PyUnicode_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok =
(obj == Py_None ||
PyBytes_Check(obj) || PyUnicode_Check(obj));
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
if (last && (arg == Py_None ||
PyBytes_Check(arg) || PyUnicode_Check(arg)))
{
varargs = true;
break;
}
}
else if (arg == Py_None ||
PyBytes_Check(arg) || PyUnicode_Check(arg))
break;
return -1;
}
case 'o': /* java.lang.Object */
break;
case 'O': /* java.lang.Object with type param */
{
PyTypeObject *type = va_arg(list, PyTypeObject *);
if (type != NULL)
{
boxfn fn = get_boxfn(type);
if (fn == NULL || fn(type, arg, NULL) < 0)
return -1;
}
break;
}
case 'T': /* tuple of python types with wrapfn_ */
{
static PyObject *wrapfn_ = PyUnicode_FromString("wrapfn_");
int len = va_arg(list, int);
if (PyTuple_Check(arg))
{
if (PyTuple_GET_SIZE(arg) != len)
return -1;
for (int i = 0; i < len; i++) {
PyObject *type = PyTuple_GET_ITEM(arg, i);
if (!(type == Py_None ||
(PyType_Check(type) &&
PyObject_HasAttr(type, wrapfn_))))
return -1;
}
break;
}
return -1;
}
default:
return -1;
}
if (tc != '[')
array = 0;
if (varargs)
{
pos = typeCount;
break;
}
}
if (array)
return -1;
if (pos == typeCount - 2 && types[pos] == '[' && types[pos + 1] != '[')
{
varargs = true;
empty = true;
pos = typeCount;
}
if (pos != typeCount)
return -1;
pos = 0;
last = false;
for (unsigned int a = 0; a <= count; a++, pos++) {
char tc = types[pos];
PyObject *arg;
if (a == count)
{
if (empty) /* empty varargs */
arg = NULL;
else
break;
}
else
arg = args[a];
last = last || types[pos + 1] == '\0';
if (array > 1 && tc != '[')
tc = 'o';
switch (tc) {
case '[':
{
array += 1;
a -= 1;
break;
}
case 'j': /* Java object except String and Object */
case 'k': /* Java object, with initializeClass */
case 'K': /* Java object, with initializeClass and params */
{
jclass cls = NULL;
switch (tc) {
case 'j':
cls = (jclass) va_arg(check, Class *)->this$;
break;
case 'k':
case 'K':
getclassfn initializeClass = va_arg(check, getclassfn);
cls = env->getClass(initializeClass);
break;
}
if (array)
{
JArray<jobject> *array = va_arg(list, JArray<jobject> *);
#ifdef _java_generics
if (tc == 'K')
{
PyTypeObject ***tp = va_arg(list, PyTypeObject ***);
va_arg(list, getparametersfn);
*tp = NULL;
}
#endif
if (arg == Py_None)
*array = JArray<jobject>((jobject) NULL);
else if (last && varargs)
*array = fromPySequence(cls, args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayObject)))
*array = ((t_JArray<jobject> *) arg)->array;
else
*array = JArray<jobject>(cls, arg);
if (PyErr_Occurred())
return -1;
}
else
{
Object *obj = va_arg(list, Object *);
if (PyObject_TypeCheck(arg, PY_TYPE(FinalizerProxy)))
arg = ((t_fp *) arg)->object;
#ifdef _java_generics
if (tc == 'K')
{
PyTypeObject ***tp = va_arg(list, PyTypeObject ***);
PyTypeObject **(*parameters_)(void *) =
va_arg(list, getparametersfn);
if (arg == Py_None)
*tp = NULL;
else
*tp = (*parameters_)(arg);
}
#endif
*obj = arg == Py_None
? Object(NULL)
: ((t_Object *) arg)->object;
}
break;
}
case 'Z': /* boolean, strict */
{
if (array)
{
JArray<jboolean> *array = va_arg(list, JArray<jboolean> *);
if (arg == Py_None)
*array = JArray<jboolean>((jobject) NULL);
else if (last && varargs)
*array = JArray<jboolean>(args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayBool)))
*array = ((t_JArray<jboolean> *) arg)->array;
else
*array = JArray<jboolean>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jboolean *b = va_arg(list, jboolean *);
*b = arg == Py_True;
}
break;
}
case 'B': /* byte */
{
if (array)
{
JArray<jbyte> *array = va_arg(list, JArray<jbyte> *);
if (arg == Py_None)
*array = JArray<jbyte>((jobject) NULL);
else if (last && varargs)
*array = JArray<jbyte>(args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayByte)))
*array = ((t_JArray<jbyte> *) arg)->array;
else
*array = JArray<jbyte>(arg);
if (PyErr_Occurred())
return -1;
}
else if (PyBytes_Check(arg))
{
jbyte *a = va_arg(list, jbyte *);
*a = (jbyte) PyBytes_AS_STRING(arg)[0];
}
else if (PyUnicode_Check(arg))
{
jbyte *a = va_arg(list, jbyte *);
*a = (jbyte) PyUnicode_AsUTF8(arg)[0];
}
else
{
jbyte *a = va_arg(list, jbyte *);
*a = (jbyte) PyLong_AsLong(arg);
}
break;
}
case 'C': /* char */
{
if (array)
{
JArray<jchar> *array = va_arg(list, JArray<jchar> *);
if (arg == Py_None)
*array = JArray<jchar>((jobject) NULL);
else if (last && varargs)
*array = JArray<jchar>(args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayChar)))
*array = ((t_JArray<jchar> *) arg)->array;
else
*array = JArray<jchar>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jchar *c = va_arg(list, jchar *);
*c = (jchar) PyUnicode_READ_CHAR(arg, 0);
}
break;
}
case 'I': /* int */
{
if (array)
{
JArray<jint> *array = va_arg(list, JArray<jint> *);
if (arg == Py_None)
*array = JArray<jint>((jobject) NULL);
else if (last && varargs)
*array = JArray<jint>(args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayInt)))
*array = ((t_JArray<jint> *) arg)->array;
else
*array = JArray<jint>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jint *n = va_arg(list, jint *);
*n = (jint) PyLong_AsLong(arg);
}
break;
}
case 'S': /* short */
{
if (array)
{
JArray<jshort> *array = va_arg(list, JArray<jshort> *);
if (arg == Py_None)
*array = JArray<jshort>((jobject) NULL);
else if (last && varargs)
*array = JArray<jshort>(args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayShort)))
*array = ((t_JArray<jshort> *) arg)->array;
else
*array = JArray<jshort>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jshort *n = va_arg(list, jshort *);
*n = (jshort) PyLong_AsLong(arg);
}
break;
}
case 'D': /* double */
{
if (array)
{
JArray<jdouble> *array = va_arg(list, JArray<jdouble> *);
if (arg == Py_None)
*array = JArray<jdouble>((jobject) NULL);
else if (last && varargs)
*array = JArray<jdouble>(args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayDouble)))
*array = ((t_JArray<jdouble> *) arg)->array;
else
*array = JArray<jdouble>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jdouble *d = va_arg(list, jdouble *);
*d = (jdouble) PyFloat_AsDouble(arg);
}
break;
}
case 'F': /* float */
{
if (array)
{
JArray<jfloat> *array = va_arg(list, JArray<jfloat> *);
if (arg == Py_None)
*array = JArray<jfloat>((jobject) NULL);
else if (last && varargs)
*array = JArray<jfloat>(args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayFloat)))
*array = ((t_JArray<jfloat> *) arg)->array;
else
*array = JArray<jfloat>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jfloat *d = va_arg(list, jfloat *);
*d = (jfloat) (float) PyFloat_AsDouble(arg);
}
break;
}
case 'J': /* long long */
{
if (array)
{
JArray<jlong> *array = va_arg(list, JArray<jlong> *);
if (arg == Py_None)
*array = JArray<jlong>((jobject) NULL);
else if (last && varargs)
*array = JArray<jlong>(args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayLong)))
*array = ((t_JArray<jlong> *) arg)->array;
else
*array = JArray<jlong>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jlong *l = va_arg(list, jlong *);
*l = (jlong) PyLong_AsLongLong(arg);
}
break;
}
case 's': /* string */
{
if (array)
{
JArray<jstring> *array = va_arg(list, JArray<jstring> *);
if (arg == Py_None)
*array = JArray<jstring>((jobject) NULL);
else if (last && varargs)
*array = fromPySequence(
env->getClass(String::initializeClass),
args + a, count - a);
else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayString)))
*array = ((t_JArray<jstring> *) arg)->array;
else
*array = JArray<jstring>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
String *str = va_arg(list, String *);
if (arg == Py_None)
*str = String(NULL);
else
{
*str = p2j(arg);
if (PyErr_Occurred())
return -1;
}
}
break;
}
case 'o': /* java.lang.Object */
case 'O': /* java.lang.Object with type param */
{
if (array)
{
JArray<Object> *array = va_arg(list, JArray<Object> *);
if (arg == Py_None)
*array = JArray<Object>((jobject) NULL);
else if (last && varargs)
*array = JArray<Object>(
env->getClass(Object::initializeClass),
args + a, count - a);
else
*array = JArray<Object>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
Object *obj = va_arg(list, Object *);
if (tc == 'O')
{
PyTypeObject *type = va_arg(check, PyTypeObject *);
if (type != NULL)
{
boxfn fn = get_boxfn(type);
if (fn == NULL || fn(type, arg, obj) < 0)
return -1;
break;
}
}
if (boxObject(NULL, arg, obj) < 0)
return -1;
}
break;
}
case 'T': /* tuple of python types with wrapfn_ */
{
int len = va_arg(check, int);
PyTypeObject **types = va_arg(list, PyTypeObject **);
for (int i = 0; i < len; i++) {
PyObject *type = PyTuple_GET_ITEM(arg, i);
if (type == Py_None)
types[i] = NULL;
else
types[i] = (PyTypeObject *) type;
}
break;
}
default:
return -1;
}
if (tc != '[')
array = 0;
if (last && varargs)
{
pos = typeCount;
break;
}
}
if (pos == typeCount)
return 0;
return -1;
}
String p2j(PyObject *object)
{
return String(env->fromPyString(object));
}
PyObject *j2p(const String& js)
{
return env->fromJString((jstring) js.this$, 0);
}
PyObject *c2p(jchar c)
{
PyObject *result = PyUnicode_New(1, c);
PyUnicode_WriteChar(result, 0, c);
return result;
}
PyObject *PyErr_SetArgsError(char *name, PyObject *args)
{
if (!PyErr_Occurred())
{
PyObject *err = Py_BuildValue("(sO)", name, args);
PyErr_SetObject(PyExc_InvalidArgsError, err);
Py_DECREF(err);
}
return NULL;
}
PyObject *PyErr_SetArgsError(PyObject *self, char *name, PyObject *args)
{
if (!PyErr_Occurred())
{
PyObject *type = (PyObject *) self->ob_type;
PyObject *err = Py_BuildValue("(OsO)", type, name, args);
PyErr_SetObject(PyExc_InvalidArgsError, err);
Py_DECREF(err);
}
return NULL;
}
PyObject *PyErr_SetArgsError(PyTypeObject *type, char *name, PyObject *args)
{
if (!PyErr_Occurred())
{
PyObject *err = Py_BuildValue("(OsO)", type, name, args);
PyErr_SetObject(PyExc_InvalidArgsError, err);
Py_DECREF(err);
}
return NULL;
}
PyObject *PyErr_SetJavaError()
{
JNIEnv *vm_env = env->get_vm_env();
jthrowable throwable = vm_env->ExceptionOccurred();
vm_env->ExceptionClear();
if (env->restorePythonException(throwable))
return NULL;
PyObject *err = t_Throwable::wrap_Object(Throwable(throwable));
PyErr_SetObject(PyExc_JavaError, err);
Py_DECREF(err);
return NULL;
}
void throwPythonError(void)
{
PyObject *exc = PyErr_Occurred();
if (exc && PyErr_GivenExceptionMatches(exc, PyExc_JavaError))
{
PyObject *value, *traceback;
PyErr_Fetch(&exc, &value, &traceback);
if (value)
{
PyObject *je = PyObject_CallMethod(value, "getJavaException", "");
if (!je)
PyErr_Restore(exc, value, traceback);
else
{
Py_DECREF(exc);
Py_DECREF(value);
Py_XDECREF(traceback);
exc = je;
if (exc && PyObject_TypeCheck(exc, PY_TYPE(Throwable)))
{
jobject jobj = ((t_Throwable *) exc)->object.this$;
env->get_vm_env()->Throw((jthrowable) jobj);
Py_DECREF(exc);
return;
}
}
}
else
{
Py_DECREF(exc);
Py_XDECREF(traceback);
}
}
else if (exc && PyErr_GivenExceptionMatches(exc, PyExc_StopIteration))
{
PyErr_Clear();
return;
}
if (exc)
{
PyObject *name = PyObject_GetAttrString(exc, "__name__");
env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(),
PyUnicode_AsUTF8(name));
Py_DECREF(name);
}
else
env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(),
"python error");
}
void throwTypeError(const char *name, PyObject *object)
{
PyObject *tuple = Py_BuildValue("(ssO)", "while calling", name, object);
PyErr_SetObject(PyExc_TypeError, tuple);
Py_DECREF(tuple);
env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(), "type error");
}
int abstract_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *err =
Py_BuildValue("(sO)", "instantiating java class", self->ob_type);
PyErr_SetObject(PyExc_NotImplementedError, err);
Py_DECREF(err);
return -1;
}
PyObject *callSuper(PyTypeObject *type, const char *name, PyObject *args,
int cardinality)
{
PyObject *super = (PyObject *) type->tp_base;
PyObject *method =
PyObject_GetAttrString(super, (char *) name); // python 2.4 cast
PyObject *value;
if (!method)
return NULL;
if (cardinality > 1)
value = PyObject_Call(method, args, NULL);
else
{
PyObject *tuple = PyTuple_Pack(1, args);
value = PyObject_Call(method, tuple, NULL);
Py_DECREF(tuple);
}
Py_DECREF(method);
return value;
}
PyObject *callSuper(PyTypeObject *type, PyObject *self,
const char *name, PyObject *args, int cardinality)
{
PyObject *tuple = PyTuple_Pack(2, type, self);
PyObject *super = PyObject_Call((PyObject *) &PySuper_Type, tuple, NULL);
PyObject *method, *value;
Py_DECREF(tuple);
if (!super)
return NULL;
method = PyObject_GetAttrString(super, (char *) name); // python 2.4 cast
Py_DECREF(super);
if (!method)
return NULL;
if (cardinality > 1)
value = PyObject_Call(method, args, NULL);
else
{
tuple = PyTuple_Pack(1, args);
value = PyObject_Call(method, tuple, NULL);
Py_DECREF(tuple);
}
Py_DECREF(method);
return value;
}
PyObject *castCheck(PyObject *obj, getclassfn initializeClass,
int reportError)
{
if (PyObject_TypeCheck(obj, PY_TYPE(FinalizerProxy)))
obj = ((t_fp *) obj)->object;
if (!PyObject_TypeCheck(obj, PY_TYPE(Object)))
{
if (reportError)
PyErr_SetObject(PyExc_TypeError, obj);
return NULL;
}
jobject jobj = ((t_Object *) obj)->object.this$;
if (jobj && !env->isInstanceOf(jobj, initializeClass))
{
if (reportError)
PyErr_SetObject(PyExc_TypeError, obj);
return NULL;
}
return obj;
}
PyObject *get_extension_iterator(PyObject *self)
{
return PyObject_CallMethod(self, "iterator", "");
}
PyObject *get_extension_next(PyObject *self)
{
return PyObject_CallMethod(self, "next", "");
}
PyObject *get_extension_nextElement(PyObject *self)
{
return PyObject_CallMethod(self, "nextElement", "");
}
static bool setArrayObj(jobjectArray array, int index, PyObject *obj)
{
bool deleteLocal = false;
jobject jobj;
if (obj == Py_None)
jobj = NULL;
else if (PyBytes_Check(obj) || PyUnicode_Check(obj))
{
jobj = env->fromPyString(obj);
deleteLocal = true;
}
else if (PyObject_TypeCheck(obj, PY_TYPE(JObject)))
jobj = ((t_JObject *) obj)->object.this$;
else if (PyObject_TypeCheck(obj, PY_TYPE(FinalizerProxy)))
jobj = ((t_JObject *) ((t_fp *) obj)->object)->object.this$;
else if (obj == Py_True || obj == Py_False)
{
jobj = env->boxBoolean(obj == Py_True);
deleteLocal = true;
}
else if (PyFloat_Check(obj))
{
jobj = env->boxDouble(PyFloat_AS_DOUBLE(obj));
deleteLocal = true;
}
else if (PyLong_Check(obj))
{
long long value = PyLong_AsLongLong(obj);
if (static_cast<long long>(static_cast<int>(value)) == value)
jobj = env->boxInteger((int) value);
else
jobj = env->boxLong(value);
deleteLocal = true;
}
else
{
PyErr_SetObject(PyExc_TypeError, obj);
Py_DECREF(obj);
return false;
}
try {
env->setObjectArrayElement(array, index, jobj);
if (deleteLocal)
env->get_vm_env()->DeleteLocalRef(jobj);
Py_DECREF(obj);
} catch (int e) {
Py_DECREF(obj);
switch (e) {
case _EXC_JAVA:
PyErr_SetJavaError();
return false;
default:
throw;
}
}
return true;
}
jobjectArray fromPySequence(jclass cls, PyObject *sequence)
{
if (sequence == Py_None)
return NULL;
if (!PySequence_Check(sequence))
{
PyErr_SetObject(PyExc_TypeError, sequence);
return NULL;
}
int length = PySequence_Length(sequence);
jobjectArray array;
try {
array = env->newObjectArray(cls, length);
} catch (int e) {
switch (e) {
case _EXC_PYTHON:
return NULL;
case _EXC_JAVA:
PyErr_SetJavaError();
return NULL;
default:
throw;
}
}
for (int i = 0; i < length; i++) {
PyObject *obj = PySequence_GetItem(sequence, i);
if (!obj)
break;
if (!setArrayObj(array, i, obj))
return NULL;
}
return array;
}
jobjectArray fromPySequence(jclass cls, PyObject **args, int length)
{
jobjectArray array;
try {
array = env->newObjectArray(cls, length);
} catch (int e) {
switch (e) {
case _EXC_PYTHON:
return NULL;
case _EXC_JAVA:
PyErr_SetJavaError();
return NULL;
default:
throw;
}
}
for (int i = 0; i < length; i++) {
PyObject *obj = args[i];
if (!obj)
break;
Py_INCREF(obj);
if (!setArrayObj(array, i, obj))
return NULL;
}
return array;
}
PyTypeObject *makeType(PyType_Def *def)
{
if (def->type == NULL)
{
int count = 0;
for (PyType_Def **base = def->bases; *base != NULL; ++base)
count += 1;
PyObject *bases = PyTuple_New(count);
for (int i = 0; i < count; ++i)
PyTuple_SET_ITEM(bases, i, (PyObject *) makeType(def->bases[i]));
def->type = (PyTypeObject *)
PyType_FromSpecWithBases(&def->spec, bases);
Py_DECREF(bases);
}
return def->type;
}
void installType(PyTypeObject **type, PyType_Def *def,
PyObject *module, char *name, int isExtension)
{
if (*type == NULL)
{
*type = makeType(def);
Py_INCREF(*type);
if (isExtension)
{
Py_TYPE(*type) = PY_TYPE(FinalizerClass);
Py_INCREF(PY_TYPE(FinalizerClass));
}
PyModule_AddObject(module, name, (PyObject *) *type);
}
}
PyObject *wrapType(PyTypeObject *type, const jobject& obj)
{
static PyObject *wrapfn_ = PyUnicode_FromString("wrapfn_");
PyObject *cobj = PyObject_GetAttr((PyObject *) type, wrapfn_);
PyObject *(*wrapfn)(const jobject&);
if (cobj == NULL)
return NULL;
wrapfn = (PyObject *(*)(const jobject &))
PyCapsule_GetPointer(cobj, "wrapfn");
Py_DECREF(cobj);
return wrapfn(obj);
}
PyObject *unboxBoolean(const jobject& obj)
{
if (obj != NULL)
{
if (!env->isInstanceOf(obj, java::lang::Boolean::initializeClass))
{
PyErr_SetObject(PyExc_TypeError,
(PyObject *) java::lang::PY_TYPE(Boolean));
return NULL;
}
if (env->booleanValue(obj))
Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
Py_RETURN_NONE;
}
PyObject *unboxByte(const jobject &obj)
{
if (obj != NULL)
{
if (!env->isInstanceOf(obj, java::lang::Byte::initializeClass))
{
PyErr_SetObject(PyExc_TypeError,
(PyObject *) java::lang::PY_TYPE(Byte));
return NULL;
}
return PyLong_FromLong((long) env->byteValue(obj));
}
Py_RETURN_NONE;
}
PyObject *unboxCharacter(const jobject &obj)
{
if (obj != NULL)
{
if (!env->isInstanceOf(obj, java::lang::Character::initializeClass))
{
PyErr_SetObject(PyExc_TypeError,
(PyObject *) java::lang::PY_TYPE(Character));
return NULL;
}
return c2p(env->charValue(obj));
}
Py_RETURN_NONE;
}
PyObject *unboxDouble(const jobject &obj)
{
if (obj != NULL)
{
if (!env->isInstanceOf(obj, java::lang::Double::initializeClass))
{
PyErr_SetObject(PyExc_TypeError,
(PyObject *) java::lang::PY_TYPE(Double));
return NULL;
}
return PyFloat_FromDouble((double) env->doubleValue(obj));
}
Py_RETURN_NONE;
}
PyObject *unboxFloat(const jobject &obj)
{
if (obj != NULL)
{
if (!env->isInstanceOf(obj, java::lang::Float::initializeClass))
{
PyErr_SetObject(PyExc_TypeError,
(PyObject *) java::lang::PY_TYPE(Float));
return NULL;
}
return PyFloat_FromDouble((double) env->floatValue(obj));
}
Py_RETURN_NONE;
}
PyObject *unboxInteger(const jobject &obj)
{
if (obj != NULL)
{
if (!env->isInstanceOf(obj, java::lang::Integer::initializeClass))
{
PyErr_SetObject(PyExc_TypeError,
(PyObject *) java::lang::PY_TYPE(Integer));
return NULL;
}
return PyLong_FromLong((long) env->intValue(obj));
}
Py_RETURN_NONE;
}
PyObject *unboxLong(const jobject &obj)
{
if (obj != NULL)
{
if (!env->isInstanceOf(obj, java::lang::Long::initializeClass))
{
PyErr_SetObject(PyExc_TypeError,
(PyObject *) java::lang::PY_TYPE(Long));
return NULL;
}
return PyLong_FromLongLong((PY_LONG_LONG) env->longValue(obj));
}
Py_RETURN_NONE;
}
PyObject *unboxShort(const jobject &obj)
{
if (obj != NULL)
{
if (!env->isInstanceOf(obj, java::lang::Short::initializeClass))
{
PyErr_SetObject(PyExc_TypeError,
(PyObject *) java::lang::PY_TYPE(Short));
return NULL;
}
return PyLong_FromLong((long) env->shortValue(obj));
}
Py_RETURN_NONE;
}
PyObject *unboxString(const jobject &obj)
{
if (obj != NULL)
{
if (!env->isInstanceOf(obj, java::lang::String::initializeClass))
{
PyErr_SetObject(PyExc_TypeError,
(PyObject *) java::lang::PY_TYPE(String));
return NULL;
}
return env->fromJString((jstring) obj, 0);
}
Py_RETURN_NONE;
}
static int boxJObject(PyTypeObject *type, PyObject *arg,
java::lang::Object *obj)
{
if (arg == Py_None)
{
if (obj != NULL)
*obj = Object(NULL);
}
else if (PyObject_TypeCheck(arg, PY_TYPE(Object)))
{
if (type != NULL && !is_instance_of(arg, type))
return -1;
if (obj != NULL)
*obj = ((t_Object *) arg)->object;
}
else if (PyObject_TypeCheck(arg, PY_TYPE(FinalizerProxy)))
{
arg = ((t_fp *) arg)->object;
if (PyObject_TypeCheck(arg, PY_TYPE(Object)))
{
if (type != NULL && !is_instance_of(arg, type))
return -1;
if (obj != NULL)
*obj = ((t_Object *) arg)->object;
}
else
return -1;
}
else
return 1;
return 0;
}
int boxBoolean(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (arg == Py_True)
{
if (obj != NULL)
*obj = *Boolean::TRUE;
}
else if (arg == Py_False)
{
if (obj != NULL)
*obj = *Boolean::FALSE;
}
else
return -1;
return 0;
}
int boxByte(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyLong_Check(arg))
{
long ln = PyLong_AS_LONG(arg);
jbyte b = (jbyte) ln;
if (b == ln)
{
if (obj != NULL)
*obj = Byte(b);
}
else
return -1;
}
else if (PyFloat_Check(arg))
{
double d = PyFloat_AS_DOUBLE(arg);
jbyte b = (jbyte) d;
if (b == d)
{
if (obj != NULL)
*obj = Byte(b);
}
else
return -1;
}
else
return -1;
return 0;
}
int boxCharacter(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyBytes_Check(arg))
{
char *c;
Py_ssize_t len;
if (PyBytes_AsStringAndSize(arg, &c, &len) < 0 || len != 1)
return -1;
if (obj != NULL)
*obj = Character((jchar) c[0]);
}
else if (PyUnicode_Check(arg))
{
Py_ssize_t len = PyUnicode_GetLength(arg);
if (len != 1)
return -1;
if (obj != NULL)
*obj = Character((jchar) PyUnicode_READ_CHAR(arg, 0));
}
else
return -1;
return 0;
}
int boxCharSequence(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyBytes_Check(arg) || PyUnicode_Check(arg))
{
if (obj != NULL)
{
*obj = p2j(arg);
if (PyErr_Occurred())
return -1;
}
}
else
return -1;
return 0;
}
int boxDouble(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyLong_Check(arg))
{
if (obj != NULL)
*obj = Double((jdouble) PyLong_AsLongLong(arg));
}
else if (PyFloat_Check(arg))
{
if (obj != NULL)
*obj = Double(PyFloat_AS_DOUBLE(arg));
}
else
return -1;
return 0;
}
int boxFloat(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyLong_Check(arg))
{
PY_LONG_LONG ln = PyLong_AsLongLong(arg);
float f = (float) ln;
if ((PY_LONG_LONG) f == ln)
{
if (obj != NULL)
*obj = Float(f);
}
else
return -1;
}
else if (PyFloat_Check(arg))
{
double d = PyFloat_AS_DOUBLE(arg);
float f = (float) d;
if ((double) f == d)
{
if (obj != NULL)
*obj = Float(f);
}
else
return -1;
}
else
return -1;
return 0;
}
int boxInteger(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyLong_Check(arg))
{
PY_LONG_LONG ln = PyLong_AsLongLong(arg);
int n = (int) ln;
if (n == ln)
{
if (obj != NULL)
*obj = Integer(n);
}
else
return -1;
}
else if (PyFloat_Check(arg))
{
double d = PyFloat_AS_DOUBLE(arg);
int n = (int) d;
if ((double) n == d)
{
if (obj != NULL)
*obj = Integer(n);
}
else
return -1;
}
else
return -1;
return 0;
}
int boxLong(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyLong_Check(arg))
{
if (obj != NULL)
*obj = Long((jlong) PyLong_AsLongLong(arg));
}
else if (PyFloat_Check(arg))
{
double d = PyFloat_AS_DOUBLE(arg);
PY_LONG_LONG n = (PY_LONG_LONG) d;
if ((double) n == d)
{
if (obj != NULL)
*obj = Long((jlong) n);
}
else
return -1;
}
else
return -1;
return 0;
}
int boxNumber(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyLong_Check(arg))
{
if (obj != NULL)
{
long long value = PyLong_AsLongLong(arg);
if (static_cast<long long>(static_cast<int>(value)) == value)
*obj = Integer((jint) value);
else
*obj = Long((jlong) value);
}
}
else if (PyFloat_Check(arg))
{
if (obj != NULL)
*obj = Double((jdouble) PyFloat_AS_DOUBLE(arg));
}
else
return -1;
return 0;
}
int boxShort(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyLong_Check(arg))
{
PY_LONG_LONG ln = PyLong_AsLongLong(arg);
short sn = (short) ln;
if (sn == ln)
{
if (obj != NULL)
*obj = Short((jshort) sn);
}
else
return -1;
}
else if (PyFloat_Check(arg))
{
double d = PyFloat_AS_DOUBLE(arg);
short sn = (short) (int) d;
if ((double) sn == d)
{
if (obj != NULL)
*obj = Short((jshort) sn);
}
else
return -1;
}
else
return -1;
return 0;
}
int boxString(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (PyBytes_Check(arg) || PyUnicode_Check(arg))
{
if (obj != NULL)
{
*obj = p2j(arg);
if (PyErr_Occurred())
return -1;
}
}
else
return -1;
return 0;
}
int boxObject(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
{
int result = boxJObject(type, arg, obj);
if (result <= 0)
return result;
if (obj != NULL)
{
if (PyBytes_Check(arg) || PyUnicode_Check(arg))
{
*obj = p2j(arg);
if (PyErr_Occurred())
return -1;
}
else if (arg == Py_True)
*obj = *Boolean::TRUE;
else if (arg == Py_False)
*obj = *Boolean::FALSE;
else if (PyLong_Check(arg))
{
long long value = PyLong_AsLongLong(arg);
if (static_cast<long long>(static_cast<int>(value)) == value)
*obj = Integer((jint) value);
else
*obj = Long((jlong) value);
}
else if (PyFloat_Check(arg))
*obj = Double((jdouble) PyFloat_AS_DOUBLE(arg));
else
return -1;
}
else if (!(PyBytes_Check(arg) || PyUnicode_Check(arg) ||
arg == Py_True || arg == Py_False ||
PyLong_Check(arg) || PyFloat_Check(arg)))
return -1;
return 0;
}
#ifdef _java_generics
PyObject *typeParameters(PyTypeObject *types[], size_t size)
{
size_t count = size / sizeof(PyTypeObject *);
PyObject *tuple = PyTuple_New(count);
for (size_t i = 0; i < count; i++) {
PyObject *type = (PyObject *) types[i];
if (type == NULL)
type = Py_None;
PyTuple_SET_ITEM(tuple, i, type);
Py_INCREF(type);
}
return tuple;
}
#endif