2 * types.c: converter functions between the internal representation
3 * and the Python objects
5 * See Copyright for the status of this software.
9 #include "libxml_wrap.h"
10 #include <libxml/xpathInternals.h>
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
17 #define PY_IMPORT_STRING_SIZE PyString_FromStringAndSize
18 #define PY_IMPORT_STRING PyString_FromString
19 #define PY_IMPORT_INT PyInt_FromLong
22 #if PY_MAJOR_VERSION >= 3
28 libxml_PyFileGet(PyObject *f) {
33 fd = PyObject_AsFileDescriptor(f);
34 if (!_PyVerify_fd(fd))
37 * Get the flags on the fd to understand how it was opened
39 flags = fcntl(fd, F_GETFL, 0);
40 switch (flags & O_ACCMODE) {
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
75 res = fdopen(fd, mode);
83 void libxml_PyFileRelease(FILE *f) {
90 libxml_intWrap(int val)
95 printf("libxml_intWrap: val = %d\n", val);
97 ret = PY_IMPORT_INT((long) val);
102 libxml_longWrap(long val)
107 printf("libxml_longWrap: val = %ld\n", val);
109 ret = PyLong_FromLong(val);
114 libxml_doubleWrap(double val)
119 printf("libxml_doubleWrap: val = %f\n", val);
121 ret = PyFloat_FromDouble((double) val);
126 libxml_charPtrWrap(char *str)
131 printf("libxml_xmlcharPtrWrap: str = %s\n", str);
137 ret = PY_IMPORT_STRING(str);
143 libxml_charPtrConstWrap(const char *str)
148 printf("libxml_xmlcharPtrWrap: str = %s\n", str);
154 ret = PY_IMPORT_STRING(str);
159 libxml_xmlCharPtrWrap(xmlChar * str)
164 printf("libxml_xmlCharPtrWrap: str = %s\n", str);
170 ret = PY_IMPORT_STRING((char *) str);
176 libxml_xmlCharPtrConstWrap(const xmlChar * str)
181 printf("libxml_xmlCharPtrWrap: str = %s\n", str);
187 ret = PY_IMPORT_STRING((char *) str);
192 libxml_constcharPtrWrap(const char *str)
197 printf("libxml_xmlcharPtrWrap: str = %s\n", str);
203 ret = PY_IMPORT_STRING(str);
208 libxml_constxmlCharPtrWrap(const xmlChar * str)
213 printf("libxml_xmlCharPtrWrap: str = %s\n", str);
219 ret = PY_IMPORT_STRING((char *) str);
224 libxml_xmlDocPtrWrap(xmlDocPtr doc)
229 printf("libxml_xmlDocPtrWrap: doc = %p\n", doc);
235 /* TODO: look at deallocation */
236 ret = PyCapsule_New((void *) doc, (char *) "xmlDocPtr", NULL);
241 libxml_xmlNodePtrWrap(xmlNodePtr node)
246 printf("libxml_xmlNodePtrWrap: node = %p\n", node);
252 ret = PyCapsule_New((void *) node, (char *) "xmlNodePtr", NULL);
257 libxml_xmlURIPtrWrap(xmlURIPtr uri)
262 printf("libxml_xmlURIPtrWrap: uri = %p\n", uri);
268 ret = PyCapsule_New((void *) uri, (char *) "xmlURIPtr", NULL);
273 libxml_xmlNsPtrWrap(xmlNsPtr ns)
278 printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
284 ret = PyCapsule_New((void *) ns, (char *) "xmlNsPtr", NULL);
289 libxml_xmlAttrPtrWrap(xmlAttrPtr attr)
294 printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
300 ret = PyCapsule_New((void *) attr, (char *) "xmlAttrPtr", NULL);
305 libxml_xmlAttributePtrWrap(xmlAttributePtr attr)
310 printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
316 ret = PyCapsule_New((void *) attr, (char *) "xmlAttributePtr", NULL);
321 libxml_xmlElementPtrWrap(xmlElementPtr elem)
326 printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
332 ret = PyCapsule_New((void *) elem, (char *) "xmlElementPtr", NULL);
337 libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)
342 printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
348 ret = PyCapsule_New((void *) ctxt, (char *) "xmlXPathContextPtr", NULL);
353 libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)
358 printf("libxml_xmlXPathParserContextPtrWrap: ctxt = %p\n", ctxt);
364 ret = PyCapsule_New((void *)ctxt, (char *)"xmlXPathParserContextPtr", NULL);
369 libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)
374 printf("libxml_xmlParserCtxtPtrWrap: ctxt = %p\n", ctxt);
381 ret = PyCapsule_New((void *) ctxt, (char *) "xmlParserCtxtPtr", NULL);
386 * libxml_xmlXPathDestructNsNode:
387 * cap: xmlNsPtr namespace node capsule object
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.
394 #if PY_VERSION_HEX < 0x02070000
396 libxml_xmlXPathDestructNsNode(void *cap, void *desc ATTRIBUTE_UNUSED)
399 libxml_xmlXPathDestructNsNode(PyObject *cap)
403 fprintf(stderr, "libxml_xmlXPathDestructNsNode called %p\n", cap);
405 #if PY_VERSION_HEX < 0x02070000
406 xmlXPathNodeSetFreeNs((xmlNsPtr) cap);
408 xmlXPathNodeSetFreeNs((xmlNsPtr) PyCapsule_GetPointer(cap, "xmlNsPtr"));
413 libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
418 printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
425 case XPATH_XSLT_TREE: {
426 if ((obj->nodesetval == NULL) ||
427 (obj->nodesetval->nodeNr == 0) ||
428 (obj->nodesetval->nodeTab == NULL)) {
434 node = obj->nodesetval->nodeTab[0]->children;
435 while (node != NULL) {
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));
447 * Return now, do not free the object passed down
452 if ((obj->nodesetval == NULL)
453 || (obj->nodesetval->nodeNr == 0)) {
459 ret = PyList_New(obj->nodesetval->nodeNr);
460 for (i = 0; i < obj->nodesetval->nodeNr; i++) {
461 node = obj->nodesetval->nodeTab[i];
462 if (node->type == XML_NAMESPACE_DECL) {
463 PyObject *ns = PyCapsule_New((void *) node,
465 libxml_xmlXPathDestructNsNode);
466 PyList_SetItem(ret, i, ns);
467 /* make sure the xmlNsPtr is not destroyed now */
468 obj->nodesetval->nodeTab[i] = NULL;
470 PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
476 ret = PY_IMPORT_INT((long) obj->boolval);
479 ret = PyFloat_FromDouble(obj->floatval);
482 ret = PY_IMPORT_STRING((char *) obj->stringval);
487 PyObject *indexIntoNode;
490 node = libxml_xmlNodePtrWrap(obj->user);
491 indexIntoNode = PY_IMPORT_INT((long) obj->index);
493 tuple = PyTuple_New(2);
494 PyTuple_SetItem(tuple, 0, node);
495 PyTuple_SetItem(tuple, 1, indexIntoNode);
502 unsigned short bCollapsedRange;
504 bCollapsedRange = ( (obj->user2 == NULL) ||
505 ((obj->user2 == obj->user) && (obj->index == obj->index2)) );
506 if ( bCollapsedRange ) {
508 PyObject *indexIntoNode;
512 list = PyList_New(1);
514 node = libxml_xmlNodePtrWrap(obj->user);
515 indexIntoNode = PY_IMPORT_INT((long) obj->index);
517 tuple = PyTuple_New(2);
518 PyTuple_SetItem(tuple, 0, node);
519 PyTuple_SetItem(tuple, 1, indexIntoNode);
521 PyList_SetItem(list, 0, tuple);
526 PyObject *indexIntoNode;
530 list = PyList_New(2);
532 node = libxml_xmlNodePtrWrap(obj->user);
533 indexIntoNode = PY_IMPORT_INT((long) obj->index);
535 tuple = PyTuple_New(2);
536 PyTuple_SetItem(tuple, 0, node);
537 PyTuple_SetItem(tuple, 1, indexIntoNode);
539 PyList_SetItem(list, 0, tuple);
541 node = libxml_xmlNodePtrWrap(obj->user2);
542 indexIntoNode = PY_IMPORT_INT((long) obj->index2);
544 tuple = PyTuple_New(2);
545 PyTuple_SetItem(tuple, 0, node);
546 PyTuple_SetItem(tuple, 1, indexIntoNode);
548 PyList_SetItem(list, 1, tuple);
554 case XPATH_LOCATIONSET:
556 xmlLocationSetPtr set;
559 if ( set && set->locNr > 0 ) {
563 list = PyList_New(set->locNr);
565 for (i=0; i<set->locNr; i++) {
566 xmlXPathObjectPtr setobj;
569 setobj = set->locTab[i]; /*xmlXPathObjectPtr setobj*/
571 pyobj = libxml_xmlXPathObjectPtrWrap(setobj);
572 /* xmlXPathFreeObject(setobj) is called */
573 set->locTab[i] = NULL;
575 PyList_SetItem(list, i, pyobj);
587 printf("Unable to convert XPath object type %d\n", obj->type);
592 xmlXPathFreeObject(obj);
597 libxml_xmlXPathObjectPtrConvert(PyObject *obj)
599 xmlXPathObjectPtr ret = NULL;
602 printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
607 if PyFloat_Check (obj) {
608 ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
609 } else if PyLong_Check(obj) {
610 #ifdef PyLong_AS_LONG
611 ret = xmlXPathNewFloat((double) PyLong_AS_LONG(obj));
613 ret = xmlXPathNewFloat((double) PyInt_AS_LONG(obj));
616 } else if PyBool_Check (obj) {
618 if (obj == Py_True) {
619 ret = xmlXPathNewBoolean(1);
622 ret = xmlXPathNewBoolean(0);
625 } else if PyBytes_Check (obj) {
628 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(obj),
629 PyBytes_GET_SIZE(obj));
630 ret = xmlXPathWrapString(str);
631 #ifdef PyUnicode_Check
632 } else if PyUnicode_Check (obj) {
633 #if PY_VERSION_HEX >= 0x03030000
638 /* tmp doesn't need to be deallocated */
639 tmp = PyUnicode_AsUTF8AndSize(obj, &size);
640 str = xmlStrndup((const xmlChar *) tmp, (int) size);
641 ret = xmlXPathWrapString(str);
646 b = PyUnicode_AsUTF8String(obj);
648 str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(b),
649 PyBytes_GET_SIZE(b));
652 ret = xmlXPathWrapString(str);
655 } else if PyList_Check (obj) {
661 set = xmlXPathNodeSetCreate(NULL);
663 for (i = 0; i < PyList_Size(obj); i++) {
664 node = PyList_GetItem(obj, i);
665 if ((node == NULL) || (node->ob_type == NULL))
669 if (PyCapsule_CheckExact(node)) {
671 printf("Got a Capsule\n");
673 cur = PyxmlNode_Get(node);
674 } else if ((PyObject_HasAttrString(node, (char *) "_o")) &&
675 (PyObject_HasAttrString(node, (char *) "get_doc"))) {
678 wrapper = PyObject_GetAttrString(node, (char *) "_o");
680 cur = PyxmlNode_Get(wrapper);
683 printf("Unknown object in Python return list\n");
687 xmlXPathNodeSetAdd(set, cur);
690 ret = xmlXPathWrapNodeSet(set);
693 printf("Unable to convert Python Object to XPath");
700 libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)
705 printf("libxml_xmlValidCtxtPtrWrap: valid = %p\n", valid);
713 PyCapsule_New((void *) valid,
714 (char *) "xmlValidCtxtPtr", NULL);
720 libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
725 printf("libxml_xmlNodePtrWrap: catal = %p\n", catal);
732 PyCapsule_New((void *) catal,
733 (char *) "xmlCatalogPtr", NULL);
738 libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)
743 printf("libxml_xmlOutputBufferPtrWrap: buffer = %p\n", buffer);
745 if (buffer == NULL) {
750 PyCapsule_New((void *) buffer,
751 (char *) "xmlOutputBufferPtr", NULL);
756 libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)
761 printf("libxml_xmlParserInputBufferPtrWrap: buffer = %p\n", buffer);
763 if (buffer == NULL) {
768 PyCapsule_New((void *) buffer,
769 (char *) "xmlParserInputBufferPtr", NULL);
773 #ifdef LIBXML_REGEXP_ENABLED
775 libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)
780 printf("libxml_xmlRegexpPtrWrap: regexp = %p\n", regexp);
782 if (regexp == NULL) {
787 PyCapsule_New((void *) regexp,
788 (char *) "xmlRegexpPtr", NULL);
791 #endif /* LIBXML_REGEXP_ENABLED */
793 #ifdef LIBXML_READER_ENABLED
795 libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
800 printf("libxml_xmlTextReaderPtrWrap: reader = %p\n", reader);
802 if (reader == NULL) {
807 PyCapsule_New((void *) reader,
808 (char *) "xmlTextReaderPtr", NULL);
813 libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)
818 printf("libxml_xmlTextReaderLocatorPtrWrap: locator = %p\n", locator);
820 if (locator == NULL) {
825 PyCapsule_New((void *) locator,
826 (char *) "xmlTextReaderLocatorPtr", NULL);
829 #endif /* LIBXML_READER_ENABLED */
831 #ifdef LIBXML_SCHEMAS_ENABLED
833 libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt)
838 printf("libxml_xmlRelaxNGPtrWrap: ctxt = %p\n", ctxt);
845 PyCapsule_New((void *) ctxt,
846 (char *) "xmlRelaxNGPtr", NULL);
851 libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt)
856 printf("libxml_xmlRelaxNGParserCtxtPtrWrap: ctxt = %p\n", ctxt);
863 PyCapsule_New((void *) ctxt,
864 (char *) "xmlRelaxNGParserCtxtPtr", NULL);
868 libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)
873 printf("libxml_xmlRelaxNGValidCtxtPtrWrap: valid = %p\n", valid);
880 PyCapsule_New((void *) valid,
881 (char *) "xmlRelaxNGValidCtxtPtr", NULL);
886 libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)
891 printf("libxml_xmlSchemaPtrWrap: ctxt = %p\n", ctxt);
898 PyCapsule_New((void *) ctxt,
899 (char *) "xmlSchemaPtr", NULL);
904 libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)
909 printf("libxml_xmlSchemaParserCtxtPtrWrap: ctxt = %p\n", ctxt);
916 PyCapsule_New((void *) ctxt,
917 (char *) "xmlSchemaParserCtxtPtr", NULL);
923 libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)
928 printf("libxml_xmlSchemaValidCtxtPtrWrap: valid = %p\n", valid);
936 PyCapsule_New((void *) valid,
937 (char *) "xmlSchemaValidCtxtPtr", NULL);
941 #endif /* LIBXML_SCHEMAS_ENABLED */
944 libxml_xmlErrorPtrWrap(xmlErrorPtr error)
949 printf("libxml_xmlErrorPtrWrap: error = %p\n", error);
955 ret = PyCapsule_New((void *) error, (char *) "xmlErrorPtr", NULL);