blob: f2376776a5d5de7d36278cc094594b3fe7589224 [file] [log] [blame]
Daniel Veillard3ce52572002-02-03 15:08:05 +00001/*
2 * types.c: converter functions between the internal representation
3 * and the Python objects
4 *
5 * See Copyright for the status of this software.
6 *
7 * daniel@veillard.com
8 */
9#include "libxml_wrap.h"
Daniel Veillard5d279c92008-03-12 09:32:04 +000010#include <libxml/xpathInternals.h>
Daniel Veillard3ce52572002-02-03 15:08:05 +000011
Daniel Veillard3798c4a2013-03-29 13:46:24 +080012#if PY_MAJOR_VERSION >= 3
13#define PY_IMPORT_STRING_SIZE PyUnicode_FromStringAndSize
14#define PY_IMPORT_STRING PyUnicode_FromString
15#define PY_IMPORT_INT PyLong_FromLong
16#else
17#define PY_IMPORT_STRING_SIZE PyString_FromStringAndSize
18#define PY_IMPORT_STRING PyString_FromString
19#define PY_IMPORT_INT PyInt_FromLong
20#endif
21
22#if PY_MAJOR_VERSION >= 3
23#include <stdio.h>
24#include <unistd.h>
25#include <fcntl.h>
26
27FILE *
28libxml_PyFileGet(PyObject *f) {
29 int fd, flags;
30 FILE *res;
31 const char *mode;
32
33 fd = PyObject_AsFileDescriptor(f);
34 if (!_PyVerify_fd(fd))
35 return(NULL);
36 /*
37 * Get the flags on the fd to understand how it was opened
38 */
39 flags = fcntl(fd, F_GETFL, 0);
40 switch (flags & O_ACCMODE) {
41 case O_RDWR:
42 if (flags & O_APPEND)
43 mode = "a+";
44 else
45 mode = "rw";
46 break;
47 case O_RDONLY:
48 if (flags & O_APPEND)
49 mode = "r+";
50 else
51 mode = "r";
52 break;
53 case O_WRONLY:
54 if (flags & O_APPEND)
55 mode = "a";
56 else
57 mode = "w";
58 break;
59 default:
60 return(NULL);
61 }
62
63 /*
64 * the FILE struct gets a new fd, so that it can be closed
65 * independently of the file descriptor given. The risk though is
66 * lack of sync. So at the python level sync must be implemented
67 * before and after a conversion took place. No way around it
68 * in the Python3 infrastructure !
69 * The duplicated fd and FILE * will be released in the subsequent
70 * call to libxml_PyFileRelease() which must be genrated accodingly
71 */
72 fd = dup(fd);
73 if (fd == -1)
74 return(NULL);
75 res = fdopen(fd, mode);
76 if (res == NULL) {
77 close(fd);
78 return(NULL);
79 }
80 return(res);
81}
82
83void libxml_PyFileRelease(FILE *f) {
84 if (f != NULL)
85 fclose(f);
86}
87#endif
88
Daniel Veillard3ce52572002-02-03 15:08:05 +000089PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +000090libxml_intWrap(int val)
91{
Daniel Veillard3ce52572002-02-03 15:08:05 +000092 PyObject *ret;
93
94#ifdef DEBUG
95 printf("libxml_intWrap: val = %d\n", val);
96#endif
Daniel Veillard3798c4a2013-03-29 13:46:24 +080097 ret = PY_IMPORT_INT((long) val);
Daniel Veillardd2379012002-03-15 22:24:56 +000098 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +000099}
100
101PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000102libxml_longWrap(long val)
103{
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000104 PyObject *ret;
105
106#ifdef DEBUG
107 printf("libxml_longWrap: val = %ld\n", val);
108#endif
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800109 ret = PyLong_FromLong(val);
Daniel Veillardd2379012002-03-15 22:24:56 +0000110 return (ret);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000111}
112
113PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000114libxml_doubleWrap(double val)
115{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000116 PyObject *ret;
117
118#ifdef DEBUG
119 printf("libxml_doubleWrap: val = %f\n", val);
120#endif
121 ret = PyFloat_FromDouble((double) val);
Daniel Veillardd2379012002-03-15 22:24:56 +0000122 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000123}
124
125PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000126libxml_charPtrWrap(char *str)
127{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000128 PyObject *ret;
129
130#ifdef DEBUG
131 printf("libxml_xmlcharPtrWrap: str = %s\n", str);
132#endif
133 if (str == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000134 Py_INCREF(Py_None);
135 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000136 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800137 ret = PY_IMPORT_STRING(str);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000138 xmlFree(str);
Daniel Veillardd2379012002-03-15 22:24:56 +0000139 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000140}
141
142PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000143libxml_charPtrConstWrap(const char *str)
144{
Daniel Veillardc575b992002-02-08 13:28:40 +0000145 PyObject *ret;
146
147#ifdef DEBUG
148 printf("libxml_xmlcharPtrWrap: str = %s\n", str);
149#endif
150 if (str == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000151 Py_INCREF(Py_None);
152 return (Py_None);
Daniel Veillardc575b992002-02-08 13:28:40 +0000153 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800154 ret = PY_IMPORT_STRING(str);
Daniel Veillardd2379012002-03-15 22:24:56 +0000155 return (ret);
Daniel Veillardc575b992002-02-08 13:28:40 +0000156}
157
158PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000159libxml_xmlCharPtrWrap(xmlChar * str)
160{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000161 PyObject *ret;
162
163#ifdef DEBUG
164 printf("libxml_xmlCharPtrWrap: str = %s\n", str);
165#endif
166 if (str == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000167 Py_INCREF(Py_None);
168 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000169 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800170 ret = PY_IMPORT_STRING((char *) str);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000171 xmlFree(str);
Daniel Veillardd2379012002-03-15 22:24:56 +0000172 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000173}
174
175PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000176libxml_xmlCharPtrConstWrap(const xmlChar * str)
177{
Daniel Veillardc575b992002-02-08 13:28:40 +0000178 PyObject *ret;
179
180#ifdef DEBUG
181 printf("libxml_xmlCharPtrWrap: str = %s\n", str);
182#endif
183 if (str == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000184 Py_INCREF(Py_None);
185 return (Py_None);
Daniel Veillardc575b992002-02-08 13:28:40 +0000186 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800187 ret = PY_IMPORT_STRING((char *) str);
Daniel Veillardd2379012002-03-15 22:24:56 +0000188 return (ret);
Daniel Veillardc575b992002-02-08 13:28:40 +0000189}
190
191PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000192libxml_constcharPtrWrap(const char *str)
193{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000194 PyObject *ret;
195
196#ifdef DEBUG
197 printf("libxml_xmlcharPtrWrap: str = %s\n", str);
198#endif
199 if (str == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000200 Py_INCREF(Py_None);
201 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000202 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800203 ret = PY_IMPORT_STRING(str);
Daniel Veillardd2379012002-03-15 22:24:56 +0000204 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000205}
206
207PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000208libxml_constxmlCharPtrWrap(const xmlChar * str)
209{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000210 PyObject *ret;
211
212#ifdef DEBUG
213 printf("libxml_xmlCharPtrWrap: str = %s\n", str);
214#endif
215 if (str == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000216 Py_INCREF(Py_None);
217 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000218 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800219 ret = PY_IMPORT_STRING((char *) str);
Daniel Veillardd2379012002-03-15 22:24:56 +0000220 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000221}
222
223PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000224libxml_xmlDocPtrWrap(xmlDocPtr doc)
225{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000226 PyObject *ret;
227
228#ifdef DEBUG
229 printf("libxml_xmlDocPtrWrap: doc = %p\n", doc);
230#endif
231 if (doc == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000232 Py_INCREF(Py_None);
233 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000234 }
235 /* TODO: look at deallocation */
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800236 ret = PyCapsule_New((void *) doc, (char *) "xmlDocPtr", NULL);
Daniel Veillardd2379012002-03-15 22:24:56 +0000237 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000238}
239
240PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000241libxml_xmlNodePtrWrap(xmlNodePtr node)
242{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000243 PyObject *ret;
244
245#ifdef DEBUG
246 printf("libxml_xmlNodePtrWrap: node = %p\n", node);
247#endif
248 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000249 Py_INCREF(Py_None);
250 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000251 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800252 ret = PyCapsule_New((void *) node, (char *) "xmlNodePtr", NULL);
Daniel Veillardd2379012002-03-15 22:24:56 +0000253 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000254}
255
256PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000257libxml_xmlURIPtrWrap(xmlURIPtr uri)
258{
Daniel Veillard6361da02002-02-23 10:10:33 +0000259 PyObject *ret;
260
261#ifdef DEBUG
262 printf("libxml_xmlURIPtrWrap: uri = %p\n", uri);
263#endif
264 if (uri == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000265 Py_INCREF(Py_None);
266 return (Py_None);
Daniel Veillard6361da02002-02-23 10:10:33 +0000267 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800268 ret = PyCapsule_New((void *) uri, (char *) "xmlURIPtr", NULL);
Daniel Veillardd2379012002-03-15 22:24:56 +0000269 return (ret);
Daniel Veillard6361da02002-02-23 10:10:33 +0000270}
271
272PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000273libxml_xmlNsPtrWrap(xmlNsPtr ns)
274{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000275 PyObject *ret;
276
277#ifdef DEBUG
278 printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
279#endif
280 if (ns == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000281 Py_INCREF(Py_None);
282 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000283 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800284 ret = PyCapsule_New((void *) ns, (char *) "xmlNsPtr", NULL);
Daniel Veillardd2379012002-03-15 22:24:56 +0000285 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000286}
287
288PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000289libxml_xmlAttrPtrWrap(xmlAttrPtr attr)
290{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000291 PyObject *ret;
292
293#ifdef DEBUG
294 printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
295#endif
296 if (attr == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000297 Py_INCREF(Py_None);
298 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000299 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800300 ret = PyCapsule_New((void *) attr, (char *) "xmlAttrPtr", NULL);
Daniel Veillardd2379012002-03-15 22:24:56 +0000301 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000302}
303
304PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000305libxml_xmlAttributePtrWrap(xmlAttributePtr attr)
306{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000307 PyObject *ret;
308
309#ifdef DEBUG
310 printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
311#endif
312 if (attr == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000313 Py_INCREF(Py_None);
314 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000315 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800316 ret = PyCapsule_New((void *) attr, (char *) "xmlAttributePtr", NULL);
Daniel Veillardd2379012002-03-15 22:24:56 +0000317 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000318}
319
320PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000321libxml_xmlElementPtrWrap(xmlElementPtr elem)
322{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000323 PyObject *ret;
324
325#ifdef DEBUG
326 printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
327#endif
328 if (elem == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000329 Py_INCREF(Py_None);
330 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000331 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800332 ret = PyCapsule_New((void *) elem, (char *) "xmlElementPtr", NULL);
Daniel Veillardd2379012002-03-15 22:24:56 +0000333 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000334}
335
336PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000337libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)
338{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000339 PyObject *ret;
340
341#ifdef DEBUG
342 printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
343#endif
344 if (ctxt == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000345 Py_INCREF(Py_None);
346 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000347 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800348 ret = PyCapsule_New((void *) ctxt, (char *) "xmlXPathContextPtr", NULL);
Daniel Veillardd2379012002-03-15 22:24:56 +0000349 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000350}
351
352PyObject *
Daniel Veillard7db38712002-02-07 16:39:11 +0000353libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)
354{
355 PyObject *ret;
356
357#ifdef DEBUG
358 printf("libxml_xmlXPathParserContextPtrWrap: ctxt = %p\n", ctxt);
359#endif
360 if (ctxt == NULL) {
361 Py_INCREF(Py_None);
362 return (Py_None);
363 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800364 ret = PyCapsule_New((void *)ctxt, (char *)"xmlXPathParserContextPtr", NULL);
Daniel Veillard7db38712002-02-07 16:39:11 +0000365 return (ret);
366}
367
368PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000369libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)
370{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000371 PyObject *ret;
372
373#ifdef DEBUG
374 printf("libxml_xmlParserCtxtPtrWrap: ctxt = %p\n", ctxt);
375#endif
376 if (ctxt == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000377 Py_INCREF(Py_None);
378 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000379 }
Daniel Veillarde6227e02003-01-14 11:42:39 +0000380
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800381 ret = PyCapsule_New((void *) ctxt, (char *) "xmlParserCtxtPtr", NULL);
Daniel Veillardd2379012002-03-15 22:24:56 +0000382 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000383}
384
Daniel Veillard5d279c92008-03-12 09:32:04 +0000385/**
386 * libxml_xmlXPathDestructNsNode:
Daniel Veillardbf4a8f02013-04-02 10:27:57 +0800387 * cap: xmlNsPtr namespace node capsule object
Daniel Veillard5d279c92008-03-12 09:32:04 +0000388 *
389 * This function is called if and when a namespace node returned in
390 * an XPath node set is to be destroyed. That's the only kind of
391 * object returned in node set not directly linked to the original
392 * xmlDoc document, see xmlXPathNodeSetDupNs.
393 */
Daniel Veillardbf4a8f02013-04-02 10:27:57 +0800394#if PY_VERSION_HEX < 0x02070000
Daniel Veillard5d279c92008-03-12 09:32:04 +0000395static void
Daniel Veillardbf4a8f02013-04-02 10:27:57 +0800396libxml_xmlXPathDestructNsNode(void *cap, void *desc ATTRIBUTE_UNUSED)
397#else
398static void
399libxml_xmlXPathDestructNsNode(PyObject *cap)
Daniel Veillard5d279c92008-03-12 09:32:04 +0000400#endif
Daniel Veillardbf4a8f02013-04-02 10:27:57 +0800401{
402#ifdef DEBUG
403 fprintf(stderr, "libxml_xmlXPathDestructNsNode called %p\n", cap);
404#endif
405#if PY_VERSION_HEX < 0x02070000
406 xmlXPathNodeSetFreeNs((xmlNsPtr) cap);
407#else
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800408 xmlXPathNodeSetFreeNs((xmlNsPtr) PyCapsule_GetPointer(cap, "xmlNsPtr"));
Daniel Veillardbf4a8f02013-04-02 10:27:57 +0800409#endif
Daniel Veillard5d279c92008-03-12 09:32:04 +0000410}
411
Daniel Veillard3ce52572002-02-03 15:08:05 +0000412PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000413libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
414{
Daniel Veillard3ce52572002-02-03 15:08:05 +0000415 PyObject *ret;
416
417#ifdef DEBUG
418 printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
419#endif
420 if (obj == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000421 Py_INCREF(Py_None);
422 return (Py_None);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000423 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000424 switch (obj->type) {
Daniel Veillardc0ac0692002-10-20 21:31:50 +0000425 case XPATH_XSLT_TREE: {
426 if ((obj->nodesetval == NULL) ||
427 (obj->nodesetval->nodeNr == 0) ||
428 (obj->nodesetval->nodeTab == NULL)) {
429 ret = PyList_New(0);
430 } else {
431 int i, len = 0;
432 xmlNodePtr node;
433
434 node = obj->nodesetval->nodeTab[0]->children;
435 while (node != NULL) {
436 len++;
437 node = node->next;
438 }
439 ret = PyList_New(len);
440 node = obj->nodesetval->nodeTab[0]->children;
441 for (i = 0;i < len;i++) {
442 PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
443 node = node->next;
444 }
445 }
446 /*
447 * Return now, do not free the object passed down
448 */
449 return (ret);
450 }
Daniel Veillard3ce52572002-02-03 15:08:05 +0000451 case XPATH_NODESET:
Daniel Veillardd2379012002-03-15 22:24:56 +0000452 if ((obj->nodesetval == NULL)
Daniel Veillardc0ac0692002-10-20 21:31:50 +0000453 || (obj->nodesetval->nodeNr == 0)) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000454 ret = PyList_New(0);
Daniel Veillardc0ac0692002-10-20 21:31:50 +0000455 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +0000456 int i;
457 xmlNodePtr node;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000458
Daniel Veillardd2379012002-03-15 22:24:56 +0000459 ret = PyList_New(obj->nodesetval->nodeNr);
460 for (i = 0; i < obj->nodesetval->nodeNr; i++) {
461 node = obj->nodesetval->nodeTab[i];
Daniel Veillard5d279c92008-03-12 09:32:04 +0000462 if (node->type == XML_NAMESPACE_DECL) {
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800463 PyObject *ns = PyCapsule_New((void *) node,
Daniel Veillard5d279c92008-03-12 09:32:04 +0000464 (char *) "xmlNsPtr",
465 libxml_xmlXPathDestructNsNode);
466 PyList_SetItem(ret, i, ns);
467 /* make sure the xmlNsPtr is not destroyed now */
468 obj->nodesetval->nodeTab[i] = NULL;
469 } else {
470 PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
471 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000472 }
473 }
474 break;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000475 case XPATH_BOOLEAN:
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800476 ret = PY_IMPORT_INT((long) obj->boolval);
Daniel Veillardd2379012002-03-15 22:24:56 +0000477 break;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000478 case XPATH_NUMBER:
Daniel Veillardd2379012002-03-15 22:24:56 +0000479 ret = PyFloat_FromDouble(obj->floatval);
480 break;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000481 case XPATH_STRING:
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800482 ret = PY_IMPORT_STRING((char *) obj->stringval);
Daniel Veillardd2379012002-03-15 22:24:56 +0000483 break;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000484 case XPATH_POINT:
Daniel Veillard46459062006-10-10 08:40:04 +0000485 {
486 PyObject *node;
487 PyObject *indexIntoNode;
488 PyObject *tuple;
489
490 node = libxml_xmlNodePtrWrap(obj->user);
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800491 indexIntoNode = PY_IMPORT_INT((long) obj->index);
Daniel Veillard46459062006-10-10 08:40:04 +0000492
493 tuple = PyTuple_New(2);
494 PyTuple_SetItem(tuple, 0, node);
495 PyTuple_SetItem(tuple, 1, indexIntoNode);
496
497 ret = tuple;
498 break;
499 }
Daniel Veillard3ce52572002-02-03 15:08:05 +0000500 case XPATH_RANGE:
Daniel Veillard46459062006-10-10 08:40:04 +0000501 {
502 unsigned short bCollapsedRange;
503
504 bCollapsedRange = ( (obj->user2 == NULL) ||
505 ((obj->user2 == obj->user) && (obj->index == obj->index2)) );
506 if ( bCollapsedRange ) {
507 PyObject *node;
508 PyObject *indexIntoNode;
509 PyObject *tuple;
510 PyObject *list;
511
512 list = PyList_New(1);
513
514 node = libxml_xmlNodePtrWrap(obj->user);
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800515 indexIntoNode = PY_IMPORT_INT((long) obj->index);
Daniel Veillard46459062006-10-10 08:40:04 +0000516
517 tuple = PyTuple_New(2);
518 PyTuple_SetItem(tuple, 0, node);
519 PyTuple_SetItem(tuple, 1, indexIntoNode);
520
521 PyList_SetItem(list, 0, tuple);
522
523 ret = list;
524 } else {
525 PyObject *node;
526 PyObject *indexIntoNode;
527 PyObject *tuple;
528 PyObject *list;
529
530 list = PyList_New(2);
531
532 node = libxml_xmlNodePtrWrap(obj->user);
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800533 indexIntoNode = PY_IMPORT_INT((long) obj->index);
Daniel Veillard46459062006-10-10 08:40:04 +0000534
535 tuple = PyTuple_New(2);
536 PyTuple_SetItem(tuple, 0, node);
537 PyTuple_SetItem(tuple, 1, indexIntoNode);
538
539 PyList_SetItem(list, 0, tuple);
540
541 node = libxml_xmlNodePtrWrap(obj->user2);
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800542 indexIntoNode = PY_IMPORT_INT((long) obj->index2);
Daniel Veillard46459062006-10-10 08:40:04 +0000543
544 tuple = PyTuple_New(2);
545 PyTuple_SetItem(tuple, 0, node);
546 PyTuple_SetItem(tuple, 1, indexIntoNode);
547
548 PyList_SetItem(list, 1, tuple);
549
550 ret = list;
551 }
552 break;
553 }
Daniel Veillard3ce52572002-02-03 15:08:05 +0000554 case XPATH_LOCATIONSET:
Daniel Veillard46459062006-10-10 08:40:04 +0000555 {
556 xmlLocationSetPtr set;
557
558 set = obj->user;
559 if ( set && set->locNr > 0 ) {
560 int i;
561 PyObject *list;
562
563 list = PyList_New(set->locNr);
564
565 for (i=0; i<set->locNr; i++) {
566 xmlXPathObjectPtr setobj;
567 PyObject *pyobj;
568
569 setobj = set->locTab[i]; /*xmlXPathObjectPtr setobj*/
570
571 pyobj = libxml_xmlXPathObjectPtrWrap(setobj);
572 /* xmlXPathFreeObject(setobj) is called */
573 set->locTab[i] = NULL;
574
575 PyList_SetItem(list, i, pyobj);
576 }
577 set->locNr = 0;
578 ret = list;
579 } else {
580 Py_INCREF(Py_None);
581 ret = Py_None;
582 }
583 break;
584 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000585 default:
Daniel Veillard634ec272006-02-22 15:11:32 +0000586#ifdef DEBUG
Daniel Veillardd2379012002-03-15 22:24:56 +0000587 printf("Unable to convert XPath object type %d\n", obj->type);
Daniel Veillard634ec272006-02-22 15:11:32 +0000588#endif
Daniel Veillardd2379012002-03-15 22:24:56 +0000589 Py_INCREF(Py_None);
590 ret = Py_None;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000591 }
592 xmlXPathFreeObject(obj);
Daniel Veillardd2379012002-03-15 22:24:56 +0000593 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000594}
595
596xmlXPathObjectPtr
Armin K6eea2f22013-05-30 19:00:50 +0200597libxml_xmlXPathObjectPtrConvert(PyObject *obj)
Daniel Veillardd2379012002-03-15 22:24:56 +0000598{
Daniel Veillarda94ec6f2002-03-01 13:00:53 +0000599 xmlXPathObjectPtr ret = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000600
601#ifdef DEBUG
602 printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
603#endif
604 if (obj == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000605 return (NULL);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000606 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800607 if PyFloat_Check (obj) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000608 ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800609 } else if PyLong_Check(obj) {
610#ifdef PyLong_AS_LONG
611 ret = xmlXPathNewFloat((double) PyLong_AS_LONG(obj));
612#else
Daniel Veillarda4bd3692006-06-18 17:40:53 +0000613 ret = xmlXPathNewFloat((double) PyInt_AS_LONG(obj));
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800614#endif
Daniel Veillarddb670152007-06-12 10:04:37 +0000615#ifdef PyBool_Check
Daniel Veillarda4bd3692006-06-18 17:40:53 +0000616 } else if PyBool_Check (obj) {
617
618 if (obj == Py_True) {
619 ret = xmlXPathNewBoolean(1);
620 }
621 else {
622 ret = xmlXPathNewBoolean(0);
623 }
Daniel Veillarddb670152007-06-12 10:04:37 +0000624#endif
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800625 } else if PyBytes_Check (obj) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000626 xmlChar *str;
Daniel Veillard3ce52572002-02-03 15:08:05 +0000627
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800628 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(obj),
629 PyBytes_GET_SIZE(obj));
Daniel Veillardd2379012002-03-15 22:24:56 +0000630 ret = xmlXPathWrapString(str);
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800631#ifdef PyUnicode_Check
632 } else if PyUnicode_Check (obj) {
633#if PY_VERSION_HEX >= 0x03030000
634 xmlChar *str;
635 const char *tmp;
Armin K6eea2f22013-05-30 19:00:50 +0200636 Py_ssize_t size;
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800637
638 /* tmp doesn't need to be deallocated */
639 tmp = PyUnicode_AsUTF8AndSize(obj, &size);
Armin K6eea2f22013-05-30 19:00:50 +0200640 str = xmlStrndup((const xmlChar *) tmp, (int) size);
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800641 ret = xmlXPathWrapString(str);
642#else
643 xmlChar *str = NULL;
644 PyObject *b;
645
646 b = PyUnicode_AsUTF8String(obj);
647 if (b != NULL) {
648 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(b),
649 PyBytes_GET_SIZE(b));
650 Py_DECREF(b);
651 }
652 ret = xmlXPathWrapString(str);
653#endif
654#endif
655 } else if PyList_Check (obj) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000656 int i;
657 PyObject *node;
658 xmlNodePtr cur;
659 xmlNodeSetPtr set;
Daniel Veillarda94ec6f2002-03-01 13:00:53 +0000660
Daniel Veillardd2379012002-03-15 22:24:56 +0000661 set = xmlXPathNodeSetCreate(NULL);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +0000662
Daniel Veillardd2379012002-03-15 22:24:56 +0000663 for (i = 0; i < PyList_Size(obj); i++) {
664 node = PyList_GetItem(obj, i);
665 if ((node == NULL) || (node->ob_type == NULL))
666 continue;
Daniel Veillard79426f22002-03-01 16:14:17 +0000667
Daniel Veillardd2379012002-03-15 22:24:56 +0000668 cur = NULL;
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800669 if (PyCapsule_CheckExact(node)) {
Daniel Veillard634ec272006-02-22 15:11:32 +0000670#ifdef DEBUG
Daniel Veillardbf4a8f02013-04-02 10:27:57 +0800671 printf("Got a Capsule\n");
Daniel Veillard634ec272006-02-22 15:11:32 +0000672#endif
Daniel Veillardd2379012002-03-15 22:24:56 +0000673 cur = PyxmlNode_Get(node);
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800674 } else if ((PyObject_HasAttrString(node, (char *) "_o")) &&
675 (PyObject_HasAttrString(node, (char *) "get_doc"))) {
676 PyObject *wrapper;
Daniel Veillard79426f22002-03-01 16:14:17 +0000677
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800678 wrapper = PyObject_GetAttrString(node, (char *) "_o");
679 if (wrapper != NULL)
680 cur = PyxmlNode_Get(wrapper);
Daniel Veillardd2379012002-03-15 22:24:56 +0000681 } else {
Daniel Veillard634ec272006-02-22 15:11:32 +0000682#ifdef DEBUG
Daniel Veillardd2379012002-03-15 22:24:56 +0000683 printf("Unknown object in Python return list\n");
Daniel Veillard634ec272006-02-22 15:11:32 +0000684#endif
Daniel Veillardd2379012002-03-15 22:24:56 +0000685 }
686 if (cur != NULL) {
687 xmlXPathNodeSetAdd(set, cur);
688 }
689 }
690 ret = xmlXPathWrapNodeSet(set);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000691 } else {
Daniel Veillard634ec272006-02-22 15:11:32 +0000692#ifdef DEBUG
Daniel Veillardd2379012002-03-15 22:24:56 +0000693 printf("Unable to convert Python Object to XPath");
Daniel Veillard634ec272006-02-22 15:11:32 +0000694#endif
Daniel Veillard3ce52572002-02-03 15:08:05 +0000695 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000696 return (ret);
Daniel Veillard3ce52572002-02-03 15:08:05 +0000697}
698
Daniel Veillard7db38712002-02-07 16:39:11 +0000699PyObject *
Daniel Veillard850ce9b2004-11-10 11:55:47 +0000700libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)
701{
702 PyObject *ret;
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800703
Daniel Veillard850ce9b2004-11-10 11:55:47 +0000704#ifdef DEBUG
705 printf("libxml_xmlValidCtxtPtrWrap: valid = %p\n", valid);
706#endif
707 if (valid == NULL) {
708 Py_INCREF(Py_None);
709 return (Py_None);
710 }
711
712 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800713 PyCapsule_New((void *) valid,
Daniel Veillard850ce9b2004-11-10 11:55:47 +0000714 (char *) "xmlValidCtxtPtr", NULL);
715
716 return (ret);
717}
718
719PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000720libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
721{
Daniel Veillard7db38712002-02-07 16:39:11 +0000722 PyObject *ret;
723
724#ifdef DEBUG
725 printf("libxml_xmlNodePtrWrap: catal = %p\n", catal);
726#endif
727 if (catal == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000728 Py_INCREF(Py_None);
729 return (Py_None);
Daniel Veillard7db38712002-02-07 16:39:11 +0000730 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000731 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800732 PyCapsule_New((void *) catal,
Daniel Veillardd2379012002-03-15 22:24:56 +0000733 (char *) "xmlCatalogPtr", NULL);
734 return (ret);
Daniel Veillard7db38712002-02-07 16:39:11 +0000735}
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000736
737PyObject *
738libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)
739{
740 PyObject *ret;
741
742#ifdef DEBUG
743 printf("libxml_xmlOutputBufferPtrWrap: buffer = %p\n", buffer);
744#endif
745 if (buffer == NULL) {
746 Py_INCREF(Py_None);
747 return (Py_None);
748 }
749 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800750 PyCapsule_New((void *) buffer,
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000751 (char *) "xmlOutputBufferPtr", NULL);
752 return (ret);
753}
754
755PyObject *
756libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)
757{
758 PyObject *ret;
759
760#ifdef DEBUG
761 printf("libxml_xmlParserInputBufferPtrWrap: buffer = %p\n", buffer);
762#endif
763 if (buffer == NULL) {
764 Py_INCREF(Py_None);
765 return (Py_None);
766 }
767 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800768 PyCapsule_New((void *) buffer,
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000769 (char *) "xmlParserInputBufferPtr", NULL);
770 return (ret);
771}
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000772
Daniel Veillard0e298ad2003-02-04 16:14:33 +0000773#ifdef LIBXML_REGEXP_ENABLED
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000774PyObject *
775libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)
776{
777 PyObject *ret;
778
779#ifdef DEBUG
780 printf("libxml_xmlRegexpPtrWrap: regexp = %p\n", regexp);
781#endif
782 if (regexp == NULL) {
783 Py_INCREF(Py_None);
784 return (Py_None);
785 }
786 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800787 PyCapsule_New((void *) regexp,
Daniel Veillardbd9afb52002-09-25 22:25:35 +0000788 (char *) "xmlRegexpPtr", NULL);
789 return (ret);
790}
Daniel Veillard0e298ad2003-02-04 16:14:33 +0000791#endif /* LIBXML_REGEXP_ENABLED */
Daniel Veillard0eb38c72002-12-14 23:00:35 +0000792
Daniel Veillard438ebbd2008-05-12 12:58:46 +0000793#ifdef LIBXML_READER_ENABLED
Daniel Veillard0eb38c72002-12-14 23:00:35 +0000794PyObject *
795libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
796{
797 PyObject *ret;
798
799#ifdef DEBUG
800 printf("libxml_xmlTextReaderPtrWrap: reader = %p\n", reader);
801#endif
802 if (reader == NULL) {
803 Py_INCREF(Py_None);
804 return (Py_None);
805 }
806 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800807 PyCapsule_New((void *) reader,
Daniel Veillard0eb38c72002-12-14 23:00:35 +0000808 (char *) "xmlTextReaderPtr", NULL);
809 return (ret);
810}
Daniel Veillard417be3a2003-01-20 21:26:34 +0000811
812PyObject *
813libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)
814{
815 PyObject *ret;
816
817#ifdef DEBUG
818 printf("libxml_xmlTextReaderLocatorPtrWrap: locator = %p\n", locator);
819#endif
820 if (locator == NULL) {
821 Py_INCREF(Py_None);
822 return (Py_None);
823 }
824 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800825 PyCapsule_New((void *) locator,
Daniel Veillard417be3a2003-01-20 21:26:34 +0000826 (char *) "xmlTextReaderLocatorPtr", NULL);
827 return (ret);
828}
Daniel Veillard438ebbd2008-05-12 12:58:46 +0000829#endif /* LIBXML_READER_ENABLED */
Daniel Veillard417be3a2003-01-20 21:26:34 +0000830
Daniel Veillard591b4be2003-02-09 23:33:36 +0000831#ifdef LIBXML_SCHEMAS_ENABLED
832PyObject *
833libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt)
834{
835 PyObject *ret;
836
837#ifdef DEBUG
838 printf("libxml_xmlRelaxNGPtrWrap: ctxt = %p\n", ctxt);
839#endif
840 if (ctxt == NULL) {
841 Py_INCREF(Py_None);
842 return (Py_None);
843 }
844 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800845 PyCapsule_New((void *) ctxt,
Daniel Veillard591b4be2003-02-09 23:33:36 +0000846 (char *) "xmlRelaxNGPtr", NULL);
847 return (ret);
848}
849
850PyObject *
851libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt)
852{
853 PyObject *ret;
854
855#ifdef DEBUG
856 printf("libxml_xmlRelaxNGParserCtxtPtrWrap: ctxt = %p\n", ctxt);
857#endif
858 if (ctxt == NULL) {
859 Py_INCREF(Py_None);
860 return (Py_None);
861 }
862 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800863 PyCapsule_New((void *) ctxt,
Daniel Veillard591b4be2003-02-09 23:33:36 +0000864 (char *) "xmlRelaxNGParserCtxtPtr", NULL);
865 return (ret);
866}
867PyObject *
868libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)
869{
870 PyObject *ret;
871
872#ifdef DEBUG
873 printf("libxml_xmlRelaxNGValidCtxtPtrWrap: valid = %p\n", valid);
874#endif
875 if (valid == NULL) {
876 Py_INCREF(Py_None);
877 return (Py_None);
878 }
879 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800880 PyCapsule_New((void *) valid,
Daniel Veillard591b4be2003-02-09 23:33:36 +0000881 (char *) "xmlRelaxNGValidCtxtPtr", NULL);
882 return (ret);
883}
Daniel Veillard259f0df2004-08-18 09:13:18 +0000884
885PyObject *
886libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)
887{
888 PyObject *ret;
889
890#ifdef DEBUG
891 printf("libxml_xmlSchemaPtrWrap: ctxt = %p\n", ctxt);
892#endif
893 if (ctxt == NULL) {
894 Py_INCREF(Py_None);
895 return (Py_None);
896 }
897 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800898 PyCapsule_New((void *) ctxt,
Daniel Veillard259f0df2004-08-18 09:13:18 +0000899 (char *) "xmlSchemaPtr", NULL);
900 return (ret);
901}
902
903PyObject *
904libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)
905{
906 PyObject *ret;
907
908#ifdef DEBUG
909 printf("libxml_xmlSchemaParserCtxtPtrWrap: ctxt = %p\n", ctxt);
910#endif
911 if (ctxt == NULL) {
912 Py_INCREF(Py_None);
913 return (Py_None);
914 }
915 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800916 PyCapsule_New((void *) ctxt,
Daniel Veillard259f0df2004-08-18 09:13:18 +0000917 (char *) "xmlSchemaParserCtxtPtr", NULL);
918
919 return (ret);
920}
921
922PyObject *
923libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)
924{
925 PyObject *ret;
926
927#ifdef DEBUG
928 printf("libxml_xmlSchemaValidCtxtPtrWrap: valid = %p\n", valid);
929#endif
930 if (valid == NULL) {
931 Py_INCREF(Py_None);
932 return (Py_None);
933 }
934
935 ret =
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800936 PyCapsule_New((void *) valid,
Daniel Veillard259f0df2004-08-18 09:13:18 +0000937 (char *) "xmlSchemaValidCtxtPtr", NULL);
938
939 return (ret);
940}
Daniel Veillard591b4be2003-02-09 23:33:36 +0000941#endif /* LIBXML_SCHEMAS_ENABLED */
Daniel Veillard46da4642004-01-06 22:54:57 +0000942
943PyObject *
944libxml_xmlErrorPtrWrap(xmlErrorPtr error)
945{
946 PyObject *ret;
947
948#ifdef DEBUG
949 printf("libxml_xmlErrorPtrWrap: error = %p\n", error);
950#endif
951 if (error == NULL) {
952 Py_INCREF(Py_None);
953 return (Py_None);
954 }
Daniel Veillard3798c4a2013-03-29 13:46:24 +0800955 ret = PyCapsule_New((void *) error, (char *) "xmlErrorPtr", NULL);
Daniel Veillard46da4642004-01-06 22:54:57 +0000956 return (ret);
957}