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