1/* ----------------------------------------------------------------------------- 2 * See the LICENSE file for information on copyright, usage and redistribution 3 * of SWIG, and the README file for authors - http://www.swig.org/release.html. 4 * 5 * arrays_java.i 6 * 7 * These typemaps give more natural support for arrays. The typemaps are not efficient 8 * as there is a lot of copying of the array values whenever the array is passed to C/C++ 9 * from Java and vice versa. The Java array is expected to be the same size as the C array. 10 * An exception is thrown if they are not. 11 * 12 * Example usage: 13 * Wrapping: 14 * 15 * %include <arrays_java.i> 16 * %inline %{ 17 * short FiddleSticks[3]; 18 * %} 19 * 20 * Use from Java like this: 21 * 22 * short[] fs = new short[] {10, 11, 12}; 23 * example.setFiddleSticks(fs); 24 * fs = example.getFiddleSticks(); 25 * ----------------------------------------------------------------------------- */ 26 27/* Primitive array support is a combination of SWIG macros and functions in order to reduce 28 * code bloat and aid maintainability. The SWIG preprocessor expands the macros into functions 29 * for inclusion in the generated code. */ 30 31/* Array support functions declarations macro */ 32%define JAVA_ARRAYS_DECL(CTYPE, JNITYPE, JAVATYPE, JFUNCNAME) 33%{ 34int SWIG_JavaArrayIn##JFUNCNAME (JNIEnv *jenv, JNITYPE **jarr, CTYPE **carr, JNITYPE##Array input); 35void SWIG_JavaArrayArgout##JFUNCNAME (JNIEnv *jenv, JNITYPE *jarr, CTYPE *carr, JNITYPE##Array input); 36JNITYPE##Array SWIG_JavaArrayOut##JFUNCNAME (JNIEnv *jenv, CTYPE *result, jsize sz); 37%} 38%enddef 39 40/* Array support functions macro */ 41%define JAVA_ARRAYS_IMPL(CTYPE, JNITYPE, JAVATYPE, JFUNCNAME) 42%{ 43/* CTYPE[] support */ 44int SWIG_JavaArrayIn##JFUNCNAME (JNIEnv *jenv, JNITYPE **jarr, CTYPE **carr, JNITYPE##Array input) { 45 int i; 46 jsize sz; 47 if (!input) { 48 SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); 49 return 0; 50 } 51 sz = JCALL1(GetArrayLength, jenv, input); 52 *jarr = JCALL2(Get##JAVATYPE##ArrayElements, jenv, input, 0); 53 if (!*jarr) 54 return 0; %} 55#ifdef __cplusplus 56%{ *carr = new CTYPE[sz]; %} 57#else 58%{ *carr = (CTYPE*) calloc(sz, sizeof(CTYPE)); %} 59#endif 60%{ if (!*carr) { 61 SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); 62 return 0; 63 } 64 for (i=0; i<sz; i++) 65 JAVA_TYPEMAP_ARRAY_ELEMENT_ASSIGN(CTYPE) 66 return 1; 67} 68 69void SWIG_JavaArrayArgout##JFUNCNAME (JNIEnv *jenv, JNITYPE *jarr, CTYPE *carr, JNITYPE##Array input) { 70 int i; 71 jsize sz = JCALL1(GetArrayLength, jenv, input); 72 for (i=0; i<sz; i++) 73 jarr[i] = (JNITYPE)carr[i]; 74 JCALL3(Release##JAVATYPE##ArrayElements, jenv, input, jarr, 0); 75} 76 77JNITYPE##Array SWIG_JavaArrayOut##JFUNCNAME (JNIEnv *jenv, CTYPE *result, jsize sz) { 78 JNITYPE *arr; 79 int i; 80 JNITYPE##Array jresult = JCALL1(New##JAVATYPE##Array, jenv, sz); 81 if (!jresult) 82 return NULL; 83 arr = JCALL2(Get##JAVATYPE##ArrayElements, jenv, jresult, 0); 84 if (!arr) 85 return NULL; 86 for (i=0; i<sz; i++) 87 arr[i] = (JNITYPE)result[i]; 88 JCALL3(Release##JAVATYPE##ArrayElements, jenv, jresult, arr, 0); 89 return jresult; 90} 91%} 92%enddef 93 94%{ 95#if defined(SWIG_NOINCLUDE) || defined(SWIG_NOARRAYS) 96%} 97 98#ifdef __cplusplus 99JAVA_ARRAYS_DECL(bool, jboolean, Boolean, Bool) /* bool[] */ 100#endif 101 102JAVA_ARRAYS_DECL(signed char, jbyte, Byte, Schar) /* signed char[] */ 103JAVA_ARRAYS_DECL(unsigned char, jshort, Short, Uchar) /* unsigned char[] */ 104JAVA_ARRAYS_DECL(short, jshort, Short, Short) /* short[] */ 105JAVA_ARRAYS_DECL(unsigned short, jint, Int, Ushort) /* unsigned short[] */ 106JAVA_ARRAYS_DECL(int, jint, Int, Int) /* int[] */ 107JAVA_ARRAYS_DECL(unsigned int, jlong, Long, Uint) /* unsigned int[] */ 108JAVA_ARRAYS_DECL(long, jint, Int, Long) /* long[] */ 109JAVA_ARRAYS_DECL(unsigned long, jlong, Long, Ulong) /* unsigned long[] */ 110JAVA_ARRAYS_DECL(jlong, jlong, Long, Longlong) /* long long[] */ 111JAVA_ARRAYS_DECL(float, jfloat, Float, Float) /* float[] */ 112JAVA_ARRAYS_DECL(double, jdouble, Double, Double) /* double[] */ 113 114%{ 115#else 116%} 117 118#ifdef __cplusplus 119/* Bool array element assignment different to other types to keep Visual C++ quiet */ 120#define JAVA_TYPEMAP_ARRAY_ELEMENT_ASSIGN(CTYPE) (*carr)[i] = ((*jarr)[i] != 0); 121JAVA_ARRAYS_IMPL(bool, jboolean, Boolean, Bool) /* bool[] */ 122#undef JAVA_TYPEMAP_ARRAY_ELEMENT_ASSIGN 123#endif 124 125#define JAVA_TYPEMAP_ARRAY_ELEMENT_ASSIGN(CTYPE) (*carr)[i] = (CTYPE)(*jarr)[i]; 126JAVA_ARRAYS_IMPL(signed char, jbyte, Byte, Schar) /* signed char[] */ 127JAVA_ARRAYS_IMPL(unsigned char, jshort, Short, Uchar) /* unsigned char[] */ 128JAVA_ARRAYS_IMPL(short, jshort, Short, Short) /* short[] */ 129JAVA_ARRAYS_IMPL(unsigned short, jint, Int, Ushort) /* unsigned short[] */ 130JAVA_ARRAYS_IMPL(int, jint, Int, Int) /* int[] */ 131JAVA_ARRAYS_IMPL(unsigned int, jlong, Long, Uint) /* unsigned int[] */ 132JAVA_ARRAYS_IMPL(long, jint, Int, Long) /* long[] */ 133JAVA_ARRAYS_IMPL(unsigned long, jlong, Long, Ulong) /* unsigned long[] */ 134JAVA_ARRAYS_IMPL(jlong, jlong, Long, Longlong) /* long long[] */ 135JAVA_ARRAYS_IMPL(float, jfloat, Float, Float) /* float[] */ 136JAVA_ARRAYS_IMPL(double, jdouble, Double, Double) /* double[] */ 137 138%{ 139#endif 140%} 141 142 143/* The rest of this file has the array typemaps */ 144 145/* Arrays of primitive types use the following macro. The array typemaps use support functions. */ 146%define JAVA_ARRAYS_TYPEMAPS(CTYPE, JTYPE, JNITYPE, JFUNCNAME, JNIDESC) 147 148%typemap(jni) CTYPE[ANY], CTYPE[] %{JNITYPE##Array%} 149%typemap(jtype) CTYPE[ANY], CTYPE[] %{JTYPE[]%} 150%typemap(jstype) CTYPE[ANY], CTYPE[] %{JTYPE[]%} 151 152%typemap(in) CTYPE[] (JNITYPE *jarr) 153%{ if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, &$1, $input)) return $null; %} 154%typemap(in) CTYPE[ANY] (JNITYPE *jarr) 155%{ if ($input && JCALL1(GetArrayLength, jenv, $input) != $1_size) { 156 SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "incorrect array size"); 157 return $null; 158 } 159 if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, &$1, $input)) return $null; %} 160%typemap(argout) CTYPE[ANY], CTYPE[] 161%{ SWIG_JavaArrayArgout##JFUNCNAME(jenv, jarr$argnum, $1, $input); %} 162%typemap(out) CTYPE[ANY] 163%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, $1, $1_dim0); %} 164%typemap(out) CTYPE[] 165%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, $1, FillMeInAsSizeCannotBeDeterminedAutomatically); %} 166%typemap(freearg) CTYPE[ANY], CTYPE[] 167#ifdef __cplusplus 168%{ delete [] $1; %} 169#else 170%{ free($1); %} 171#endif 172 173%typemap(javain) CTYPE[ANY], CTYPE[] "$javainput" 174%typemap(javaout) CTYPE[ANY], CTYPE[] { 175 return $jnicall; 176 } 177 178%enddef 179 180JAVA_ARRAYS_TYPEMAPS(bool, boolean, jboolean, Bool, "[Z") /* bool[ANY] */ 181JAVA_ARRAYS_TYPEMAPS(signed char, byte, jbyte, Schar, "[B") /* signed char[ANY] */ 182JAVA_ARRAYS_TYPEMAPS(unsigned char, short, jshort, Uchar, "[S") /* unsigned char[ANY] */ 183JAVA_ARRAYS_TYPEMAPS(short, short, jshort, Short, "[S") /* short[ANY] */ 184JAVA_ARRAYS_TYPEMAPS(unsigned short, int, jint, Ushort, "[I") /* unsigned short[ANY] */ 185JAVA_ARRAYS_TYPEMAPS(int, int, jint, Int, "[I") /* int[ANY] */ 186JAVA_ARRAYS_TYPEMAPS(unsigned int, long, jlong, Uint, "[J") /* unsigned int[ANY] */ 187JAVA_ARRAYS_TYPEMAPS(long, int, jint, Long, "[I") /* long[ANY] */ 188JAVA_ARRAYS_TYPEMAPS(unsigned long, long, jlong, Ulong, "[J") /* unsigned long[ANY] */ 189JAVA_ARRAYS_TYPEMAPS(long long, long, jlong, Longlong, "[J") /* long long[ANY] */ 190JAVA_ARRAYS_TYPEMAPS(float, float, jfloat, Float, "[F") /* float[ANY] */ 191JAVA_ARRAYS_TYPEMAPS(double, double, jdouble, Double, "[D") /* double[ANY] */ 192 193 194%typecheck(SWIG_TYPECHECK_BOOL_ARRAY) /* Java boolean[] */ 195 bool[ANY], bool[] 196 "" 197 198%typecheck(SWIG_TYPECHECK_INT8_ARRAY) /* Java byte[] */ 199 signed char[ANY], signed char[] 200 "" 201 202%typecheck(SWIG_TYPECHECK_INT16_ARRAY) /* Java short[] */ 203 unsigned char[ANY], unsigned char[], 204 short[ANY], short[] 205 "" 206 207%typecheck(SWIG_TYPECHECK_INT32_ARRAY) /* Java int[] */ 208 unsigned short[ANY], unsigned short[], 209 int[ANY], int[], 210 long[ANY], long[] 211 "" 212 213%typecheck(SWIG_TYPECHECK_INT64_ARRAY) /* Java long[] */ 214 unsigned int[ANY], unsigned int[], 215 unsigned long[ANY], unsigned long[], 216 long long[ANY], long long[] 217 "" 218 219%typecheck(SWIG_TYPECHECK_INT128_ARRAY) /* Java BigInteger[] */ 220 unsigned long long[ANY], unsigned long long[] 221 "" 222 223%typecheck(SWIG_TYPECHECK_FLOAT_ARRAY) /* Java float[] */ 224 float[ANY], float[] 225 "" 226 227%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY) /* Java double[] */ 228 double[ANY], double[] 229 "" 230 231 232/* Arrays of proxy classes. The typemaps in this macro make it possible to treat an array of 233 * class/struct/unions as an array of Java classes. 234 * Use the following macro to use these typemaps for an array of class/struct/unions called name: 235 * JAVA_ARRAYSOFCLASSES(name) 236 * Note that multiple copies of the class/struct is made when using the array as a parameter input. */ 237%define JAVA_ARRAYSOFCLASSES(ARRAYSOFCLASSES) 238 239%typemap(jni) ARRAYSOFCLASSES[ANY], ARRAYSOFCLASSES[] "jlongArray" 240%typemap(jtype) ARRAYSOFCLASSES[ANY], ARRAYSOFCLASSES[] "long[]" 241%typemap(jstype) ARRAYSOFCLASSES[ANY], ARRAYSOFCLASSES[] "$javaclassname[]" 242 243%typemap(javain) ARRAYSOFCLASSES[ANY], ARRAYSOFCLASSES[] "$javaclassname.cArrayUnwrap($javainput)" 244%typemap(javaout) ARRAYSOFCLASSES[ANY], ARRAYSOFCLASSES[] { 245 return $javaclassname.cArrayWrap($jnicall, $owner); 246 } 247 248%typemap(in) ARRAYSOFCLASSES[] (jlong *jarr, jsize sz) 249{ 250 int i; 251 if (!$input) { 252 SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); 253 return $null; 254 } 255 sz = JCALL1(GetArrayLength, jenv, $input); 256 jarr = JCALL2(GetLongArrayElements, jenv, $input, 0); 257 if (!jarr) { 258 return $null; 259 } 260#ifdef __cplusplus 261 $1 = new $*1_ltype[sz]; 262#else 263 $1 = ($1_ltype) calloc(sz, sizeof($*1_ltype)); 264#endif 265 if (!$1) { 266 SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); 267 return $null; 268 } 269 for (i=0; i<sz; i++) { 270 $1[i] = **($&1_ltype)&jarr[i]; 271 } 272} 273 274%typemap(in) ARRAYSOFCLASSES[ANY] (jlong *jarr, jsize sz) 275{ 276 int i; 277 if (!$input) { 278 SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array"); 279 return $null; 280 } 281 sz = JCALL1(GetArrayLength, jenv, $input); 282 if (sz != $1_size) { 283 SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "incorrect array size"); 284 return $null; 285 } 286 jarr = JCALL2(GetLongArrayElements, jenv, $input, 0); 287 if (!jarr) { 288 return $null; 289 } 290#ifdef __cplusplus 291 $1 = new $*1_ltype[sz]; 292#else 293 $1 = ($1_ltype) calloc(sz, sizeof($*1_ltype)); 294#endif 295 if (!$1) { 296 SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "array memory allocation failed"); 297 return $null; 298 } 299 for (i=0; i<sz; i++) { 300 $1[i] = **($&1_ltype)&jarr[i]; 301 } 302} 303 304%typemap(argout) ARRAYSOFCLASSES[ANY], ARRAYSOFCLASSES[] 305{ 306 int i; 307 for (i=0; i<sz$argnum; i++) { 308 **($&1_ltype)&jarr$argnum[i] = $1[i]; 309 } 310 JCALL3(ReleaseLongArrayElements, jenv, $input, jarr$argnum, 0); 311} 312 313%typemap(out) ARRAYSOFCLASSES[ANY] 314{ 315 jlong *arr; 316 int i; 317 $result = JCALL1(NewLongArray, jenv, $1_dim0); 318 if (!$result) { 319 return $null; 320 } 321 arr = JCALL2(GetLongArrayElements, jenv, $result, 0); 322 if (!arr) { 323 return $null; 324 } 325 for (i=0; i<$1_dim0; i++) { 326 arr[i] = 0; 327 *($&1_ltype)&arr[i] = &$1[i]; 328 } 329 JCALL3(ReleaseLongArrayElements, jenv, $result, arr, 0); 330} 331 332%typemap(freearg) ARRAYSOFCLASSES[ANY], ARRAYSOFCLASSES[] 333#ifdef __cplusplus 334%{ delete [] $1; %} 335#else 336%{ free($1); %} 337#endif 338 339/* Add some code to the proxy class of the array type for converting between type used in 340 * JNI class (long[]) and type used in proxy class ( ARRAYSOFCLASSES[] ) */ 341%typemap(javacode) ARRAYSOFCLASSES %{ 342 protected static long[] cArrayUnwrap($javaclassname[] arrayWrapper) { 343 long[] cArray = new long[arrayWrapper.length]; 344 for (int i=0; i<arrayWrapper.length; i++) 345 cArray[i] = $javaclassname.getCPtr(arrayWrapper[i]); 346 return cArray; 347 } 348 349 protected static $javaclassname[] cArrayWrap(long[] cArray, boolean cMemoryOwn) { 350 $javaclassname[] arrayWrapper = new $javaclassname[cArray.length]; 351 for (int i=0; i<cArray.length; i++) 352 arrayWrapper[i] = new $javaclassname(cArray[i], cMemoryOwn); 353 return arrayWrapper; 354 } 355%} 356 357%enddef /* JAVA_ARRAYSOFCLASSES */ 358 359 360/* Arrays of enums. 361 * Use the following to use these typemaps for an array of enums called name: 362 * %apply ARRAYSOFENUMS[ANY] { name[ANY] }; */ 363%typemap(jni) ARRAYSOFENUMS[ANY], ARRAYSOFENUMS[] "jintArray" 364%typemap(jtype) ARRAYSOFENUMS[ANY], ARRAYSOFENUMS[] "int[]" 365%typemap(jstype) ARRAYSOFENUMS[ANY], ARRAYSOFENUMS[] "int[]" 366 367%typemap(javain) ARRAYSOFENUMS[ANY], ARRAYSOFENUMS[] "$javainput" 368%typemap(javaout) ARRAYSOFENUMS[ANY], ARRAYSOFENUMS[] { 369 return $jnicall; 370 } 371 372%typemap(in) ARRAYSOFENUMS[] (jint *jarr) 373%{ if (!SWIG_JavaArrayInInt(jenv, &jarr, (int **)&$1, $input)) return $null; %} 374%typemap(in) ARRAYSOFENUMS[ANY] (jint *jarr) { 375 if ($input && JCALL1(GetArrayLength, jenv, $input) != $1_size) { 376 SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "incorrect array size"); 377 return $null; 378 } 379 if (!SWIG_JavaArrayInInt(jenv, &jarr, (int **)&$1, $input)) return $null; 380} 381%typemap(argout) ARRAYSOFENUMS[ANY], ARRAYSOFENUMS[] 382%{ SWIG_JavaArrayArgoutInt(jenv, jarr$argnum, (int *)$1, $input); %} 383%typemap(out) ARRAYSOFENUMS[ANY] 384%{$result = SWIG_JavaArrayOutInt(jenv, (int *)$1, $1_dim0); %} 385%typemap(freearg) ARRAYSOFENUMS[ANY], ARRAYSOFENUMS[] 386#ifdef __cplusplus 387%{ delete [] $1; %} 388#else 389%{ free($1); %} 390#endif 391 392