mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
add interop with simplexml - dom_import_simplexml
fix cloneNode with elements
This commit is contained in:
parent
d29fb55bbb
commit
207dc90924
15 changed files with 139 additions and 347 deletions
|
@ -74,9 +74,9 @@ PHP_FUNCTION(dom_attr_attr)
|
|||
if (intern != NULL) {
|
||||
oldnode = (xmlNodePtr)intern->ptr;
|
||||
if (oldnode != NULL) {
|
||||
node_free_resource(oldnode TSRMLS_CC);
|
||||
php_libxml_node_free_resource(oldnode TSRMLS_CC);
|
||||
}
|
||||
php_dom_set_object(intern, (xmlNodePtr) nodep TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,9 +66,9 @@ PHP_FUNCTION(dom_cdatasection_cdatasection)
|
|||
if (intern != NULL) {
|
||||
oldnode = (xmlNodePtr)intern->ptr;
|
||||
if (oldnode != NULL) {
|
||||
node_free_resource(oldnode TSRMLS_CC);
|
||||
php_libxml_node_free_resource(oldnode TSRMLS_CC);
|
||||
}
|
||||
php_dom_set_object(intern, nodep TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} end dom_cdatasection_cdatasection */
|
||||
|
|
|
@ -65,9 +65,9 @@ PHP_FUNCTION(dom_comment_comment)
|
|||
if (intern != NULL) {
|
||||
oldnode = (xmlNodePtr)intern->ptr;
|
||||
if (oldnode != NULL) {
|
||||
node_free_resource(oldnode TSRMLS_CC);
|
||||
php_libxml_node_free_resource(oldnode TSRMLS_CC);
|
||||
}
|
||||
php_dom_set_object(intern, nodep TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} end dom_comment_comment */
|
||||
|
|
|
@ -1164,16 +1164,15 @@ PHP_FUNCTION(dom_document_document)
|
|||
if (intern != NULL) {
|
||||
olddoc = (xmlDocPtr) dom_object_get_node(intern);
|
||||
if (olddoc != NULL) {
|
||||
decrement_node_ptr(intern TSRMLS_CC);
|
||||
refcount = decrement_document_reference(intern TSRMLS_CC);
|
||||
php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
|
||||
refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
|
||||
if (refcount != 0) {
|
||||
olddoc->_private = NULL;
|
||||
}
|
||||
}
|
||||
intern->document = NULL;
|
||||
increment_document_reference(intern, docp TSRMLS_CC);
|
||||
|
||||
php_dom_set_object(intern, (xmlNodePtr) docp TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)docp, (void *)intern TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} end dom_document_document */
|
||||
|
@ -1230,7 +1229,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC)
|
|||
xmlParserCtxtPtr ctxt = NULL;
|
||||
dom_doc_props *doc_props;
|
||||
dom_object *intern;
|
||||
dom_ref_obj *document = NULL;
|
||||
php_libxml_ref_obj *document = NULL;
|
||||
int validate, resolve_externals, keep_blanks, substitute_ent;
|
||||
int resolved_path_len;
|
||||
char *directory=NULL, resolved_path[MAXPATHLEN];
|
||||
|
@ -1352,20 +1351,20 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) {
|
|||
docp = (xmlDocPtr) dom_object_get_node(intern);
|
||||
doc_prop = NULL;
|
||||
if (docp != NULL) {
|
||||
decrement_node_ptr(intern TSRMLS_CC);
|
||||
php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
|
||||
doc_prop = intern->document->doc_props;
|
||||
intern->document->doc_props = NULL;
|
||||
refcount = decrement_document_reference(intern TSRMLS_CC);
|
||||
refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
|
||||
if (refcount != 0) {
|
||||
docp->_private = NULL;
|
||||
}
|
||||
}
|
||||
intern->document = NULL;
|
||||
increment_document_reference(intern, newdoc TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC);
|
||||
intern->document->doc_props = doc_prop;
|
||||
}
|
||||
|
||||
php_dom_set_object(intern, (xmlNodePtr) newdoc TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
|
||||
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
|
@ -1710,20 +1709,20 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode)
|
|||
docp = (xmlDocPtr) dom_object_get_node(intern);
|
||||
doc_prop = NULL;
|
||||
if (docp != NULL) {
|
||||
decrement_node_ptr(intern TSRMLS_CC);
|
||||
php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
|
||||
doc_prop = intern->document->doc_props;
|
||||
intern->document->doc_props = NULL;
|
||||
refcount = decrement_document_reference(intern TSRMLS_CC);
|
||||
refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
|
||||
if (refcount != 0) {
|
||||
docp->_private = NULL;
|
||||
}
|
||||
}
|
||||
intern->document = NULL;
|
||||
increment_document_reference(intern, newdoc TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC);
|
||||
intern->document->doc_props = doc_prop;
|
||||
}
|
||||
|
||||
php_dom_set_object(intern, (xmlNodePtr) newdoc TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
|
||||
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
|
|
|
@ -59,9 +59,10 @@ PHP_FUNCTION(dom_documentfragment_documentfragment)
|
|||
if (intern != NULL) {
|
||||
oldnode = (xmlNodePtr)intern->ptr;
|
||||
if (oldnode != NULL) {
|
||||
node_free_resource(oldnode TSRMLS_CC);
|
||||
php_libxml_node_free_resource(oldnode TSRMLS_CC);
|
||||
}
|
||||
php_dom_set_object(intern, nodep TSRMLS_CC);
|
||||
//php_dom_set_object(intern, nodep TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} end dom_documentfragment_documentfragment */
|
||||
|
|
|
@ -217,8 +217,8 @@ PHP_FUNCTION(dom_domimplementation_create_document)
|
|||
DOM_RET_OBJ(rv, (xmlNodePtr) docp, &ret, NULL);
|
||||
|
||||
if (doctobj != NULL) {
|
||||
doctobj->document = ((dom_object *)((node_ptr *)docp->_private)->_private)->document;
|
||||
increment_document_reference(doctobj, docp TSRMLS_CC);
|
||||
doctobj->document = ((dom_object *)((php_libxml_node_ptr *)docp->_private)->_private)->document;
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)doctobj, docp TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} end dom_domimplementation_create_document */
|
||||
|
|
|
@ -92,9 +92,9 @@ PHP_FUNCTION(dom_element_element)
|
|||
if (intern != NULL) {
|
||||
oldnode = (xmlNodePtr)intern->ptr;
|
||||
if (oldnode != NULL) {
|
||||
node_free_resource(oldnode TSRMLS_CC);
|
||||
php_libxml_node_free_resource(oldnode TSRMLS_CC);
|
||||
}
|
||||
php_dom_set_object(intern, nodep TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} end dom_element_element */
|
||||
|
@ -322,7 +322,7 @@ PHP_FUNCTION(dom_element_set_attribute_node)
|
|||
existattrp = xmlHasProp(nodep, attrp->name);
|
||||
if (existattrp != NULL) {
|
||||
if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) != NULL &&
|
||||
((node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
|
||||
((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
|
||||
{
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ PHP_FUNCTION(dom_element_set_attribute_node)
|
|||
|
||||
if (attrp->doc == NULL && nodep->doc != NULL) {
|
||||
attrobj->document = intern->document;
|
||||
increment_document_reference(attrobj, NULL TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
xmlAddChild(nodep, (xmlNodePtr) attrp);
|
||||
|
@ -673,7 +673,7 @@ PHP_FUNCTION(dom_element_set_attribute_node_ns)
|
|||
|
||||
if (existattrp != NULL) {
|
||||
if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) != NULL &&
|
||||
((node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
|
||||
((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
|
||||
{
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
@ -682,7 +682,7 @@ PHP_FUNCTION(dom_element_set_attribute_node_ns)
|
|||
|
||||
if (attrp->doc == NULL && nodep->doc != NULL) {
|
||||
attrobj->document = intern->document;
|
||||
increment_document_reference(attrobj, NULL TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
xmlAddChild(nodep, (xmlNodePtr) attrp);
|
||||
|
|
|
@ -70,9 +70,9 @@ PHP_FUNCTION(dom_entityreference_entityreference)
|
|||
if (intern != NULL) {
|
||||
oldnode = (xmlNodePtr)intern->ptr;
|
||||
if (oldnode != NULL) {
|
||||
node_free_resource(oldnode TSRMLS_CC);
|
||||
php_libxml_node_free_resource(oldnode TSRMLS_CC);
|
||||
}
|
||||
php_dom_set_object(intern, node TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, node, (void *)intern TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -780,7 +780,7 @@ PHP_FUNCTION(dom_node_insert_before)
|
|||
|
||||
if (child->doc == NULL && parentp->doc != NULL) {
|
||||
childobj->document = intern->document;
|
||||
increment_document_reference(childobj, NULL TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (ref != NULL) {
|
||||
|
@ -802,14 +802,14 @@ PHP_FUNCTION(dom_node_insert_before)
|
|||
tmp = xmlStrcat(tmp, refp->content);
|
||||
xmlNodeSetContent(refp, tmp);
|
||||
xmlFree(tmp);
|
||||
node_free_resource(child TSRMLS_CC);
|
||||
php_libxml_node_free_resource(child TSRMLS_CC);
|
||||
DOM_RET_OBJ(rv, refp, &ret, intern);
|
||||
return;
|
||||
}
|
||||
if ((refp->prev != NULL) && (refp->prev->type == XML_TEXT_NODE)
|
||||
&& (refp->name == refp->prev->name)) {
|
||||
xmlNodeAddContent(refp->prev, child->content);
|
||||
node_free_resource(child TSRMLS_CC);
|
||||
php_libxml_node_free_resource(child TSRMLS_CC);
|
||||
DOM_RET_OBJ(rv, refp->prev, &ret, intern);
|
||||
return;
|
||||
}
|
||||
|
@ -823,9 +823,7 @@ PHP_FUNCTION(dom_node_insert_before)
|
|||
if (lastattr != NULL) {
|
||||
if (lastattr != (xmlAttrPtr) child) {
|
||||
xmlUnlinkNode((xmlNodePtr) lastattr);
|
||||
node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
|
||||
/* Freed above
|
||||
xmlFreeProp(lastattr); */
|
||||
php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
|
||||
} else {
|
||||
DOM_RET_OBJ(rv, child, &ret, intern);
|
||||
return;
|
||||
|
@ -843,7 +841,7 @@ PHP_FUNCTION(dom_node_insert_before)
|
|||
(parentp->content != NULL) &&
|
||||
(parentp != child)) {
|
||||
xmlNodeAddContent(parentp, child->content);
|
||||
node_free_resource(child TSRMLS_CC);
|
||||
php_libxml_node_free_resource(child TSRMLS_CC);
|
||||
DOM_RET_OBJ(rv, parentp, &ret, intern);
|
||||
return;
|
||||
}
|
||||
|
@ -851,7 +849,7 @@ PHP_FUNCTION(dom_node_insert_before)
|
|||
(parentp->last->name == child->name) &&
|
||||
(parentp->last != child)) {
|
||||
xmlNodeAddContent(parentp->last, child->content);
|
||||
node_free_resource(child TSRMLS_CC);
|
||||
php_libxml_node_free_resource(child TSRMLS_CC);
|
||||
DOM_RET_OBJ(rv, parentp->last, &ret, intern);
|
||||
return;
|
||||
}
|
||||
|
@ -865,9 +863,7 @@ PHP_FUNCTION(dom_node_insert_before)
|
|||
if (lastattr != NULL) {
|
||||
if (lastattr != (xmlAttrPtr) child) {
|
||||
xmlUnlinkNode((xmlNodePtr) lastattr);
|
||||
node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
|
||||
/* Freed above
|
||||
xmlFreeProp(lastattr); */
|
||||
php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
|
||||
} else {
|
||||
DOM_RET_OBJ(rv, child, &ret, intern);
|
||||
return;
|
||||
|
@ -960,7 +956,7 @@ PHP_FUNCTION(dom_node_replace_child)
|
|||
if (newchild->doc == NULL && nodep->doc != NULL) {
|
||||
xmlSetTreeDoc(newchild, nodep->doc);
|
||||
newchildobj->document = intern->document;
|
||||
increment_document_reference(newchildobj, NULL TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL TSRMLS_CC);
|
||||
}
|
||||
node = xmlReplaceNode(oldchild, newchild);
|
||||
}
|
||||
|
@ -1072,7 +1068,7 @@ PHP_FUNCTION(dom_node_append_child)
|
|||
|
||||
if (child->doc == NULL && nodep->doc != NULL) {
|
||||
childobj->document = intern->document;
|
||||
increment_document_reference(childobj, NULL TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (child->parent != NULL){
|
||||
|
@ -1083,14 +1079,14 @@ PHP_FUNCTION(dom_node_append_child)
|
|||
if ((nodep->type == XML_TEXT_NODE) &&
|
||||
(nodep->content != NULL)) {
|
||||
xmlNodeAddContent(nodep, child->content);
|
||||
node_free_resource(child TSRMLS_CC);
|
||||
php_libxml_node_free_resource(child TSRMLS_CC);
|
||||
DOM_RET_OBJ(rv, nodep, &ret, intern);
|
||||
return;
|
||||
}
|
||||
if ((nodep->last != NULL) && (nodep->last->type == XML_TEXT_NODE) &&
|
||||
(nodep->last->name == child->name)) {
|
||||
xmlNodeAddContent(nodep->last, child->content);
|
||||
node_free_resource(child TSRMLS_CC);
|
||||
php_libxml_node_free_resource(child TSRMLS_CC);
|
||||
DOM_RET_OBJ(rv, nodep->last, &ret, intern);
|
||||
return;
|
||||
}
|
||||
|
@ -1104,9 +1100,7 @@ PHP_FUNCTION(dom_node_append_child)
|
|||
if (lastattr != NULL) {
|
||||
if (lastattr != (xmlAttrPtr) child) {
|
||||
xmlUnlinkNode((xmlNodePtr) lastattr);
|
||||
node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
|
||||
/* Freed above
|
||||
xmlFreeProp(lastattr); */
|
||||
php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
} else if (child->type == XML_DOCUMENT_FRAG_NODE) {
|
||||
|
@ -1186,6 +1180,35 @@ PHP_FUNCTION(dom_node_clone_node)
|
|||
}
|
||||
|
||||
node = xmlDocCopyNode(n, n->doc, recursive);
|
||||
|
||||
/* When deep is false Element nodes still require the attributes
|
||||
Following taken from libxml as xmlDocCopyNode doesnt do this */
|
||||
if (node && n->type == XML_ELEMENT_NODE && recursive == 0) {
|
||||
if (n->nsDef != NULL) {
|
||||
node->nsDef = xmlCopyNamespaceList(n->nsDef);
|
||||
}
|
||||
if (n->ns != NULL) {
|
||||
xmlNsPtr ns;
|
||||
ns = xmlSearchNs(n->doc, node, n->ns->prefix);
|
||||
if (ns == NULL) {
|
||||
ns = xmlSearchNs(n->doc, n, n->ns->prefix);
|
||||
if (ns != NULL) {
|
||||
xmlNodePtr root = node;
|
||||
|
||||
while (root->parent != NULL) {
|
||||
root = root->parent;
|
||||
}
|
||||
node->ns = xmlNewNs(root, ns->href, ns->prefix);
|
||||
}
|
||||
} else {
|
||||
node->ns = ns;
|
||||
}
|
||||
}
|
||||
if (n->properties != NULL) {
|
||||
node->properties = xmlCopyPropList(node, n->properties);
|
||||
}
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "dom_properties.h"
|
||||
|
||||
#include "ext/standard/info.h"
|
||||
#include "ext/libxml/php_libxml.h"
|
||||
#define PHP_XPATH 1
|
||||
#define PHP_XPTR 2
|
||||
|
||||
|
@ -71,10 +70,6 @@ typedef struct _dom_prop_handler {
|
|||
dom_write_t write_func;
|
||||
} dom_prop_handler;
|
||||
|
||||
static zend_function_entry dom_functions[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/* {{{ int dom_node_is_read_only(xmlNodePtr node) */
|
||||
int dom_node_is_read_only(xmlNodePtr node) {
|
||||
switch (node->type) {
|
||||
|
@ -117,7 +112,7 @@ int dom_node_children_valid(xmlNodePtr node) {
|
|||
/* }}} end dom_node_children_valid */
|
||||
|
||||
/* {{{ dom_get_doc_props() */
|
||||
dom_doc_propsptr dom_get_doc_props(dom_ref_obj *document)
|
||||
dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document)
|
||||
{
|
||||
dom_doc_props *doc_props;
|
||||
|
||||
|
@ -140,7 +135,7 @@ dom_doc_propsptr dom_get_doc_props(dom_ref_obj *document)
|
|||
/* }}} */
|
||||
|
||||
/* {{{ dom_get_strict_error() */
|
||||
int dom_get_strict_error(dom_ref_obj *document) {
|
||||
int dom_get_strict_error(php_libxml_ref_obj *document) {
|
||||
int stricterror;
|
||||
dom_doc_props *doc_props;
|
||||
|
||||
|
@ -154,151 +149,28 @@ int dom_get_strict_error(dom_ref_obj *document) {
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ increment_document_reference() */
|
||||
int increment_document_reference(dom_object *object, xmlDocPtr docp TSRMLS_DC) {
|
||||
int ret_refcount = -1;
|
||||
|
||||
if (object->document != NULL) {
|
||||
object->document->refcount++;
|
||||
ret_refcount = object->document->refcount;
|
||||
} else if (docp != NULL) {
|
||||
ret_refcount = 1;
|
||||
object->document = emalloc(sizeof(dom_ref_obj));
|
||||
object->document->ptr = docp;
|
||||
object->document->refcount = ret_refcount;
|
||||
object->document->doc_props = NULL;
|
||||
}
|
||||
|
||||
return ret_refcount;
|
||||
}
|
||||
/* }}} end increment_document_reference */
|
||||
|
||||
/* {{{ int decrement_document_reference(dom_object *object) */
|
||||
int decrement_document_reference(dom_object *object TSRMLS_DC) {
|
||||
int ret_refcount = -1;
|
||||
|
||||
if (object != NULL && object->document != NULL) {
|
||||
object->document->refcount--;
|
||||
ret_refcount = object->document->refcount;
|
||||
if (ret_refcount == 0) {
|
||||
if (object->document->ptr != NULL) {
|
||||
xmlFreeDoc((xmlDoc *) object->document->ptr);
|
||||
object->document->ptr = NULL;
|
||||
}
|
||||
if (object->document->doc_props != NULL) {
|
||||
efree(object->document->doc_props);
|
||||
}
|
||||
efree(object->document);
|
||||
}
|
||||
object->document = NULL;
|
||||
}
|
||||
|
||||
return ret_refcount;
|
||||
}
|
||||
/* }}} end decrement_document_reference */
|
||||
|
||||
/* {{{ int decrement_node_ptr(dom_object *object) */
|
||||
int decrement_node_ptr(dom_object *object TSRMLS_DC) {
|
||||
int ret_refcount = -1;
|
||||
node_ptr *obj_node;
|
||||
|
||||
if (object != NULL && object->ptr != NULL) {
|
||||
obj_node = (node_ptr *) object->ptr;
|
||||
ret_refcount = --obj_node->refcount;
|
||||
if (ret_refcount == 0) {
|
||||
if (obj_node->node != NULL) {
|
||||
obj_node->node->_private = NULL;
|
||||
}
|
||||
efree(object->ptr);
|
||||
}
|
||||
object->ptr = NULL;
|
||||
}
|
||||
|
||||
return ret_refcount;
|
||||
}
|
||||
/* }}} end decrement_node_ptr */
|
||||
|
||||
/* {{{ xmlNodePtr dom_object_get_node(dom_object *obj) */
|
||||
xmlNodePtr dom_object_get_node(dom_object *obj)
|
||||
{
|
||||
if (obj->ptr != NULL) {
|
||||
return ((node_ptr *)obj->ptr)->node;
|
||||
return ((php_libxml_node_ptr *)obj->ptr)->node;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* }}} end dom_object_get_node */
|
||||
|
||||
/* {{{ dom_object_set_data */
|
||||
static void dom_object_set_data(xmlNodePtr obj, dom_object *wrapper TSRMLS_DC)
|
||||
{
|
||||
if (wrapper == NULL) {
|
||||
obj->_private = NULL;
|
||||
} else {
|
||||
obj->_private = wrapper->ptr;
|
||||
}
|
||||
}
|
||||
/* }}} end dom_object_set_data */
|
||||
|
||||
/* {{{ dom_object *dom_object_get_data(xmlNodePtr obj) */
|
||||
dom_object *dom_object_get_data(xmlNodePtr obj)
|
||||
{
|
||||
if (obj->_private != NULL) {
|
||||
return (dom_object *) ((node_ptr *) obj->_private)->_private;
|
||||
return (dom_object *) ((php_libxml_node_ptr *) obj->_private)->_private;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* }}} end dom_object_get_data */
|
||||
|
||||
/* {{{ php_dom_clear_object */
|
||||
static int php_dom_clear_object(dom_object *object TSRMLS_DC)
|
||||
{
|
||||
if (object->prop_handler) {
|
||||
object->prop_handler = NULL;
|
||||
}
|
||||
decrement_node_ptr(object TSRMLS_CC);
|
||||
return decrement_document_reference(object TSRMLS_CC);
|
||||
}
|
||||
/* }}} end php_dom_clear_object */
|
||||
|
||||
/* {{{ void php_dom_set_object(dom_object *object, xmlNodePtr obj TSRMLS_DC) */
|
||||
void php_dom_set_object(dom_object *object, xmlNodePtr obj TSRMLS_DC)
|
||||
{
|
||||
node_ptr *obj_node;
|
||||
|
||||
if (obj->_private == NULL) {
|
||||
object->ptr = emalloc(sizeof(node_ptr));
|
||||
obj_node = (node_ptr *)object->ptr;
|
||||
obj_node->node = obj;
|
||||
obj_node->refcount = 1;
|
||||
obj_node->_private = object;
|
||||
dom_object_set_data(obj, object TSRMLS_CC);
|
||||
} else if (object->ptr == NULL) {
|
||||
(node_ptr *)object->ptr = obj->_private;
|
||||
obj_node = (node_ptr *)object->ptr;
|
||||
obj_node->refcount++;
|
||||
if (obj_node->_private == NULL) {
|
||||
obj_node->_private = object;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} end php_dom_set_object */
|
||||
|
||||
/* {{{ dom_unregister_node */
|
||||
static int dom_unregister_node(xmlNodePtr nodep TSRMLS_DC)
|
||||
{
|
||||
dom_object *wrapper;
|
||||
|
||||
wrapper = dom_object_get_data(nodep);
|
||||
if (wrapper != NULL ) {
|
||||
return php_dom_clear_object(wrapper TSRMLS_CC);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
/* }}} end dom_unregister_node */
|
||||
|
||||
/* {{{ dom_read_na */
|
||||
static int dom_read_na(dom_object *obj, zval **retval TSRMLS_DC)
|
||||
{
|
||||
|
@ -409,6 +281,41 @@ void dom_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto somNode dom_import_simplexml(sxeobject node)
|
||||
Get a simplexml_element object from dom to allow for processing */
|
||||
PHP_FUNCTION(dom_import_simplexml)
|
||||
{
|
||||
#ifdef HAVE_SIMPLEXML
|
||||
zval *rv = NULL;
|
||||
zval *node;
|
||||
xmlNodePtr nodep;
|
||||
php_libxml_node_object *nodeobj;
|
||||
int ret;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
NODE_GET_OBJ(nodep, node, xmlNodePtr, nodeobj);
|
||||
|
||||
if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE) {
|
||||
DOM_RET_OBJ(rv, (xmlNodePtr) nodep, &ret, (dom_object *)nodeobj);
|
||||
} else {
|
||||
php_error(E_WARNING, "Invalid Nodetype to import");
|
||||
RETURN_NULL();
|
||||
}
|
||||
#else
|
||||
php_error(E_WARNING, "SimpleXML support is not enabled");
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_function_entry dom_functions[] = {
|
||||
PHP_FE(dom_import_simplexml, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
zend_module_entry dom_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"dom",
|
||||
|
@ -815,125 +722,6 @@ void node_list_unlink(xmlNodePtr node TSRMLS_DC)
|
|||
}
|
||||
/* }}} end node_list_unlink */
|
||||
|
||||
|
||||
/* {{{ void dom_node_free(xmlNodePtr node) */
|
||||
void dom_node_free(xmlNodePtr node)
|
||||
{
|
||||
if(node) {
|
||||
if (node->_private != NULL) {
|
||||
((node_ptr *) node->_private)->node = NULL;
|
||||
}
|
||||
switch (node->type) {
|
||||
case XML_ATTRIBUTE_NODE:
|
||||
xmlFreeProp((xmlAttrPtr) node);
|
||||
break;
|
||||
case XML_ENTITY_DECL:
|
||||
case XML_ELEMENT_DECL:
|
||||
case XML_ATTRIBUTE_DECL:
|
||||
break;
|
||||
case XML_NOTATION_NODE:
|
||||
/* These require special handling */
|
||||
if (node->name != NULL) {
|
||||
xmlFree((char *) node->name);
|
||||
}
|
||||
if (((xmlEntityPtr) node)->ExternalID != NULL) {
|
||||
xmlFree((char *) ((xmlEntityPtr) node)->ExternalID);
|
||||
}
|
||||
if (((xmlEntityPtr) node)->SystemID != NULL) {
|
||||
xmlFree((char *) ((xmlEntityPtr) node)->SystemID);
|
||||
}
|
||||
xmlFree(node);
|
||||
break;
|
||||
case XML_NAMESPACE_DECL:
|
||||
if (node->ns) {
|
||||
xmlFreeNs(node->ns);
|
||||
node->ns = NULL;
|
||||
}
|
||||
node->type = XML_ELEMENT_NODE;
|
||||
default:
|
||||
xmlFreeNode(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} end dom_node_free */
|
||||
|
||||
/* {{{ node_free_list */
|
||||
void node_free_list(xmlNodePtr node TSRMLS_DC)
|
||||
{
|
||||
xmlNodePtr curnode;
|
||||
|
||||
if (node != NULL) {
|
||||
curnode = node;
|
||||
while (curnode != NULL) {
|
||||
node = curnode;
|
||||
switch (node->type) {
|
||||
/* Skip property freeing for the following types */
|
||||
case XML_NOTATION_NODE:
|
||||
break;
|
||||
case XML_ENTITY_REF_NODE:
|
||||
node_free_list((xmlNodePtr) node->properties TSRMLS_CC);
|
||||
break;
|
||||
case XML_ATTRIBUTE_DECL:
|
||||
case XML_DTD_NODE:
|
||||
case XML_DOCUMENT_TYPE_NODE:
|
||||
case XML_ENTITY_DECL:
|
||||
case XML_ATTRIBUTE_NODE:
|
||||
case XML_NAMESPACE_DECL:
|
||||
node_free_list(node->children TSRMLS_CC);
|
||||
break;
|
||||
default:
|
||||
node_free_list(node->children TSRMLS_CC);
|
||||
node_free_list((xmlNodePtr) node->properties TSRMLS_CC);
|
||||
}
|
||||
|
||||
curnode = node->next;
|
||||
xmlUnlinkNode(node);
|
||||
if (dom_unregister_node(node TSRMLS_CC) == 0) {
|
||||
node->doc = NULL;
|
||||
}
|
||||
dom_node_free(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} end node_free_list */
|
||||
|
||||
/* {{{ node_free_resource */
|
||||
void node_free_resource(xmlNodePtr node TSRMLS_DC)
|
||||
{
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (node->type) {
|
||||
case XML_DOCUMENT_NODE:
|
||||
case XML_HTML_DOCUMENT_NODE:
|
||||
break;
|
||||
default:
|
||||
if (node->parent == NULL || node->type == XML_NAMESPACE_DECL) {
|
||||
node_free_list((xmlNodePtr) node->children TSRMLS_CC);
|
||||
switch (node->type) {
|
||||
/* Skip property freeing for the following types */
|
||||
case XML_ATTRIBUTE_DECL:
|
||||
case XML_DTD_NODE:
|
||||
case XML_DOCUMENT_TYPE_NODE:
|
||||
case XML_ENTITY_DECL:
|
||||
case XML_ATTRIBUTE_NODE:
|
||||
case XML_NAMESPACE_DECL:
|
||||
break;
|
||||
default:
|
||||
node_free_list((xmlNodePtr) node->properties TSRMLS_CC);
|
||||
}
|
||||
if (dom_unregister_node(node TSRMLS_CC) == 0) {
|
||||
node->doc = NULL;
|
||||
}
|
||||
dom_node_free(node);
|
||||
} else {
|
||||
dom_unregister_node(node TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ dom_objects_clone */
|
||||
void dom_objects_clone(void *object, void **object_clone TSRMLS_DC)
|
||||
{
|
||||
|
@ -952,7 +740,7 @@ void dom_xpath_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC)
|
|||
|
||||
if (intern->ptr != NULL) {
|
||||
xmlXPathFreeContext((xmlXPathContextPtr) intern->ptr);
|
||||
decrement_document_reference((dom_object *) intern TSRMLS_CC);
|
||||
php_libxml_decrement_doc_ref((php_libxml_node_object *) intern TSRMLS_CC);
|
||||
intern->ptr = NULL;
|
||||
}
|
||||
|
||||
|
@ -970,12 +758,13 @@ void dom_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC)
|
|||
zend_hash_destroy(intern->std.properties);
|
||||
FREE_HASHTABLE(intern->std.properties);
|
||||
|
||||
if (intern->ptr != NULL && ((node_ptr *)intern->ptr)->node != NULL) {
|
||||
if (((xmlNodePtr) ((node_ptr *)intern->ptr)->node)->type != XML_DOCUMENT_NODE && ((xmlNodePtr) ((node_ptr *)intern->ptr)->node)->type != XML_HTML_DOCUMENT_NODE) {
|
||||
node_free_resource(dom_object_get_node(intern) TSRMLS_CC);
|
||||
if (intern->ptr != NULL && ((php_libxml_node_ptr *)intern->ptr)->node != NULL) {
|
||||
if (((xmlNodePtr) ((php_libxml_node_ptr *)intern->ptr)->node)->type != XML_DOCUMENT_NODE && ((xmlNodePtr) ((php_libxml_node_ptr *)intern->ptr)->node)->type != XML_HTML_DOCUMENT_NODE) {
|
||||
// php_libxml_node_free_resource(dom_object_get_node(intern) TSRMLS_CC);
|
||||
php_libxml_node_decrement_resource((php_libxml_node_object *) intern TSRMLS_CC);
|
||||
} else {
|
||||
decrement_node_ptr(intern TSRMLS_CC);
|
||||
retcount = decrement_document_reference(intern TSRMLS_CC);
|
||||
php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
|
||||
retcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
|
||||
}
|
||||
intern->ptr = NULL;
|
||||
}
|
||||
|
@ -1004,7 +793,7 @@ static dom_object* dom_objects_set_class(zend_class_entry *class_type TSRMLS_DC)
|
|||
base_class = base_class->parent;
|
||||
}
|
||||
|
||||
zend_hash_find(&classes, base_class->name , base_class->name_length + 1, (void **) &intern->prop_handler);
|
||||
zend_hash_find(&classes, base_class->name, base_class->name_length + 1, (void **) &intern->prop_handler);
|
||||
|
||||
ALLOC_HASHTABLE(intern->std.properties);
|
||||
zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
|
@ -1157,10 +946,10 @@ zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *wrapper_in, zval *
|
|||
if (domobj != NULL) {
|
||||
intern->document = domobj->document;
|
||||
}
|
||||
increment_document_reference(intern, obj->doc TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)intern, obj->doc TSRMLS_CC);
|
||||
}
|
||||
|
||||
php_dom_set_object(intern, (void *) obj TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, obj, (void *)intern TSRMLS_CC);
|
||||
return (wrapper);
|
||||
}
|
||||
/* }}} end php_domobject_new */
|
||||
|
@ -1247,7 +1036,7 @@ void dom_normalize (xmlNodePtr nodep TSRMLS_DC)
|
|||
xmlNodeAddContent(child, strContent);
|
||||
xmlFree(strContent);
|
||||
xmlUnlinkNode(nextp);
|
||||
node_free_resource(nextp TSRMLS_CC);
|
||||
php_libxml_node_free_resource(nextp TSRMLS_CC);
|
||||
nextp = newnextp;
|
||||
} else {
|
||||
break;
|
||||
|
|
|
@ -54,6 +54,7 @@ extern zend_module_entry dom_module_entry;
|
|||
#endif
|
||||
|
||||
#include "xml_common.h"
|
||||
#include "ext/libxml/php_libxml.h"
|
||||
#include "zend_default_classes.h"
|
||||
/* DOM API_VERSION, please bump it up, if you change anything in the API
|
||||
therefore it's easier for the script-programmers to check, what's working how
|
||||
|
@ -63,21 +64,16 @@ extern zend_module_entry dom_module_entry;
|
|||
|
||||
#include "dom_fe.h"
|
||||
|
||||
void php_dom_set_object(dom_object *object, xmlNodePtr obj TSRMLS_DC);
|
||||
dom_object *dom_object_get_data(xmlNodePtr obj);
|
||||
xmlNodePtr dom_object_get_node(dom_object *obj);
|
||||
dom_doc_propsptr dom_get_doc_props(dom_ref_obj *document);
|
||||
dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document);
|
||||
zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC);
|
||||
#if defined(LIBXML_XPATH_ENABLED)
|
||||
zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC);
|
||||
#endif
|
||||
int dom_get_strict_error(dom_ref_obj *document);
|
||||
int dom_get_strict_error(php_libxml_ref_obj *document);
|
||||
void php_dom_throw_error(int error_code, int strict_error TSRMLS_DC);
|
||||
void node_free_resource(xmlNodePtr node TSRMLS_DC);
|
||||
void node_list_unlink(xmlNodePtr node TSRMLS_DC);
|
||||
int decrement_node_ptr(dom_object *object TSRMLS_DC);
|
||||
int increment_document_reference(dom_object *object, xmlDocPtr docp TSRMLS_DC);
|
||||
int decrement_document_reference(dom_object *object TSRMLS_DC);
|
||||
int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len);
|
||||
xmlNsPtr dom_get_ns(xmlNodePtr node, char *uri, int *errorcode, char *prefix);
|
||||
void dom_set_old_ns(xmlDoc *doc, xmlNs *ns);
|
||||
|
@ -97,7 +93,7 @@ entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
|
|||
|
||||
#define DOM_GET_OBJ(__ptr, __id, __prtype, __intern) { \
|
||||
__intern = (dom_object *)zend_object_store_get_object(__id TSRMLS_CC); \
|
||||
if (__intern->ptr == NULL || !(__ptr = (__prtype)((node_ptr *)__intern->ptr)->node)) { \
|
||||
if (__intern->ptr == NULL || !(__ptr = (__prtype)((php_libxml_node_ptr *)__intern->ptr)->node)) { \
|
||||
php_error(E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\
|
||||
RETURN_NULL();\
|
||||
} \
|
||||
|
|
|
@ -70,9 +70,9 @@ PHP_FUNCTION(dom_processinginstruction_processinginstruction)
|
|||
if (intern != NULL) {
|
||||
oldnode = (xmlNodePtr)intern->ptr;
|
||||
if (oldnode != NULL) {
|
||||
node_free_resource(oldnode TSRMLS_CC);
|
||||
php_libxml_node_free_resource(oldnode TSRMLS_CC);
|
||||
}
|
||||
php_dom_set_object(intern, nodep TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} end dom_processinginstruction_processinginstruction */
|
||||
|
|
|
@ -68,9 +68,9 @@ PHP_FUNCTION(dom_text_text)
|
|||
if (intern != NULL) {
|
||||
oldnode = (xmlNodePtr)intern->ptr;
|
||||
if (oldnode != NULL) {
|
||||
node_free_resource(oldnode TSRMLS_CC);
|
||||
php_libxml_node_free_resource(oldnode TSRMLS_CC);
|
||||
}
|
||||
php_dom_set_object(intern, nodep TSRMLS_CC);
|
||||
php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} end dom_text_text */
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#ifndef PHP_XML_COMMON_H
|
||||
#define PHP_XML_COMMON_H
|
||||
|
||||
#include "ext/libxml/php_libxml.h"
|
||||
|
||||
typedef struct _dom_doc_props {
|
||||
int formatoutput;
|
||||
int validateonparse;
|
||||
|
@ -33,28 +35,10 @@ typedef struct _dom_doc_props {
|
|||
|
||||
typedef dom_doc_props *dom_doc_propsptr;
|
||||
|
||||
typedef struct _dom_ref_obj {
|
||||
void *ptr;
|
||||
int refcount;
|
||||
dom_doc_props *doc_props;
|
||||
} dom_ref_obj;
|
||||
|
||||
typedef struct _node_ptr {
|
||||
xmlNodePtr node;
|
||||
int refcount;
|
||||
void *_private;
|
||||
} node_ptr;
|
||||
|
||||
typedef struct _node_object {
|
||||
zend_object std;
|
||||
node_ptr *node;
|
||||
dom_ref_obj *document;
|
||||
} node_object;
|
||||
|
||||
typedef struct _dom_object {
|
||||
zend_object std;
|
||||
void *ptr;
|
||||
dom_ref_obj *document;
|
||||
php_libxml_ref_obj *document;
|
||||
HashTable *prop_handler;
|
||||
zend_object_handle handle;
|
||||
} dom_object;
|
||||
|
@ -80,15 +64,15 @@ PHP_DOM_EXPORT(void) dom_write_property(zval *object, zval *member, zval *value
|
|||
(const xmlChar *) "http://www.w3.org/2000/xmlns/"
|
||||
|
||||
#define NODE_GET_OBJ(__ptr, __id, __prtype, __intern) { \
|
||||
__intern = (node_object *)zend_object_store_get_object(__id TSRMLS_CC); \
|
||||
if (__intern->ptr == NULL || !(__ptr = (__prtype)__intern->ptr->node)) { \
|
||||
__intern = (php_libxml_node_object *)zend_object_store_get_object(__id TSRMLS_CC); \
|
||||
if (__intern->node == NULL || !(__ptr = (__prtype)__intern->node->node)) { \
|
||||
php_error(E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\
|
||||
RETURN_NULL();\
|
||||
} \
|
||||
}
|
||||
|
||||
#define DOC_GET_OBJ(__ptr, __id, __prtype, __intern) { \
|
||||
__intern = (node_object *)zend_object_store_get_object(__id TSRMLS_CC); \
|
||||
__intern = (php_libxml_node_object *)zend_object_store_get_object(__id TSRMLS_CC); \
|
||||
if (__intern->document != NULL) { \
|
||||
if (!(__ptr = (__prtype)__intern->document->ptr)) { \
|
||||
php_error(E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\
|
||||
|
|
|
@ -66,12 +66,12 @@ PHP_FUNCTION(dom_xpath_xpath)
|
|||
if (intern != NULL) {
|
||||
oldctx = (xmlXPathContextPtr)intern->ptr;
|
||||
if (oldctx != NULL) {
|
||||
decrement_document_reference(intern TSRMLS_CC);
|
||||
php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
|
||||
xmlXPathFreeContext(oldctx);
|
||||
}
|
||||
intern->ptr = ctx;
|
||||
intern->document = docobj->document;
|
||||
increment_document_reference(intern, docp TSRMLS_CC);
|
||||
php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} end dom_xpath_xpath */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue