diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2017-02-18 22:54:50 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2017-02-18 22:54:50 +0100 |
commit | 9585896fd11da4511f954cb81d1e6dcc82f4996e (patch) | |
tree | 3af6f5d831626c609c4b280a41f86df915c2b56e /src/lxml/proxy.pxi | |
parent | dade8722c8f25177d633b12846d611d2bef1448b (diff) | |
download | python-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.pxi | 31 |
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) |