add interop with simplexml - dom_import_simplexml

fix cloneNode with elements
This commit is contained in:
Rob Richards 2003-10-26 15:57:02 +00:00
parent d29fb55bbb
commit 207dc90924
15 changed files with 139 additions and 347 deletions

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -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 */

View file

@ -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 {

View file

@ -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 */

View file

@ -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 */

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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();\
} \

View file

@ -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 */

View file

@ -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 */

View file

@ -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);\

View file

@ -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 */