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.