/* arrays_java.i * These typemaps give more natural support for arrays. The typemaps are not efficient * as there is a lot of copying of the array values whenever the array is passed to C/C++ * from Java and visa versa. The Java array is expected to be the same size as the C array. * An exception is thrown if they are not. Example usage: Wrapping: %include "arrays_java.i" %inline %{ short FiddleSticks[3]; %} Use from Java like this: short[] fs = new short[] {10, 11, 12}; example.setFiddleSticks(fs); fs = example.getFiddleSticks(); */ /* Primitive array support is a combination of SWIG macros and functions in order to reduce * code bloat and aid maintainability. The SWIG preprocessor expands the macros into functions * for inclusion in the generated code. */ /* Array support functions declarations macro */ %define JAVA_ARRAYS_DECL(CTYPE, JNITYPE, JAVATYPE, JFUNCNAME) %{ int SWIG_JavaArrayIn##JFUNCNAME (JNIEnv *jenv, JNITYPE **jarr, CTYPE **carr, JNITYPE##Array input); void SWIG_JavaArrayArgout##JFUNCNAME (JNIEnv *jenv, JNITYPE *jarr, CTYPE *carr, JNITYPE##Array input); JNITYPE##Array SWIG_JavaArrayOut##JFUNCNAME (JNIEnv *jenv, CTYPE *result, jsize sz); %} %enddef /* Array support functions macro */ %define JAVA_ARRAYS_IMPL(CTYPE, JNITYPE, JAVATYPE, JFUNCNAME) %{ /* CTYPE[] support */ int SWIG_JavaArrayIn##JFUNCNAME (JNIEnv *jenv, JNITYPE **jarr, CTYPE **carr, JNITYPE##Array input) { int i; jsize sz; if (!input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return 0; } sz = JCALL1(GetArrayLength, jenv, input); *jarr = JCALL2(Get##JAVATYPE##ArrayElements, jenv, input, 0); if (!*jarr) return 0; %} #if __cplusplus %{ *carr = new CTYPE[sz]; %} #else %{ *carr = (CTYPE*) calloc(sz, sizeof(CTYPE)); %} #endif %{ if (!*carr) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return 0; } for (i=0; i<sz; i++) JAVA_TYPEMAP_ARRAY_ELEMENT_ASSIGN(CTYPE) return 1; } void SWIG_JavaArrayArgout##JFUNCNAME (JNIEnv *jenv, JNITYPE *jarr, CTYPE *carr, JNITYPE##Array input) { int i; jsize sz = JCALL1(GetArrayLength, jenv, input); for (i=0; i<sz; i++) jarr[i] = (JNITYPE)carr[i]; JCALL3(Release##JAVATYPE##ArrayElements, jenv, input, jarr, 0); } JNITYPE##Array SWIG_JavaArrayOut##JFUNCNAME (JNIEnv *jenv, CTYPE *result, jsize sz) { JNITYPE *arr; int i; JNITYPE##Array jresult = JCALL1(New##JAVATYPE##Array, jenv, sz); if (!jresult) return NULL; arr = JCALL2(Get##JAVATYPE##ArrayElements, jenv, jresult, 0); if (!arr) return NULL; for (i=0; i<sz; i++) arr[i] = (JNITYPE)result[i]; JCALL3(Release##JAVATYPE##ArrayElements, jenv, jresult, arr, 0); return jresult; } %} %enddef %{ #if defined(SWIG_NOINCLUDE) || defined(SWIG_NOARRAYS) %} #ifdef __cplusplus JAVA_ARRAYS_DECL(bool, jboolean, Boolean, Bool) /* bool[] */ #endif JAVA_ARRAYS_DECL(signed char, jbyte, Byte, Schar) /* signed char[] */ JAVA_ARRAYS_DECL(unsigned char, jshort, Short, Uchar) /* unsigned char[] */ JAVA_ARRAYS_DECL(short, jshort, Short, Short) /* short[] */ JAVA_ARRAYS_DECL(unsigned short, jint, Int, Ushort) /* unsigned short[] */ JAVA_ARRAYS_DECL(int, jint, Int, Int) /* int[] */ JAVA_ARRAYS_DECL(unsigned int, jlong, Long, Uint) /* unsigned int[] */ JAVA_ARRAYS_DECL(long, jint, Int, Long) /* long[] */ JAVA_ARRAYS_DECL(unsigned long, jlong, Long, Ulong) /* unsigned long[] */ JAVA_ARRAYS_DECL(jlong, jlong, Long, Longlong) /* long long[] */ JAVA_ARRAYS_DECL(float, jfloat, Float, Float) /* float[] */ JAVA_ARRAYS_DECL(double, jdouble, Double, Double) /* double[] */ %{ #else %} #ifdef __cplusplus /* Bool array element assignment different to other types to keep Visual C++ quiet */ #define JAVA_TYPEMAP_ARRAY_ELEMENT_ASSIGN(CTYPE) (*carr)[i] = ((*jarr)[i] != 0); JAVA_ARRAYS_IMPL(bool, jboolean, Boolean, Bool) /* bool[] */ #undef JAVA_TYPEMAP_ARRAY_ELEMENT_ASSIGN #endif #define JAVA_TYPEMAP_ARRAY_ELEMENT_ASSIGN(CTYPE) (*carr)[i] = (CTYPE)(*jarr)[i]; JAVA_ARRAYS_IMPL(signed char, jbyte, Byte, Schar) /* signed char[] */ JAVA_ARRAYS_IMPL(unsigned char, jshort, Short, Uchar) /* unsigned char[] */ JAVA_ARRAYS_IMPL(short, jshort, Short, Short) /* short[] */ JAVA_ARRAYS_IMPL(unsigned short, jint, Int, Ushort) /* unsigned short[] */ JAVA_ARRAYS_IMPL(int, jint, Int, Int) /* int[] */ JAVA_ARRAYS_IMPL(unsigned int, jlong, Long, Uint) /* unsigned int[] */ JAVA_ARRAYS_IMPL(long, jint, Int, Long) /* long[] */ JAVA_ARRAYS_IMPL(unsigned long, jlong, Long, Ulong) /* unsigned long[] */ JAVA_ARRAYS_IMPL(jlong, jlong, Long, Longlong) /* long long[] */ JAVA_ARRAYS_IMPL(float, jfloat, Float, Float) /* float[] */ JAVA_ARRAYS_IMPL(double, jdouble, Double, Double) /* double[] */ %{ #endif %} /* The rest of this file has the array typemaps */ /* Arrays of primitive types. * These typemaps are applied merely by including this file. */ %typemap(jni) bool[ANY] "jbooleanArray" %typemap(jni) signed char[ANY] "jbyteArray" %typemap(jni) unsigned char[ANY] "jshortArray" %typemap(jni) short[ANY] "jshortArray" %typemap(jni) unsigned short[ANY] "jintArray" %typemap(jni) int[ANY] "jintArray" %typemap(jni) unsigned int[ANY] "jlongArray" %typemap(jni) long[ANY] "jintArray" %typemap(jni) unsigned long[ANY] "jlongArray" %typemap(jni) long long[ANY] "jlongArray" /*%typemap(jni) unsigned long long[ANY] "jobjectArray"*/ %typemap(jni) float[ANY] "jfloatArray" %typemap(jni) double[ANY] "jdoubleArray" %typemap(jtype) bool[ANY] "boolean[]" %typemap(jtype) signed char[ANY] "byte[]" %typemap(jtype) unsigned char[ANY] "short[]" %typemap(jtype) short[ANY] "short[]" %typemap(jtype) unsigned short[ANY] "int[]" %typemap(jtype) int[ANY] "int[]" %typemap(jtype) unsigned int[ANY] "long[]" %typemap(jtype) long[ANY] "int[]" %typemap(jtype) unsigned long[ANY] "long[]" %typemap(jtype) long long[ANY] "long[]" /*%typemap(jtype) unsigned long long[ANY] "java.math.BigInteger[]"*/ %typemap(jtype) float[ANY] "float[]" %typemap(jtype) double[ANY] "double[]" %typemap(jstype) bool[ANY] "boolean[]" %typemap(jstype) signed char[ANY] "byte[]" %typemap(jstype) unsigned char[ANY] "short[]" %typemap(jstype) short[ANY] "short[]" %typemap(jstype) unsigned short[ANY] "int[]" %typemap(jstype) int[ANY] "int[]" %typemap(jstype) unsigned int[ANY] "long[]" %typemap(jstype) long[ANY] "int[]" %typemap(jstype) unsigned long[ANY] "long[]" %typemap(jstype) long long[ANY] "long[]" /*%typemap(jstype) unsigned long long[ANY] "java.math.BigInteger[]"*/ %typemap(jstype) float[ANY] "float[]" %typemap(jstype) double[ANY] "double[]" %typemap(javadirectorin) bool[ANY], signed char[ANY], unsigned char[ANY], short[ANY], unsigned short[ANY], int[ANY], unsigned int[ANY], long[ANY], unsigned long[ANY], long long[ANY], /* unsigned long long[ANY], */ float[ANY], double[ANY] "$jniinput" %typemap(javadirectorout) bool[ANY], signed char[ANY], unsigned char[ANY], short[ANY], unsigned short[ANY], int[ANY], unsigned int[ANY], long[ANY], unsigned long[ANY], long long[ANY], /* unsigned long long[ANY], */ float[ANY], double[ANY] "$javacall" /* Arrays of primitive types use the following macro. The array typemaps use support functions. */ %define JAVA_ARRAYS_TYPEMAPS(CTYPE, JNITYPE, JFUNCNAME, JNIDESC) %typemap(in) CTYPE[] (JNITYPE *jarr) %{ if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, &$1, $input)) return $null; %} %typemap(in) CTYPE[ANY] (JNITYPE *jarr) %{ if ($input && JCALL1(GetArrayLength, jenv, $input) != $1_size) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "incorrect array size"); return $null; } if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, &$1, $input)) return $null; %} %typemap(argout) CTYPE[ANY] %{ SWIG_JavaArrayArgout##JFUNCNAME(jenv, jarr$argnum, $1, $input); %} %typemap(directorin,descriptor=JNIDESC) CTYPE[ANY] %{$input = SWIG_JavaArrayOut##JFUNCNAME(jenv, $1, $1_dim0); %} %typemap(out) CTYPE[ANY] %{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, $1, $1_dim0); %} %typemap(freearg) CTYPE[ANY] #if __cplusplus %{ delete [] $1; %} #else %{ free($1); %} #endif %typemap(director_in) CTYPE[ANY] %{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, $1, $1_dim0); %} %typemap(director_out) CTYPE[] (JNITYPE *jarr) %{ if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, &$1, $input)) return $null; %} %enddef JAVA_ARRAYS_TYPEMAPS(bool, jboolean, Bool, "[Z") /* bool[ANY] */ JAVA_ARRAYS_TYPEMAPS(signed char, jbyte, Schar, "[B") /* signed char[ANY] */ JAVA_ARRAYS_TYPEMAPS(unsigned char, jshort, Uchar, "[S") /* unsigned char[ANY] */ JAVA_ARRAYS_TYPEMAPS(short, jshort, Short, "[S") /* short[ANY] */ JAVA_ARRAYS_TYPEMAPS(unsigned short, jint, Ushort, "[I") /* unsigned short[ANY] */ JAVA_ARRAYS_TYPEMAPS(int, jint, Int, "[I") /* int[ANY] */ JAVA_ARRAYS_TYPEMAPS(unsigned int, jlong, Uint, "[J") /* unsigned int[ANY] */ JAVA_ARRAYS_TYPEMAPS(long, jint, Long, "[I") /* long[ANY] */ JAVA_ARRAYS_TYPEMAPS(unsigned long, jlong, Ulong, "[J") /* unsigned long[ANY] */ JAVA_ARRAYS_TYPEMAPS(long long, jlong, Longlong, "[J") /* long long[ANY] */ JAVA_ARRAYS_TYPEMAPS(float, jfloat, Float, "[F") /* float[ANY] */ JAVA_ARRAYS_TYPEMAPS(double, jdouble, Double, "[D") /* double[ANY] */ %typecheck(SWIG_TYPECHECK_BOOL_ARRAY) /* Java boolean[] */ bool[ANY] "" %typecheck(SWIG_TYPECHECK_INT8_ARRAY) /* Java byte[] */ signed char[ANY] "" %typecheck(SWIG_TYPECHECK_INT16_ARRAY) /* Java short[] */ unsigned char[ANY], short[ANY] "" %typecheck(SWIG_TYPECHECK_INT32_ARRAY) /* Java int[] */ unsigned short[ANY], int[ANY], long[ANY] "" %typecheck(SWIG_TYPECHECK_INT64_ARRAY) /* Java long[] */ unsigned int[ANY], unsigned long[ANY], long long[ANY] "" %typecheck(SWIG_TYPECHECK_INT128_ARRAY) /* Java BigInteger[] */ unsigned long long[ANY] "" %typecheck(SWIG_TYPECHECK_FLOAT_ARRAY) /* Java float[] */ float[ANY] "" %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY) /* Java double[] */ double[ANY] "" %typemap(javain) bool[ANY], signed char[ANY], unsigned char[ANY], short[ANY], unsigned short[ANY], int[ANY], unsigned int[ANY], long[ANY], unsigned long[ANY], long long[ANY], /* unsigned long long[ANY], */ float[ANY], double[ANY] "$javainput" %typemap(javaout) bool[ANY], signed char[ANY], unsigned char[ANY], short[ANY], unsigned short[ANY], int[ANY], unsigned int[ANY], long[ANY], unsigned long[ANY], long long[ANY], /* unsigned long long[ANY], */ float[ANY], double[ANY] { return $jnicall; } /* Arrays of proxy classes. The typemaps in this macro make it possible to treat an array of * class/struct/unions as an array of Java classes. * Use the following macro to use these typemaps for an array of class/struct/unions called name: * JAVA_ARRAYSOFCLASSES(name) */ %define JAVA_ARRAYSOFCLASSES(ARRAYSOFCLASSES) %typemap(jni) ARRAYSOFCLASSES[ANY] "jlongArray" %typemap(jtype) ARRAYSOFCLASSES[ANY] "long[]" %typemap(jstype) ARRAYSOFCLASSES[ANY] "$javaclassname[]" %typemap(javain) ARRAYSOFCLASSES[ANY] "$javaclassname.cArrayUnwrap($javainput)" %typemap(javaout) ARRAYSOFCLASSES[ANY] { return $javaclassname.cArrayWrap($jnicall, $owner); } %typemap(in) ARRAYSOFCLASSES[] (jlong *jarr, jsize sz) { int i; if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return $null; } sz = JCALL1(GetArrayLength, jenv, $input); jarr = JCALL2(GetLongArrayElements, jenv, $input, 0); if (!jarr) { return $null; } #if __cplusplus $1 = new $*1_ltype[sz]; #else $1 = ($1_ltype) calloc(sz, sizeof($*1_ltype)); #endif if (!$1) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return $null; } for (i=0; i<sz; i++) { $1[i] = **($&1_ltype)&jarr[i]; } } %typemap(in) ARRAYSOFCLASSES[ANY] (jlong *jarr, jsize sz) { int i; if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); return $null; } sz = JCALL1(GetArrayLength, jenv, $input); if (sz != $1_size) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "incorrect array size"); return $null; } jarr = JCALL2(GetLongArrayElements, jenv, $input, 0); if (!jarr) { return $null; } #if __cplusplus $1 = new $*1_ltype[sz]; #else $1 = ($1_ltype) calloc(sz, sizeof($*1_ltype)); #endif if (!$1) { SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); return $null; } for (i=0; i<sz; i++) { $1[i] = **($&1_ltype)&jarr[i]; } } %typemap(argout) ARRAYSOFCLASSES[ANY] { int i; for (i=0; i<sz$argnum; i++) { jarr$argnum[i] = 0; *($&1_ltype)&jarr$argnum[i] = &$1[i]; } JCALL3(ReleaseLongArrayElements, jenv, $input, jarr$argnum, 0); } %typemap(out) ARRAYSOFCLASSES[ANY] { jlong *arr; int i; $result = JCALL1(NewLongArray, jenv, $1_dim0); if (!$result) { return $null; } arr = JCALL2(GetLongArrayElements, jenv, $result, 0); if (!arr) { return $null; } for (i=0; i<$1_dim0; i++) { arr[i] = 0; *($&1_ltype)&arr[i] = &$1[i]; } JCALL3(ReleaseLongArrayElements, jenv, $result, arr, 0); } %typemap(freearg) ARRAYSOFCLASSES[ANY] #if __cplusplus %{ delete [] $1; %} #else %{ free($1); %} #endif /* Add some code to the proxy class of the array type for converting between type used in * JNI class (long[]) and type used in proxy class ( ARRAYSOFCLASSES[] ) */ %typemap(javacode) ARRAYSOFCLASSES %{ protected static long[] cArrayUnwrap($javaclassname[] arrayWrapper) { long[] cArray = new long[arrayWrapper.length]; for (int i=0; i<arrayWrapper.length; i++) cArray[i] = $javaclassname.getCPtr(arrayWrapper[i]); return cArray; } protected static $javaclassname[] cArrayWrap(long[] cArray, boolean cMemoryOwn) { $javaclassname[] arrayWrapper = new $javaclassname[cArray.length]; for (int i=0; i<cArray.length; i++) arrayWrapper[i] = new $javaclassname(cArray[i], cMemoryOwn); return arrayWrapper; } %} %enddef /* JAVA_ARRAYSOFCLASSES */ /* Arrays of enums. * Use the following to use these typemaps for an array of enums called name: * %apply ARRAYSOFENUMS[ANY] { name[ANY] }; */ %typemap(jni) ARRAYSOFENUMS[ANY] "jintArray" %typemap(jtype) ARRAYSOFENUMS[ANY] "int[]" %typemap(jstype) ARRAYSOFENUMS[ANY] "int[]" %typemap(javain) ARRAYSOFENUMS[ANY] "$javainput" %typemap(javaout) ARRAYSOFENUMS[ANY] { return $jnicall; } %typemap(in) ARRAYSOFENUMS[] (jint *jarr) %{ if (!SWIG_JavaArrayInInt(jenv, &jarr, (int**)&$1, $input)) return $null; %} %typemap(in) ARRAYSOFENUMS[ANY] (jint *jarr) { if ($input && JCALL1(GetArrayLength, jenv, $input) != $1_size) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "incorrect array size"); return $null; } if (!SWIG_JavaArrayInInt(jenv, &jarr, (int**)&$1, $input)) return $null; } %typemap(argout) ARRAYSOFENUMS[ANY] %{ SWIG_JavaArrayArgoutInt(jenv, jarr$argnum, (int*)$1, $input); %} %typemap(out) ARRAYSOFENUMS[ANY] %{$result = SWIG_JavaArrayOutInt(jenv, (int*)$1, $1_dim0); %} %typemap(freearg) ARRAYSOFENUMS[ANY] #ifdef __cplusplus %{ delete [] $1; %} #else %{ free($1); %} #endif