2 // SWIG pointer conversion and utility library
 
   7 // Python specific implementation.   This file is included
 
   8 // by the file ../pointer.i
 
  14 /*------------------------------------------------------------------
 
  17   Constructs a new pointer value.   Value may either be a string
 
  18   or an integer. Type is a string corresponding to either the
 
  19   C datatype or mangled datatype.
 
  24   ------------------------------------------------------------------ */
 
  26 static PyObject *ptrcast(PyObject *_PTRVALUE, char *type) {
 
  33   /* Produce a "mangled" version of the type string.  */
 
  35   typestr = (char *) malloc(strlen(type)+2);
 
  37   /* Go through and munge the typestring */
 
  44       if ((*c == '*') || (*c == '&')) {
 
  55   /* Check to see what kind of object _PTRVALUE is */
 
  57   if (PyInt_Check(_PTRVALUE)) {
 
  58     ptr = (void *) PyInt_AsLong(_PTRVALUE);
 
  59     /* Received a numerical value. Make a pointer out of it */
 
  60     r = (char *) malloc(strlen(typestr)+22);
 
  62       SWIG_MakePtr(r, ptr, typestr);
 
  64       sprintf(r,"_0%s",typestr);
 
  66     obj = PyString_FromString(r);
 
  68   } else if (PyString_Check(_PTRVALUE)) {
 
  69     /* Have a real pointer value now.  Try to strip out the pointer
 
  71     s = PyString_AsString(_PTRVALUE);
 
  72     r = (char *) malloc(strlen(type)+22);
 
  74     /* Now extract the pointer value */
 
  75     if (!SWIG_GetPtr(s,&ptr,0)) {
 
  77         SWIG_MakePtr(r,ptr,typestr);
 
  79         sprintf(r,"_0%s",typestr);
 
  81       obj = PyString_FromString(r);
 
  91     PyErr_SetString(PyExc_TypeError,"Type error in ptrcast. Argument is not a valid pointer value.");
 
  95 /*------------------------------------------------------------------
 
  96   ptrvalue(ptr,type = 0)
 
  98   Attempts to dereference a pointer value.  If type is given, it 
 
  99   will try to use that type.  Otherwise, this function will attempt
 
 100   to "guess" the proper datatype by checking against all of the 
 
 102   ------------------------------------------------------------------ */
 
 104 static PyObject *ptrvalue(PyObject *_PTRVALUE, int index, char *type) {
 
 109   if (!PyString_Check(_PTRVALUE)) {
 
 110     PyErr_SetString(PyExc_TypeError,"Type error in ptrvalue. Argument is not a valid pointer value.");
 
 113   s = PyString_AsString(_PTRVALUE);
 
 114   if (SWIG_GetPtr(s,&ptr,0)) {
 
 115     PyErr_SetString(PyExc_TypeError,"Type error in ptrvalue. Argument is not a valid pointer value.");
 
 119   /* If no datatype was passed, try a few common datatypes first */
 
 123     /* No datatype was passed.   Type to figure out if it's a common one */
 
 125     if (!SWIG_GetPtr(s,&ptr,"_int_p")) {
 
 127     } else if (!SWIG_GetPtr(s,&ptr,"_double_p")) {
 
 129     } else if (!SWIG_GetPtr(s,&ptr,"_short_p")) {
 
 131     } else if (!SWIG_GetPtr(s,&ptr,"_long_p")) {
 
 133     } else if (!SWIG_GetPtr(s,&ptr,"_float_p")) {
 
 135     } else if (!SWIG_GetPtr(s,&ptr,"_char_p")) {
 
 137     } else if (!SWIG_GetPtr(s,&ptr,"_char_pp")) {
 
 145     PyErr_SetString(PyExc_TypeError,"Unable to dereference NULL pointer.");
 
 149   /* Now we have a datatype.  Try to figure out what to do about it */
 
 150   if (strcmp(type,"int") == 0) {
 
 151     obj = PyInt_FromLong((long) *(((int *) ptr) + index));
 
 152   } else if (strcmp(type,"double") == 0) {
 
 153     obj = PyFloat_FromDouble((double) *(((double *) ptr)+index));
 
 154   } else if (strcmp(type,"short") == 0) {
 
 155     obj = PyInt_FromLong((long) *(((short *) ptr)+index));
 
 156   } else if (strcmp(type,"long") == 0) {
 
 157     obj = PyInt_FromLong((long) *(((long *) ptr)+index));
 
 158   } else if (strcmp(type,"float") == 0) {
 
 159     obj = PyFloat_FromDouble((double) *(((float *) ptr)+index));
 
 160   } else if (strcmp(type,"char") == 0) {
 
 161     obj = PyString_FromString(((char *) ptr)+index);
 
 162   } else if (strcmp(type,"char *") == 0) {
 
 163     char *c = *(((char **) ptr)+index);
 
 164     if (c) obj = PyString_FromString(c);
 
 165     else obj = PyString_FromString("NULL");
 
 167     PyErr_SetString(PyExc_TypeError,"Unable to dereference unsupported datatype.");
 
 173 /*------------------------------------------------------------------
 
 174   ptrcreate(type,value = 0,numelements = 1)
 
 176   Attempts to create a new object of given type.  Type must be
 
 177   a basic C datatype.  Will not create complex objects.
 
 178   ------------------------------------------------------------------ */
 
 180 static PyObject *ptrcreate(char *type, PyObject *_PYVALUE, int numelements) {
 
 187   /* Check the type string against a variety of possibilities */
 
 189   if (strcmp(type,"int") == 0) {
 
 190     sz = sizeof(int)*numelements;
 
 192   } else if (strcmp(type,"short") == 0) {
 
 193     sz = sizeof(short)*numelements;
 
 195   } else if (strcmp(type,"long") == 0) {
 
 196     sz = sizeof(long)*numelements;
 
 198   } else if (strcmp(type,"double") == 0) {
 
 199     sz = sizeof(double)*numelements;
 
 201   } else if (strcmp(type,"float") == 0) {
 
 202     sz = sizeof(float)*numelements;
 
 204   } else if (strcmp(type,"char") == 0) {
 
 205     sz = sizeof(char)*numelements;
 
 207   } else if (strcmp(type,"char *") == 0) {
 
 208     sz = sizeof(char *)*(numelements+1);
 
 211     PyErr_SetString(PyExc_TypeError,"Unable to create unknown datatype."); 
 
 215   /* Create the new object */
 
 217   ptr = (void *) malloc(sz);
 
 219     PyErr_SetString(PyExc_MemoryError,"Out of memory in swig_create."); 
 
 223   /* Now try to set its default value */
 
 226     if (strcmp(type,"int") == 0) {
 
 228       ivalue = (int) PyInt_AsLong(_PYVALUE);
 
 230       for (i = 0; i < numelements; i++)
 
 232     } else if (strcmp(type,"short") == 0) {
 
 235       ivalue = (short) PyInt_AsLong(_PYVALUE);
 
 237       for (i = 0; i < numelements; i++)
 
 239     } else if (strcmp(type,"long") == 0) {
 
 242       ivalue = (long) PyInt_AsLong(_PYVALUE);
 
 244       for (i = 0; i < numelements; i++)
 
 246     } else if (strcmp(type,"double") == 0) {
 
 249       ivalue = (double) PyFloat_AsDouble(_PYVALUE);
 
 251       for (i = 0; i < numelements; i++)
 
 253     } else if (strcmp(type,"float") == 0) {
 
 256       ivalue = (float) PyFloat_AsDouble(_PYVALUE);
 
 258       for (i = 0; i < numelements; i++)
 
 260     } else if (strcmp(type,"char") == 0) {
 
 262       ivalue = (char *) PyString_AsString(_PYVALUE);
 
 264       strncpy(ip,ivalue,numelements-1);
 
 265     } else if (strcmp(type,"char *") == 0) {
 
 268       ivalue = (char *) PyString_AsString(_PYVALUE);
 
 270       for (i = 0; i < numelements; i++) {
 
 272           ip[i] = (char *) malloc(strlen(ivalue)+1);
 
 273           strcpy(ip[i],ivalue);
 
 281   /* Create the pointer value */
 
 283   SWIG_MakePtr(temp,ptr,cast);
 
 284   obj = PyString_FromString(temp);
 
 289 /*------------------------------------------------------------------
 
 290   ptrset(ptr,value,index = 0,type = 0)
 
 292   Attempts to set the value of a pointer variable.  If type is
 
 293   given, we will use that type.  Otherwise, we'll guess the datatype.
 
 294   ------------------------------------------------------------------ */
 
 296 static PyObject *ptrset(PyObject *_PTRVALUE, PyObject *_PYVALUE, int index, char *type) {
 
 301   if (!PyString_Check(_PTRVALUE)) {
 
 302     PyErr_SetString(PyExc_TypeError,"Type error in ptrset. Argument is not a valid pointer value.");
 
 305   s = PyString_AsString(_PTRVALUE);
 
 306   if (SWIG_GetPtr(s,&ptr,0)) {
 
 307     PyErr_SetString(PyExc_TypeError,"Type error in ptrset. Argument is not a valid pointer value.");
 
 311   /* If no datatype was passed, try a few common datatypes first */
 
 315     /* No datatype was passed.   Type to figure out if it's a common one */
 
 317     if (!SWIG_GetPtr(s,&ptr,"_int_p")) {
 
 319     } else if (!SWIG_GetPtr(s,&ptr,"_double_p")) {
 
 321     } else if (!SWIG_GetPtr(s,&ptr,"_short_p")) {
 
 323     } else if (!SWIG_GetPtr(s,&ptr,"_long_p")) {
 
 325     } else if (!SWIG_GetPtr(s,&ptr,"_float_p")) {
 
 327     } else if (!SWIG_GetPtr(s,&ptr,"_char_p")) {
 
 329     } else if (!SWIG_GetPtr(s,&ptr,"_char_pp")) {
 
 337     PyErr_SetString(PyExc_TypeError,"Unable to set NULL pointer.");
 
 341   /* Now we have a datatype.  Try to figure out what to do about it */
 
 342   if (strcmp(type,"int") == 0) {
 
 343     *(((int *) ptr)+index) = (int) PyInt_AsLong(_PYVALUE);
 
 344   } else if (strcmp(type,"double") == 0) {
 
 345     *(((double *) ptr)+index) = (double) PyFloat_AsDouble(_PYVALUE);
 
 346   } else if (strcmp(type,"short") == 0) {
 
 347     *(((short *) ptr)+index) = (short) PyInt_AsLong(_PYVALUE);
 
 348   } else if (strcmp(type,"long") == 0) {
 
 349     *(((long *) ptr)+index) = (long) PyInt_AsLong(_PYVALUE);
 
 350   } else if (strcmp(type,"float") == 0) {
 
 351     *(((float *) ptr)+index) = (float) PyFloat_AsDouble(_PYVALUE);
 
 352   } else if (strcmp(type,"char") == 0) {
 
 353     char *c = PyString_AsString(_PYVALUE);
 
 354     strcpy(((char *) ptr)+index, c);
 
 355   } else if (strcmp(type,"char *") == 0) {
 
 356     char *c = PyString_AsString(_PYVALUE);
 
 357     char **ca = (char **) ptr;
 
 358     if (ca[index]) free(ca[index]);
 
 359     if (strcmp(c,"NULL") == 0) {
 
 362       ca[index] = (char *) malloc(strlen(c)+1);
 
 366     PyErr_SetString(PyExc_TypeError,"Unable to set unsupported datatype.");
 
 374 /*------------------------------------------------------------------
 
 377   Adds a value to an existing pointer value.  Will do a type-dependent
 
 378   add for basic datatypes.  For other datatypes, will do a byte-add.
 
 379   ------------------------------------------------------------------ */
 
 381 static PyObject *ptradd(PyObject *_PTRVALUE, int offset) {
 
 388   /* Check to see what kind of object _PTRVALUE is */
 
 390   if (PyString_Check(_PTRVALUE)) {
 
 391     /* Have a potential pointer value now.  Try to strip out the value */
 
 392     s = PyString_AsString(_PTRVALUE);
 
 394     /* Try to handle a few common datatypes first */
 
 396     if (!SWIG_GetPtr(s,&ptr,"_int_p")) {
 
 397       ptr = (void *) (((int *) ptr) + offset);
 
 398     } else if (!SWIG_GetPtr(s,&ptr,"_double_p")) {
 
 399       ptr = (void *) (((double *) ptr) + offset);
 
 400     } else if (!SWIG_GetPtr(s,&ptr,"_short_p")) {
 
 401       ptr = (void *) (((short *) ptr) + offset);
 
 402     } else if (!SWIG_GetPtr(s,&ptr,"_long_p")) {
 
 403       ptr = (void *) (((long *) ptr) + offset);
 
 404     } else if (!SWIG_GetPtr(s,&ptr,"_float_p")) {
 
 405       ptr = (void *) (((float *) ptr) + offset);
 
 406     } else if (!SWIG_GetPtr(s,&ptr,"_char_p")) {
 
 407       ptr = (void *) (((char *) ptr) + offset);
 
 408     } else if (!SWIG_GetPtr(s,&ptr,0)) {
 
 409       ptr = (void *) (((char *) ptr) + offset);
 
 411       PyErr_SetString(PyExc_TypeError,"Type error in ptradd. Argument is not a valid pointer value.");
 
 414     type = SWIG_GetPtr(s,&junk,"INVALID POINTER");
 
 415     r = (char *) malloc(strlen(type)+20);
 
 417       SWIG_MakePtr(r,ptr,type);
 
 419       sprintf(r,"_0%s",type);
 
 421     obj = PyString_FromString(r);
 
 427 /*------------------------------------------------------------------
 
 430   Allows a mapping between type1 and type2. (Like a typedef)
 
 431   ------------------------------------------------------------------ */
 
 433 static void ptrmap(char *type1, char *type2) {
 
 435   char *typestr1,*typestr2,*c,*r;
 
 437   /* Produce a "mangled" version of the type string.  */
 
 439   typestr1 = (char *) malloc(strlen(type1)+2);
 
 441   /* Go through and munge the typestring */
 
 448       if ((*c == '*') || (*c == '&')) {
 
 459   typestr2 = (char *) malloc(strlen(type2)+2);
 
 461   /* Go through and munge the typestring */
 
 468       if ((*c == '*') || (*c == '&')) {
 
 478   SWIG_RegisterMapping(typestr1,typestr2,0);
 
 479   SWIG_RegisterMapping(typestr2,typestr1,0);
 
 482 /*------------------------------------------------------------------
 
 485   Destroys a pointer value
 
 486   ------------------------------------------------------------------ */
 
 488 PyObject *ptrfree(PyObject *_PTRVALUE) {
 
 492   if (!PyString_Check(_PTRVALUE)) {
 
 493     PyErr_SetString(PyExc_TypeError,"Type error in ptrfree. Argument is not a valid pointer value.");
 
 496   s = PyString_AsString(_PTRVALUE);
 
 497   if (SWIG_GetPtr(s,&ptr,0)) {
 
 498     PyErr_SetString(PyExc_TypeError,"Type error in ptrfree. Argument is not a valid pointer value.");
 
 502   /* Check to see if this pointer is a char ** */
 
 503   if (!SWIG_GetPtr(s,&junk,"_char_pp")) {
 
 504     char **c = (char **) ptr;
 
 521 %typemap(python,in) PyObject *ptr, PyObject *value {
 
 525 %typemap(python,out) PyObject *ptrcast,
 
 535 %typemap(python,ret) int ptrset {
 
 536   if ($source == -1) return NULL;
 
 539 PyObject *ptrcast(PyObject *ptr, char *type); 
 
 540 // Casts a pointer ptr to a new datatype given by the string type.
 
 541 // type may be either the SWIG generated representation of a datatype
 
 542 // or the C representation.  For example :
 
 544 //    ptrcast(ptr,"double_p");   # Python representation
 
 545 //    ptrcast(ptr,"double *");    # C representation
 
 547 // A new pointer value is returned.   ptr may also be an integer
 
 548 // value in which case the value will be used to set the pointer
 
 549 // value.  For example :
 
 551 //    a = ptrcast(0,"Vector_p");
 
 553 // Will create a NULL pointer of type "Vector_p"
 
 555 // The casting operation is sensitive to formatting.  As a result,
 
 556 // "double *" is different than "double*".  As a result of thumb,
 
 557 // there should always be exactly one space between the C datatype
 
 558 // and any pointer specifiers (*).
 
 560 PyObject *ptrvalue(PyObject *ptr, int index = 0, char *type = 0);
 
 561 // Returns the value that a pointer is pointing to (ie. dereferencing).
 
 562 // The type is automatically inferred by the pointer type--thus, an
 
 563 // integer pointer will return an integer, a double will return a double,
 
 564 // and so on.   The index and type fields are optional parameters.  When
 
 565 // an index is specified, this function returns the value of ptr[index].
 
 566 // This allows array access.   When a type is specified, it overrides
 
 567 // the given pointer type.   Examples :
 
 569 //    ptrvalue(a)             #  Returns the value *a
 
 570 //    ptrvalue(a,10)          #  Returns the value a[10]
 
 571 //    ptrvalue(a,10,"double") #  Returns a[10] assuming a is a double *
 
 573 PyObject *ptrset(PyObject *ptr, PyObject *value, int index = 0, char *type = 0);
 
 574 // Sets the value pointed to by a pointer.  The type is automatically
 
 575 // inferred from the pointer type so this function will work for
 
 576 // integers, floats, doubles, etc...  The index and type fields are
 
 577 // optional.  When an index is given, it provides array access.  When
 
 578 // type is specified, it overrides the given pointer type.  Examples :
 
 580 //   ptrset(a,3)            # Sets the value *a = 3
 
 581 //   ptrset(a,3,10)         # Sets a[10] = 3
 
 582 //   ptrset(a,3,10,"int")   # Sets a[10] = 3 assuming a is a int *
 
 584 PyObject *ptrcreate(char *type, PyObject *value = 0, int nitems = 1);
 
 585 // Creates a new object and returns a pointer to it.  This function 
 
 586 // can be used to create various kinds of objects for use in C functions.
 
 587 // type specifies the basic C datatype to create and value is an
 
 588 // optional parameter that can be used to set the initial value of the
 
 589 // object.  nitems is an optional parameter that can be used to create
 
 590 // an array.  This function results in a memory allocation using
 
 591 // malloc().  Examples :
 
 593 //   a = ptrcreate("double")     # Create a new double, return pointer
 
 594 //   a = ptrcreate("int",7)      # Create an integer, set value to 7
 
 595 //   a = ptrcreate("int",0,1000) # Create an integer array with initial
 
 596 //                               # values all set to zero
 
 598 // This function only recognizes a few common C datatypes as listed below :
 
 600 //        int, short, long, float, double, char, char *, void
 
 602 // All other datatypes will result in an error.  However, other
 
 603 // datatypes can be created by using the ptrcast function.  For
 
 606 //  a = ptrcast(ptrcreate("int",0,100),"unsigned int *")
 
 608 PyObject *ptrfree(PyObject *ptr);
 
 609 // Destroys the memory pointed to by ptr.  This function calls free()
 
 610 // and should only be used with objects created by ptrcreate().  Since
 
 611 // this function calls free, it may work with other objects, but this
 
 612 // is generally discouraged unless you absolutely know what you're
 
 615 PyObject *ptradd(PyObject *ptr, int offset);
 
 616 // Adds a value to the current pointer value.  For the C datatypes of
 
 617 // int, short, long, float, double, and char, the offset value is the
 
 618 // number of objects and works in exactly the same manner as in C.  For
 
 619 // example, the following code steps through the elements of an array
 
 621 //  a = ptrcreate("double",0,100);    # Create an array double a[100]
 
 623 //  for i in range(0,100):
 
 624 //      ptrset(b,0.0025*i);           # set *b = 0.0025*i
 
 625 //      b = ptradd(b,1);              # b++ (go to next double)
 
 627 // In this case, adding one to b goes to the next double.
 
 629 // For all other datatypes (including all complex datatypes), the
 
 630 // offset corresponds to bytes.  This function does not perform any
 
 631 // bounds checking and negative offsets are perfectly legal.  
 
 633 void      ptrmap(char *type1, char *type2);
 
 634 // This is a rarely used function that performs essentially the same
 
 635 // operation as a C typedef.  To manage datatypes at run-time, SWIG
 
 636 // modules manage an internal symbol table of type mappings.  This
 
 637 // table keeps track of which types are equivalent to each other.  The
 
 638 // ptrmap() function provides a mechanism for scripts to add symbols
 
 639 // to this table.  For example :
 
 641 //    ptrmap("double_p","Real_p");
 
 643 // would make the types "doublePtr" and "RealPtr" equivalent to each
 
 644 // other.  Pointers of either type could now be used interchangably.
 
 646 // Normally this function is not needed, but it can be used to
 
 647 // circumvent SWIG's normal type-checking behavior or to work around
 
 648 // weird type-handling problems.