1 /******************************************************************************
2  * $Id: typemaps_csharp.i 1d35ff4614d952ace3dc4436133d5b9e65be47f1 2020-09-01 22:28:17 +0200 Björn Harrtell $
3  *
4  * Name:     typemaps_csharp.i
5  * Project:  GDAL CSharp Interface
6  * Purpose:  Typemaps for C# bindings.
7  * Author:   Tamas Szekeres, szekerest@gmail.com
8  *
9  ******************************************************************************
10  * Copyright (c) 2007, Tamas Szekeres
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  *****************************************************************************/
30 
31 
32 %include "typemaps.i"
33 
34 /* CSHARP TYPEMAPS */
35 
36 %typemap(csdispose) SWIGTYPE %{
~$csclassname()37   ~$csclassname() {
38     Dispose();
39   }
40 %}
41 
42 %typemap(csdispose_derived) SWIGTYPE %{
~$csclassname()43   ~$csclassname() {
44     Dispose();
45   }
46 %}
47 
48 %typemap(csdisposing, methodname="Dispose", methodmodifiers="public", parameters="") SWIGTYPE {
lock(this)49     lock(this) {
50       if (swigCPtr.Handle != global::System.IntPtr.Zero) {
51         if (swigCMemOwn) {
52           swigCMemOwn = false;
53           $imcall;
54         }
55         swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
56       }
57       global::System.GC.SuppressFinalize(this);
58     }
59   }
60 
61 %typemap(csdisposing_derived, methodname="Dispose", methodmodifiers="public", parameters="") SWIGTYPE {
lock(this)62     lock(this) {
63       if (swigCPtr.Handle != global::System.IntPtr.Zero) {
64         if (swigCMemOwn) {
65           swigCMemOwn = false;
66           $imcall;
67         }
68         swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
69       }
70       global::System.GC.SuppressFinalize(this);
71       base.Dispose();
72     }
73   }
74 
75 %apply (int) {VSI_RETVAL};
76 
77 %fragment("OGRErrMessages","header") %{
78 static char const *
OGRErrMessages(int rc)79 OGRErrMessages( int rc ) {
80   switch( rc ) {
81   case 0:
82     return "OGR Error %d: None";
83   case 1:
84     return "OGR Error %d: Not enough data";
85   case 2:
86     return "OGR Error %d: Unsupported geometry type";
87   case 3:
88     return "OGR Error %d: Unsupported operation";
89   case 4:
90     return "OGR Error %d: Corrupt data";
91   case 5:
92     return "OGR Error %d: General Error";
93   case 6:
94     return "OGR Error %d: Unsupported SRS";
95   default:
96     return "OGR Error %d: Unknown";
97   }
98 }
99 %}
100 
101 %typemap(out,fragment="OGRErrMessages",canthrow=1) OGRErr
102 {
103   /* %typemap(out,fragment="OGRErrMessages",canthrow=1) OGRErr */
104   $result = result;
105 }
106 %typemap(ret) OGRErr
107 {
108   /* %typemap(ret) OGRErr */
109 
110 }
111 
112 %typemap(in) (tostring argin) (string str)
113 {
114   /* %typemap(in) (tostring argin) */
115   $1 = ($1_ltype)$input;
116 }
117 
118 /* GDAL Typemaps */
119 
120 %typemap(out) IF_FALSE_RETURN_NONE %{ $result = $1; %}
121 %typemap(ctype) IF_FALSE_RETURN_NONE "int"
122 %typemap(imtype) IF_FALSE_RETURN_NONE "int"
123 %typemap(cstype) IF_FALSE_RETURN_NONE "int"
124 %typemap(csout, excode=SWIGEXCODE) IF_FALSE_RETURN_NONE {
125     int res = $imcall;$excode
126     return res;
127 }
128 
129 %typemap(out) IF_ERROR_RETURN_NONE %{ $result = $1; %}
130 
131 %define OPTIONAL_POD(CTYPE, CSTYPE)
132 %typemap(imtype) (CTYPE *optional_##CTYPE) "IntPtr"
133 %typemap(cstype) (CTYPE *optional_##CTYPE) "ref CSTYPE"
134 %typemap(csin) (CTYPE *optional_##CTYPE) "(IntPtr)$csinput"
135 
136 %typemap(in) (CTYPE *optional_##CTYPE)
137 {
138   /* %typemap(in) (type *optional_##CTYPE) */
139   $1 = ($1_type)$input;
140 }
141 %enddef
142 
143 OPTIONAL_POD(int, int);
144 
145 
146 /***************************************************
147  * Typemaps for  (retStringAndCPLFree*)
148  ***************************************************/
149 
150 %typemap(out) (retStringAndCPLFree*)
151 %{
152     /* %typemap(out) (retStringAndCPLFree*) */
153     if($1)
154     {
155         $result = SWIG_csharp_string_callback((const char *)$1);
156         CPLFree($1);
157     }
158     else
159     {
160         $result = NULL;
161     }
162 %}
163 
164 /*
165  * Typemap for GIntBig (int64)
166  */
167 
168 %typemap(ctype, out="GIntBig") GIntBig  %{GIntBig%}
169 %typemap(imtype, out="long") GIntBig "long"
170 %typemap(cstype) GIntBig %{long%}
171 %typemap(in) GIntBig %{ $1 = $input; %}
172 %typemap(out) GIntBig %{ $result = $1; %}
173 %typemap(csin) GIntBig "$csinput"
174 %typemap(csout, excode=SWIGEXCODE) GIntBig {
175     long res = $imcall;$excode
176     return res;
177 }
178 
179 
180 /******************************************************************************
181  * Marshaler for NULL terminated string arrays                                *
182  *****************************************************************************/
183 
184 %pragma(csharp) imclasscode=%{
185   public class StringListMarshal : IDisposable {
186     public readonly IntPtr[] _ar;
StringListMarshal(string[]ar)187     public StringListMarshal(string[] ar) {
188       _ar = new IntPtr[ar.Length+1];
189       for (int cx = 0; cx < ar.Length; cx++) {
190 	      _ar[cx] = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(ar[cx]);
191       }
192       _ar[ar.Length] = IntPtr.Zero;
193     }
Dispose()194     public virtual void Dispose() {
195 	  for (int cx = 0; cx < _ar.Length-1; cx++) {
196           System.Runtime.InteropServices.Marshal.FreeHGlobal(_ar[cx]);
197       }
198       GC.SuppressFinalize(this);
199     }
200   }
201 %}
202 
203 /*
204  * Typemap for char** options
205  */
206 
207 /* FIXME: all those typemaps are not equivalent... out(char **CSL) should free */
208 /* the list with CSLDestroy() for example */
209 
210 %typemap(imtype, out="IntPtr") char **options, char **dict, char **CSL "IntPtr[]"
211 %typemap(cstype) char **options, char **dict, char **CSL %{string[]%}
212 %typemap(in) char **options, char **dict, char **CSL %{ $1 = ($1_ltype)$input; %}
213 %typemap(out) char **options, char **dict, char **CSL %{ $result = $1; %}
214 %typemap(csin) char **options, char **dict, char **CSL "($csinput != null)? new $modulePINVOKE.StringListMarshal($csinput)._ar : null"
215 %typemap(csout, excode=SWIGEXCODE) char**options, char **dict {
216         /* %typemap(csout) char**options */
217         IntPtr cPtr = $imcall;
218         IntPtr objPtr;
219         int count = 0;
220         if (cPtr != IntPtr.Zero) {
221             while (Marshal.ReadIntPtr(cPtr, count*IntPtr.Size) != IntPtr.Zero)
222                 ++count;
223         }
224         string[] ret = new string[count];
225         if (count > 0) {
226 	        for(int cx = 0; cx < count; cx++) {
227                 objPtr = System.Runtime.InteropServices.Marshal.ReadIntPtr(cPtr, cx * System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)));
228                 ret[cx]= (objPtr == IntPtr.Zero) ? null : System.Runtime.InteropServices.Marshal.PtrToStringAnsi(objPtr);
229             }
230         }
231         $excode
232         return ret;
233 }
234 
235 %typemap(csout, excode=SWIGEXCODE) char** CSL {
236         /* %typemap(csout) char** CSL */
237         IntPtr cPtr = $imcall;
238         IntPtr objPtr;
239         int count = 0;
240         if (cPtr != IntPtr.Zero) {
241             while (Marshal.ReadIntPtr(cPtr, count*IntPtr.Size) != IntPtr.Zero)
242                 ++count;
243         }
244         string[] ret = new string[count];
245         if (count > 0) {
246 	        for(int cx = 0; cx < count; cx++) {
247                 objPtr = System.Runtime.InteropServices.Marshal.ReadIntPtr(cPtr, cx * System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)));
248                 ret[cx]= (objPtr == IntPtr.Zero) ? null : System.Runtime.InteropServices.Marshal.PtrToStringAnsi(objPtr);
249             }
250         }
251         if (cPtr != IntPtr.Zero)
252             $modulePINVOKE.StringListDestroy(cPtr);
253         $excode
254         return ret;
255 }
256 
257 %typemap(imtype, out="IntPtr") int *intList "int[]"
258 %typemap(cstype) int *intList %{int[]%}
259 %typemap(in) int *intList %{ $1 = ($1_ltype)$input; %}
260 %typemap(out) int *intList %{ $result = $1; %}
261 %typemap(csout, excode=SWIGEXCODE) int *intList {
262         /* %typemap(csout) int *intList */
263         IntPtr cPtr = $imcall;
264         int[] ret = new int[count];
265         if (count > 0) {
266 	        System.Runtime.InteropServices.Marshal.Copy(cPtr, ret, 0, count);
267         }
268         $excode
269         return ret;
270 }
271 
272 %typemap(imtype, out="IntPtr") double *doubleList "double[]"
273 %typemap(cstype) double *doubleList %{double[]%}
274 %typemap(in) double *doubleList %{ $1 = ($1_ltype)$input; %}
275 %typemap(out) double *doubleList %{ $result = $1; %}
276 %typemap(csout, excode=SWIGEXCODE) double *doubleList {
277         /* %typemap(csout) int *intList */
278         IntPtr cPtr = $imcall;
279         double[] ret = new double[count];
280         if (count > 0) {
281 	        System.Runtime.InteropServices.Marshal.Copy(cPtr, ret, 0, count);
282         }
283         $excode
284         return ret;
285 }
286 
287 /*
288  * Typemap for char **argout.
289  */
290 %typemap(imtype) (char **argout), (char **username), (char **usrname), (char **type) "out string"
291 %typemap(cstype) (char **argout), (char **username), (char **usrname), (char **type) "out string"
292 %typemap(csin) (char** argout), (char **username), (char **usrname), (char **type) "out $csinput"
293 
294 %typemap(in) (char **argout), (char **username), (char **usrname), (char **type)
295 {
296   /* %typemap(in) (char **argout) */
297 	$1 = ($1_ltype)$input;
298 }
299 %typemap(argout) (char **argout)
300 {
301   /* %typemap(argout) (char **argout) */
302   char* temp_string;
303   temp_string = SWIG_csharp_string_callback(*$1);
304   if (*$1)
305 		CPLFree(*$1);
306   *$1 = temp_string;
307 }
308 %typemap(argout) (char **staticstring), (char **username), (char **usrname), (char **type)
309 {
310   /* %typemap(argout) (char **staticstring) */
311   *$1 = SWIG_csharp_string_callback(*$1);
312 }
313 
314 /*
315  * Typemap for char **ignorechange.
316  */
317 
318 %typemap(imtype) (char **ignorechange) "ref string"
319 %typemap(cstype) (char **ignorechange) "ref string"
320 %typemap(csin) (char** ignorechange) "ref $csinput"
321 
322 %typemap(in, noblock="1") (char **ignorechange)
323 {
324   /* %typemap(in) (char **ignorechange) */
325     $*1_type savearg = *(($1_type)$input);
326 	$1 = ($1_ltype)$input;
327 }
328 %typemap(argout, noblock="1") (char **ignorechange)
329 {
330   /* %typemap(argout) (char **ignorechange) */
331   if ((*$1 - savearg) > 0)
332      memmove(savearg, *$1, strlen(*$1)+1);
333   *$1 = savearg;
334 }
335 
336 /*
337  * Typemap for double argout[ANY].
338  */
339 %typemap(imtype) (double argout[ANY]) "double[]"
340 %typemap(cstype) (double argout[ANY]) "double[]"
341 %typemap(csin) (double argout[ANY]) "$csinput"
342 
343 %typemap(in) (double argout[ANY])
344 {
345   /* %typemap(in) (double argout[ANY]) */
346   $1 = ($1_ltype)$input;
347 }
348 
349 %typemap(in,numinputs=0) ( double *argout[ANY]) (double *argout[$dim0])
350 {
351   /* %typemap(in,numinputs=0) (double *argout[ANY]) */
352   $1 = (double**)&argout;
353 }
354 %typemap(argout) ( double *argout[ANY])
355 {
356   /* %typemap(argout) (double *argout[ANY]) */
357 
358 }
359 %typemap(freearg) (double *argout[ANY])
360 {
361   /* %typemap(freearg) (double *argout[ANY]) */
362 
363 }
364 
365 %apply double argout[ANY] {double *inout}
366 
367 /*
368  * Typemap for double argin[ANY].
369  */
370 
371 %typemap(imtype) (double argin[ANY])  "double[]"
372 %typemap(cstype) (double argin[ANY]) "double[]"
373 %typemap(csin) (double argin[ANY])  "$csinput"
374 
375 %typemap(in) (double argin[ANY])
376 {
377   /* %typemap(in) (double argin[ANY]) */
378   $1 = ($1_ltype)$input;
379 }
380 
381 /*
382  * Typemap for int argin[ANY].
383  */
384 
385 %typemap(imtype) (int argin[ANY])  "int[]"
386 %typemap(cstype) (int argin[ANY]) "int[]"
387 %typemap(csin) (int argin[ANY])  "$csinput"
388 
389 %typemap(in) (int argin[ANY])
390 {
391   /* %typemap(in) (int argin[ANY]) */
392   $1 = ($1_ltype)$input;
393 }
394 
395 /*
396  * Typemap for double inout[ANY].
397  */
398 
399 %typemap(imtype) (double inout[ANY])  "double[]"
400 %typemap(cstype) (double inout[ANY]) "double[]"
401 %typemap(csin) (double inout[ANY])  "$csinput"
402 
403 %typemap(in) (double inout[ANY])
404 {
405   /* %typemap(in) (double inout[ANY]) */
406   $1 = ($1_ltype)$input;
407 }
408 
409 %apply (double inout[ANY]) {double *pList};
410 
411 /*
412  * Typemap for int inout[ANY].
413  */
414 
415 %typemap(imtype) (int inout[ANY])  "int[]"
416 %typemap(cstype) (int inout[ANY]) "int[]"
417 %typemap(csin) (int inout[ANY])  "$csinput"
418 
419 %typemap(in) (int inout[ANY])
420 {
421   /* %typemap(in) (int inout[ANY]) */
422   $1 = ($1_ltype)$input;
423 }
424 
425 %apply (int inout[ANY]) {int *pList};
426 
427 /*
428  * Helper to marshal utf8 strings.
429  */
430 
431 %pragma(csharp) modulecode=%{
StringToUtf8Bytes(string str)432   internal static byte[] StringToUtf8Bytes(string str)
433   {
434     if (str == null)
435       return null;
436 
437     int bytecount = System.Text.Encoding.UTF8.GetMaxByteCount(str.Length);
438     byte[] bytes = new byte[bytecount + 1];
439     System.Text.Encoding.UTF8.GetBytes(str, 0, str.Length, bytes, 0);
440     return bytes;
441   }
442 
Utf8BytesToString(IntPtr pNativeData)443   internal unsafe static string Utf8BytesToString(IntPtr pNativeData)
444   {
445     if (pNativeData == IntPtr.Zero)
446         return null;
447 
448     byte* pStringUtf8 = (byte*) pNativeData;
449     int len = 0;
450     while (pStringUtf8[len] != 0) len++;
451     return System.Text.Encoding.UTF8.GetString(pStringUtf8, len);
452   }
453 %}
454 
455 /*
456  * Typemap for const char *utf8_path.
457  */
458 %typemap(csin) (const char *utf8_path)  "$module.StringToUtf8Bytes($csinput)"
459 %typemap(imtype, out="IntPtr") (const char *utf8_path) "byte[]"
460 %typemap(out) (const char *utf8_path) %{ $result = $1; %}
461 %typemap(csout, excode=SWIGEXCODE) (const char *utf8_path) {
462         /* %typemap(csout) (const char *utf8_path) */
463         IntPtr cPtr = $imcall;
464         string ret = $module.Utf8BytesToString(cPtr);
465         $excode
466         return ret;
467 }
468 
469 %apply ( const char *utf8_path ) { const char* GetFieldAsString };
470 
471 /*
472  * Typemap for double *defaultval.
473  */
474 
475 %typemap(imtype) (double *defaultval)  "ref double"
476 %typemap(cstype) (double *defaultval) "ref double"
477 %typemap(csin) (double *defaultval)  "ref $csinput"
478 
479 %typemap(in) (double *defaultval)
480 {
481   /* %typemap(in) (double inout[ANY]) */
482   $1 = ($1_ltype)$input;
483 }
484 
485 /*
486  * Typemap for out double.
487  */
488 
489 %typemap(imtype) (double *OUTPUT), (double *val), (double *min), (double *max), (double *mean), (double *stddev) "out double"
490 %typemap(cstype) (double *OUTPUT), (double *val), (double *min), (double *max), (double *mean), (double *stddev) "out double"
491 %typemap(csin) (double *OUTPUT), (double *val), (double *min), (double *max), (double *mean), (double *stddev) "out $csinput"
492 
493 %typemap(in) (double *OUTPUT), (double *val), (double *min), (double *max), (double *mean), (double *stddev)
494 {
495   /* %typemap(in) (double *val) */
496   $1 = ($1_ltype)$input;
497 }
498 
499 /*
500  * Typemap for 'out int'.
501  */
502 
503 %typemap(imtype) (int *hasval)  "out int"
504 %typemap(cstype) (int *hasval) "out int"
505 %typemap(csin) (int *hasval)  "out $csinput"
506 
507 %typemap(in) (int *hasval)
508 {
509   /* %typemap(in) (int *hasval) */
510   $1 = ($1_ltype)$input;
511 }
512 
513 %apply (int *hasval) {int *nLen};
514 %apply (int *hasval) {int *pnBytes};
515 
516 /*
517  * Typemap for int **array_argout.
518  */
519 
520 %typemap(imtype) (int **array_argout)  "out int[]"
521 %typemap(cstype) (int **array_argout) "out int[]"
522 %typemap(csin) (int **array_argout)  "out $csinput"
523 
524 %typemap(in) (int **array_argout)
525 {
526   /* %typemap(in) (int **array_argout) */
527   $1 = ($1_ltype)$input;
528 }
529 
530 %apply (int **array_argout) {int **pList};
531 
532 /*
533  * Typemap for double **array_argout.
534  */
535 
536 %typemap(imtype) (double **array_argout)  "out double[]"
537 %typemap(cstype) (double **array_argout) "out double[]"
538 %typemap(csin) (double **array_argout)  "out $csinput"
539 
540 %typemap(in) (double **array_argout)
541 {
542   /* %typemap(in) (double **array_argout) */
543   $1 = ($1_ltype)$input;
544 }
545 
546 %apply (double **array_argout) {double **pList};
547 
548 /******************************************************************************
549  * GDAL raster R/W support                                                    *
550  *****************************************************************************/
551 
552 %typemap(imtype, out="IntPtr") void *buffer_ptr "IntPtr"
553 %typemap(cstype) void *buffer_ptr %{IntPtr%}
554 %typemap(in) void *buffer_ptr %{ $1 = ($1_ltype)$input; %}
555 %typemap(out) void *buffer_ptr %{ $result = $1; %}
556 %typemap(csin) void *buffer_ptr "$csinput"
557 %typemap(csout, excode=SWIGEXCODE) void *buffer_ptr {
558       IntPtr ret = $imcall;$excode
559       return ret;
560 }
561 %typemap(csvarout, excode=SWIGEXCODE2) (void *buffer_ptr)   %{
562     get {
563       IntPtr ret = $imcall;$excode
564       return ret;
565     } %}
566 
567 %apply (void *buffer_ptr) {GByte*, VSILFILE*};
568 
569 %csmethodmodifiers StringListDestroy "internal";
570 %inline %{
StringListDestroy(void * buffer_ptr)571     void StringListDestroy(void *buffer_ptr) {
572        CSLDestroy((char**)buffer_ptr);
573     }
574 %}
575 
576 /******************************************************************************
577  * ErrorHandler callback support                                              *
578  *****************************************************************************/
579 %pragma(csharp) modulecode="public delegate void GDALErrorHandlerDelegate(int eclass, int code, IntPtr msg);"
580 %typemap(imtype) (CPLErrorHandler)  "$module.GDALErrorHandlerDelegate"
581 %typemap(cstype) (CPLErrorHandler) "$module.GDALErrorHandlerDelegate"
582 %typemap(csin) (CPLErrorHandler)  "$csinput"
583 %typemap(in) (CPLErrorHandler) %{ $1 = ($1_ltype)$input; %}
584 
585 /******************************************************************************
586  * GDALProgressFunc typemaps                                                  *
587  *****************************************************************************/
588 %pragma(csharp) modulecode="public delegate int GDALProgressFuncDelegate(double Complete, IntPtr Message, IntPtr Data);"
589 
590 %typemap(imtype) (GDALProgressFunc callback)  "$module.GDALProgressFuncDelegate"
591 %typemap(cstype) (GDALProgressFunc callback) "$module.GDALProgressFuncDelegate"
592 %typemap(csin) (GDALProgressFunc callback)  "$csinput"
593 %typemap(csvarout, excode=SWIGEXCODE2) (GDALProgressFunc callback)   %{
594     get {
595       Gdal.GDALProgressFuncDelegate ret = $imcall;$excode
596       return ret;
597     } %}
598 %typemap(in) (GDALProgressFunc callback) %{ $1 = ($1_ltype)$input; %}
599 %typemap(imtype) (void* callback_data) "string"
600 %typemap(cstype) (void* callback_data) "string"
601 %typemap(csin) (void* callback_data) "$csinput"
602