1/*
2xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
3	                                       const char *ID,
4					       xmlParserCtxtPtr ctxt);
5
6 * types.c: converter functions between the internal representation
7 *          and the Python objects
8 *
9 * See Copyright for the status of this software.
10 *
11 * daniel@veillard.com
12 */
13#include "libxml_wrap.h"
14#include <libxml/xpathInternals.h>
15
16PyObject *
17libxml_intWrap(int val)
18{
19    PyObject *ret;
20
21#ifdef DEBUG
22    printf("libxml_intWrap: val = %d\n", val);
23#endif
24    ret = PyInt_FromLong((long) val);
25    return (ret);
26}
27
28PyObject *
29libxml_longWrap(long val)
30{
31    PyObject *ret;
32
33#ifdef DEBUG
34    printf("libxml_longWrap: val = %ld\n", val);
35#endif
36    ret = PyInt_FromLong(val);
37    return (ret);
38}
39
40PyObject *
41libxml_doubleWrap(double val)
42{
43    PyObject *ret;
44
45#ifdef DEBUG
46    printf("libxml_doubleWrap: val = %f\n", val);
47#endif
48    ret = PyFloat_FromDouble((double) val);
49    return (ret);
50}
51
52PyObject *
53libxml_charPtrWrap(char *str)
54{
55    PyObject *ret;
56
57#ifdef DEBUG
58    printf("libxml_xmlcharPtrWrap: str = %s\n", str);
59#endif
60    if (str == NULL) {
61        Py_INCREF(Py_None);
62        return (Py_None);
63    }
64    /* TODO: look at deallocation */
65    ret = PyString_FromString(str);
66    xmlFree(str);
67    return (ret);
68}
69
70PyObject *
71libxml_charPtrConstWrap(const char *str)
72{
73    PyObject *ret;
74
75#ifdef DEBUG
76    printf("libxml_xmlcharPtrWrap: str = %s\n", str);
77#endif
78    if (str == NULL) {
79        Py_INCREF(Py_None);
80        return (Py_None);
81    }
82    /* TODO: look at deallocation */
83    ret = PyString_FromString(str);
84    return (ret);
85}
86
87PyObject *
88libxml_xmlCharPtrWrap(xmlChar * str)
89{
90    PyObject *ret;
91
92#ifdef DEBUG
93    printf("libxml_xmlCharPtrWrap: str = %s\n", str);
94#endif
95    if (str == NULL) {
96        Py_INCREF(Py_None);
97        return (Py_None);
98    }
99    /* TODO: look at deallocation */
100    ret = PyString_FromString((char *) str);
101    xmlFree(str);
102    return (ret);
103}
104
105PyObject *
106libxml_xmlCharPtrConstWrap(const xmlChar * str)
107{
108    PyObject *ret;
109
110#ifdef DEBUG
111    printf("libxml_xmlCharPtrWrap: str = %s\n", str);
112#endif
113    if (str == NULL) {
114        Py_INCREF(Py_None);
115        return (Py_None);
116    }
117    /* TODO: look at deallocation */
118    ret = PyString_FromString((char *) str);
119    return (ret);
120}
121
122PyObject *
123libxml_constcharPtrWrap(const char *str)
124{
125    PyObject *ret;
126
127#ifdef DEBUG
128    printf("libxml_xmlcharPtrWrap: str = %s\n", str);
129#endif
130    if (str == NULL) {
131        Py_INCREF(Py_None);
132        return (Py_None);
133    }
134    /* TODO: look at deallocation */
135    ret = PyString_FromString(str);
136    return (ret);
137}
138
139PyObject *
140libxml_constxmlCharPtrWrap(const xmlChar * str)
141{
142    PyObject *ret;
143
144#ifdef DEBUG
145    printf("libxml_xmlCharPtrWrap: str = %s\n", str);
146#endif
147    if (str == NULL) {
148        Py_INCREF(Py_None);
149        return (Py_None);
150    }
151    /* TODO: look at deallocation */
152    ret = PyString_FromString((char *) str);
153    return (ret);
154}
155
156PyObject *
157libxml_xmlDocPtrWrap(xmlDocPtr doc)
158{
159    PyObject *ret;
160
161#ifdef DEBUG
162    printf("libxml_xmlDocPtrWrap: doc = %p\n", doc);
163#endif
164    if (doc == NULL) {
165        Py_INCREF(Py_None);
166        return (Py_None);
167    }
168    /* TODO: look at deallocation */
169    ret =
170        PyCObject_FromVoidPtrAndDesc((void *) doc, (char *) "xmlDocPtr",
171                                     NULL);
172    return (ret);
173}
174
175PyObject *
176libxml_xmlNodePtrWrap(xmlNodePtr node)
177{
178    PyObject *ret;
179
180#ifdef DEBUG
181    printf("libxml_xmlNodePtrWrap: node = %p\n", node);
182#endif
183    if (node == NULL) {
184        Py_INCREF(Py_None);
185        return (Py_None);
186    }
187    ret =
188        PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "xmlNodePtr",
189                                     NULL);
190    return (ret);
191}
192
193PyObject *
194libxml_xmlURIPtrWrap(xmlURIPtr uri)
195{
196    PyObject *ret;
197
198#ifdef DEBUG
199    printf("libxml_xmlURIPtrWrap: uri = %p\n", uri);
200#endif
201    if (uri == NULL) {
202        Py_INCREF(Py_None);
203        return (Py_None);
204    }
205    ret =
206        PyCObject_FromVoidPtrAndDesc((void *) uri, (char *) "xmlURIPtr",
207                                     NULL);
208    return (ret);
209}
210
211PyObject *
212libxml_xmlNsPtrWrap(xmlNsPtr ns)
213{
214    PyObject *ret;
215
216#ifdef DEBUG
217    printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
218#endif
219    if (ns == NULL) {
220        Py_INCREF(Py_None);
221        return (Py_None);
222    }
223    ret =
224        PyCObject_FromVoidPtrAndDesc((void *) ns, (char *) "xmlNsPtr",
225                                     NULL);
226    return (ret);
227}
228
229PyObject *
230libxml_xmlAttrPtrWrap(xmlAttrPtr attr)
231{
232    PyObject *ret;
233
234#ifdef DEBUG
235    printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
236#endif
237    if (attr == NULL) {
238        Py_INCREF(Py_None);
239        return (Py_None);
240    }
241    ret =
242        PyCObject_FromVoidPtrAndDesc((void *) attr, (char *) "xmlAttrPtr",
243                                     NULL);
244    return (ret);
245}
246
247PyObject *
248libxml_xmlAttributePtrWrap(xmlAttributePtr attr)
249{
250    PyObject *ret;
251
252#ifdef DEBUG
253    printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
254#endif
255    if (attr == NULL) {
256        Py_INCREF(Py_None);
257        return (Py_None);
258    }
259    ret =
260        PyCObject_FromVoidPtrAndDesc((void *) attr,
261                                     (char *) "xmlAttributePtr", NULL);
262    return (ret);
263}
264
265PyObject *
266libxml_xmlElementPtrWrap(xmlElementPtr elem)
267{
268    PyObject *ret;
269
270#ifdef DEBUG
271    printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
272#endif
273    if (elem == NULL) {
274        Py_INCREF(Py_None);
275        return (Py_None);
276    }
277    ret =
278        PyCObject_FromVoidPtrAndDesc((void *) elem,
279                                     (char *) "xmlElementPtr", NULL);
280    return (ret);
281}
282
283PyObject *
284libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)
285{
286    PyObject *ret;
287
288#ifdef DEBUG
289    printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
290#endif
291    if (ctxt == NULL) {
292        Py_INCREF(Py_None);
293        return (Py_None);
294    }
295    ret =
296        PyCObject_FromVoidPtrAndDesc((void *) ctxt,
297                                     (char *) "xmlXPathContextPtr", NULL);
298    return (ret);
299}
300
301PyObject *
302libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)
303{
304    PyObject *ret;
305
306#ifdef DEBUG
307    printf("libxml_xmlXPathParserContextPtrWrap: ctxt = %p\n", ctxt);
308#endif
309    if (ctxt == NULL) {
310        Py_INCREF(Py_None);
311        return (Py_None);
312    }
313    ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt,
314                                       (char *) "xmlXPathParserContextPtr",
315                                       NULL);
316    return (ret);
317}
318
319PyObject *
320libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)
321{
322    PyObject *ret;
323
324#ifdef DEBUG
325    printf("libxml_xmlParserCtxtPtrWrap: ctxt = %p\n", ctxt);
326#endif
327    if (ctxt == NULL) {
328        Py_INCREF(Py_None);
329        return (Py_None);
330    }
331    ret =
332        PyCObject_FromVoidPtrAndDesc((void *) ctxt,
333                                     (char *) "xmlParserCtxtPtr", NULL);
334    return (ret);
335}
336
337/**
338 * libxml_xmlXPathDestructNsNode:
339 * cobj: xmlNsPtr namespace node
340 * desc: ignored string
341 *
342 * This function is called if and when a namespace node returned in
343 * an XPath node set is to be destroyed. That's the only kind of
344 * object returned in node set not directly linked to the original
345 * xmlDoc document, see xmlXPathNodeSetDupNs.
346 */
347static void
348libxml_xmlXPathDestructNsNode(void *cobj, void *desc ATTRIBUTE_UNUSED) {
349#ifdef DEBUG
350    fprintf(stderr, "libxml_xmlXPathDestructNsNode called %p\n", cobj);
351#endif
352    xmlXPathNodeSetFreeNs((xmlNsPtr) cobj);
353}
354
355PyObject *
356libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
357{
358    PyObject *ret;
359
360#ifdef DEBUG
361    printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
362#endif
363    if (obj == NULL) {
364        Py_INCREF(Py_None);
365        return (Py_None);
366    }
367    switch (obj->type) {
368        case XPATH_XSLT_TREE: {
369            if ((obj->nodesetval == NULL) ||
370		(obj->nodesetval->nodeNr == 0) ||
371		(obj->nodesetval->nodeTab == NULL)) {
372                ret = PyList_New(0);
373	    } else {
374		int i, len = 0;
375		xmlNodePtr node;
376
377		node = obj->nodesetval->nodeTab[0]->children;
378		while (node != NULL) {
379		    len++;
380		    node = node->next;
381		}
382		ret = PyList_New(len);
383		node = obj->nodesetval->nodeTab[0]->children;
384		for (i = 0;i < len;i++) {
385                    PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
386		    node = node->next;
387		}
388	    }
389	    /*
390	     * Return now, do not free the object passed down
391	     */
392	    return (ret);
393	}
394        case XPATH_NODESET:
395            if ((obj->nodesetval == NULL)
396                || (obj->nodesetval->nodeNr == 0)) {
397                ret = PyList_New(0);
398	    } else {
399                int i;
400                xmlNodePtr node;
401
402                ret = PyList_New(obj->nodesetval->nodeNr);
403                for (i = 0; i < obj->nodesetval->nodeNr; i++) {
404                    node = obj->nodesetval->nodeTab[i];
405                    if (node->type == XML_NAMESPACE_DECL) {
406		        PyObject *ns =
407			    PyCObject_FromVoidPtrAndDesc((void *) node,
408                                     (char *) "xmlNsPtr",
409				     libxml_xmlXPathDestructNsNode);
410			PyList_SetItem(ret, i, ns);
411			/* make sure the xmlNsPtr is not destroyed now */
412			obj->nodesetval->nodeTab[i] = NULL;
413		    } else {
414			PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
415		    }
416                }
417            }
418            break;
419        case XPATH_BOOLEAN:
420            ret = PyInt_FromLong((long) obj->boolval);
421            break;
422        case XPATH_NUMBER:
423            ret = PyFloat_FromDouble(obj->floatval);
424            break;
425        case XPATH_STRING:
426            ret = PyString_FromString((char *) obj->stringval);
427            break;
428        case XPATH_POINT:
429        case XPATH_RANGE:
430        case XPATH_LOCATIONSET:
431        default:
432#ifdef DEBUG
433            printf("Unable to convert XPath object type %d\n", obj->type);
434#endif
435            Py_INCREF(Py_None);
436            ret = Py_None;
437    }
438    xmlXPathFreeObject(obj);
439    return (ret);
440}
441
442xmlXPathObjectPtr
443libxml_xmlXPathObjectPtrConvert(PyObject * obj)
444{
445    xmlXPathObjectPtr ret = NULL;
446
447#ifdef DEBUG
448    printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
449#endif
450    if (obj == NULL) {
451        return (NULL);
452    }
453    if PyFloat_Check
454        (obj) {
455        ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
456    } else if PyInt_Check(obj) {
457
458        ret = xmlXPathNewFloat((double) PyInt_AS_LONG(obj));
459
460    } else if PyBool_Check (obj) {
461
462        if (obj == Py_True) {
463          ret = xmlXPathNewBoolean(1);
464        }
465        else {
466          ret = xmlXPathNewBoolean(0);
467        }
468
469    } else if PyString_Check
470        (obj) {
471        xmlChar *str;
472
473        str = xmlStrndup((const xmlChar *) PyString_AS_STRING(obj),
474                         PyString_GET_SIZE(obj));
475        ret = xmlXPathWrapString(str);
476    } else if PyList_Check
477        (obj) {
478        int i;
479        PyObject *node;
480        xmlNodePtr cur;
481        xmlNodeSetPtr set;
482
483        set = xmlXPathNodeSetCreate(NULL);
484
485        for (i = 0; i < PyList_Size(obj); i++) {
486            node = PyList_GetItem(obj, i);
487            if ((node == NULL) || (node->ob_type == NULL))
488                continue;
489
490            cur = NULL;
491            if (PyCObject_Check(node)) {
492#ifdef DEBUG
493                printf("Got a CObject\n");
494#endif
495                cur = PyxmlNode_Get(node);
496            } else if (PyInstance_Check(node)) {
497                PyInstanceObject *inst = (PyInstanceObject *) node;
498                PyObject *name = inst->in_class->cl_name;
499
500                if PyString_Check
501                    (name) {
502                    char *type = PyString_AS_STRING(name);
503                    PyObject *wrapper;
504
505                    if (!strcmp(type, "xmlNode")) {
506                        wrapper =
507                            PyObject_GetAttrString(node, (char *) "_o");
508                        if (wrapper != NULL) {
509                            cur = PyxmlNode_Get(wrapper);
510                        }
511                    }
512                    }
513            } else {
514#ifdef DEBUG
515                printf("Unknown object in Python return list\n");
516#endif
517            }
518            if (cur != NULL) {
519                xmlXPathNodeSetAdd(set, cur);
520            }
521        }
522        ret = xmlXPathWrapNodeSet(set);
523    } else {
524#ifdef DEBUG
525        printf("Unable to convert Python Object to XPath");
526#endif
527    }
528    Py_DECREF(obj);
529    return (ret);
530}
531
532PyObject *
533libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
534{
535    PyObject *ret;
536
537#ifdef DEBUG
538    printf("libxml_xmlNodePtrWrap: catal = %p\n", catal);
539#endif
540    if (catal == NULL) {
541        Py_INCREF(Py_None);
542        return (Py_None);
543    }
544    ret =
545        PyCObject_FromVoidPtrAndDesc((void *) catal,
546                                     (char *) "xmlCatalogPtr", NULL);
547    return (ret);
548}
549
550PyObject *
551libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)
552{
553    PyObject *ret;
554
555#ifdef DEBUG
556    printf("libxml_xmlOutputBufferPtrWrap: buffer = %p\n", buffer);
557#endif
558    if (buffer == NULL) {
559        Py_INCREF(Py_None);
560        return (Py_None);
561    }
562    ret =
563        PyCObject_FromVoidPtrAndDesc((void *) buffer,
564                                     (char *) "xmlOutputBufferPtr", NULL);
565    return (ret);
566}
567
568PyObject *
569libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)
570{
571    PyObject *ret;
572
573#ifdef DEBUG
574    printf("libxml_xmlParserInputBufferPtrWrap: buffer = %p\n", buffer);
575#endif
576    if (buffer == NULL) {
577        Py_INCREF(Py_None);
578        return (Py_None);
579    }
580    ret =
581        PyCObject_FromVoidPtrAndDesc((void *) buffer,
582                                     (char *) "xmlParserInputBufferPtr", NULL);
583    return (ret);
584}
585
586PyObject *
587libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)
588{
589    PyObject *ret;
590
591#ifdef DEBUG
592    printf("libxml_xmlRegexpPtrWrap: regexp = %p\n", regexp);
593#endif
594    if (regexp == NULL) {
595        Py_INCREF(Py_None);
596        return (Py_None);
597    }
598    ret =
599        PyCObject_FromVoidPtrAndDesc((void *) regexp,
600                                     (char *) "xmlRegexpPtr", NULL);
601    return (ret);
602}
603