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