PageRenderTime 20ms CodeModel.GetById 16ms app.highlight 2ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1-3-25/SWIG/Lib/java/typemaps.i

#
Swig | 443 lines | 241 code | 45 blank | 157 comment | 0 complexity | 72352c84dfee25fc40800ac9d0f542b9 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1//
  2// SWIG Typemap library
  3// William Fulton
  4// 4 January 2002
  5//
  6// Java implementation
  7//
  8
  9// ------------------------------------------------------------------------
 10// Pointer and reference handling
 11//
 12// These mappings provide support for input/output arguments and common
 13// uses for C/C++ pointers and C++ references.
 14// ------------------------------------------------------------------------
 15
 16// INPUT typemaps.
 17// These remap a C pointer or C++ reference to be an "INPUT" value which is passed by value
 18// instead of reference.
 19
 20/*
 21The following methods can be applied to turn a pointer or reference into a simple
 22"input" value.  That is, instead of passing a pointer or reference to an object,
 23you would use a real value instead.
 24
 25        bool               *INPUT, bool               &INPUT
 26        signed char        *INPUT, signed char        &INPUT
 27        unsigned char      *INPUT, unsigned char      &INPUT
 28        short              *INPUT, short              &INPUT
 29        unsigned short     *INPUT, unsigned short     &INPUT
 30        int                *INPUT, int                &INPUT
 31        unsigned int       *INPUT, unsigned int       &INPUT
 32        long               *INPUT, long               &INPUT
 33        unsigned long      *INPUT, unsigned long      &INPUT
 34        long long          *INPUT, long long          &INPUT
 35        unsigned long long *INPUT, unsigned long long &INPUT
 36        float              *INPUT, float              &INPUT
 37        double             *INPUT, double             &INPUT
 38         
 39To use these, suppose you had a C function like this :
 40
 41        double fadd(double *a, double *b) {
 42               return *a+*b;
 43        }
 44
 45You could wrap it with SWIG as follows :
 46        
 47        %include "typemaps.i"
 48        double fadd(double *INPUT, double *INPUT);
 49
 50or you can use the %apply directive :
 51
 52        %include "typemaps.i"
 53        %apply double *INPUT { double *a, double *b };
 54        double fadd(double *a, double *b);
 55
 56In Java you could then use it like this:
 57        double answer = modulename.fadd(10.0, 20.0);
 58
 59There are no char *INPUT typemaps, however you can apply the signed char * typemaps instead:
 60        %include "typemaps.i"
 61        %apply signed char *INPUT {char *input};
 62        void f(char *input);
 63*/
 64
 65%define INPUT_TYPEMAP(TYPE, JNITYPE, JTYPE, JNIDESC)
 66%typemap(jni) TYPE *INPUT, TYPE &INPUT "JNITYPE"
 67%typemap(jtype) TYPE *INPUT, TYPE &INPUT "JTYPE"
 68%typemap(jstype) TYPE *INPUT, TYPE &INPUT "JTYPE"
 69%typemap(javain) TYPE *INPUT, TYPE &INPUT "$javainput"
 70%typemap(javadirectorin) TYPE *INPUT, TYPE &INPUT "$jniinput"
 71%typemap(javadirectorout) TYPE *INPUT, TYPE &INPUT "$javacall"
 72
 73%typemap(in) TYPE *INPUT, TYPE &INPUT
 74%{ $1 = ($1_ltype)&$input; %}
 75
 76%typemap(directorout) TYPE *INPUT, TYPE &INPUT
 77%{ $1 = ($1_ltype)&$input; %}
 78
 79%typemap(directorin,descriptor=JNIDESC) TYPE &INPUT
 80%{ *(($&1_ltype) $input) = (JNITYPE *) &$1; %}
 81
 82%typemap(directorin,descriptor=JNIDESC) TYPE *INPUT
 83%{ *(($&1_ltype) $input) = (JNITYPE *) $1; %}
 84
 85%typemap(freearg) TYPE *INPUT, TYPE &INPUT ""
 86
 87%typemap(typecheck) TYPE *INPUT = TYPE;
 88%typemap(typecheck) TYPE &INPUT = TYPE;
 89%enddef
 90
 91INPUT_TYPEMAP(bool, jboolean, boolean, "Z");
 92INPUT_TYPEMAP(signed char, jbyte, byte, "B");
 93INPUT_TYPEMAP(unsigned char, jshort, short, "S");
 94INPUT_TYPEMAP(short, jshort, short, "S");
 95INPUT_TYPEMAP(unsigned short, jint, int, "I");
 96INPUT_TYPEMAP(int, jint, int, "I");
 97INPUT_TYPEMAP(unsigned int, jlong, long, "J");
 98INPUT_TYPEMAP(long, jint, int, "I");
 99INPUT_TYPEMAP(unsigned long, jlong, long, "J");
100INPUT_TYPEMAP(long long, jlong, long, "J");
101INPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, "Ljava/math/BigInteger;");
102INPUT_TYPEMAP(float, jfloat, float, "F");
103INPUT_TYPEMAP(double, jdouble, double, "D");
104
105#undef INPUT_TYPEMAP
106
107/* Convert from BigInteger using the toByteArray member function */
108/* Overrides the typemap in the INPUT_TYPEMAP macro */
109%typemap(in) unsigned long long *INPUT($*1_ltype temp), unsigned long long &INPUT($*1_ltype temp) {
110  jclass clazz;
111  jmethodID mid;
112  jbyteArray ba;
113  jbyte* bae;
114  jsize sz;
115  int i;
116
117  if (!$input) {
118    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null");
119    return $null;
120  }
121  clazz = JCALL1(GetObjectClass, jenv, $input);
122  mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B");
123  ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid);
124  bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
125  sz = JCALL1(GetArrayLength, jenv, ba);
126  temp = 0;
127  if (bae[0] == 0) {
128    for(i=sz-1; i>0; i-- ) {
129      temp = (temp << 8) | (unsigned char)bae[sz-i];
130    }
131  } 
132  else {
133    for(i=sz; i>=0; i-- ) {
134      temp = (temp << 8) | (unsigned char)bae[sz-1-i];
135    }
136  }
137  JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
138  $1 = &temp;
139}
140
141// OUTPUT typemaps.   These typemaps are used for parameters that
142// are output only.   An array replaces the c pointer or reference parameter. 
143// The output value is returned in this array passed in. 
144
145/*
146The following methods can be applied to turn a pointer or reference into an "output"
147value.  When calling a function, no input value would be given for
148a parameter, but an output value would be returned.  This works by a 
149Java array being passed as a parameter where a c pointer or reference is required. 
150As with any Java function, the array is passed by reference so that 
151any modifications to the array will be picked up in the calling function.
152Note that the array passed in MUST have at least one element, but as the 
153c function does not require any input, the value can be set to anything.
154
155        bool               *OUTPUT, bool               &OUTPUT
156        signed char        *OUTPUT, signed char        &OUTPUT
157        unsigned char      *OUTPUT, unsigned char      &OUTPUT
158        short              *OUTPUT, short              &OUTPUT
159        unsigned short     *OUTPUT, unsigned short     &OUTPUT
160        int                *OUTPUT, int                &OUTPUT
161        unsigned int       *OUTPUT, unsigned int       &OUTPUT
162        long               *OUTPUT, long               &OUTPUT
163        unsigned long      *OUTPUT, unsigned long      &OUTPUT
164        long long          *OUTPUT, long long          &OUTPUT
165        unsigned long long *OUTPUT, unsigned long long &OUTPUT
166        float              *OUTPUT, float              &OUTPUT
167        double             *OUTPUT, double             &OUTPUT
168         
169For example, suppose you were trying to wrap the modf() function in the
170C math library which splits x into integral and fractional parts (and
171returns the integer part in one of its parameters):
172
173        double modf(double x, double *ip);
174
175You could wrap it with SWIG as follows :
176
177        %include "typemaps.i"
178        double modf(double x, double *OUTPUT);
179
180or you can use the %apply directive :
181
182        %include "typemaps.i"
183        %apply double *OUTPUT { double *ip };
184        double modf(double x, double *ip);
185
186The Java output of the function would be the function return value and the 
187value in the single element array. In Java you would use it like this:
188
189    double[] ptr = {0.0};
190    double fraction = modulename.modf(5.0,ptr);
191
192There are no char *OUTPUT typemaps, however you can apply the signed char * typemaps instead:
193        %include "typemaps.i"
194        %apply signed char *OUTPUT {char *output};
195        void f(char *output);
196*/
197
198/* Java BigInteger[] */
199%typecheck(SWIG_TYPECHECK_INT128_ARRAY) SWIGBIGINTEGERARRAY ""
200
201%define OUTPUT_TYPEMAP(TYPE, JNITYPE, JTYPE, JAVATYPE, JNIDESC, TYPECHECKTYPE)
202%typemap(jni) TYPE *OUTPUT, TYPE &OUTPUT %{JNITYPE##Array%}
203%typemap(jtype) TYPE *OUTPUT, TYPE &OUTPUT "JTYPE[]"
204%typemap(jstype) TYPE *OUTPUT, TYPE &OUTPUT "JTYPE[]"
205%typemap(javain) TYPE *OUTPUT, TYPE &OUTPUT "$javainput"
206%typemap(javadirectorin) TYPE *OUTPUT, TYPE &OUTPUT "$jniinput"
207%typemap(javadirectorout) TYPE *OUTPUT, TYPE &OUTPUT "$javacall"
208
209%typemap(in) TYPE *OUTPUT($*1_ltype temp), TYPE &OUTPUT($*1_ltype temp)
210{
211  if (!$input) {
212    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
213    return $null;
214  }
215  if (JCALL1(GetArrayLength, jenv, $input) == 0) {
216    SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
217    return $null;
218  }
219  $1 = &temp; 
220}
221
222%typemap(directorout) TYPE *OUTPUT, TYPE &OUTPUT {
223#error "Need to provide OUTPUT directorout typemap"
224}
225
226%typemap(directorin,descriptor=JNIDESC) TYPE &OUTPUT
227%{ *(($&1_ltype) $input = &$1; %}
228
229%typemap(directorin,descriptor=JNIDESC) TYPE *OUTPUT
230%{
231#error "Need to provide OUT directorin typemap, TYPE array length is unknown"
232%}
233
234%typemap(freearg) TYPE *OUTPUT, TYPE &OUTPUT ""
235
236%typemap(argout) TYPE *OUTPUT, TYPE &OUTPUT 
237{
238  JNITYPE jvalue = (JNITYPE)temp$argnum;
239  JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &jvalue);
240}
241
242%typemap(typecheck) TYPE *INOUT = TYPECHECKTYPE;
243%typemap(typecheck) TYPE &INOUT = TYPECHECKTYPE;
244%enddef
245
246OUTPUT_TYPEMAP(bool, jboolean, boolean, Boolean, "[Ljava/lang/Boolean;", jbooleanArray);
247OUTPUT_TYPEMAP(signed char, jbyte, byte, Byte, "[Ljava/lang/Byte;", jbyteArray);               
248OUTPUT_TYPEMAP(unsigned char, jshort, short, Short, "[Ljava/lang/Short;", jshortArray);              
249OUTPUT_TYPEMAP(short, jshort, short, Short, "[Ljava/lang/Short;", jshortArray);              
250OUTPUT_TYPEMAP(unsigned short, jint, int, Int, "[Ljava/lang/Integer;", jintArray);                
251OUTPUT_TYPEMAP(int, jint, int, Int, "[Ljava/lang/Integer;", jintArray);                
252OUTPUT_TYPEMAP(unsigned int, jlong, long, Long, "[Ljava/lang/Long;", jlongArray);               
253OUTPUT_TYPEMAP(long, jint, int, Int, "[Ljava/lang/Integer;", jintArray);                
254OUTPUT_TYPEMAP(unsigned long, jlong, long, Long, "[Ljava/lang/Long;", jlongArray);               
255OUTPUT_TYPEMAP(long long, jlong, long, Long, "[Ljava/lang/Long;", jlongArray);               
256OUTPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, NOTUSED, "[Ljava/lang/BigInteger;", SWIGBIGINTEGERARRAY);
257OUTPUT_TYPEMAP(float, jfloat, float, Float, "[Ljava/lang/Float;", jfloatArray);              
258OUTPUT_TYPEMAP(double, jdouble, double, Double, "[Ljava/lang/Double;", jdoubleArray);             
259
260#undef OUTPUT_TYPEMAP
261
262/* Convert to BigInteger - byte array holds number in 2's complement big endian format */
263/* Use first element in BigInteger array for output */
264/* Overrides the typemap in the OUTPUT_TYPEMAP macro */
265%typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT { 
266  jbyteArray ba = JCALL1(NewByteArray, jenv, 9);
267  jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
268  jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger");
269  jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "<init>", "([B)V");
270  jobject bigint;
271  int i;
272
273  bae[0] = 0;
274  for(i=1; i<9; i++ ) {
275    bae[i] = (jbyte)(temp$argnum>>8*(8-i));
276  }
277
278  JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
279  bigint = JCALL3(NewObject, jenv, clazz, mid, ba);
280  JCALL3(SetObjectArrayElement, jenv, $input, 0, bigint);
281}
282
283// INOUT
284// Mappings for an argument that is both an input and output
285// parameter
286
287/*
288The following methods can be applied to make a function parameter both
289an input and output value.  This combines the behavior of both the
290"INPUT" and "OUTPUT" methods described earlier.  Output values are
291returned as an element in a Java array.
292
293        bool               *INOUT, bool               &INOUT
294        signed char        *INOUT, signed char        &INOUT
295        unsigned char      *INOUT, unsigned char      &INOUT
296        short              *INOUT, short              &INOUT
297        unsigned short     *INOUT, unsigned short     &INOUT
298        int                *INOUT, int                &INOUT
299        unsigned int       *INOUT, unsigned int       &INOUT
300        long               *INOUT, long               &INOUT
301        unsigned long      *INOUT, unsigned long      &INOUT
302        long long          *INOUT, long long          &INOUT
303        unsigned long long *INOUT, unsigned long long &INOUT
304        float              *INOUT, float              &INOUT
305        double             *INOUT, double             &INOUT
306         
307For example, suppose you were trying to wrap the following function :
308
309        void neg(double *x) {
310             *x = -(*x);
311        }
312
313You could wrap it with SWIG as follows :
314
315        %include "typemaps.i"
316        void neg(double *INOUT);
317
318or you can use the %apply directive :
319
320        %include "typemaps.i"
321        %apply double *INOUT { double *x };
322        void neg(double *x);
323
324This works similarly to C in that the mapping directly modifies the
325input value - the input must be an array with a minimum of one element. 
326The element in the array is the input and the output is the element in 
327the array.
328
329       double x[] = {5.0};
330       neg(x);
331
332The implementation of the OUTPUT and INOUT typemaps is different to other 
333languages in that other languages will return the output value as part 
334of the function return value. This difference is due to Java being a typed language.
335
336There are no char *INOUT typemaps, however you can apply the signed char * typemaps instead:
337        %include "typemaps.i"
338        %apply signed char *INOUT {char *inout};
339        void f(char *inout);
340*/
341
342%define INOUT_TYPEMAP(TYPE, JNITYPE, JTYPE, JAVATYPE, JNIDESC, TYPECHECKTYPE)
343%typemap(jni) TYPE *INOUT, TYPE &INOUT %{JNITYPE##Array%}
344%typemap(jtype) TYPE *INOUT, TYPE &INOUT "JTYPE[]"
345%typemap(jstype) TYPE *INOUT, TYPE &INOUT "JTYPE[]"
346%typemap(javain) TYPE *INOUT, TYPE &INOUT "$javainput"
347%typemap(javadirectorin) TYPE *INOUT, TYPE &INOUT "$jniinput"
348%typemap(javadirectorout) TYPE *INOUT, TYPE &INOUT "$javacall"
349
350%typemap(in) TYPE *INOUT, TYPE &INOUT {
351  if (!$input) {
352    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
353    return $null;
354  }
355  if (JCALL1(GetArrayLength, jenv, $input) == 0) {
356    SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
357    return $null;
358  }
359  $1 = ($1_ltype) JCALL2(Get##JAVATYPE##ArrayElements, jenv, $input, 0); 
360}
361
362%typemap(directorout) TYPE *INOUT, TYPE &INOUT {
363#error "Need to provide INOUT directorout typemap"
364}
365
366%typemap(directorin,descriptor=JNIDESC) TYPE &INOUT
367%{ *(($&1_ltype)&$input) = &$1; %}
368
369%typemap(directorin,descriptor=JNIDESC) TYPE *INOUT, TYPE &INOUT
370{
371#error "Need to provide INOUT directorin typemap, TYPE array length is unknown"
372}
373
374%typemap(freearg) TYPE *INOUT, TYPE &INOUT ""
375
376%typemap(argout) TYPE *INOUT, TYPE &INOUT
377{ JCALL3(Release##JAVATYPE##ArrayElements, jenv, $input, (JNITYPE *)$1, 0); }
378
379%typemap(typecheck) TYPE *INOUT = TYPECHECKTYPE;
380%typemap(typecheck) TYPE &INOUT = TYPECHECKTYPE;
381%enddef
382
383INOUT_TYPEMAP(bool, jboolean, boolean, Boolean, "[Ljava/lang/Boolean;", jbooleanArray); 
384INOUT_TYPEMAP(signed char, jbyte, byte, Byte, "[Ljava/lang/Byte;", jbyteArray); 
385INOUT_TYPEMAP(unsigned char, jshort, short, Short, "[Ljava/lang/Short;", jshortArray);     
386INOUT_TYPEMAP(short, jshort, short, Short, "[Ljava/lang/Short;", jshortArray);
387INOUT_TYPEMAP(unsigned short, jint, int, Int, "[Ljava/lang/Integer;", jintArray); 
388INOUT_TYPEMAP(int, jint, int, Int, "[Ljava/lang/Integer;", jintArray);
389INOUT_TYPEMAP(unsigned int, jlong, long, Long, "[Ljava/lang/Long;", jlongArray); 
390INOUT_TYPEMAP(long, jint, int, Int, "[Ljava/lang/Integer;", jintArray);
391INOUT_TYPEMAP(unsigned long, jlong, long, Long, "[Ljava/lang/Long;", jlongArray); 
392INOUT_TYPEMAP(long long, jlong, long, Long, "[Ljava/lang/Long;", jlongArray);
393INOUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, NOTUSED, "[Ljava.math.BigInteger;", SWIGBIGINTEGERARRAY);
394INOUT_TYPEMAP(float, jfloat, float, Float, "[Ljava/lang/Float;", jfloatArray);
395INOUT_TYPEMAP(double, jdouble, double, Double, "[Ljava/lang/Double;", jdoubleArray); 
396
397#undef INOUT_TYPEMAP
398
399/* Override the typemap in the INOUT_TYPEMAP macro */
400%typemap(in) unsigned long long *INOUT ($*1_ltype temp), unsigned long long &INOUT ($*1_ltype temp) { 
401  jobject bigint;
402  jclass clazz;
403  jmethodID mid;
404  jbyteArray ba;
405  jbyte* bae;
406  jsize sz;
407  int i;
408
409  if (!$input) {
410    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
411    return $null;
412  }
413  if (JCALL1(GetArrayLength, jenv, $input) == 0) {
414    SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
415    return $null;
416  }
417  bigint = JCALL2(GetObjectArrayElement, jenv, $input, 0);
418  if (!bigint) {
419    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array element null");
420    return $null;
421  }
422  clazz = JCALL1(GetObjectClass, jenv, bigint);
423  mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B");
424  ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, bigint, mid);
425  bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
426  sz = JCALL1(GetArrayLength, jenv, ba);
427  temp = 0;
428  if (bae[0] == 0) {
429    for(i=sz-1; i>0; i-- ) {
430      temp = (temp << 8) | (unsigned char)bae[sz-i];
431    }
432  } 
433  else {
434    for(i=sz; i>=0; i-- ) {
435      temp = (temp << 8) | (unsigned char)bae[sz-1-i];
436    }
437  }
438  JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
439  $1 = &temp;
440}
441
442%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT;
443%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT;