source: trunk/src/cee/rappture_interface.c @ 49

Last change on this file since 49 was 49, checked in by dkearney, 16 years ago

changed all functions with PyString_AsString calls to copy the contents
of the returned python object to newly allocated memory and return the
newly allocated memory. this leaves it up to the user to free all of
the returned items, while the interface function is still responsible
for taking care of python's memory.

File size: 29.1 KB
Line 
1#include "rappture_interface.h"
2
3/**********************************************************************/
4// FUNCTION: PyObject* importRappture()
5/// fxn to mimic/implement the python call "import Rappture"
6/**
7 * Clients use this function to import the Rappture module into
8 *          the Python Interpretor.
9 *
10 * Notes: It is the client's responsibility to increment and
11 *          decrement the reference count of the returned object
12 *          as needed.
13 *
14 * Returns pointer (PyObject*) to the Rappture.library class
15 *          if successful, or NULL if something goes wrong.
16 */
17
18
19PyObject* importRappture()
20{
21   
22    // it is the callers responsibility to Py_DECREF the returned object
23    // if it exists.
24
25    PyObject* pName     = NULL;
26    PyObject* pModule   = NULL;
27    PyObject* mClass    = NULL;
28    PyObject* retVal    = NULL;    /* return object */
29
30    // create a string object holding the name of the module
31    pName = PyString_FromString("Rappture");
32
33    if (pName) {
34        pModule = PyImport_Import(pName);
35        if (pModule) {
36            /* fetch module.class */
37            mClass = PyObject_GetAttrString(pModule, "library");
38            Py_DECREF(pModule);
39
40            if (mClass) {
41                // try to instantiate the class
42                if (PyCallable_Check(mClass)) {
43
44                    retVal = mClass;
45                   
46                }
47                else {
48                    // mClass not callable
49                    // something went wrong
50                    // python will probably raise error
51                }
52
53                // not sure if we need to increase and decrease
54                // increase because we are returning a ref to the object
55                // decrease because this function no longer needs the ref.
56                //
57                // the decrease is left as an exercise to the calling fxn.
58                //
59                // Py_DECREF(mClass);
60            }
61
62            // Py_DECREF(pModule);
63        }
64        else {
65            // pModule was not created
66        }
67
68        Py_DECREF(pName);
69    }
70    else {
71        // pName was not able to be created as a PyObject string
72    }       
73
74    return retVal;
75
76
77
78/**********************************************************************/
79// FUNCTION: PyObject* createRapptureObj(PyObject* rpObj, const char* path)
80/// fxn to mimic/implement the python call "lib = Rappture.library(".")"
81/// fxn instatiates a Rappture Object and returns it to the caller.
82/**
83 * Clients use this function to create a Rappture object which can
84 *          access the Rappture member functions.
85 *
86 * Notes: It is the client's responsibility to increment and
87 *          decrement the reference count of the returned object
88 *          as needed.
89 *       
90 *        Neither of the two arguments (rpObj,path) are optional.
91 *          if either value is NULL, NULL will be returned.
92 *
93 * Returns pointer (PyObject*) to an instantiated Rappture object
94 *          if successful, or NULL if something goes wrong.
95 */
96
97PyObject* createRapptureObj (PyObject* rpObj, const char* path)
98{
99    PyObject* args      = NULL;      /* args tuple */
100    PyObject* stringarg = NULL;      /* string of arguments */
101    PyObject* lib       = NULL;      /* results from fxn call */
102    PyObject* retVal    = NULL;      /* fxn return value */
103
104    long int fileLength = 0;
105    char* fileContents = NULL;
106    FILE* fp = NULL;
107
108
109    if (rpObj) {
110        if (path) {
111
112            fp = fopen(path,"rb");
113            if (fp) {
114                fseek(fp, 0, SEEK_END);
115                fileLength = ftell(fp);
116                rewind(fp);
117            }
118            fileContents = (char*) calloc(fileLength,sizeof(char));
119
120            if (fp && fileContents) {
121                fread((void*)fileContents,sizeof(char),fileLength,fp);
122                fclose(fp);
123                fp = NULL;
124
125                // setup our arguments in a Python tuple
126                args = PyTuple_New(1);
127                stringarg = PyString_FromString(fileContents);
128               
129                // clean up used memory
130                free (fileContents);
131                fileContents = NULL;
132               
133                PyTuple_SetItem(args, 0, stringarg);
134                       
135                // call the class ... lib = Rappture.library("...")
136                lib = PyObject_CallObject(rpObj, args);
137               
138                // following line could cause a segfault if used in place of above
139                // maybe path could == NULL or bad memory
140                // lib = PyObject_CallFunction(rpObj,"(s)", path);
141
142                if (lib) {
143                    // return the Rappture instantiation.
144                    retVal = lib;
145                }
146                else {
147                    // lib was not successfully created
148                }
149
150                Py_DECREF(stringarg);
151                Py_DECREF(args);
152            }
153            else {
154                // fp or fileContents were NULL;
155            }
156        }
157        else {
158            // path was null
159        }
160    }
161    else {
162        // rpObj was null
163    }
164
165    return retVal;
166
167}
168
169/**********************************************************************/
170// FUNCTION: void* rpElement(PyObject* lib, const char* path, const char* flavor)
171/// fxn to mimic/implement the python call "element = lib.element("..")"
172/// fxn calls the element() member function of the Rappture.library
173///     class and returns the text to the caller
174/**
175 * Clients use this function to call the element() member function of the
176 *          Rappture.library class and get the text of the Rappture
177 *          object lib.
178 *
179 * Notes:   If (flavor == "object") || (flavor == NULL),
180 *          1) it is the client's responsibility to increment and
181 *             decrement the reference count of the returned object
182 *             as needed.
183 *          2) the return object will need to be cast as a PyObject*
184 *             to use it.
185 *
186 *          If (flavor == type) || (flavor == id) || (flavor == component),
187 *          1) the return object will need to be cast as a char*
188 *             to use it.
189 *          2) It is the caller's responsibility to free the returned pointer
190 *       
191 *        The Arguments lib and path are not optional.
192 *          If either value is NULL, NULL will be returned.
193 *
194 * Returns pointer (char*) to the c style string representing the
195 *          xml text of the Rappture object if successful, or
196 *          NULL if something goes wrong.
197 */
198
199void* rpElement(PyObject* lib, const char* path, const char* flavor)
200{
201    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
202    PyObject* rslt      = NULL;      /* results from fxn call */
203    char* tmpRetVal     = NULL;      /* fxn return value */
204    char* tmpString     = NULL;      /* fxn return value */
205    void* retVal        = NULL;      /* fxn return value */
206    int retValSize      = 0;
207
208    if (lib && path) {
209       
210        // retrieve the lib.element() function
211        mbr_fxn = PyObject_GetAttrString(lib, "element");
212
213        if (mbr_fxn) {
214
215            if (PyCallable_Check(mbr_fxn)) {
216               
217                // call the lib.element() function with arguments
218                if (flavor) {
219                    rslt = PyObject_CallFunction(mbr_fxn,"(ss)", path, flavor);
220                }
221                else {
222                    rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
223                }
224
225                if (rslt) {
226
227                    if (flavor == NULL) {
228                        // return a PyObject*
229                        retVal = (void*) rslt;
230                    }
231                    else if((*flavor == 'o')&&(strncmp(flavor,"object", 6)==0)){
232                        // return a PyObject*
233                        retVal = (void*) rslt;
234                    }
235                    else if (
236                      ((*flavor == 't')&&(strncmp(flavor,"type", 4) == 0))
237                    ||((*flavor == 'i')&&(strncmp(flavor,"id", 2) == 0))
238                    ||((*flavor == 'c')&&(strncmp(flavor,"component", 9) == 0)))
239                    {
240                        // return a char*
241                        // convert the result to c style strings
242                        // retVal = (void*) PyString_AsString(rslt);
243                        tmpRetVal = PyString_AsString(rslt);
244                        if (tmpRetVal) {
245                            // get str length, add 1 for null termination
246                            retValSize = strlen(tmpRetVal) + 1;
247                            tmpString = (char*) calloc(retValSize,sizeof(char));
248                            if (tmpString) {
249                                strncpy(tmpString,tmpRetVal,retValSize);
250                                retVal = (void*) tmpString;
251                            }
252                            else {
253                                // raise error, out of memory
254                            }
255                        }
256                        Py_DECREF(rslt);
257                    }
258                    else {
259                        // unrecognized format
260                    }
261                   
262                    // Py_DECREF(rslt);
263
264                } // rslt was null
265               
266            } // mbr_fxn was not callable
267           
268            Py_DECREF(mbr_fxn);
269        } // mbr_fxn was null
270    }
271    else {
272        // lib or path was set to NULL
273    }
274
275    return retVal;
276}
277
278
279/**********************************************************************/
280// FUNCTION: void** rpChildren(PyObject* lib, const char* path, const char* flavor)
281/// fxn to mimic/implement the python call "xmlText = lib.children("..")"
282/// fxn calls the element() member function of the Rappture.library
283///     class and returns the text to the caller
284/**
285 * Clients use this function to call the xml() member function of the
286 *          Rappture.library class and get the text of the Rappture
287 *          object lib.
288 *
289 * Notes:   If (flavor == "object") || (flavor == NULL),
290 *          1) it is the client's responsibility to increment and
291 *             decrement the reference count of the returned object
292 *             as needed.
293 *          2) the return object will need to be cast as a PyObject*
294 *             to use it.
295 *
296 *          If (flavor == "type")||(flavor == "id")||(flavor == "component"),
297 *          1) the return object will need to be case as a char*
298 *             to use it.
299 *          2) It is the caller's responsibility to free the contents of
300 *              the returned pointer (ie. free(*retVal))
301 *       
302 *        The Arguments lib and pathare not optional.
303 *          If either value is NULL, NULL will be returned.
304 *
305 * Returns pointer (char*) to the c style string representing the
306 *          xml text of the Rappture object if successful, or
307 *          NULL if something goes wrong.
308 */
309
310void** rpChildren(PyObject* lib, const char* path, const char* flavor)
311{
312    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
313    PyObject* rslt      = NULL;      /* results from fxn call */
314    PyObject* list_item = NULL;      /* item from list of returned children */
315//    void* retVal        = NULL;      /* fxn return value */
316    int list_size       = 0;
317    int index           = 0;
318    char** rslt_arr_c   = NULL;
319    void** rslt_arr  = NULL;
320    char*  tmpRetVal    = NULL;
321    char*  tmpString    = 0;
322    int retValSize      = 0;
323   
324
325    if (lib && path) {
326       
327        // retrieve the lib.children() function
328        mbr_fxn = PyObject_GetAttrString(lib, "children");
329
330        if (mbr_fxn) {
331
332            if (PyCallable_Check(mbr_fxn)) {
333               
334                // call the lib.element() function with arguments
335                if (flavor) {
336                    rslt = PyObject_CallFunction(mbr_fxn,"(ss)", path, flavor);
337                }
338                else {
339                    rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
340                }
341
342                if (rslt) {
343
344                    if (flavor == NULL) {
345                        // return a PyObject*
346                        // retVal = (void*) rslt;
347                        //
348                        // the PyObject* points to a list, so we need to
349                        // convert this to an array of char*'s
350
351                        list_size = PyList_Size(rslt);
352                        rslt_arr = (void**) calloc(list_size+1,sizeof(void*));
353                        if (rslt_arr) {
354                            while (index < list_size) {
355                                // list_item is a borrowed reference
356                                list_item = PyList_GetItem(rslt,index);
357                                rslt_arr[index] = (void*) (list_item);
358                                index++;
359                            }
360                            // *(rslt_arr[index]) = (void*)NULL;
361                        }
362                    }
363                    else if((*flavor == 'o')&&(strncmp(flavor,"object", 6)==0)){
364                        // return a PyObject*
365                        // retVal = (void*) rslt;
366                        //
367                        // the PyObject* points to a list, so we need to
368                        // convert this to an array of char*'s
369
370                        list_size = PyList_Size(rslt);
371                        rslt_arr = (void**) calloc(list_size+1,sizeof(void*));
372                        if (rslt_arr) {
373                            while (index < list_size) {
374                                // list_item is a borrowed reference
375                                list_item = PyList_GetItem(rslt,index);
376                                rslt_arr[index] = (void*) (list_item);
377                                index++;
378                            }
379                            // *(rslt_arr[index]) = NULL;
380                        }
381                    }
382                    else if (
383                      ((*flavor == 't')&&(strncmp(flavor,"type", 4) == 0))
384                    ||((*flavor == 'i')&&(strncmp(flavor,"id", 2) == 0))
385                    ||((*flavor == 'c')&&(strncmp(flavor,"component", 9) == 0)))
386                    {
387                        // the PyObject* points to a list, so we need to
388                        // convert this to an array of char*'s
389
390                        list_size = PyList_Size(rslt);
391                        rslt_arr_c = (char**) calloc(list_size+1,sizeof(char*));
392                        if (rslt_arr_c) {
393                            while (index < list_size) {
394                                // list_item is a borrowed reference
395                                list_item = PyList_GetItem(rslt,index);
396                                // we cannot deallocate the results of
397                                // PyString_AsString()
398
399                                tmpRetVal = PyString_AsString(list_item);
400                                if (tmpRetVal) {
401                                    // get str length, add 1 for null termination
402                                    retValSize = strlen(tmpRetVal) + 1;
403                                    tmpString = (char*) calloc(retValSize,sizeof(char));
404                                    if (tmpString) {
405                                        strncpy(tmpString,tmpRetVal,retValSize);
406                                        rslt_arr_c[index] = tmpString;
407                                        tmpString = NULL;
408                                        index++;
409                                    }
410                                }
411
412                                // rslt_arr_c[index] = PyString_AsString(list_item);
413                                // index++;
414                               
415                            }
416                            // *(rslt_arr[index]) = NULL;
417                            rslt_arr = (void**) rslt_arr_c;
418                        }
419                        // return a char*
420                        // convert the result to c style strings
421                        // retVal = (void*) PyString_AsString(rslt);
422                        Py_DECREF(rslt);
423                    }
424                    else {
425                        // unrecognized format
426                    }
427                   
428                    // Py_DECREF(rslt);
429
430                } // rslt was null
431               
432            } // mbr_fxn was not callable
433           
434            Py_DECREF(mbr_fxn);
435        } // mbr_fxn was null
436    }
437    else {
438        // lib or path was set to NULL
439    }
440
441    // return retVal;
442    return (void**) rslt_arr;
443}
444
445/**********************************************************************/
446// FUNCTION: PyObject* rpChildren_f(PyObject* lib, const char* path, const char* flavor)
447/// fxn to mimic/implement the python call "xmlText = lib.children("..")"
448/// fxn calls the element() member function of the Rappture.library
449///     class and returns the text to the caller
450/**
451 * Clients use this function to call the xml() member function of the
452 *          Rappture.library class and get the text of the Rappture
453 *          object lib.
454 *
455 * Notes:   If (flavor == "object") || (flavor == NULL),
456 *          1) it is the client's responsibility to increment and
457 *             decrement the reference count of the returned object
458 *             as needed.
459 *          2) the return object will need to be cast as a PyObject*
460 *             to use it.
461 *
462 *          If (flavor == "type")||(flavor == "id")||(flavor == "component"),
463 *          1) the return object will need to be case as a char*
464 *             to use it.
465 *       
466 *        The Arguments lib and pathare not optional.
467 *          If either value is NULL, NULL will be returned.
468 *
469 * Returns pointer (char*) to the c style string representing the
470 *          xml text of the Rappture object if successful, or
471 *          NULL if something goes wrong.
472 */
473
474PyObject* rpChildren_f(PyObject* lib, const char* path, const char* flavor)
475{
476    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
477    PyObject* rslt      = NULL;      /* results from fxn call */
478//    PyObject* list_item = NULL;      /* item from list of returned children */
479//    void* retVal        = NULL;      /* fxn return value */
480//    int list_size       = 0;
481//    int index           = 0;
482//    char** rslt_arr_c   = NULL;
483//    void** rslt_arr  = NULL;
484
485//    char* xmlChild = NULL;
486
487    if (lib && path) {
488       
489        // retrieve the lib.children() function
490        mbr_fxn = PyObject_GetAttrString(lib, "children");
491
492        if (mbr_fxn) {
493
494            if (PyCallable_Check(mbr_fxn)) {
495               
496                // call the lib.children() function with arguments
497                if (flavor) {
498                    rslt = PyObject_CallFunction(mbr_fxn,"(ss)", path, flavor);
499                }
500                else {
501                    rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
502                }
503
504                /*
505                if (rslt) {
506                    list_size = PyList_Size(rslt);
507                    while (index < list_size) {
508                        // list_item is a borrowed reference
509                        list_item = PyList_GetItem(rslt,index);
510                        // we cannot deallocate the results of
511                        // PyString_AsString()
512                        // printf("list item = :%x:\n", list_item);
513                        xmlChild = PyString_AsString(list_item);
514                        printf("xml = :%s:\n",xmlChild);
515                        index++;
516                    }
517                }
518                */
519
520                /*
521                if (rslt) {
522                    list_item = PyList_GetItem(rslt,0);
523                    xmlChild = PyString_AsString(list_item);
524                    printf("xml0 = :%s:\n",xmlChild);
525                    list_item = PyList_GetItem(rslt,1);
526                    xmlChild = PyString_AsString(list_item);
527                    printf("xml1 = :%s:\n",xmlChild);
528                } // rslt was null
529                */
530               
531            } // mbr_fxn was not callable
532           
533            Py_DECREF(mbr_fxn);
534        } // mbr_fxn was null
535    }
536    else {
537        // lib or path was set to NULL
538    }
539
540    return rslt;
541}
542
543/**********************************************************************/
544// FUNCTION: const char* rpGet(PyObject* lib, const char* path)
545/// fxn to mimic/implement the python call "xmlText = lib.get('...')"
546/// fxn calls the get() member function of the Rappture.library class
547///     and returns the text to the caller
548/**
549 * Clients use this function to call the get() member function of the
550 *          Rappture.library class and get the text of the Rappture
551 *          object lib.
552 *
553 * Notes: The argument (lib) is not optional. If it is NULL,
554 *          NULL will be returned.
555 *
556 * Returns pointer (char*) to the c style string representing the
557 *          xml text provided by the path of the Rappture object if
558 *          successful, or NULL if something goes wrong.
559 *
560 *          It is the responsibility of the caller to free the
561 *          returned pointer
562 *
563 */
564char* rpGet(PyObject* lib, const char* path)
565{
566    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
567    PyObject* rslt      = NULL;      /* results from fxn call */
568    char* tmpRetVal     = NULL;      /* return value */
569    char* retVal        = NULL;      /* return value */
570    int retValSize      = 0;
571
572    if (lib) {
573        // retrieve the lib.get() function
574        mbr_fxn = PyObject_GetAttrString(lib, "get");
575
576        if (mbr_fxn) {
577
578            if (PyCallable_Check(mbr_fxn)) {
579               
580                // call the lib.get() function
581                rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
582                if (rslt) {
583                    // convert the result to c style strings
584                    tmpRetVal = PyString_AsString(rslt);
585
586                    if (tmpRetVal) {
587                        // get str length, add 1 for null termination
588                        retValSize = strlen(tmpRetVal) + 1;
589                        retVal = (char*) calloc(retValSize,sizeof(char));
590                        if (retVal) {
591                            strncpy(retVal,tmpRetVal,retValSize);
592                        }
593                        else {
594                            // raise error, out of memory
595                        }                           
596                    }
597
598                    Py_DECREF(rslt);
599                }
600               
601            }
602            Py_DECREF(mbr_fxn);
603        }
604    }
605    else {
606        // lib was set to NULL
607    }
608
609    return retVal;
610   
611}
612
613/**********************************************************************/
614// FUNCTION: void rpPut( PyObject* lib,
615//                       const char* path,
616//                       const char* value,
617//                       const char* id,
618//                       int append)
619/// fxn to mimic/implement the python call "lib.put('...')"
620/// fxn calls the put() member function of the Rappture.library class
621///     and creates user specified fields within xml document
622/**
623 * Clients use this function to call the put() member function of the
624 *          Rappture.library class and place custom text into the
625 *          Rappture object lib.
626 *
627 * Notes: The argument (lib) is not optional. If it is NULL,
628 *          NULL will be returned.
629 *
630 * Returns nothing.
631 */
632void rpPut( PyObject* lib,
633            const char* path,
634            const char* value,
635            const char* id,
636            int append )
637{
638    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
639
640    if (lib) {
641        // retrieve the lib.xml() function
642        mbr_fxn = PyObject_GetAttrString(lib, "put");
643
644        if (mbr_fxn) {
645
646            if (PyCallable_Check(mbr_fxn)) {
647                PyObject_CallFunction(mbr_fxn,"(sssi)",path,value,id,append);
648            }
649            Py_DECREF(mbr_fxn);
650        }
651    }
652    else {
653        // lib was set to NULL
654    }
655
656}
657
658/**********************************************************************/
659// FUNCTION: void rpPutObj( PyObject* lib,
660//                       const char* path,
661//                       const char* value,
662//                       const char* id,
663//                       int append)
664/// fxn to mimic/implement the python call "lib.put('...')"
665/// fxn calls the put() member function of the Rappture.library class
666///     and creates user specified fields within xml document
667/**
668 * Clients use this function to call the put() member function of the
669 *          Rappture.library class and place custom text into the
670 *          Rappture object lib.
671 *
672 * Notes: The argument (lib) is not optional. If it is NULL,
673 *          NULL will be returned.
674 *
675 * Returns nothing.
676 */
677void rpPutObj( PyObject* lib,
678            const char* path,
679            PyObject* value,
680            const char* id,
681            int append )
682{
683    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
684
685    if (lib) {
686        // retrieve the lib.xml() function
687        mbr_fxn = PyObject_GetAttrString(lib, "put");
688
689        if (mbr_fxn) {
690
691            if (PyCallable_Check(mbr_fxn)) {
692                PyObject_CallFunction(mbr_fxn,"(sOsi)",path,value,id,append);
693                // PyObject_CallFunctionObjArgs(mbr_fxn,path,value,id,append,NULL);
694            }
695            Py_DECREF(mbr_fxn);
696        }
697    }
698    else {
699        // lib was set to NULL
700    }
701
702}
703
704/**********************************************************************/
705// FUNCTION: PyObject* rpRemove(PyObject* lib, const char* path)
706/// fxn to mimic/implement the python call "lib.remove('...')"
707/// fxn calls the remove() member function of the Rappture.library class
708///     and removes the elements listed, if they exist
709/**
710 * Clients use this function to call the remove() member function of the
711 *          Rappture.library class and remove the elements of the
712 *          Rappture object lib.
713 *
714 * Notes: The argument (lib) is not optional. If it is NULL,
715 *          NULL will be returned.
716 *
717 * Returns nothin.
718 *
719 */
720PyObject* rpRemove(PyObject* lib, const char* path)
721{
722    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
723    PyObject* rslt      = NULL;      /* results from fxn call */
724   
725//    PyObject* args = NULL;
726//    PyObject* stringarg = NULL;
727
728
729    if (lib) {
730        // retrieve the lib.remove() function
731        mbr_fxn = PyObject_GetAttrString(lib, "remove");
732
733        if (mbr_fxn) {
734
735            if (PyCallable_Check(mbr_fxn)) {
736
737                // setup our arguments in a Python tuple
738                // args = PyTuple_New(1);
739                // stringarg = PyString_FromString(path);
740                // PyTuple_SetItem(args, 0, stringarg);
741
742                // call the class ... lib = Rappture.library("...")
743                // rslt = PyObject_CallObject(mbr_fxn, args);
744
745               
746                // call the lib.xml() function with no arguments
747                rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
748                // it is caller's responsibility to adjust reference count
749                // Py_DECREF(rslt);
750               
751            }
752            Py_DECREF(mbr_fxn);
753        }
754    }
755    else {
756        // lib was set to NULL
757    }
758
759    return rslt;
760   
761}
762
763/**********************************************************************/
764// FUNCTION: const char* rpXml(PyObject* lib)
765/// fxn to mimic/implement the python call "xmlText = lib.xml()"
766/// fxn calls the xml() member function of the Rappture.library class
767///     and returns the text to the caller
768/**
769 * Clients use this function to call the xml() member function of the
770 *          Rappture.library class and get the text of the Rappture
771 *          object lib.
772 *
773 * Notes: The argument (lib) is not optional. If it is NULL,
774 *          NULL will be returned.
775 *
776 * Returns pointer (char*) to the c style string representing the
777 *          xml text of the Rappture object if successful, or
778 *          NULL if something goes wrong.
779 *
780 *          return value no longer needs to be const because i copy it
781 *          to tmp space but it will need to be free'd now
782 */
783
784
785char* rpXml(PyObject* lib)
786{
787    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
788    PyObject* rslt      = NULL;      /* results from fxn call */
789    char* tmpretVal     = NULL;      /* return value */
790    char* retVal        = NULL;      /* return value */
791    int retValSize      = 0;
792
793    if (lib) {
794        // retrieve the lib.xml() function
795        mbr_fxn = PyObject_GetAttrString(lib, "xml");
796
797        if (mbr_fxn) {
798
799            if (PyCallable_Check(mbr_fxn)) {
800               
801                // call the lib.xml() function
802                rslt = PyObject_CallFunction(mbr_fxn,NULL);
803                if (rslt) {
804                    // convert the result to c style strings
805                    tmpretVal = PyString_AsString(rslt);
806                    if (tmpretVal) {
807                        // get str length, add 1 for null termination
808                        retValSize = strlen(tmpretVal) + 1;
809                        retVal = (char*) calloc(retValSize,sizeof(char));
810                        if (retVal) {
811                            strncpy(retVal,tmpretVal,retValSize);
812                        }
813                        else {
814                            // raise error, out of memory
815                        }
816                    }
817                    Py_DECREF(rslt);
818                }
819               
820            }
821            Py_DECREF(mbr_fxn);
822        }
823    }
824    else {
825        // lib was set to NULL
826    }
827
828    return retVal;
829   
830}
Note: See TracBrowser for help on using the repository browser.