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

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

initial submission of the Rappture Core components and language bindings

File size: 25.4 KB
Line 
1#include "../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
105    if (rpObj) {
106        if (path) {
107            // setup our arguments in a Python tuple
108            args = PyTuple_New(1);
109            stringarg = PyString_FromString(path);
110            PyTuple_SetItem(args, 0, stringarg);
111                   
112            // call the class ... lib = Rappture.library("...")
113            lib = PyObject_CallObject(rpObj, args);
114           
115            // following line could cause a segfault if used in place of above
116            // maybe path could == NULL or bad memory
117            // lib = PyObject_CallFunction(rpObj,"(s)", path);
118
119            if (lib) {
120                // return the Rappture instantiation.
121                retVal = lib;
122            }
123            else {
124                // lib was not successfully created
125            }
126
127            Py_DECREF(stringarg);
128            Py_DECREF(args);
129        }
130        else {
131            // path was null
132        }
133    }
134    else {
135        // rpObj was null
136    }
137
138    return retVal;
139
140}
141
142/**********************************************************************/
143// FUNCTION: void* rpElement(PyObject* lib, const char* path, const char* flavor)
144/// fxn to mimic/implement the python call "element = lib.element("..")"
145/// fxn calls the element() member function of the Rappture.library
146///     class and returns the text to the caller
147/**
148 * Clients use this function to call the element() member function of the
149 *          Rappture.library class and get the text of the Rappture
150 *          object lib.
151 *
152 * Notes:   If (flavor == "object") || (flavor == NULL),
153 *          1) it is the client's responsibility to increment and
154 *             decrement the reference count of the returned object
155 *             as needed.
156 *          2) the return object will need to be cast as a PyObject*
157 *             to use it.
158 *
159 *          If (flavor == type) || (flavor == id) || (flavor == component),
160 *          1) the return object will need to be cast as a char*
161 *             to use it.
162 *       
163 *        The Arguments lib and pathare not optional.
164 *          If either value is NULL, NULL will be returned.
165 *
166 * Returns pointer (char*) to the c style string representing the
167 *          xml text of the Rappture object if successful, or
168 *          NULL if something goes wrong.
169 */
170
171void* rpElement(PyObject* lib, const char* path, const char* flavor)
172{
173    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
174    PyObject* rslt      = NULL;      /* results from fxn call */
175    void* retVal        = NULL;      /* fxn return value */
176
177    if (lib && path) {
178       
179        // retrieve the lib.element() function
180        mbr_fxn = PyObject_GetAttrString(lib, "element");
181
182        if (mbr_fxn) {
183
184            if (PyCallable_Check(mbr_fxn)) {
185               
186                // call the lib.element() function with arguments
187                if (flavor) {
188                    rslt = PyObject_CallFunction(mbr_fxn,"(ss)", path, flavor);
189                }
190                else {
191                    rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
192                }
193
194                if (rslt) {
195
196                    if (flavor == NULL) {
197                        // return a PyObject*
198                        retVal = (void*) rslt;
199                    }
200                    else if((*flavor == 'o')&&(strncmp(flavor,"object", 6)==0)){
201                        // return a PyObject*
202                        retVal = (void*) rslt;
203                    }
204                    else if (
205                      ((*flavor == 't')&&(strncmp(flavor,"type", 4) == 0))
206                    ||((*flavor == 'i')&&(strncmp(flavor,"id", 2) == 0))
207                    ||((*flavor == 'c')&&(strncmp(flavor,"component", 9) == 0)))
208                    {
209                        // return a char*
210                        // convert the result to c style strings
211                        retVal = (void*) PyString_AsString(rslt);
212                        Py_DECREF(rslt);
213                    }
214                    else {
215                        // unrecognized format
216                    }
217                   
218                    // Py_DECREF(rslt);
219
220                } // rslt was null
221               
222            } // mbr_fxn was not callable
223           
224            Py_DECREF(mbr_fxn);
225        } // mbr_fxn was null
226    }
227    else {
228        // lib or path was set to NULL
229    }
230
231    return retVal;
232}
233
234
235/**********************************************************************/
236// FUNCTION: void** rpChildren(PyObject* lib, const char* path, const char* flavor)
237/// fxn to mimic/implement the python call "xmlText = lib.children("..")"
238/// fxn calls the element() member function of the Rappture.library
239///     class and returns the text to the caller
240/**
241 * Clients use this function to call the xml() member function of the
242 *          Rappture.library class and get the text of the Rappture
243 *          object lib.
244 *
245 * Notes:   If (flavor == "object") || (flavor == NULL),
246 *          1) it is the client's responsibility to increment and
247 *             decrement the reference count of the returned object
248 *             as needed.
249 *          2) the return object will need to be cast as a PyObject*
250 *             to use it.
251 *
252 *          If (flavor == "type")||(flavor == "id")||(flavor == "component"),
253 *          1) the return object will need to be case as a char*
254 *             to use it.
255 *       
256 *        The Arguments lib and pathare not optional.
257 *          If either value is NULL, NULL will be returned.
258 *
259 * Returns pointer (char*) to the c style string representing the
260 *          xml text of the Rappture object if successful, or
261 *          NULL if something goes wrong.
262 */
263
264void** rpChildren(PyObject* lib, const char* path, const char* flavor)
265{
266    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
267    PyObject* rslt      = NULL;      /* results from fxn call */
268    PyObject* list_item = NULL;      /* item from list of returned children */
269//    void* retVal        = NULL;      /* fxn return value */
270    int list_size       = 0;
271    int index           = 0;
272    char** rslt_arr_c   = NULL;
273    void** rslt_arr  = NULL;
274
275    if (lib && path) {
276       
277        // retrieve the lib.children() function
278        mbr_fxn = PyObject_GetAttrString(lib, "children");
279
280        if (mbr_fxn) {
281
282            if (PyCallable_Check(mbr_fxn)) {
283               
284                // call the lib.element() function with arguments
285                if (flavor) {
286                    rslt = PyObject_CallFunction(mbr_fxn,"(ss)", path, flavor);
287                }
288                else {
289                    rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
290                }
291
292                if (rslt) {
293
294                    if (flavor == NULL) {
295                        // return a PyObject*
296                        // retVal = (void*) rslt;
297                        //
298                        // the PyObject* points to a list, so we need to
299                        // convert this to an array of char*'s
300
301                        list_size = PyList_Size(rslt);
302                        rslt_arr = (void**) calloc(list_size+1,sizeof(void*));
303                        if (rslt_arr) {
304                            while (index < list_size) {
305                                // list_item is a borrowed reference
306                                list_item = PyList_GetItem(rslt,index);
307                                rslt_arr[index] = (void*) (list_item);
308                                index++;
309                            }
310                            // *(rslt_arr[index]) = (void*)NULL;
311                        }
312                    }
313                    else if((*flavor == 'o')&&(strncmp(flavor,"object", 6)==0)){
314                        // return a PyObject*
315                        // retVal = (void*) rslt;
316                        //
317                        // the PyObject* points to a list, so we need to
318                        // convert this to an array of char*'s
319
320                        list_size = PyList_Size(rslt);
321                        rslt_arr = (void**) calloc(list_size+1,sizeof(void*));
322                        if (rslt_arr) {
323                            while (index < list_size) {
324                                // list_item is a borrowed reference
325                                list_item = PyList_GetItem(rslt,index);
326                                rslt_arr[index] = (void*) (list_item);
327                                index++;
328                            }
329                            // *(rslt_arr[index]) = NULL;
330                        }
331                    }
332                    else if (
333                      ((*flavor == 't')&&(strncmp(flavor,"type", 4) == 0))
334                    ||((*flavor == 'i')&&(strncmp(flavor,"id", 2) == 0))
335                    ||((*flavor == 'c')&&(strncmp(flavor,"component", 9) == 0)))
336                    {
337                        // the PyObject* points to a list, so we need to
338                        // convert this to an array of char*'s
339
340                        list_size = PyList_Size(rslt);
341                        rslt_arr_c = (char**) calloc(list_size+1,sizeof(char*));
342                        if (rslt_arr_c) {
343                            while (index < list_size) {
344                                // list_item is a borrowed reference
345                                list_item = PyList_GetItem(rslt,index);
346                                // we cannot deallocate the results of
347                                // PyString_AsString()
348                                rslt_arr_c[index] = PyString_AsString(list_item);
349                                index++;
350                               
351                            }
352                            // *(rslt_arr[index]) = NULL;
353                            rslt_arr = (void**) rslt_arr_c;
354                        }
355                        // return a char*
356                        // convert the result to c style strings
357                        // retVal = (void*) PyString_AsString(rslt);
358                        Py_DECREF(rslt);
359                    }
360                    else {
361                        // unrecognized format
362                    }
363                   
364                    // Py_DECREF(rslt);
365
366                } // rslt was null
367               
368            } // mbr_fxn was not callable
369           
370            Py_DECREF(mbr_fxn);
371        } // mbr_fxn was null
372    }
373    else {
374        // lib or path was set to NULL
375    }
376
377    // return retVal;
378    return (void**) rslt_arr;
379}
380
381/**********************************************************************/
382// FUNCTION: PyObject* rpChildren_f(PyObject* lib, const char* path, const char* flavor)
383/// fxn to mimic/implement the python call "xmlText = lib.children("..")"
384/// fxn calls the element() member function of the Rappture.library
385///     class and returns the text to the caller
386/**
387 * Clients use this function to call the xml() member function of the
388 *          Rappture.library class and get the text of the Rappture
389 *          object lib.
390 *
391 * Notes:   If (flavor == "object") || (flavor == NULL),
392 *          1) it is the client's responsibility to increment and
393 *             decrement the reference count of the returned object
394 *             as needed.
395 *          2) the return object will need to be cast as a PyObject*
396 *             to use it.
397 *
398 *          If (flavor == "type")||(flavor == "id")||(flavor == "component"),
399 *          1) the return object will need to be case as a char*
400 *             to use it.
401 *       
402 *        The Arguments lib and pathare not optional.
403 *          If either value is NULL, NULL will be returned.
404 *
405 * Returns pointer (char*) to the c style string representing the
406 *          xml text of the Rappture object if successful, or
407 *          NULL if something goes wrong.
408 */
409
410PyObject* rpChildren_f(PyObject* lib, const char* path, const char* flavor)
411{
412    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
413    PyObject* rslt      = NULL;      /* results from fxn call */
414//    PyObject* list_item = NULL;      /* item from list of returned children */
415//    void* retVal        = NULL;      /* fxn return value */
416//    int list_size       = 0;
417//    int index           = 0;
418//    char** rslt_arr_c   = NULL;
419//    void** rslt_arr  = NULL;
420
421//    char* xmlChild = NULL;
422
423    if (lib && path) {
424       
425        // retrieve the lib.children() function
426        mbr_fxn = PyObject_GetAttrString(lib, "children");
427
428        if (mbr_fxn) {
429
430            if (PyCallable_Check(mbr_fxn)) {
431               
432                // call the lib.children() function with arguments
433                if (flavor) {
434                    rslt = PyObject_CallFunction(mbr_fxn,"(ss)", path, flavor);
435                }
436                else {
437                    rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
438                }
439
440                /*
441                if (rslt) {
442                    list_size = PyList_Size(rslt);
443                    while (index < list_size) {
444                        // list_item is a borrowed reference
445                        list_item = PyList_GetItem(rslt,index);
446                        // we cannot deallocate the results of
447                        // PyString_AsString()
448                        // printf("list item = :%x:\n", list_item);
449                        xmlChild = PyString_AsString(list_item);
450                        printf("xml = :%s:\n",xmlChild);
451                        index++;
452                    }
453                }
454                */
455
456                /*
457                if (rslt) {
458                    list_item = PyList_GetItem(rslt,0);
459                    xmlChild = PyString_AsString(list_item);
460                    printf("xml0 = :%s:\n",xmlChild);
461                    list_item = PyList_GetItem(rslt,1);
462                    xmlChild = PyString_AsString(list_item);
463                    printf("xml1 = :%s:\n",xmlChild);
464                } // rslt was null
465                */
466               
467            } // mbr_fxn was not callable
468           
469            Py_DECREF(mbr_fxn);
470        } // mbr_fxn was null
471    }
472    else {
473        // lib or path was set to NULL
474    }
475
476    return rslt;
477}
478
479/**********************************************************************/
480// FUNCTION: const char* rpGet(PyObject* lib, const char* path)
481/// fxn to mimic/implement the python call "xmlText = lib.get('...')"
482/// fxn calls the get() member function of the Rappture.library class
483///     and returns the text to the caller
484/**
485 * Clients use this function to call the get() member function of the
486 *          Rappture.library class and get the text of the Rappture
487 *          object lib.
488 *
489 * Notes: The argument (lib) is not optional. If it is NULL,
490 *          NULL will be returned.
491 *
492 * Returns pointer (const char*) to the c style string representing the
493 *          xml text provided by the path of the Rappture object if
494 *          successful, or NULL if something goes wrong.
495 *
496 *          The return value's contents should not be changed because
497 *          it is a pointer being borrowed from python's buffer space
498 *          (hence the _const_)
499 */
500const char* rpGet(PyObject* lib, const char* path)
501{
502    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
503    PyObject* rslt      = NULL;      /* results from fxn call */
504    char* retVal        = NULL;      /* return value */
505
506    if (lib) {
507        // retrieve the lib.get() function
508        mbr_fxn = PyObject_GetAttrString(lib, "get");
509
510        if (mbr_fxn) {
511
512            if (PyCallable_Check(mbr_fxn)) {
513               
514                // call the lib.get() function
515                rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
516                if (rslt) {
517                    // convert the result to c style strings
518                    retVal = PyString_AsString(rslt);
519                    // Py_DECREF(rslt);
520                }
521               
522            }
523            Py_DECREF(mbr_fxn);
524        }
525    }
526    else {
527        // lib was set to NULL
528    }
529
530    return (const char*) retVal;
531   
532}
533
534/**********************************************************************/
535// FUNCTION: void rpPut( PyObject* lib,
536//                       const char* path,
537//                       const char* value,
538//                       const char* id,
539//                       int append)
540/// fxn to mimic/implement the python call "lib.put('...')"
541/// fxn calls the put() member function of the Rappture.library class
542///     and creates user specified fields within xml document
543/**
544 * Clients use this function to call the put() member function of the
545 *          Rappture.library class and place custom text into the
546 *          Rappture object lib.
547 *
548 * Notes: The argument (lib) is not optional. If it is NULL,
549 *          NULL will be returned.
550 *
551 * Returns nothing.
552 */
553void rpPut( PyObject* lib,
554            const char* path,
555            const char* value,
556            const char* id,
557            int append )
558{
559    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
560
561    if (lib) {
562        // retrieve the lib.xml() function
563        mbr_fxn = PyObject_GetAttrString(lib, "put");
564
565        if (mbr_fxn) {
566
567            if (PyCallable_Check(mbr_fxn)) {
568                PyObject_CallFunction(mbr_fxn,"(sssi)",path,value,id,append);
569            }
570            Py_DECREF(mbr_fxn);
571        }
572    }
573    else {
574        // lib was set to NULL
575    }
576
577}
578
579/**********************************************************************/
580// FUNCTION: void rpPutObj( PyObject* lib,
581//                       const char* path,
582//                       const char* value,
583//                       const char* id,
584//                       int append)
585/// fxn to mimic/implement the python call "lib.put('...')"
586/// fxn calls the put() member function of the Rappture.library class
587///     and creates user specified fields within xml document
588/**
589 * Clients use this function to call the put() member function of the
590 *          Rappture.library class and place custom text into the
591 *          Rappture object lib.
592 *
593 * Notes: The argument (lib) is not optional. If it is NULL,
594 *          NULL will be returned.
595 *
596 * Returns nothing.
597 */
598void rpPutObj( PyObject* lib,
599            const char* path,
600            PyObject* value,
601            const char* id,
602            int append )
603{
604    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
605
606    if (lib) {
607        // retrieve the lib.xml() function
608        mbr_fxn = PyObject_GetAttrString(lib, "put");
609
610        if (mbr_fxn) {
611
612            if (PyCallable_Check(mbr_fxn)) {
613                PyObject_CallFunction(mbr_fxn,"(sOsi)",path,value,id,append);
614                // PyObject_CallFunctionObjArgs(mbr_fxn,path,value,id,append,NULL);
615            }
616            Py_DECREF(mbr_fxn);
617        }
618    }
619    else {
620        // lib was set to NULL
621    }
622
623}
624
625/**********************************************************************/
626// FUNCTION: PyObject* rpRemove(PyObject* lib, const char* path)
627/// fxn to mimic/implement the python call "lib.remove('...')"
628/// fxn calls the remove() member function of the Rappture.library class
629///     and removes the elements listed, if they exist
630/**
631 * Clients use this function to call the remove() member function of the
632 *          Rappture.library class and remove the elements of the
633 *          Rappture object lib.
634 *
635 * Notes: The argument (lib) is not optional. If it is NULL,
636 *          NULL will be returned.
637 *
638 * Returns nothin.
639 *
640 */
641PyObject* rpRemove(PyObject* lib, const char* path)
642{
643    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
644    PyObject* rslt      = NULL;      /* results from fxn call */
645   
646//    PyObject* args = NULL;
647//    PyObject* stringarg = NULL;
648
649
650    if (lib) {
651        // retrieve the lib.remove() function
652        mbr_fxn = PyObject_GetAttrString(lib, "remove");
653
654        if (mbr_fxn) {
655
656            if (PyCallable_Check(mbr_fxn)) {
657
658                // setup our arguments in a Python tuple
659                // args = PyTuple_New(1);
660                // stringarg = PyString_FromString(path);
661                // PyTuple_SetItem(args, 0, stringarg);
662
663                // call the class ... lib = Rappture.library("...")
664                // rslt = PyObject_CallObject(mbr_fxn, args);
665
666               
667                // call the lib.xml() function with no arguments
668                rslt = PyObject_CallFunction(mbr_fxn,"(s)", path);
669                // it is caller's responsibility to adjust reference count
670                // Py_DECREF(rslt);
671               
672            }
673            Py_DECREF(mbr_fxn);
674        }
675    }
676    else {
677        // lib was set to NULL
678    }
679
680    return rslt;
681   
682}
683
684/**********************************************************************/
685// FUNCTION: const char* rpXml(PyObject* lib)
686/// fxn to mimic/implement the python call "xmlText = lib.xml()"
687/// fxn calls the xml() member function of the Rappture.library class
688///     and returns the text to the caller
689/**
690 * Clients use this function to call the xml() member function of the
691 *          Rappture.library class and get the text of the Rappture
692 *          object lib.
693 *
694 * Notes: The argument (lib) is not optional. If it is NULL,
695 *          NULL will be returned.
696 *
697 * Returns pointer (const char*) to the c style string representing the
698 *          xml text of the Rappture object if successful, or
699 *          NULL if something goes wrong.
700 *
701 *          The return value's contents should not be changed because
702 *          it is a pointer being borrowed from python's buffer space
703 *          (hence the _const_)
704 */
705
706
707const char* rpXml(PyObject* lib)
708{
709    PyObject* mbr_fxn   = NULL;      /* pointer to fxn of class lib */
710    PyObject* rslt      = NULL;      /* results from fxn call */
711    char* retVal        = NULL;      /* return value */
712
713    if (lib) {
714        // retrieve the lib.xml() function
715        mbr_fxn = PyObject_GetAttrString(lib, "xml");
716
717        if (mbr_fxn) {
718
719            if (PyCallable_Check(mbr_fxn)) {
720               
721                // call the lib.xml() function
722                rslt = PyObject_CallFunction(mbr_fxn,NULL);
723                if (rslt) {
724                    // convert the result to c style strings
725                    retVal = PyString_AsString(rslt);
726                    Py_DECREF(rslt);
727                }
728               
729            }
730            Py_DECREF(mbr_fxn);
731        }
732    }
733    else {
734        // lib was set to NULL
735    }
736
737    return (const char*) retVal;
738   
739}
Note: See TracBrowser for help on using the repository browser.