Home | History | Annotate | Download | only in typemaps
      1 /* -----------------------------------------------------------------------------
      2  * cstrings.swg
      3  *
      4  * This file provides typemaps and macros for dealing with various forms
      5  * of C character string handling.   The primary use of this module
      6  * is in returning character data that has been allocated or changed in
      7  * some way.
      8  * ----------------------------------------------------------------------------- */
      9 
     10 %define %typemaps_cstring(Name, Char,
     11 			  SWIG_AsCharPtr,
     12 			  SWIG_AsCharPtrAndSize,
     13 			  SWIG_FromCharPtr,
     14 			  SWIG_FromCharPtrAndSize)
     15 
     16 
     17 /* %cstring_input_binary(TYPEMAP, SIZE)
     18  *
     19  * Macro makes a function accept binary string data along with
     20  * a size.  For example:
     21  *
     22  *     %cstring_input_binary(Char *buff, int size);
     23  *     void foo(Char *buff, int size) {
     24  *     }
     25  *
     26  */
     27 
     28 %define Name ## _input_binary(TYPEMAP, SIZE)
     29 %typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize) (TYPEMAP, SIZE)
     30   (int res, Char *buf = 0, size_t size = 0, int alloc = 0)  {
     31   res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc);
     32   if (!SWIG_IsOK(res)) {
     33     %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
     34   }
     35   $1 = ($1_ltype) buf;
     36   $2 = ($2_ltype) size - 1;
     37 }
     38 %typemap(freearg,noblock=1,match="in") (TYPEMAP, SIZE) {
     39   if (alloc$argnum == SWIG_NEWOBJ) %delete_array(buf$argnum);
     40 }
     41 %enddef
     42 
     43 
     44 
     45 /*
     46  * %cstring_bounded_output(TYPEMAP, MAX)
     47  *
     48  * This macro is used to return a NULL-terminated output string of
     49  * some maximum length.  For example:
     50  *
     51  *     %cstring_bounded_output(Char *outx, 512);
     52  *     void foo(Char *outx) {
     53  *         sprintf(outx,"blah blah\n");
     54  *     }
     55  *
     56  */
     57 
     58 %define Name ## _bounded_output(TYPEMAP,MAX)
     59 %typemap(in,noblock=1,numinputs=0) TYPEMAP (Char temp[MAX+1])  {
     60   $1 = ($1_ltype) temp;
     61 }
     62 %typemap(freearg,match="in") TYPEMAP "";
     63 %typemap(argout,noblock=1,fragment= #SWIG_FromCharPtr ) TYPEMAP {
     64   $1[MAX] = 0;
     65   %append_output(SWIG_FromCharPtr($1));
     66 }
     67 %enddef
     68 
     69 
     70 
     71 /*
     72  * %cstring_chunk_output(TYPEMAP, SIZE)
     73  *
     74  * This macro is used to return a chunk of binary string data.
     75  * Embedded NULLs are okay.  For example:
     76  *
     77  *     %cstring_chunk_output(Char *outx, 512);
     78  *     void foo(Char *outx) {
     79  *         memmove(outx, somedata, 512);
     80  *     }
     81  *
     82  */
     83 
     84 %define Name ## _chunk_output(TYPEMAP,SIZE)
     85 %typemap(in,noblock=1,numinputs=0) TYPEMAP(Char temp[SIZE]) {
     86   $1 = ($1_ltype) temp;
     87 }
     88 %typemap(freearg,match="in") TYPEMAP "";
     89 %typemap(argout,noblock=1,fragment= #SWIG_FromCharPtrAndSize) TYPEMAP {
     90   %append_output(SWIG_FromCharPtrAndSize($1,SIZE));
     91 }
     92 %enddef
     93 
     94 
     95 
     96 /*
     97  * %cstring_bounded_mutable(TYPEMAP, SIZE)
     98  *
     99  * This macro is used to wrap a string that's going to mutate.
    100  *
    101  *     %cstring_bounded_mutable(Char *in, 512);
    102  *     void foo(in *x) {
    103  *         while (*x) {
    104  *            *x = toupper(*x);
    105  *            x++;
    106  *         }
    107  *     }
    108  *
    109  */
    110 
    111 
    112 %define Name ## _bounded_mutable(TYPEMAP,MAX)
    113 %typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize) TYPEMAP
    114   (int res,Char temp[MAX+1], Char *t = 0, size_t n = 0, int alloc = 0) {
    115   res = SWIG_AsCharPtrAndSize($input, &t, &n, &alloc);
    116   if (!SWIG_IsOK(res)) {
    117     %argument_fail(res, "TYPEMAP", $symname, $argnum);
    118   }
    119   if ( n > (size_t) MAX ) n = (size_t) MAX;
    120   memcpy(temp, t, sizeof(Char)*n);
    121   if (alloc == SWIG_NEWOBJ) %delete_array(t);
    122   temp[n - 1] = 0;
    123   $1 = ($1_ltype) temp;
    124 }
    125 %typemap(freearg,match="in") TYPEMAP "";
    126 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) TYPEMAP {
    127   $1[MAX] = 0;
    128   %append_output(SWIG_FromCharPtr($1));
    129 }
    130 %enddef
    131 
    132 
    133 /*
    134  * %cstring_mutable(TYPEMAP [, expansion])
    135  *
    136  * This macro is used to wrap a string that will mutate in place.
    137  * It may change size up to a user-defined expansion.
    138  *
    139  *     %cstring_mutable(Char *in);
    140  *     void foo(in *x) {
    141  *         while (*x) {
    142  *            *x = toupper(*x);
    143  *            x++;
    144  *         }
    145  *     }
    146  *
    147  */
    148 
    149 %define Name ## _mutable(TYPEMAP,EXP...)
    150 %typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize) TYPEMAP (int res, Char *t = 0, size_t n = 0, int alloc = 0, size_t expansion = 0) {
    151 #if #EXP != ""
    152   expansion += EXP;
    153 #endif
    154   res = SWIG_AsCharPtrAndSize($input, &t, &n, &alloc);
    155   if (!SWIG_IsOK(res)) {
    156     %argument_fail(res, "TYPEMAP", $symname, $argnum);
    157   }
    158   $1 = %new_array(n+expansion, $*1_ltype);
    159   memcpy($1,t,sizeof(Char)*n);
    160   if (alloc == SWIG_NEWOBJ) %delete_array(t);
    161   $1[n-1] = 0;
    162 }
    163 %typemap(freearg,match="in") TYPEMAP "";
    164 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) TYPEMAP {
    165   %append_output(SWIG_FromCharPtr($1));
    166   %delete_array($1);
    167 }
    168 %enddef
    169 
    170 
    171 /*
    172  * %cstring_output_maxsize(TYPEMAP, SIZE)
    173  *
    174  * This macro returns data in a string of some user-defined size.
    175  *
    176  *     %cstring_output_maxsize(Char *outx, int max) {
    177  *     void foo(Char *outx, int max) {
    178  *         sprintf(outx,"blah blah\n");
    179  *     }
    180  */
    181 
    182 %define Name ## _output_maxsize(TYPEMAP, SIZE)
    183 %typemap(in,noblock=1,fragment=SWIG_AsVal_frag(size_t)) (TYPEMAP, SIZE) (int res, size_t size, Char *buff = 0) {
    184   res = SWIG_AsVal(size_t)($input, &size);
    185   if (!SWIG_IsOK(res)) {
    186     %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
    187   }
    188   buff= %new_array(size+1, Char);
    189   $2 = %numeric_cast(size, $2_ltype);
    190   $1 = %static_cast(buff, $1_ltype);
    191 }
    192 %typemap(freearg,noblock=1,match="in") (TYPEMAP,SIZE) {
    193   if (buff$argnum) %delete_array(buff$argnum);
    194 }
    195 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) (TYPEMAP,SIZE) {
    196   %append_output(SWIG_FromCharPtr($1));
    197 }
    198 %enddef
    199 
    200 /*
    201  * %cstring_output_withsize(TYPEMAP, SIZE)
    202  *
    203  * This macro is used to return Character data along with a size
    204  * parameter.
    205  *
    206  *     %cstring_output_maxsize(Char *outx, int *max) {
    207  *     void foo(Char *outx, int *max) {
    208  *         sprintf(outx,"blah blah\n");
    209  *         *max = strlen(outx);
    210  *     }
    211  */
    212 
    213 %define Name ## _output_withsize(TYPEMAP, SIZE)
    214 %typemap(in,noblock=1,fragment=SWIG_AsVal_frag(size_t)) (TYPEMAP, SIZE) (int res, size_t n, Char *buff = 0, $*2_ltype size) {
    215   res = SWIG_AsVal(size_t)($input, &n);
    216   if (!SWIG_IsOK(res)) {
    217     %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
    218   }
    219   buff= %new_array(n+1, Char);
    220   $1 = %static_cast(buff, $1_ltype);
    221   size = %numeric_cast(n,$*2_ltype);
    222   $2 = &size;
    223 }
    224 %typemap(freearg,noblock=1,match="in")(TYPEMAP,SIZE) {
    225   if (buff$argnum) %delete_array(buff$argnum);
    226 }
    227 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtrAndSize) (TYPEMAP,SIZE) {
    228   %append_output(SWIG_FromCharPtrAndSize($1,*$2));
    229 }
    230 %enddef
    231 
    232 
    233 /*
    234  * %cstring_output_allocate(TYPEMAP, RELEASE)
    235  *
    236  * This macro is used to return Character data that was
    237  * allocated with new or malloc.
    238  *
    239  *     %cstring_output_allocated(Char **outx, free($1));
    240  *     void foo(Char **outx) {
    241  *         *outx = (Char *) malloc(512);
    242  *         sprintf(outx,"blah blah\n");
    243  *     }
    244  */
    245 
    246 %define Name ## _output_allocate(TYPEMAP, RELEASE)
    247 %typemap(in,noblock=1,numinputs=0) TYPEMAP($*1_ltype temp = 0) {
    248   $1 = &temp;
    249 }
    250 %typemap(freearg,match="in") TYPEMAP "";
    251 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) TYPEMAP {
    252   if (*$1) {
    253     %append_output(SWIG_FromCharPtr(*$1));
    254     RELEASE;
    255   }
    256 }
    257 %enddef
    258 
    259 
    260 /*
    261  * %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE)
    262  *
    263  * This macro is used to return Character data that was
    264  * allocated with new or malloc.
    265  *
    266  *     %cstring_output_allocated(Char **outx, int *sz, free($1));
    267  *     void foo(Char **outx, int *sz) {
    268  *         *outx = (Char *) malloc(512);
    269  *         sprintf(outx,"blah blah\n");
    270  *         *sz = strlen(outx);
    271  *     }
    272  */
    273 
    274 %define Name ## _output_allocate_size(TYPEMAP, SIZE, RELEASE)
    275 %typemap(in,noblock=1,numinputs=0) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) {
    276   $1 = &temp; $2 = &tempn;
    277 }
    278 %typemap(freearg,match="in") (TYPEMAP,SIZE) "";
    279 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtrAndSize)(TYPEMAP,SIZE) {
    280   if (*$1) {
    281     %append_output(SWIG_FromCharPtrAndSize(*$1,*$2));
    282     RELEASE;
    283   }
    284 }
    285 %enddef
    286 
    287 %enddef
    288 
    289