1 /*
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"
10 #include <libxml/xpathInternals.h>
11
12 #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 <stdint.h>
25
26 #ifdef _WIN32
27
28 #include <windows.h>
29 #include <crtdbg.h>
30
31 /* Taken from info on MSDN site, as we may not have the Windows WDK/DDK headers */
32 typedef struct _IO_STATUS_BLOCK {
33 union {
34 NTSTATUS Status;
35 PVOID Pointer;
36 } DUMMYUNIONNAME;
37 ULONG_PTR Information;
38 } IO_STATUS_BLOCK;
39
40 typedef struct _FILE_ACCESS_INFORMATION {
41 ACCESS_MASK AccessFlags;
42 } FILE_ACCESS_INFORMATION;
43
44 typedef NTSTATUS (*t_NtQueryInformationFile) (HANDLE FileHandle,
45 IO_STATUS_BLOCK *IoStatusBlock,
46 PVOID FileInformation,
47 ULONG Length,
48 int FileInformationClass); /* this is an Enum */
49
50 #if (defined (_MSC_VER) && _MSC_VER >= 1400)
51 /*
52 * This is the (empty) invalid parameter handler
53 * that is used for Visual C++ 2005 (and later) builds
54 * so that we can use this instead of the system automatically
55 * aborting the process.
56 *
57 * This is necessary as we use _get_oshandle() to check the validity
58 * of the file descriptors as we close them, so when an invalid file
59 * descriptor is passed into that function as we check on it, we get
60 * -1 as the result, instead of the gspawn helper program aborting.
61 *
62 * Please see http://msdn.microsoft.com/zh-tw/library/ks2530z6%28v=vs.80%29.aspx
63 * for an explanation on this.
64 */
65 void
myInvalidParameterHandler(const wchar_t * expression,const wchar_t * function,const wchar_t * file,unsigned int line,uintptr_t pReserved)66 myInvalidParameterHandler(const wchar_t *expression,
67 const wchar_t *function,
68 const wchar_t *file,
69 unsigned int line,
70 uintptr_t pReserved)
71 {
72 }
73 #endif
74 #else
75 #include <unistd.h>
76 #include <fcntl.h>
77 #endif
78
79 FILE *
libxml_PyFileGet(PyObject * f)80 libxml_PyFileGet(PyObject *f) {
81 int flags;
82 FILE *res;
83 const char *mode;
84
85 int fd = PyObject_AsFileDescriptor(f);
86 intptr_t w_fh = -1;
87
88 #ifdef _WIN32
89 HMODULE hntdll = NULL;
90 IO_STATUS_BLOCK status_block;
91 FILE_ACCESS_INFORMATION ai;
92 t_NtQueryInformationFile NtQueryInformationFile;
93 BOOL is_read = FALSE;
94 BOOL is_write = FALSE;
95 BOOL is_append = FALSE;
96
97 #if (defined (_MSC_VER) && _MSC_VER >= 1400)
98 /* set up our empty invalid parameter handler */
99 _invalid_parameter_handler oldHandler, newHandler;
100 newHandler = myInvalidParameterHandler;
101 oldHandler = _set_invalid_parameter_handler(newHandler);
102
103 /* Disable the message box for assertions. */
104 _CrtSetReportMode(_CRT_ASSERT, 0);
105 #endif
106
107 w_fh = _get_osfhandle(fd);
108
109 if (w_fh == -1)
110 return(NULL);
111
112 hntdll = GetModuleHandleW(L"ntdll.dll");
113
114 if (hntdll == NULL)
115 return(NULL);
116
117 NtQueryInformationFile = (t_NtQueryInformationFile)GetProcAddress(hntdll, "NtQueryInformationFile");
118
119 if (NtQueryInformationFile != NULL &&
120 (NtQueryInformationFile((HANDLE)w_fh,
121 &status_block,
122 &ai,
123 sizeof(FILE_ACCESS_INFORMATION),
124 8) == 0)) /* 8 means "FileAccessInformation" */
125 {
126 if (ai.AccessFlags & FILE_READ_DATA)
127 is_read = TRUE;
128 if (ai.AccessFlags & FILE_WRITE_DATA)
129 is_write = TRUE;
130 if (ai.AccessFlags & FILE_APPEND_DATA)
131 is_append = TRUE;
132
133 if (is_write && is_read)
134 if (is_append)
135 mode = "a+";
136 else
137 mode = "rw";
138
139 if (!is_write && is_read)
140 if (is_append)
141 mode = "r+";
142 else
143 mode = "r";
144
145 if (is_write && !is_read)
146 if (is_append)
147 mode = "a";
148 else
149 mode = "w";
150 }
151
152 FreeLibrary(hntdll);
153
154 if (!is_write && !is_read) /* also happens if we did not load or run NtQueryInformationFile() successfully */
155 return(NULL);
156 #else
157 /*
158 * Get the flags on the fd to understand how it was opened
159 */
160 flags = fcntl(fd, F_GETFL, 0);
161 switch (flags & O_ACCMODE) {
162 case O_RDWR:
163 if (flags & O_APPEND)
164 mode = "a+";
165 else
166 mode = "rw";
167 break;
168 case O_RDONLY:
169 if (flags & O_APPEND)
170 mode = "r+";
171 else
172 mode = "r";
173 break;
174 case O_WRONLY:
175 if (flags & O_APPEND)
176 mode = "a";
177 else
178 mode = "w";
179 break;
180 default:
181 return(NULL);
182 }
183 #endif
184
185 /*
186 * the FILE struct gets a new fd, so that it can be closed
187 * independently of the file descriptor given. The risk though is
188 * lack of sync. So at the python level sync must be implemented
189 * before and after a conversion took place. No way around it
190 * in the Python3 infrastructure !
191 * The duplicated fd and FILE * will be released in the subsequent
192 * call to libxml_PyFileRelease() which must be generated accordingly
193 */
194 fd = dup(fd);
195 if (fd == -1)
196 return(NULL);
197 res = fdopen(fd, mode);
198 if (res == NULL) {
199 close(fd);
200 return(NULL);
201 }
202 return(res);
203 }
204
libxml_PyFileRelease(FILE * f)205 void libxml_PyFileRelease(FILE *f) {
206 if (f != NULL)
207 fclose(f);
208 }
209 #endif
210
211 PyObject *
libxml_intWrap(int val)212 libxml_intWrap(int val)
213 {
214 PyObject *ret;
215
216 #ifdef DEBUG
217 printf("libxml_intWrap: val = %d\n", val);
218 #endif
219 ret = PY_IMPORT_INT((long) val);
220 return (ret);
221 }
222
223 PyObject *
libxml_longWrap(long val)224 libxml_longWrap(long val)
225 {
226 PyObject *ret;
227
228 #ifdef DEBUG
229 printf("libxml_longWrap: val = %ld\n", val);
230 #endif
231 ret = PyLong_FromLong(val);
232 return (ret);
233 }
234
235 PyObject *
libxml_doubleWrap(double val)236 libxml_doubleWrap(double val)
237 {
238 PyObject *ret;
239
240 #ifdef DEBUG
241 printf("libxml_doubleWrap: val = %f\n", val);
242 #endif
243 ret = PyFloat_FromDouble((double) val);
244 return (ret);
245 }
246
247 PyObject *
libxml_charPtrWrap(char * str)248 libxml_charPtrWrap(char *str)
249 {
250 PyObject *ret;
251
252 #ifdef DEBUG
253 printf("libxml_xmlcharPtrWrap: str = %s\n", str);
254 #endif
255 if (str == NULL) {
256 Py_INCREF(Py_None);
257 return (Py_None);
258 }
259 ret = PY_IMPORT_STRING(str);
260 xmlFree(str);
261 return (ret);
262 }
263
264 PyObject *
libxml_charPtrConstWrap(const char * str)265 libxml_charPtrConstWrap(const char *str)
266 {
267 PyObject *ret;
268
269 #ifdef DEBUG
270 printf("libxml_xmlcharPtrWrap: str = %s\n", str);
271 #endif
272 if (str == NULL) {
273 Py_INCREF(Py_None);
274 return (Py_None);
275 }
276 ret = PY_IMPORT_STRING(str);
277 return (ret);
278 }
279
280 PyObject *
libxml_xmlCharPtrWrap(xmlChar * str)281 libxml_xmlCharPtrWrap(xmlChar * str)
282 {
283 PyObject *ret;
284
285 #ifdef DEBUG
286 printf("libxml_xmlCharPtrWrap: str = %s\n", str);
287 #endif
288 if (str == NULL) {
289 Py_INCREF(Py_None);
290 return (Py_None);
291 }
292 ret = PY_IMPORT_STRING((char *) str);
293 xmlFree(str);
294 return (ret);
295 }
296
297 PyObject *
libxml_xmlCharPtrConstWrap(const xmlChar * str)298 libxml_xmlCharPtrConstWrap(const xmlChar * str)
299 {
300 PyObject *ret;
301
302 #ifdef DEBUG
303 printf("libxml_xmlCharPtrWrap: str = %s\n", str);
304 #endif
305 if (str == NULL) {
306 Py_INCREF(Py_None);
307 return (Py_None);
308 }
309 ret = PY_IMPORT_STRING((char *) str);
310 return (ret);
311 }
312
313 PyObject *
libxml_constcharPtrWrap(const char * str)314 libxml_constcharPtrWrap(const char *str)
315 {
316 PyObject *ret;
317
318 #ifdef DEBUG
319 printf("libxml_xmlcharPtrWrap: str = %s\n", str);
320 #endif
321 if (str == NULL) {
322 Py_INCREF(Py_None);
323 return (Py_None);
324 }
325 ret = PY_IMPORT_STRING(str);
326 return (ret);
327 }
328
329 PyObject *
libxml_constxmlCharPtrWrap(const xmlChar * str)330 libxml_constxmlCharPtrWrap(const xmlChar * str)
331 {
332 PyObject *ret;
333
334 #ifdef DEBUG
335 printf("libxml_xmlCharPtrWrap: str = %s\n", str);
336 #endif
337 if (str == NULL) {
338 Py_INCREF(Py_None);
339 return (Py_None);
340 }
341 ret = PY_IMPORT_STRING((char *) str);
342 return (ret);
343 }
344
345 PyObject *
libxml_xmlDocPtrWrap(xmlDocPtr doc)346 libxml_xmlDocPtrWrap(xmlDocPtr doc)
347 {
348 PyObject *ret;
349
350 #ifdef DEBUG
351 printf("libxml_xmlDocPtrWrap: doc = %p\n", doc);
352 #endif
353 if (doc == NULL) {
354 Py_INCREF(Py_None);
355 return (Py_None);
356 }
357 /* TODO: look at deallocation */
358 ret = PyCapsule_New((void *) doc, (char *) "xmlDocPtr", NULL);
359 return (ret);
360 }
361
362 PyObject *
libxml_xmlNodePtrWrap(xmlNodePtr node)363 libxml_xmlNodePtrWrap(xmlNodePtr node)
364 {
365 PyObject *ret;
366
367 #ifdef DEBUG
368 printf("libxml_xmlNodePtrWrap: node = %p\n", node);
369 #endif
370 if (node == NULL) {
371 Py_INCREF(Py_None);
372 return (Py_None);
373 }
374 ret = PyCapsule_New((void *) node, (char *) "xmlNodePtr", NULL);
375 return (ret);
376 }
377
378 PyObject *
libxml_xmlURIPtrWrap(xmlURIPtr uri)379 libxml_xmlURIPtrWrap(xmlURIPtr uri)
380 {
381 PyObject *ret;
382
383 #ifdef DEBUG
384 printf("libxml_xmlURIPtrWrap: uri = %p\n", uri);
385 #endif
386 if (uri == NULL) {
387 Py_INCREF(Py_None);
388 return (Py_None);
389 }
390 ret = PyCapsule_New((void *) uri, (char *) "xmlURIPtr", NULL);
391 return (ret);
392 }
393
394 PyObject *
libxml_xmlNsPtrWrap(xmlNsPtr ns)395 libxml_xmlNsPtrWrap(xmlNsPtr ns)
396 {
397 PyObject *ret;
398
399 #ifdef DEBUG
400 printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
401 #endif
402 if (ns == NULL) {
403 Py_INCREF(Py_None);
404 return (Py_None);
405 }
406 ret = PyCapsule_New((void *) ns, (char *) "xmlNsPtr", NULL);
407 return (ret);
408 }
409
410 PyObject *
libxml_xmlAttrPtrWrap(xmlAttrPtr attr)411 libxml_xmlAttrPtrWrap(xmlAttrPtr attr)
412 {
413 PyObject *ret;
414
415 #ifdef DEBUG
416 printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
417 #endif
418 if (attr == NULL) {
419 Py_INCREF(Py_None);
420 return (Py_None);
421 }
422 ret = PyCapsule_New((void *) attr, (char *) "xmlAttrPtr", NULL);
423 return (ret);
424 }
425
426 PyObject *
libxml_xmlAttributePtrWrap(xmlAttributePtr attr)427 libxml_xmlAttributePtrWrap(xmlAttributePtr attr)
428 {
429 PyObject *ret;
430
431 #ifdef DEBUG
432 printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
433 #endif
434 if (attr == NULL) {
435 Py_INCREF(Py_None);
436 return (Py_None);
437 }
438 ret = PyCapsule_New((void *) attr, (char *) "xmlAttributePtr", NULL);
439 return (ret);
440 }
441
442 PyObject *
libxml_xmlElementPtrWrap(xmlElementPtr elem)443 libxml_xmlElementPtrWrap(xmlElementPtr elem)
444 {
445 PyObject *ret;
446
447 #ifdef DEBUG
448 printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
449 #endif
450 if (elem == NULL) {
451 Py_INCREF(Py_None);
452 return (Py_None);
453 }
454 ret = PyCapsule_New((void *) elem, (char *) "xmlElementPtr", NULL);
455 return (ret);
456 }
457
458 PyObject *
libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)459 libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)
460 {
461 PyObject *ret;
462
463 #ifdef DEBUG
464 printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
465 #endif
466 if (ctxt == NULL) {
467 Py_INCREF(Py_None);
468 return (Py_None);
469 }
470 ret = PyCapsule_New((void *) ctxt, (char *) "xmlXPathContextPtr", NULL);
471 return (ret);
472 }
473
474 PyObject *
libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)475 libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)
476 {
477 PyObject *ret;
478
479 #ifdef DEBUG
480 printf("libxml_xmlXPathParserContextPtrWrap: ctxt = %p\n", ctxt);
481 #endif
482 if (ctxt == NULL) {
483 Py_INCREF(Py_None);
484 return (Py_None);
485 }
486 ret = PyCapsule_New((void *)ctxt, (char *)"xmlXPathParserContextPtr", NULL);
487 return (ret);
488 }
489
490 PyObject *
libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)491 libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)
492 {
493 PyObject *ret;
494
495 #ifdef DEBUG
496 printf("libxml_xmlParserCtxtPtrWrap: ctxt = %p\n", ctxt);
497 #endif
498 if (ctxt == NULL) {
499 Py_INCREF(Py_None);
500 return (Py_None);
501 }
502
503 ret = PyCapsule_New((void *) ctxt, (char *) "xmlParserCtxtPtr", NULL);
504 return (ret);
505 }
506
507 /**
508 * libxml_xmlXPathDestructNsNode:
509 * cap: xmlNsPtr namespace node capsule object
510 *
511 * This function is called if and when a namespace node returned in
512 * an XPath node set is to be destroyed. That's the only kind of
513 * object returned in node set not directly linked to the original
514 * xmlDoc document, see xmlXPathNodeSetDupNs.
515 */
516 #if PY_VERSION_HEX < 0x02070000
517 static void
libxml_xmlXPathDestructNsNode(void * cap,void * desc ATTRIBUTE_UNUSED)518 libxml_xmlXPathDestructNsNode(void *cap, void *desc ATTRIBUTE_UNUSED)
519 #else
520 static void
521 libxml_xmlXPathDestructNsNode(PyObject *cap)
522 #endif
523 {
524 #ifdef DEBUG
525 fprintf(stderr, "libxml_xmlXPathDestructNsNode called %p\n", cap);
526 #endif
527 #if PY_VERSION_HEX < 0x02070000
528 xmlXPathNodeSetFreeNs((xmlNsPtr) cap);
529 #else
530 xmlXPathNodeSetFreeNs((xmlNsPtr) PyCapsule_GetPointer(cap, "xmlNsPtr"));
531 #endif
532 }
533
534 PyObject *
libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)535 libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
536 {
537 PyObject *ret;
538
539 #ifdef DEBUG
540 printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
541 #endif
542 if (obj == NULL) {
543 Py_INCREF(Py_None);
544 return (Py_None);
545 }
546 switch (obj->type) {
547 case XPATH_XSLT_TREE: {
548 if ((obj->nodesetval == NULL) ||
549 (obj->nodesetval->nodeNr == 0) ||
550 (obj->nodesetval->nodeTab == NULL)) {
551 ret = PyList_New(0);
552 } else {
553 int i, len = 0;
554 xmlNodePtr node;
555
556 node = obj->nodesetval->nodeTab[0]->children;
557 while (node != NULL) {
558 len++;
559 node = node->next;
560 }
561 ret = PyList_New(len);
562 node = obj->nodesetval->nodeTab[0]->children;
563 for (i = 0;i < len;i++) {
564 PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
565 node = node->next;
566 }
567 }
568 /*
569 * Return now, do not free the object passed down
570 */
571 return (ret);
572 }
573 case XPATH_NODESET:
574 if ((obj->nodesetval == NULL)
575 || (obj->nodesetval->nodeNr == 0)) {
576 ret = PyList_New(0);
577 } else {
578 int i;
579 xmlNodePtr node;
580
581 ret = PyList_New(obj->nodesetval->nodeNr);
582 for (i = 0; i < obj->nodesetval->nodeNr; i++) {
583 node = obj->nodesetval->nodeTab[i];
584 if (node->type == XML_NAMESPACE_DECL) {
585 PyObject *ns = PyCapsule_New((void *) node,
586 (char *) "xmlNsPtr",
587 libxml_xmlXPathDestructNsNode);
588 PyList_SetItem(ret, i, ns);
589 /* make sure the xmlNsPtr is not destroyed now */
590 obj->nodesetval->nodeTab[i] = NULL;
591 } else {
592 PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
593 }
594 }
595 }
596 break;
597 case XPATH_BOOLEAN:
598 ret = PY_IMPORT_INT((long) obj->boolval);
599 break;
600 case XPATH_NUMBER:
601 ret = PyFloat_FromDouble(obj->floatval);
602 break;
603 case XPATH_STRING:
604 ret = PY_IMPORT_STRING((char *) obj->stringval);
605 break;
606 case XPATH_POINT:
607 {
608 PyObject *node;
609 PyObject *indexIntoNode;
610 PyObject *tuple;
611
612 node = libxml_xmlNodePtrWrap(obj->user);
613 indexIntoNode = PY_IMPORT_INT((long) obj->index);
614
615 tuple = PyTuple_New(2);
616 PyTuple_SetItem(tuple, 0, node);
617 PyTuple_SetItem(tuple, 1, indexIntoNode);
618
619 ret = tuple;
620 break;
621 }
622 case XPATH_RANGE:
623 {
624 unsigned short bCollapsedRange;
625
626 bCollapsedRange = ( (obj->user2 == NULL) ||
627 ((obj->user2 == obj->user) && (obj->index == obj->index2)) );
628 if ( bCollapsedRange ) {
629 PyObject *node;
630 PyObject *indexIntoNode;
631 PyObject *tuple;
632 PyObject *list;
633
634 list = PyList_New(1);
635
636 node = libxml_xmlNodePtrWrap(obj->user);
637 indexIntoNode = PY_IMPORT_INT((long) obj->index);
638
639 tuple = PyTuple_New(2);
640 PyTuple_SetItem(tuple, 0, node);
641 PyTuple_SetItem(tuple, 1, indexIntoNode);
642
643 PyList_SetItem(list, 0, tuple);
644
645 ret = list;
646 } else {
647 PyObject *node;
648 PyObject *indexIntoNode;
649 PyObject *tuple;
650 PyObject *list;
651
652 list = PyList_New(2);
653
654 node = libxml_xmlNodePtrWrap(obj->user);
655 indexIntoNode = PY_IMPORT_INT((long) obj->index);
656
657 tuple = PyTuple_New(2);
658 PyTuple_SetItem(tuple, 0, node);
659 PyTuple_SetItem(tuple, 1, indexIntoNode);
660
661 PyList_SetItem(list, 0, tuple);
662
663 node = libxml_xmlNodePtrWrap(obj->user2);
664 indexIntoNode = PY_IMPORT_INT((long) obj->index2);
665
666 tuple = PyTuple_New(2);
667 PyTuple_SetItem(tuple, 0, node);
668 PyTuple_SetItem(tuple, 1, indexIntoNode);
669
670 PyList_SetItem(list, 1, tuple);
671
672 ret = list;
673 }
674 break;
675 }
676 case XPATH_LOCATIONSET:
677 {
678 xmlLocationSetPtr set;
679
680 set = obj->user;
681 if ( set && set->locNr > 0 ) {
682 int i;
683 PyObject *list;
684
685 list = PyList_New(set->locNr);
686
687 for (i=0; i<set->locNr; i++) {
688 xmlXPathObjectPtr setobj;
689 PyObject *pyobj;
690
691 setobj = set->locTab[i]; /*xmlXPathObjectPtr setobj*/
692
693 pyobj = libxml_xmlXPathObjectPtrWrap(setobj);
694 /* xmlXPathFreeObject(setobj) is called */
695 set->locTab[i] = NULL;
696
697 PyList_SetItem(list, i, pyobj);
698 }
699 set->locNr = 0;
700 ret = list;
701 } else {
702 Py_INCREF(Py_None);
703 ret = Py_None;
704 }
705 break;
706 }
707 default:
708 #ifdef DEBUG
709 printf("Unable to convert XPath object type %d\n", obj->type);
710 #endif
711 Py_INCREF(Py_None);
712 ret = Py_None;
713 }
714 xmlXPathFreeObject(obj);
715 return (ret);
716 }
717
718 xmlXPathObjectPtr
libxml_xmlXPathObjectPtrConvert(PyObject * obj)719 libxml_xmlXPathObjectPtrConvert(PyObject *obj)
720 {
721 xmlXPathObjectPtr ret = NULL;
722
723 #ifdef DEBUG
724 printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
725 #endif
726 if (obj == NULL) {
727 return (NULL);
728 }
729 if (PyFloat_Check (obj)) {
730 ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
731 } else if (PyLong_Check(obj)) {
732 #ifdef PyLong_AS_LONG
733 ret = xmlXPathNewFloat((double) PyLong_AS_LONG(obj));
734 #else
735 ret = xmlXPathNewFloat((double) PyInt_AS_LONG(obj));
736 #endif
737 #ifdef PyBool_Check
738 } else if (PyBool_Check (obj)) {
739
740 if (obj == Py_True) {
741 ret = xmlXPathNewBoolean(1);
742 }
743 else {
744 ret = xmlXPathNewBoolean(0);
745 }
746 #endif
747 } else if (PyBytes_Check (obj)) {
748 xmlChar *str;
749
750 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(obj),
751 PyBytes_GET_SIZE(obj));
752 ret = xmlXPathWrapString(str);
753 #ifdef PyUnicode_Check
754 } else if (PyUnicode_Check (obj)) {
755 #if PY_VERSION_HEX >= 0x03030000
756 xmlChar *str;
757 const char *tmp;
758 Py_ssize_t size;
759
760 /* tmp doesn't need to be deallocated */
761 tmp = PyUnicode_AsUTF8AndSize(obj, &size);
762 str = xmlStrndup((const xmlChar *) tmp, (int) size);
763 ret = xmlXPathWrapString(str);
764 #else
765 xmlChar *str = NULL;
766 PyObject *b;
767
768 b = PyUnicode_AsUTF8String(obj);
769 if (b != NULL) {
770 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(b),
771 PyBytes_GET_SIZE(b));
772 Py_DECREF(b);
773 }
774 ret = xmlXPathWrapString(str);
775 #endif
776 #endif
777 } else if (PyList_Check (obj)) {
778 int i;
779 PyObject *node;
780 xmlNodePtr cur;
781 xmlNodeSetPtr set;
782
783 set = xmlXPathNodeSetCreate(NULL);
784
785 for (i = 0; i < PyList_Size(obj); i++) {
786 node = PyList_GetItem(obj, i);
787 if ((node == NULL) || (node->ob_type == NULL))
788 continue;
789
790 cur = NULL;
791 if (PyCapsule_CheckExact(node)) {
792 #ifdef DEBUG
793 printf("Got a Capsule\n");
794 #endif
795 cur = PyxmlNode_Get(node);
796 } else if ((PyObject_HasAttrString(node, (char *) "_o")) &&
797 (PyObject_HasAttrString(node, (char *) "get_doc"))) {
798 PyObject *wrapper;
799
800 wrapper = PyObject_GetAttrString(node, (char *) "_o");
801 if (wrapper != NULL)
802 cur = PyxmlNode_Get(wrapper);
803 } else {
804 #ifdef DEBUG
805 printf("Unknown object in Python return list\n");
806 #endif
807 }
808 if (cur != NULL) {
809 xmlXPathNodeSetAdd(set, cur);
810 }
811 }
812 ret = xmlXPathWrapNodeSet(set);
813 } else {
814 #ifdef DEBUG
815 printf("Unable to convert Python Object to XPath");
816 #endif
817 }
818 return (ret);
819 }
820
821 PyObject *
libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)822 libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)
823 {
824 PyObject *ret;
825
826 #ifdef DEBUG
827 printf("libxml_xmlValidCtxtPtrWrap: valid = %p\n", valid);
828 #endif
829 if (valid == NULL) {
830 Py_INCREF(Py_None);
831 return (Py_None);
832 }
833
834 ret =
835 PyCapsule_New((void *) valid,
836 (char *) "xmlValidCtxtPtr", NULL);
837
838 return (ret);
839 }
840
841 PyObject *
libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)842 libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
843 {
844 PyObject *ret;
845
846 #ifdef DEBUG
847 printf("libxml_xmlNodePtrWrap: catal = %p\n", catal);
848 #endif
849 if (catal == NULL) {
850 Py_INCREF(Py_None);
851 return (Py_None);
852 }
853 ret =
854 PyCapsule_New((void *) catal,
855 (char *) "xmlCatalogPtr", NULL);
856 return (ret);
857 }
858
859 PyObject *
libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)860 libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)
861 {
862 PyObject *ret;
863
864 #ifdef DEBUG
865 printf("libxml_xmlOutputBufferPtrWrap: buffer = %p\n", buffer);
866 #endif
867 if (buffer == NULL) {
868 Py_INCREF(Py_None);
869 return (Py_None);
870 }
871 ret =
872 PyCapsule_New((void *) buffer,
873 (char *) "xmlOutputBufferPtr", NULL);
874 return (ret);
875 }
876
877 PyObject *
libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)878 libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)
879 {
880 PyObject *ret;
881
882 #ifdef DEBUG
883 printf("libxml_xmlParserInputBufferPtrWrap: buffer = %p\n", buffer);
884 #endif
885 if (buffer == NULL) {
886 Py_INCREF(Py_None);
887 return (Py_None);
888 }
889 ret =
890 PyCapsule_New((void *) buffer,
891 (char *) "xmlParserInputBufferPtr", NULL);
892 return (ret);
893 }
894
895 #ifdef LIBXML_REGEXP_ENABLED
896 PyObject *
libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)897 libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)
898 {
899 PyObject *ret;
900
901 #ifdef DEBUG
902 printf("libxml_xmlRegexpPtrWrap: regexp = %p\n", regexp);
903 #endif
904 if (regexp == NULL) {
905 Py_INCREF(Py_None);
906 return (Py_None);
907 }
908 ret =
909 PyCapsule_New((void *) regexp,
910 (char *) "xmlRegexpPtr", NULL);
911 return (ret);
912 }
913 #endif /* LIBXML_REGEXP_ENABLED */
914
915 #ifdef LIBXML_READER_ENABLED
916 PyObject *
libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)917 libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
918 {
919 PyObject *ret;
920
921 #ifdef DEBUG
922 printf("libxml_xmlTextReaderPtrWrap: reader = %p\n", reader);
923 #endif
924 if (reader == NULL) {
925 Py_INCREF(Py_None);
926 return (Py_None);
927 }
928 ret =
929 PyCapsule_New((void *) reader,
930 (char *) "xmlTextReaderPtr", NULL);
931 return (ret);
932 }
933
934 PyObject *
libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)935 libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)
936 {
937 PyObject *ret;
938
939 #ifdef DEBUG
940 printf("libxml_xmlTextReaderLocatorPtrWrap: locator = %p\n", locator);
941 #endif
942 if (locator == NULL) {
943 Py_INCREF(Py_None);
944 return (Py_None);
945 }
946 ret =
947 PyCapsule_New((void *) locator,
948 (char *) "xmlTextReaderLocatorPtr", NULL);
949 return (ret);
950 }
951 #endif /* LIBXML_READER_ENABLED */
952
953 #ifdef LIBXML_SCHEMAS_ENABLED
954 PyObject *
libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt)955 libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt)
956 {
957 PyObject *ret;
958
959 #ifdef DEBUG
960 printf("libxml_xmlRelaxNGPtrWrap: ctxt = %p\n", ctxt);
961 #endif
962 if (ctxt == NULL) {
963 Py_INCREF(Py_None);
964 return (Py_None);
965 }
966 ret =
967 PyCapsule_New((void *) ctxt,
968 (char *) "xmlRelaxNGPtr", NULL);
969 return (ret);
970 }
971
972 PyObject *
libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt)973 libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt)
974 {
975 PyObject *ret;
976
977 #ifdef DEBUG
978 printf("libxml_xmlRelaxNGParserCtxtPtrWrap: ctxt = %p\n", ctxt);
979 #endif
980 if (ctxt == NULL) {
981 Py_INCREF(Py_None);
982 return (Py_None);
983 }
984 ret =
985 PyCapsule_New((void *) ctxt,
986 (char *) "xmlRelaxNGParserCtxtPtr", NULL);
987 return (ret);
988 }
989 PyObject *
libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)990 libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)
991 {
992 PyObject *ret;
993
994 #ifdef DEBUG
995 printf("libxml_xmlRelaxNGValidCtxtPtrWrap: valid = %p\n", valid);
996 #endif
997 if (valid == NULL) {
998 Py_INCREF(Py_None);
999 return (Py_None);
1000 }
1001 ret =
1002 PyCapsule_New((void *) valid,
1003 (char *) "xmlRelaxNGValidCtxtPtr", NULL);
1004 return (ret);
1005 }
1006
1007 PyObject *
libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)1008 libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)
1009 {
1010 PyObject *ret;
1011
1012 #ifdef DEBUG
1013 printf("libxml_xmlSchemaPtrWrap: ctxt = %p\n", ctxt);
1014 #endif
1015 if (ctxt == NULL) {
1016 Py_INCREF(Py_None);
1017 return (Py_None);
1018 }
1019 ret =
1020 PyCapsule_New((void *) ctxt,
1021 (char *) "xmlSchemaPtr", NULL);
1022 return (ret);
1023 }
1024
1025 PyObject *
libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)1026 libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)
1027 {
1028 PyObject *ret;
1029
1030 #ifdef DEBUG
1031 printf("libxml_xmlSchemaParserCtxtPtrWrap: ctxt = %p\n", ctxt);
1032 #endif
1033 if (ctxt == NULL) {
1034 Py_INCREF(Py_None);
1035 return (Py_None);
1036 }
1037 ret =
1038 PyCapsule_New((void *) ctxt,
1039 (char *) "xmlSchemaParserCtxtPtr", NULL);
1040
1041 return (ret);
1042 }
1043
1044 PyObject *
libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)1045 libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)
1046 {
1047 PyObject *ret;
1048
1049 #ifdef DEBUG
1050 printf("libxml_xmlSchemaValidCtxtPtrWrap: valid = %p\n", valid);
1051 #endif
1052 if (valid == NULL) {
1053 Py_INCREF(Py_None);
1054 return (Py_None);
1055 }
1056
1057 ret =
1058 PyCapsule_New((void *) valid,
1059 (char *) "xmlSchemaValidCtxtPtr", NULL);
1060
1061 return (ret);
1062 }
1063 #endif /* LIBXML_SCHEMAS_ENABLED */
1064
1065 PyObject *
libxml_xmlErrorPtrWrap(xmlErrorPtr error)1066 libxml_xmlErrorPtrWrap(xmlErrorPtr error)
1067 {
1068 PyObject *ret;
1069
1070 #ifdef DEBUG
1071 printf("libxml_xmlErrorPtrWrap: error = %p\n", error);
1072 #endif
1073 if (error == NULL) {
1074 Py_INCREF(Py_None);
1075 return (Py_None);
1076 }
1077 ret = PyCapsule_New((void *) error, (char *) "xmlErrorPtr", NULL);
1078 return (ret);
1079 }
1080