summaryrefslogtreecommitdiff
path: root/src/lxml/proxy.pxi
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2017-02-18 22:54:50 +0100
committerStefan Behnel <stefan_ml@behnel.de>2017-02-18 22:54:50 +0100
commit9585896fd11da4511f954cb81d1e6dcc82f4996e (patch)
tree3af6f5d831626c609c4b280a41f86df915c2b56e /src/lxml/proxy.pxi
parentdade8722c8f25177d633b12846d611d2bef1448b (diff)
downloadpython-lxml-9585896fd11da4511f954cb81d1e6dcc82f4996e.tar.gz
Implement new API function "adopt_external_document()" that accepts a PyCapsule with a libxml2 document pointer and wraps it in an lxml ElementTree
Diffstat (limited to 'src/lxml/proxy.pxi')
-rw-r--r--src/lxml/proxy.pxi31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/lxml/proxy.pxi b/src/lxml/proxy.pxi
index 959b5be3..f10c6cfe 100644
--- a/src/lxml/proxy.pxi
+++ b/src/lxml/proxy.pxi
@@ -552,3 +552,34 @@ cdef void fixThreadDictNamesForDtd(tree.xmlDtd* c_dtd,
_fixThreadDictPtr(&c_entity.SystemID, c_src_dict, c_dict)
_fixThreadDictPtr(<const_xmlChar**>&c_entity.content, c_src_dict, c_dict)
c_node = c_node.next
+
+
+################################################################################
+# adopt an xmlDoc from an external libxml2 document source
+
+cdef _Document _adoptForeignDoc(xmlDoc* c_doc, _BaseParser parser=None, bint is_owned=True):
+ """Convert and wrap an externally produced xmlDoc for use in lxml.
+ Assures that all '_private' pointers are NULL to prevent accidental
+ dereference into lxml proxy objects.
+ """
+ if c_doc is NULL:
+ raise ValueError("Illegal document provided: NULL")
+ if c_doc.type not in (tree.XML_DOCUMENT_NODE, tree.XML_HTML_DOCUMENT_NODE):
+ doc_type = c_doc.type
+ if is_owned:
+ tree.xmlFreeDoc(c_doc)
+ raise ValueError("Illegal document provided: expected XML or HTML, found %s" % doc_type)
+
+ cdef xmlNode* c_node = <xmlNode*>c_doc
+
+ if is_owned:
+ tree.BEGIN_FOR_EACH_FROM(<xmlNode*>c_doc, c_node, 1)
+ c_node._private = NULL
+ tree.END_FOR_EACH_FROM(c_node)
+ else:
+ # create a fresh copy that lxml owns
+ c_doc = tree.xmlCopyDoc(c_doc, 1)
+ if c_doc is NULL:
+ raise MemoryError()
+
+ return _documentFactory(c_doc, parser)