// //\r
///////////////////////////////////////////////////////\r
\r
-#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\r
-#ifdef _DEBUG\r
- #undef _DEBUG\r
- #include <Python.h> //header for system python import; add include paths\r
- #include <numpy/arrayobject.h>\r
- #define _DEBUG 1\r
-#else\r
- #include <Python.h> //header for system python import; add include paths\r
- #include <numpy/arrayobject.h>\r
-#endif\r
-\r
#include "sclpy.h"\r
\r
-#include <jni.h> //java connection header\r
-\r
#include <windows.h>\r
\r
-#define JAVA_MAXINT (0x7fffffff)\r
-\r
-#define RUNTIME_EXCEPTION "java/lang/RuntimeException"\r
-#define ILLEGAL_ARGUMENT_EXCEPTION "java/lang/IllegalArgumentException"\r
-#define STRING_CLASS "java/lang/String"\r
-\r
-#define PACKAGE_PREFIX "org/simantics/pythonlink/"\r
-\r
-#define NDARRAY_CLASS (PACKAGE_PREFIX "NDArray")\r
-\r
jint throwException( JNIEnv *env, char *className, char *message )\r
{\r
jclass exClass = (*env)->FindClass( env, className);\r
return (*env)->ThrowNew( env, exClass, message );\r
}\r
\r
+jint throwPythonException( JNIEnv *env, char *message ) {\r
+ return throwException( env, PYTHON_EXCEPTION, message );\r
+}\r
+\r
jint throwIllegalArgumentException( JNIEnv *env, char *message ) {\r
return throwException( env, ILLEGAL_ARGUMENT_EXCEPTION, message );\r
}\r
\r
int moduleCount = 0;\r
+int initCalled = 0;\r
+int hasNumpy = 0;\r
\r
JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_createContextImpl(JNIEnv *env, jobject thisObj) {\r
char name[16];\r
+\r
+ if (!initCalled) {\r
+ Py_Initialize();\r
+ initCalled = 1;\r
+\r
+ hasNumpy = _import_array();\r
+ hasNumpy = hasNumpy != -1;\r
+ }\r
+\r
sprintf(name, "SCL_%d", ++moduleCount);\r
\r
{\r
PyObject *main = PyImport_AddModule("__main__");\r
\r
PyDict_Merge(PyModule_GetDict(module), PyModule_GetDict(main), 0);\r
+\r
return (jlong)module;\r
}\r
}\r
Py_XDECREF(module);\r
}\r
\r
+PyObject *getPythonBool(jboolean value) {\r
+ if (value) {\r
+ Py_RETURN_TRUE;\r
+ }\r
+ else {\r
+ Py_RETURN_FALSE;\r
+ }\r
+}\r
+\r
PyObject *getPythonString(JNIEnv *env, jstring string) {\r
jsize len = (*env)->GetStringLength(env, string);\r
const jchar *chars = (*env)->GetStringChars(env, string, NULL);\r
return result;\r
}\r
\r
+PyObject *getPythonBooleanList(JNIEnv *env, jbooleanArray value) {\r
+ jsize nitems = (*env)->GetArrayLength(env, value);\r
+ jboolean *values = (*env)->GetBooleanArrayElements(env, value, NULL);\r
+ jint i;\r
+\r
+ PyObject *result = PyList_New(nitems);\r
+ for (i = 0; i < nitems; i++) {\r
+ PyList_SetItem(result, i, getPythonBool(values[i]));\r
+ }\r
+\r
+ (*env)->ReleaseBooleanArrayElements(env, value, values, JNI_ABORT);\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonByteArray(JNIEnv *env, jbyteArray value) {\r
+ jint len = (*env)->GetArrayLength(env, value);\r
+ jbyte *values = (*env)->GetByteArrayElements(env, value, NULL);\r
+\r
+ PyObject *result = PyByteArray_FromStringAndSize(values, len);\r
+\r
+ (*env)->ReleaseByteArrayElements(env, value, values, JNI_ABORT);\r
+ return result;\r
+}\r
+\r
PyObject *getPythonIntegerList(JNIEnv *env, jintArray value) {\r
jsize nitems = (*env)->GetArrayLength(env, value);\r
jint *values = (*env)->GetIntArrayElements(env, value, NULL);\r
return result;\r
}\r
\r
+PyObject *getPythonLongList(JNIEnv *env, jlongArray value) {\r
+ jsize nitems = (*env)->GetArrayLength(env, value);\r
+ jlong *values = (*env)->GetLongArrayElements(env, value, NULL);\r
+ jint i;\r
+\r
+ PyObject *result = PyList_New(nitems);\r
+ for (i = 0; i < nitems; i++) {\r
+ PyList_SetItem(result, i, PyLong_FromLongLong(values[i]));\r
+ }\r
+\r
+ (*env)->ReleaseLongArrayElements(env, value, values, JNI_ABORT);\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonFloatList(JNIEnv *env, jfloatArray value) {\r
+ jsize nitems = (*env)->GetArrayLength(env, value);\r
+ float *values = (*env)->GetFloatArrayElements(env, value, NULL);\r
+ jint i;\r
+\r
+ PyObject *result = PyList_New(nitems);\r
+ for (i = 0; i < nitems; i++) {\r
+ PyList_SetItem(result, i, PyFloat_FromDouble((double)values[i]));\r
+ }\r
+\r
+ (*env)->ReleaseFloatArrayElements(env, value, values, JNI_ABORT);\r
+ return result;\r
+}\r
+\r
PyObject *getPythonDoubleList(JNIEnv *env, jdoubleArray value) {\r
jsize nitems = (*env)->GetArrayLength(env, value);\r
double *values = (*env)->GetDoubleArrayElements(env, value, NULL);\r
}\r
}\r
\r
+PyObject *getPythonBooleanObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, BOOLEANBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)Z");\r
+\r
+ jboolean bvalue = (*env)->CallBooleanMethod(env, binding, getValueMethod, object);\r
+ return getPythonBool(bvalue);\r
+}\r
+\r
+PyObject *getPythonByteObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, BYTEBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)B");\r
+\r
+ jbyte v = (*env)->CallByteMethod(env, binding, getValueMethod, object);\r
+ return PyLong_FromLong(v);\r
+}\r
+\r
+PyObject *getPythonIntegerObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, INTEGERBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)I");\r
+\r
+ jint v = (*env)->CallIntMethod(env, binding, getValueMethod, object);\r
+ return PyLong_FromLong(v);\r
+}\r
+\r
+PyObject *getPythonLongObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, LONGBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)J");\r
+\r
+ jlong v = (*env)->CallLongMethod(env, binding, getValueMethod, object);\r
+ return PyLong_FromLongLong(v);\r
+}\r
+\r
+PyObject *getPythonFloatObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, FLOATBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)F");\r
+\r
+ jfloat v = (*env)->CallFloatMethod(env, binding, getValueMethod, object);\r
+ return PyFloat_FromDouble(v);\r
+}\r
+\r
+PyObject *getPythonDoubleObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, DOUBLEBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)D");\r
+\r
+ jdouble v = (*env)->CallDoubleMethod(env, binding, getValueMethod, object);\r
+ return PyFloat_FromDouble(v);\r
+}\r
+\r
+PyObject *getPythonStringObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, STRINGBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue", "(L" OBJECT_CLASS ";)L" STRING_CLASS ";");\r
+\r
+ jobject string = (*env)->CallObjectMethod(env, binding, getValueMethod, object);\r
+ jsize len = (*env)->GetStringLength(env, string);\r
+ const jchar *chars = (*env)->GetStringChars(env, string, NULL);\r
+\r
+ PyObject *value = PyUnicode_DecodeUTF16((char*)chars, 2*len, NULL, NULL);\r
+\r
+ (*env)->ReleaseStringChars(env, string, chars);\r
+ return value;\r
+}\r
+\r
+PyObject *getPythonRecordObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, RECORDBINDING_CLASS);\r
+ jmethodID typeMethod = (*env)->GetMethodID(env, bindingClass, "type", "()L" RECORDTYPE_CLASS ";");\r
+ jmethodID getComponent = (*env)->GetMethodID(env, bindingClass, "getComponent", "(L" OBJECT_CLASS ";I)L" OBJECT_CLASS ";");\r
+ jmethodID getComponentBinding = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "(I)L" BINDING_CLASS ";");\r
+\r
+ jclass recordType = (*env)->FindClass(env, RECORDTYPE_CLASS);\r
+ jmethodID getTypeComponent = (*env)->GetMethodID(env, recordType, "getComponent", "(I)L" COMPONENT_CLASS ";");\r
+ jmethodID getComponentCount = (*env)->GetMethodID(env, recordType, "getComponentCount", "()I");\r
+\r
+ jclass componentClass = (*env)->FindClass(env, COMPONENT_CLASS);\r
+ jfieldID nameField = (*env)->GetFieldID(env, componentClass, "name", "L" STRING_CLASS ";");\r
+\r
+ jobject type = (*env)->CallObjectMethod(env, binding, typeMethod);\r
+ jint n = (*env)->CallIntMethod(env, type, getComponentCount);\r
+ jint i;\r
+\r
+ PyObject *result = PyDict_New();\r
+ for (i = 0; i < n; i++) {\r
+ jobject recordTypeComponent = (*env)->CallObjectMethod(env, type, getComponent, i);\r
+ jstring fieldName = (jstring)(*env)->GetObjectField(env, recordTypeComponent, nameField);\r
+ jobject componentObject = (*env)->CallObjectMethod(env, binding, getComponent, object, i);\r
+ jobject componentBinding = (*env)->CallObjectMethod(env, binding, getComponentBinding, i);\r
+\r
+ PyObject *item = getPythonObject(env, componentObject, componentBinding);\r
+ PyDict_SetItem(result, getPythonString(env, fieldName), item);\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonArrayObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, ARRAYBINDING_CLASS);\r
+ jmethodID componentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "()L" BINDING_CLASS ";");\r
+ jmethodID sizeMethod = (*env)->GetMethodID(env, bindingClass, "size", "(L" OBJECT_CLASS ";)I");\r
+ jmethodID getMethod = (*env)->GetMethodID(env, bindingClass, "get", "(L" OBJECT_CLASS ";I)L" OBJECT_CLASS ";");\r
+\r
+ jobject componentBinding = (*env)->CallObjectMethod(env, binding, componentBindingMethod);\r
+\r
+ jint size = (*env)->CallIntMethod(env, binding, sizeMethod, object);\r
+\r
+ PyObject *result = PyList_New(size);\r
+\r
+ jint i;\r
+ for (i = 0; i < size; i++) {\r
+ jobject item = (*env)->CallObjectMethod(env, binding, getMethod, object, i);\r
+ if (item != NULL)\r
+ PyList_SetItem(result, i, getPythonObject(env, item, componentBinding));\r
+ else\r
+ PyList_SetItem(result, i, Py_None);\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonMapObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass objectClass = (*env)->FindClass(env, OBJECT_CLASS);\r
+ jclass bindingClass = (*env)->FindClass(env, MAPBINDING_CLASS);\r
+ jmethodID getKeyBindingMethod = (*env)->GetMethodID(env, bindingClass, "getKeyBinding", "()L" BINDING_CLASS ";");\r
+ jmethodID getValueBindingMethod = (*env)->GetMethodID(env, bindingClass, "getValueBinding", "()L" BINDING_CLASS ";");\r
+ jmethodID sizeMethod = (*env)->GetMethodID(env, bindingClass, "size", "(L" OBJECT_CLASS ";)I");\r
+ jmethodID getAllMethod = (*env)->GetMethodID(env, bindingClass, "getAll", "(L" OBJECT_CLASS ";[L" OBJECT_CLASS ";[L" OBJECT_CLASS ";)V");\r
+\r
+ jobject keyBinding = (*env)->CallObjectMethod(env, binding, getKeyBindingMethod);\r
+ jobject valueBinding = (*env)->CallObjectMethod(env, binding, getValueBindingMethod);\r
+\r
+ jint size = (*env)->CallIntMethod(env, binding, sizeMethod, object);\r
+ jobjectArray keys = (*env)->NewObjectArray(env, size, objectClass, NULL);\r
+ jobjectArray values = (*env)->NewObjectArray(env, size, objectClass, NULL);\r
+\r
+ PyObject *result = PyDict_New();\r
+ jint i;\r
+\r
+ (*env)->CallVoidMethod(env, binding, getAllMethod, object, keys, values);\r
+\r
+ for (i = 0; i < size; i++) {\r
+ jobject key = (*env)->GetObjectArrayElement(env, keys, i);\r
+ jobject item = (*env)->GetObjectArrayElement(env, values, i);\r
+ PyDict_SetItem(result, getPythonObject(env, key, keyBinding), getPythonObject(env, item, valueBinding));\r
+ }\r
+\r
+ (*env)->DeleteLocalRef(env, keys);\r
+ (*env)->DeleteLocalRef(env, values);\r
+\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonOptionalObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, OPTIONALBINDING_CLASS);\r
+ jmethodID hasValueMethod = (*env)->GetMethodID(env, bindingClass, "hasValue", "(L" OBJECT_CLASS ";)Z");\r
+\r
+ jboolean hasValue = (*env)->CallBooleanMethod(env, binding, hasValueMethod, object);\r
+\r
+ if (hasValue) {\r
+ jmethodID componentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "()L" BINDING_CLASS ";");\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "hasValue", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");\r
+\r
+ jobject componentBinding = (*env)->CallObjectMethod(env, binding, componentBindingMethod);\r
+ jobject value = (*env)->CallObjectMethod(env, binding, getValueMethod, object);\r
+\r
+ return getPythonObject(env, value, componentBinding);\r
+ }\r
+ else {\r
+ return Py_None;\r
+ }\r
+}\r
+\r
+PyObject *getPythonUnionObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, UNIONBINDING_CLASS);\r
+ jmethodID typeMethod = (*env)->GetMethodID(env, bindingClass, "type", "()L" RECORDTYPE_CLASS ";");\r
+ jmethodID getTagMethod = (*env)->GetMethodID(env, bindingClass, "getTag", "(L" OBJECT_CLASS ";)I");\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");\r
+ jmethodID getComponentBinding = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "(I)L" BINDING_CLASS ";");\r
+\r
+ jclass unionType = (*env)->FindClass(env, UNIONTYPE_CLASS);\r
+ jmethodID getTypeComponent = (*env)->GetMethodID(env, unionType, "getComponent", "(I)L" COMPONENT_CLASS ";");\r
+\r
+ jclass componentClass = (*env)->FindClass(env, COMPONENT_CLASS);\r
+ jfieldID nameField = (*env)->GetFieldID(env, componentClass, "name", "L" STRING_CLASS ";");\r
+\r
+ jint tag = (*env)->CallIntMethod(env, binding, getTagMethod, object);\r
+ jobject value = (*env)->CallObjectMethod(env, binding, getValueMethod, object);\r
+\r
+ jobject type = (*env)->CallObjectMethod(env, binding, typeMethod);\r
+ jobject typeComponent = (*env)->CallObjectMethod(env, type, getTypeComponent, tag);\r
+ jstring compName = (*env)->GetObjectField(env, typeComponent, nameField);\r
+\r
+ jobject componentBinding = (*env)->CallObjectMethod(env, binding, getComponentBinding, tag);\r
+\r
+ PyObject *result = PyTuple_New(2);\r
+ PyTuple_SetItem(result, 0, getPythonString(env, compName));\r
+ PyTuple_SetItem(result, 1, getPythonObject(env, value, componentBinding));\r
+\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonVariantObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, VARIANTBINDING_CLASS);\r
+ jmethodID getContentMethod = (*env)->GetMethodID(env, bindingClass, "getContent", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");\r
+ jmethodID getContentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getContentBinding", "(L" OBJECT_CLASS ";)L" BINDING_CLASS ";");\r
+\r
+ jobject content = (*env)->CallObjectMethod(env, binding, getContentMethod, object);\r
+ jobject contentBinding = (*env)->CallObjectMethod(env, binding, getContentBindingMethod, object);\r
+\r
+ return getPythonObject(env, content, contentBinding);\r
+}\r
+\r
+PyObject *getPythonObject(JNIEnv *env, jobject value, jobject binding) {\r
+ jclass booleanBinding = (*env)->FindClass(env, BOOLEANBINDING_CLASS);\r
+ jclass byteBinding = (*env)->FindClass(env, BYTEBINDING_CLASS);\r
+ jclass integerBinding = (*env)->FindClass(env, INTEGERBINDING_CLASS);\r
+ jclass longBinding = (*env)->FindClass(env, LONGBINDING_CLASS);\r
+ jclass floatBinding = (*env)->FindClass(env, FLOATBINDING_CLASS);\r
+ jclass doubleBinding = (*env)->FindClass(env, DOUBLEBINDING_CLASS);\r
+ jclass stringBinding = (*env)->FindClass(env, STRINGBINDING_CLASS);\r
+ jclass recordBinding = (*env)->FindClass(env, RECORDBINDING_CLASS);\r
+ jclass arrayBinding = (*env)->FindClass(env, ARRAYBINDING_CLASS);\r
+ jclass mapBinding = (*env)->FindClass(env, MAPBINDING_CLASS);\r
+ jclass optionalBinding = (*env)->FindClass(env, OPTIONALBINDING_CLASS);\r
+ jclass untionBinding = (*env)->FindClass(env, UNIONBINDING_CLASS);\r
+ jclass variantBinding = (*env)->FindClass(env, VARIANTBINDING_CLASS);\r
+\r
+ if (value == NULL)\r
+ return Py_None;\r
+\r
+ if ((*env)->IsInstanceOf(env, binding, booleanBinding)) {\r
+ return getPythonBooleanObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, byteBinding)) {\r
+ return getPythonByteObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, integerBinding)) {\r
+ return getPythonIntegerObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, longBinding)) {\r
+ return getPythonLongObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, floatBinding)) {\r
+ return getPythonFloatObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, doubleBinding)) {\r
+ return getPythonDoubleObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, stringBinding)) {\r
+ return getPythonStringObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, recordBinding)) {\r
+ return getPythonRecordObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, arrayBinding)) {\r
+ return getPythonArrayObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, mapBinding)) {\r
+ return getPythonMapObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, optionalBinding)) {\r
+ return getPythonOptionalObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, untionBinding)) {\r
+ return getPythonUnionObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, variantBinding)) {\r
+ return getPythonVariantObject(env, value, binding);\r
+ }\r
+ else {\r
+ return Py_None;\r
+ }\r
+}\r
+\r
void setPythonVariable(PyObject *module, PyObject *name, PyObject *value) {\r
if (name && value) {\r
PyDict_SetItem(PyModule_GetDict(module), name, value);\r
Py_XDECREF(value);\r
}\r
\r
+static npy_intp nContiguous(int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {\r
+ if (d == nd) {\r
+ ncont[d] = 1;\r
+ return 1;\r
+ }\r
+ else {\r
+ npy_intp n = nContiguous(d+1, nd, strides, dims, ncont);\r
+ ncont[d] = n > 0 && strides[d] == sizeof(double) * n ? dims[d] * n : 0;\r
+ return ncont[d];\r
+ }\r
+}\r
+\r
+static void copyDoubleArrayValues(JNIEnv *env, jdoubleArray array, double *data, npy_intp *offset, int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {\r
+ if (ncont[d] > 0) {\r
+ (*env)->SetDoubleArrayRegion(env, array, (jint)*offset, (jint)ncont[d], data);\r
+ *offset += ncont[d];\r
+ }\r
+ else {\r
+ int i;\r
+ for (i = 0; i < dims[d]; i++) {\r
+ copyDoubleArrayValues(env, array, (double*)((char*)data + strides[d] * i), offset, d+1, nd, strides, dims, ncont);\r
+ }\r
+ }\r
+}\r
+\r
+jobject pythonBoolAsBooleanObject(JNIEnv *env, PyObject *value) {\r
+ jclass booleanClass = (*env)->FindClass(env, "java/lang/Boolean");\r
+ jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, booleanClass, "valueOf", "(Z)Ljava/lang/Boolean;");\r
+\r
+ return (*env)->CallStaticObjectMethod(env, booleanClass, valueOfMethod, (jboolean)(value == Py_True));\r
+}\r
+\r
+jobject pythonLongAsLongObject(JNIEnv *env, PyObject *value) {\r
+ jclass longClass = (*env)->FindClass(env, "java/lang/Long");\r
+ jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, longClass, "valueOf", "(J)Ljava/lang/Long;");\r
+\r
+ return (*env)->CallStaticObjectMethod(env, longClass, valueOfMethod, PyLong_AsLongLong(value));\r
+}\r
+\r
+jobject pythonFloatAsDoubleObject(JNIEnv *env, PyObject *value) {\r
+ jclass doubleClass = (*env)->FindClass(env, "java/lang/Double");\r
+ jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, doubleClass, "valueOf", "(D)Ljava/lang/Double;");\r
+\r
+ return (*env)->CallStaticObjectMethod(env, doubleClass, valueOfMethod, PyFloat_AsDouble(value));\r
+}\r
+\r
+jobject pythonByteArrayAsByteArray(JNIEnv *env, PyObject *value) {\r
+ Py_ssize_t size = PyByteArray_Size(value);\r
+ jbyteArray result = (*env)->NewByteArray(env, (jsize)size);\r
+ char *bytes = PyByteArray_AsString(value);\r
+\r
+ (*env)->SetByteArrayRegion(env, result, 0, size, bytes);\r
+\r
+ return result;\r
+}\r
+\r
jstring pythonStringAsJavaString(JNIEnv *env, PyObject *string) {\r
PyObject *utf16Value = PyUnicode_AsUTF16String(string);\r
Py_ssize_t len = PyBytes_Size(utf16Value) / 2;\r
return result;\r
}\r
\r
-jobjectArray pythonStringListAsJavaArray(JNIEnv *env, PyObject *list) {\r
- Py_ssize_t len = PyList_Size(list);\r
+jobjectArray pythonSequenceAsStringArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
jobjectArray array = (*env)->NewObjectArray(env, jlen, (*env)->FindClass(env, STRING_CLASS), NULL);\r
\r
jint i;\r
\r
for (i = 0; i < jlen; i++) {\r
- PyObject *item = PyList_GetItem(list, i);\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
if (PyUnicode_Check(item)) {\r
jstring value = pythonStringAsJavaString(env, item);\r
(*env)->SetObjectArrayElement(env, array, i, value);\r
}\r
else {\r
- throwException(env, RUNTIME_EXCEPTION, "List item not a string");\r
+ throwPythonException(env, "List item not a string");\r
return NULL;\r
}\r
}\r
return array;\r
}\r
\r
-jdoubleArray pythonListAsDoubleArray(JNIEnv *env, PyObject *list) {\r
- Py_ssize_t len = PyList_Size(list);\r
+jdoubleArray pythonSequenceAsDoubleArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
jdoubleArray array = (*env)->NewDoubleArray(env, jlen);\r
\r
jint i;\r
\r
for (i = 0; i < jlen; i++) {\r
- PyObject *item = PyList_GetItem(list, i);\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
if (PyFloat_Check(item)) {\r
double value = PyFloat_AsDouble(item);\r
(*env)->SetDoubleArrayRegion(env, array, i, 1, &value);\r
}\r
else {\r
- throwException(env, RUNTIME_EXCEPTION, "List item not a floating point value");\r
+ throwPythonException(env, "List item not a floating point value");\r
return NULL;\r
}\r
}\r
return array;\r
}\r
\r
-npy_intp nContiguous(int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {\r
- if (d == nd) {\r
- ncont[d] = 1;\r
- return 1;\r
+jobject pythonObjectAsObject(JNIEnv *env, PyObject *value) {\r
+ if (PyBool_Check(value))\r
+ return pythonBoolAsBooleanObject(env, value);\r
+ else if (PyLong_Check(value))\r
+ return pythonLongAsLongObject(env, value);\r
+ else if (PyFloat_Check(value))\r
+ return pythonFloatAsDoubleObject(env, value);\r
+ else if (PyUnicode_Check(value))\r
+ return pythonStringAsJavaString(env, value);\r
+ else if (PyByteArray_Check(value))\r
+ return pythonByteArrayAsByteArray(env, value);\r
+ else if (PyDict_Check(value))\r
+ return pythonDictionaryAsMap(env, value);\r
+ else if (hasNumpy && PyArray_Check(value))\r
+ return pythonArrayAsNDArray(env, (PyArrayObject *)value);\r
+ else if (PySequence_Check(value))\r
+ return pythonSequenceAsObjectArray(env, value);\r
+ else\r
+ return NULL;\r
+}\r
+\r
+jobjectArray pythonSequenceAsObjectArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
+ jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
+ jobjectArray array = (*env)->NewObjectArray(env, jlen, (*env)->FindClass(env, OBJECT_CLASS), NULL);\r
+\r
+ jint i;\r
+\r
+ for (i = 0; i < jlen; i++) {\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
+ jobject object = pythonObjectAsObject(env, item);\r
+ (*env)->SetObjectArrayElement(env, array, i, object);\r
}\r
- else {\r
- npy_intp n = nContiguous(d+1, nd, strides, dims, ncont);\r
- ncont[d] = n > 0 && strides[d] == sizeof(double) * n ? dims[d] * n : 0;\r
- return ncont[d];\r
+\r
+ return array;\r
+}\r
+\r
+jbooleanArray pythonSequenceAsBooleanArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
+ jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
+ jbooleanArray array = (*env)->NewBooleanArray(env, jlen);\r
+\r
+ jint i;\r
+\r
+ for (i = 0; i < jlen; i++) {\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
+ if (PyBool_Check(item)) {\r
+ jboolean value = item == Py_True;\r
+ (*env)->SetBooleanArrayRegion(env, array, i, 1, &value);\r
+ }\r
+ else {\r
+ throwPythonException(env, "List item not a boolean");\r
+ return NULL;\r
+ }\r
}\r
+\r
+ return array;\r
}\r
\r
-void copyDoubleArrayValues(JNIEnv *env, jdoubleArray array, double *data, npy_intp *offset, int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {\r
- if (ncont[d] > 0) {\r
- (*env)->SetDoubleArrayRegion(env, array, (jint)*offset, (jint)ncont[d], data);\r
- *offset += ncont[d];\r
+jintArray pythonSequenceAsIntegerArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
+ jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
+ jintArray array = (*env)->NewIntArray(env, jlen);\r
+\r
+ jint i;\r
+\r
+ for (i = 0; i < jlen; i++) {\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
+ if (PyLong_Check(item)) {\r
+ jint value = PyLong_AsLong(item);\r
+ (*env)->SetIntArrayRegion(env, array, i, 1, &value);\r
+ }\r
+ else {\r
+ throwPythonException(env, "List item not an integer");\r
+ return NULL;\r
+ }\r
}\r
- else {\r
- int i;\r
- for (i = 0; i < dims[d]; i++) {\r
- copyDoubleArrayValues(env, array, (double*)((char*)data + strides[d] * i), offset, d+1, nd, strides, dims, ncont);\r
+\r
+ return array;\r
+}\r
+\r
+jlongArray pythonSequenceAsLongArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
+ jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
+ jlongArray array = (*env)->NewLongArray(env, jlen);\r
+\r
+ jint i;\r
+\r
+ for (i = 0; i < jlen; i++) {\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
+ if (PyLong_Check(item)) {\r
+ jlong value = PyLong_AsLongLong(item);\r
+ (*env)->SetLongArrayRegion(env, array, i, 1, &value);\r
+ }\r
+ else {\r
+ throwPythonException(env, "List item not an integer");\r
+ return NULL;\r
}\r
}\r
+\r
+ return array;\r
}\r
\r
jobject pythonArrayAsNDArray(JNIEnv *env, PyArrayObject *array) {\r
int i;\r
\r
if (len > JAVA_MAXINT) {\r
- throwException(env, RUNTIME_EXCEPTION, "Array too large");\r
+ throwPythonException(env, "Array too large");\r
return NULL;\r
}\r
\r
}\r
}\r
\r
-jintArray pythonListAsIntegerArray(JNIEnv *env, PyObject *list) {\r
- Py_ssize_t len = PyList_Size(list);\r
- jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
- jdoubleArray array = (*env)->NewIntArray(env, jlen);\r
+jobject pythonDictionaryAsMap(JNIEnv *env, PyObject *dict) {\r
+ jclass hashmapClass = (*env)->FindClass(env, "java/util/HashMap");\r
+ jmethodID constructor = (*env)->GetMethodID(env, hashmapClass, "<init>", "(I)V");\r
+ jmethodID putMethod = (*env)->GetMethodID(env, hashmapClass, "put", "(L" OBJECT_CLASS ";L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");\r
\r
- jint i;\r
+ Py_ssize_t size = PyDict_Size(dict);\r
+ jobject map = (*env)->NewObject(env, hashmapClass, constructor, (jint)size);\r
\r
- for (i = 0; i < jlen; i++) {\r
- PyObject *item = PyList_GetItem(list, i);\r
- if (PyLong_Check(item)) {\r
- jint value = PyLong_AsLong(item);\r
- (*env)->SetIntArrayRegion(env, array, i, 1, &value);\r
- }\r
- else {\r
- throwException(env, RUNTIME_EXCEPTION, "List item not an integer");\r
- return NULL;\r
- }\r
+ PyObject *key, *value;\r
+ Py_ssize_t pos = 0;\r
+\r
+ while (PyDict_Next(dict, &pos, &key, &value)) {\r
+ jobject keyObject = pythonObjectAsObject(env, key);\r
+ jobject valueObject = pythonObjectAsObject(env, value);\r
+ (*env)->CallObjectMethod(env, map, putMethod, keyObject, valueObject);\r
}\r
\r
- return array;\r
+ return map;\r
+}\r
+\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonBooleanVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jboolean value) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = getPythonBool(value);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
}\r
\r
-JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonIntegerVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jint value) {\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonBooleanArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jbooleanArray value) {\r
PyObject *module = (PyObject*)contextID;\r
\r
PyObject *pythonName = getPythonString(env, variableName);\r
- PyObject *val = PyLong_FromLong(value);\r
+ PyObject *val = getPythonBooleanList(env, value);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
+}\r
+\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonLongVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jlong value) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = PyLong_FromLongLong(value);\r
\r
setPythonVariable(module, pythonName, val);\r
}\r
setPythonVariable(module, pythonName, val);\r
}\r
\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonLongArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jlongArray value) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = getPythonLongList(env, value);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
+}\r
+\r
JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonDoubleVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jdouble value) {\r
PyObject *module = (PyObject*)contextID;\r
\r
setPythonVariable(module, pythonName, val);\r
}\r
\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonFloatArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jfloatArray value) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = getPythonFloatList(env, value);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
+}\r
+\r
JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonDoubleArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jdoubleArray value) {\r
PyObject *module = (PyObject*)contextID;\r
\r
JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonNDArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobject value) {\r
PyObject *module = (PyObject*)contextID;\r
\r
- if (_import_array() < 0) {\r
- throwException(env, RUNTIME_EXCEPTION, "Importing numpy failed");\r
+ if (!hasNumpy) {\r
+ throwPythonException(env, "Importing numpy failed");\r
return;\r
}\r
\r
}\r
}\r
\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonVariantVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobject value, jobject binding) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = getPythonObject(env, value, binding);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
+}\r
+\r
JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring statement) {\r
PyObject *module = (PyObject*)contextID;\r
\r
\r
PyObject *exceptionType = PyErr_Occurred();\r
if (exceptionType != NULL) {\r
- PyObject *exception, *stackTrace;\r
- char *message;\r
- PyErr_Fetch(&exceptionType, &exception, &stackTrace);\r
- message = PyUnicode_AsUTF8(exception);\r
- throwException(env, RUNTIME_EXCEPTION, message);\r
+ PyObject *exception, *traceback;\r
+ PyErr_Fetch(&exceptionType, &exception, &traceback);\r
+\r
+ {\r
+ PyObject *tracebackModule = PyImport_ImportModule("traceback");\r
+ if (tracebackModule != NULL) {\r
+ PyObject *formatExc = PyDict_GetItemString(PyModule_GetDict(tracebackModule), "format_exception");\r
+ if (formatExc != NULL) {\r
+ PyObject *args = PyTuple_Pack(3, exceptionType, exception, traceback);\r
+ PyObject *message = PyObject_CallObject(formatExc, args);\r
+ if (message != NULL) {\r
+ PyObject *emptyStr = PyUnicode_FromString("");\r
+ PyObject *joined = PyUnicode_Join(emptyStr, message);\r
+ char *messageStr = PyUnicode_AsUTF8(joined);\r
+ throwPythonException(env, messageStr);\r
+ Py_DECREF(joined);\r
+ Py_DECREF(emptyStr);\r
+ Py_DECREF(message);\r
+ }\r
+ else {\r
+ throwPythonException(env, "Internal error, no message");\r
+ }\r
+ Py_DECREF(args);\r
+ Py_DECREF(formatExc);\r
+ }\r
+ else {\r
+ throwPythonException(env, "Internal error, no format_exc function");\r
+ }\r
+ Py_DECREF(tracebackModule);\r
+ }\r
+ else {\r
+ throwPythonException(env, "Internal error, no traceback module");\r
+ }\r
+ }\r
}\r
\r
- // Py_XDECREF(globals);\r
-\r
(*env)->ReleaseStringUTFChars(env, statement, utfchars);\r
\r
return result != NULL ? 0 : 1;\r
\r
PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
if (value == NULL) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ throwPythonException(env, "Python variable not found");\r
return 0;\r
}\r
\r
if (!PyUnicode_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not a string");\r
+ throwPythonException(env, "Python variable not a string");\r
return 0;\r
}\r
\r
- return pythonStringAsJavaString(env, value);\r
+ {\r
+ jstring result = pythonStringAsJavaString(env, value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonStringArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
\r
PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
if (value == NULL) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ throwPythonException(env, "Python variable not found");\r
+ return 0;\r
+ }\r
+\r
+ if (!PySequence_Check(value)) {\r
+ throwPythonException(env, "Python variable not a sequence");\r
+ return 0;\r
+ }\r
+\r
+ {\r
+ jobjectArray result = pythonSequenceAsStringArray(env, value);\r
+ return result;\r
+ }\r
+}\r
+\r
+JNIEXPORT jboolean JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
+ if (value == NULL) {\r
+ throwPythonException(env, "Python variable not found");\r
+ return 0;\r
+ }\r
+\r
+ if (!PyBool_Check(value)) {\r
+ throwPythonException(env, "Python variable not a boolean");\r
+ return 0;\r
+ }\r
+\r
+ return value == Py_True;\r
+}\r
+\r
+JNIEXPORT jbooleanArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
+ if (value == NULL) {\r
+ throwPythonException(env, "Python variable not found");\r
return 0;\r
}\r
\r
- if (!PyList_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not a list");\r
+ if (!PySequence_Check(value)) {\r
+ throwPythonException(env, "Python variable not a sequence");\r
return 0;\r
}\r
\r
- return pythonStringListAsJavaArray(env, value);\r
+ {\r
+ jbooleanArray result = pythonSequenceAsBooleanArray(env, value);\r
+ return result;\r
+ }\r
}\r
\r
-JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonIntegerVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
PyObject *module = (PyObject*)contextID;\r
\r
PyObject *pythonName = getPythonString(env, variableName);\r
\r
PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
if (value == NULL) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ throwPythonException(env, "Python variable not found");\r
return 0;\r
}\r
\r
if (!PyLong_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not an integer");\r
+ throwPythonException(env, "Python variable not an integer");\r
return 0;\r
}\r
\r
- return PyLong_AsLong(value);\r
+ {\r
+ jlong result = PyLong_AsLongLong(value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jintArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonIntegerArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
\r
PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
if (value == NULL) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ throwPythonException(env, "Python variable not found");\r
+ return NULL;\r
+ }\r
+\r
+ if (!PySequence_Check(value)) {\r
+ throwPythonException(env, "Python variable not a sequence");\r
+ return NULL;\r
+ }\r
+\r
+ {\r
+ jintArray result = pythonSequenceAsIntegerArray(env, value);\r
+ return result;\r
+ }\r
+}\r
+\r
+JNIEXPORT jlongArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
+ if (value == NULL) {\r
+ throwPythonException(env, "Python variable not found");\r
return NULL;\r
}\r
\r
- if (!PyList_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not a list");\r
+ if (!PySequence_Check(value)) {\r
+ throwPythonException(env, "Python variable not a sequence");\r
return NULL;\r
}\r
\r
- return pythonListAsIntegerArray(env, value);\r
+ {\r
+ jlongArray result = pythonSequenceAsLongArray(env, value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jdouble JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
\r
PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
if (value == NULL) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ throwPythonException(env, "Python variable not found");\r
return 0.0;\r
}\r
\r
if (!PyFloat_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not a float");\r
+ throwPythonException(env, "Python variable not a float");\r
return 0.0;\r
}\r
\r
- return PyFloat_AsDouble(value);\r
+ {\r
+ jdouble result = PyFloat_AsDouble(value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jdoubleArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
\r
PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
if (value == NULL) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ throwPythonException(env, "Python variable not found");\r
return NULL;\r
}\r
\r
- if (!PyList_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not a list");\r
+ if (!PySequence_Check(value)) {\r
+ throwPythonException(env, "Python variable not a sequence");\r
return NULL;\r
}\r
\r
- return pythonListAsDoubleArray(env, value);\r
+ {\r
+ jdoubleArray result = pythonSequenceAsDoubleArray(env, value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonNDArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
PyObject *module = (PyObject*)contextID;\r
\r
- if (_import_array() < 0) {\r
- throwException(env, RUNTIME_EXCEPTION, "Importing numpy failed");\r
+ if (!hasNumpy) {\r
+ throwPythonException(env, "Importing numpy failed");\r
return NULL;\r
}\r
\r
\r
PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
if (value == NULL) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ throwPythonException(env, "Python variable not found");\r
return NULL;\r
}\r
\r
if (!PyArray_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not an ndarray");\r
+ throwPythonException(env, "Python variable not an ndarray");\r
return NULL;\r
}\r
\r
if (PyArray_TYPE((PyArrayObject*)value) != NPY_DOUBLE) {\r
- throwException(env, RUNTIME_EXCEPTION, "Only ndarrays of type double are supported");\r
+ throwPythonException(env, "Only ndarrays of type double are supported");\r
return NULL;\r
}\r
\r
- return pythonArrayAsNDArray(env, (PyArrayObject *)value);\r
+ {\r
+ jobject result = pythonArrayAsNDArray(env, (PyArrayObject *)value);\r
+ return result;\r
+ }\r
+ }\r
+}\r
+\r
+JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariantVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
+ if (value == NULL) {\r
+ throwPythonException(env, "Python variable not found");\r
+ return NULL;\r
}\r
+\r
+ hasNumpy = _import_array() != -1;\r
+\r
+ {\r
+ jobject result = pythonObjectAsObject(env, value);\r
+ return result;\r
+ }\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableTypeImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+ PyObject *dict = PyModule_GetDict(module);\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ if (!PyDict_Contains(dict, pythonName)) {\r
+ return 0;\r
+ }\r
+\r
+ {\r
+ PyObject *value = PyDict_GetItem(dict, pythonName);\r
+\r
+ jint result;\r
+\r
+ if (PyBool_Check(value))\r
+ result = 1;\r
+ else if (PyLong_Check(value))\r
+ result = 2;\r
+ else if (PyFloat_Check(value))\r
+ result = 3;\r
+ else if (PyUnicode_Check(value))\r
+ result = 4;\r
+ else if (PyByteArray_Check(value))\r
+ result = 5;\r
+ else if (PyDict_Check(value))\r
+ result = 6;\r
+ else if (hasNumpy && PyArray_Check(value))\r
+ result = 7;\r
+ else if (PySequence_Check(value))\r
+ result = 8;\r
+ else\r
+ result = -1;\r
+\r
+ return result;\r
+ }\r
+}\r
+\r
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableNamesImpl(JNIEnv *env, jobject thisObj, jlong contextID) {\r
+ PyObject *module = (PyObject*)contextID;\r
+ PyObject *dict = PyModule_GetDict(module);\r
+\r
+ PyObject *keys = PyDict_Keys(dict);\r
+ Py_ssize_t size = PyList_Size(keys);\r
+\r
+ jobjectArray result = (*env)->NewObjectArray(env, (jsize)size, (*env)->FindClass(env, STRING_CLASS), NULL);\r
+\r
+ Py_ssize_t i;\r
+ for (i = 0; i < size; i++) {\r
+ jstring javaName = pythonStringAsJavaString(env, PyList_GetItem(keys, i));\r
+ (*env)->SetObjectArrayElement(env, result, (jint)i, javaName);\r
+ }\r
+\r
+ Py_XDECREF(keys);\r
+\r
+ return result;\r
}\r
\r
BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
case DLL_PROCESS_ATTACH:\r
// attach to process\r
// return FALSE to fail DLL load\r
- Py_Initialize();\r
break;\r
\r
case DLL_PROCESS_DETACH:\r
// detach from process\r
- Py_Finalize();\r
break;\r
\r
case DLL_THREAD_ATTACH:\r