diff options
author | Rob Richards <rrichards@php.net> | 2003-07-07 19:37:32 +0000 |
---|---|---|
committer | Rob Richards <rrichards@php.net> | 2003-07-07 19:37:32 +0000 |
commit | 4cd06845f9ba63f1fe4fa640eeb0e7b9c21f7365 (patch) | |
tree | 19ce92323ce5b1fec1b0b59fdaaa0ebc813543c6 | |
parent | 134338522f524b84d8ee43bdd457486a15d5128a (diff) | |
download | php-git-4cd06845f9ba63f1fe4fa640eeb0e7b9c21f7365.tar.gz |
implement node proxies: next phase of interop
-rw-r--r-- | ext/dom/attr.c | 8 | ||||
-rw-r--r-- | ext/dom/characterdata.c | 6 | ||||
-rw-r--r-- | ext/dom/document.c | 28 | ||||
-rw-r--r-- | ext/dom/documenttype.c | 12 | ||||
-rw-r--r-- | ext/dom/element.c | 6 | ||||
-rw-r--r-- | ext/dom/entity.c | 8 | ||||
-rw-r--r-- | ext/dom/node.c | 48 | ||||
-rw-r--r-- | ext/dom/notation.c | 4 | ||||
-rw-r--r-- | ext/dom/php_dom.c | 131 | ||||
-rw-r--r-- | ext/dom/php_dom.h | 6 | ||||
-rw-r--r-- | ext/dom/processinginstruction.c | 6 | ||||
-rw-r--r-- | ext/dom/text.c | 2 | ||||
-rw-r--r-- | ext/dom/xml_common.h | 12 |
13 files changed, 152 insertions, 125 deletions
diff --git a/ext/dom/attr.c b/ext/dom/attr.c index 26d1a26d74..398796261f 100644 --- a/ext/dom/attr.c +++ b/ext/dom/attr.c @@ -89,7 +89,7 @@ int dom_attr_name_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlAttrPtr attrp; - attrp = obj->ptr; + attrp = (xmlAttrPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); ZVAL_STRING(*retval, (char *) (attrp->name), 1); @@ -127,7 +127,7 @@ int dom_attr_value_read(dom_object *obj, zval **retval TSRMLS_DC) xmlAttrPtr attrp; xmlChar *content; - attrp = obj->ptr; + attrp = (xmlAttrPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); @@ -148,7 +148,7 @@ int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC) { xmlAttrPtr attrp; - attrp = obj->ptr; + attrp = (xmlAttrPtr) dom_object_get_node(obj); if (attrp->children) { node_list_unlink(attrp->children TSRMLS_CC); @@ -172,7 +172,7 @@ int dom_attr_owner_element_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNodePtr nodep, nodeparent; int ret; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); nodeparent = nodep->parent; if (!nodeparent) { diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c index 0ed5dffa27..bfc1b9232e 100644 --- a/ext/dom/characterdata.c +++ b/ext/dom/characterdata.c @@ -53,7 +53,7 @@ int dom_characterdata_data_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNodePtr nodep; xmlChar *content; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); @@ -72,7 +72,7 @@ int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC) { xmlNode *nodep; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); return SUCCESS; } @@ -104,7 +104,7 @@ int dom_characterdata_length_read(dom_object *obj, zval **retval TSRMLS_DC) xmlChar *content; long length; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); diff --git a/ext/dom/document.c b/ext/dom/document.c index b24445bdb4..429b84b2fc 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -107,8 +107,7 @@ int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC) xmlDtdPtr dtdptr; int ret; - docp = obj->ptr; - + docp = (xmlDocPtr) dom_object_get_node(obj); dtdptr = xmlGetIntSubset(docp); if (!dtdptr) { @@ -155,7 +154,7 @@ int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *root; int ret; - docp = obj->ptr; + docp = (xmlDocPtr) dom_object_get_node(obj); root = xmlDocGetRootElement(docp); if (!root) { @@ -204,7 +203,7 @@ int dom_document_encoding_read(dom_object *obj, zval **retval TSRMLS_DC) xmlDoc *docp; char *encoding; - docp = obj->ptr; + docp = (xmlDocPtr) dom_object_get_node(obj); encoding = (char *) docp->encoding; ALLOC_ZVAL(*retval); @@ -253,7 +252,7 @@ int dom_document_standalone_read(dom_object *obj, zval **retval TSRMLS_DC) xmlDoc *docp; int standalone; - docp = obj->ptr; + docp = (xmlDocPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); standalone = docp->standalone; ZVAL_BOOL(*retval, standalone); @@ -266,7 +265,7 @@ int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC) xmlDoc *docp; int standalone; - docp = obj->ptr; + docp = (xmlDocPtr) dom_object_get_node(obj); standalone = Z_LVAL_P(newval); if (standalone > 0) { docp->standalone = 1; @@ -295,7 +294,7 @@ int dom_document_version_read(dom_object *obj, zval **retval TSRMLS_DC) xmlDoc *docp; char *version; - docp = obj->ptr; + docp = (xmlDocPtr) dom_object_get_node(obj); version = (char *) docp->version; ALLOC_ZVAL(*retval); @@ -312,7 +311,7 @@ int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC) { xmlDoc *docp; - docp = obj->ptr; + docp = (xmlDocPtr) dom_object_get_node(obj); if (docp->version != NULL) { xmlFree((xmlChar *) docp->version ); } @@ -357,7 +356,7 @@ int dom_document_document_uri_read(dom_object *obj, zval **retval TSRMLS_DC) xmlDoc *docp; char *url; - docp = obj->ptr; + docp = (xmlDocPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); url = (char *) docp->URL; @@ -374,7 +373,7 @@ int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC) { xmlDoc *docp; - docp = obj->ptr; + docp = (xmlDocPtr) dom_object_get_node(obj); if (docp->URL != NULL) { xmlFree((xmlChar *) docp->URL); } @@ -975,6 +974,7 @@ PHP_FUNCTION(dom_document_document) if (intern != NULL) { olddoc = (xmlDocPtr)intern->ptr; if (olddoc != NULL) { + decrement_node_ptr(intern TSRMLS_CC); refcount = decrement_document_reference(intern TSRMLS_CC); if (refcount != 0) { olddoc->_private = NULL; @@ -983,7 +983,7 @@ PHP_FUNCTION(dom_document_document) intern->document = NULL; increment_document_reference(intern, docp TSRMLS_CC); - php_dom_set_object(intern, docp TSRMLS_CC); + php_dom_set_object(intern, (xmlNodePtr) docp TSRMLS_CC); } add_property_bool(id, "formatOutput", 0); @@ -1019,6 +1019,7 @@ PHP_FUNCTION(dom_document_load) if (intern != NULL) { docp = (xmlDocPtr)intern->ptr; if (docp != NULL) { + decrement_node_ptr(intern TSRMLS_CC); refcount = decrement_document_reference(intern TSRMLS_CC); if (refcount != 0) { docp->_private = NULL; @@ -1028,7 +1029,7 @@ PHP_FUNCTION(dom_document_load) increment_document_reference(intern, newdoc TSRMLS_CC); } - php_dom_set_object(intern, newdoc TSRMLS_CC); + php_dom_set_object(intern, (xmlNodePtr) newdoc TSRMLS_CC); RETURN_TRUE; } else { @@ -1064,6 +1065,7 @@ PHP_FUNCTION(dom_document_loadxml) if (intern != NULL) { docp = (xmlDocPtr)intern->ptr; if (docp != NULL) { + decrement_node_ptr(intern TSRMLS_CC); refcount = decrement_document_reference(intern TSRMLS_CC); if (refcount != 0) { docp->_private = NULL; @@ -1074,7 +1076,7 @@ PHP_FUNCTION(dom_document_loadxml) increment_document_reference(intern, newdoc TSRMLS_CC); } - php_dom_set_object(intern, newdoc TSRMLS_CC); + php_dom_set_object(intern, (xmlNodePtr) newdoc TSRMLS_CC); RETURN_TRUE; } else { diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c index c00509f94d..f937883b5f 100644 --- a/ext/dom/documenttype.c +++ b/ext/dom/documenttype.c @@ -67,7 +67,7 @@ int dom_documenttype_name_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlDtdPtr dtdptr; - dtdptr = obj->ptr; + dtdptr = (xmlDtdPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); ZVAL_STRING(*retval, (char *) (dtdptr->name), 1); @@ -91,7 +91,7 @@ int dom_documenttype_entities_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep = NULL; int ret, htsize, index = 0; - doctypep = obj->ptr; + doctypep = (xmlDtdPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); array_init(*retval); @@ -137,7 +137,7 @@ int dom_documenttype_notations_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep = NULL; int ret, htsize, index = 0; - doctypep = obj->ptr; + doctypep = (xmlDtdPtr) dom_object_get_node(obj); MAKE_STD_ZVAL(*retval); array_init(*retval); @@ -179,7 +179,7 @@ int dom_documenttype_public_id_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlDtdPtr dtdptr; - dtdptr = obj->ptr; + dtdptr = (xmlDtdPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); if (dtdptr->ExternalID) { @@ -204,7 +204,7 @@ int dom_documenttype_system_id_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlDtdPtr dtdptr; - dtdptr = obj->ptr; + dtdptr = (xmlDtdPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); if (dtdptr->SystemID) { @@ -232,7 +232,7 @@ int dom_documenttype_internal_subset_read(dom_object *obj, zval **retval TSRMLS_ xmlOutputBuffer *buff = NULL; xmlChar *strintsubset; - dtdptr = obj->ptr; + dtdptr = (xmlDtdPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); diff --git a/ext/dom/element.c b/ext/dom/element.c index 37086d4cd0..b46d3bd62d 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -107,7 +107,7 @@ int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlNodePtr nodep; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); ZVAL_STRING(*retval, (char *) (nodep->name), 1); return SUCCESS; @@ -296,7 +296,7 @@ PHP_FUNCTION(dom_element_set_attribute_node) if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) == NULL) { xmlUnlinkNode((xmlNodePtr) existattrp); } else { - if (oldobj->ptr == attrp) { + if (oldobj->ptr->node == (xmlNodePtr) attrp) { RETURN_NULL(); } xmlUnlinkNode((xmlNodePtr) existattrp); @@ -637,7 +637,7 @@ PHP_FUNCTION(dom_element_set_attribute_node_ns) if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) == NULL) { xmlUnlinkNode((xmlNodePtr) existattrp); } else { - if (oldobj->ptr == attrp) { + if (oldobj->ptr->node == (xmlNodePtr) attrp) { RETURN_NULL(); } xmlUnlinkNode((xmlNodePtr) existattrp); diff --git a/ext/dom/entity.c b/ext/dom/entity.c index 2e1b184f74..84ad9423e5 100644 --- a/ext/dom/entity.c +++ b/ext/dom/entity.c @@ -48,7 +48,8 @@ Since: int dom_entity_public_id_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlEntity *nodep; - nodep = obj->ptr; + + nodep = (xmlEntity *) dom_object_get_node(obj); ALLOC_ZVAL(*retval); if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { @@ -72,7 +73,8 @@ Since: int dom_entity_system_id_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlEntity *nodep; - nodep = obj->ptr; + + nodep = (xmlEntity *) dom_object_get_node(obj); ALLOC_ZVAL(*retval); if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { @@ -98,7 +100,7 @@ int dom_entity_notation_name_read(dom_object *obj, zval **retval TSRMLS_DC) xmlEntity *nodep; char *content; - nodep = obj->ptr; + nodep = (xmlEntity *) dom_object_get_node(obj); ALLOC_ZVAL(*retval); if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { diff --git a/ext/dom/node.c b/ext/dom/node.c index d176dd684c..87b0cff72f 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -66,7 +66,7 @@ int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep; char *str = NULL; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); switch (nodep->type) { case XML_ATTRIBUTE_NODE: @@ -131,7 +131,7 @@ int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep; char *str = NULL; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); /* TODO: Element node is invalid for this property - currently here as a convience method while developing */ switch (nodep->type) { @@ -166,7 +166,7 @@ int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC) { xmlNode *nodep; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); switch (nodep->type) { case XML_ATTRIBUTE_NODE: @@ -199,7 +199,7 @@ int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlNode *nodep; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); ZVAL_LONG(*retval, nodep->type); @@ -220,7 +220,7 @@ int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep, *nodeparent; int ret; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); nodeparent = nodep->parent; if (!nodeparent) { @@ -249,7 +249,8 @@ int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlNodePtr nodep, last; int ret; - nodep = obj->ptr; + + nodep = dom_object_get_node(obj); if ((nodep->type == XML_DOCUMENT_NODE) || (nodep->type == XML_HTML_DOCUMENT_NODE)) { last = ((xmlDoc *) nodep)->children; @@ -285,8 +286,7 @@ int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep, *first; int ret; - nodep = obj->ptr; - + nodep = dom_object_get_node(obj); first = nodep->children; if (!first) { @@ -316,7 +316,7 @@ int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep, *last; int ret; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); last = nodep->last; if (!last) { @@ -346,7 +346,7 @@ int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep, *prevsib; int ret; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); prevsib = nodep->prev; if (!prevsib) { @@ -376,7 +376,7 @@ int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep, *nextsib; int ret; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); nextsib = nodep->next; if (!nextsib) { @@ -405,9 +405,9 @@ int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlNodePtr nodep; xmlAttr *attr; - int ret; - nodep = obj->ptr; + + nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); @@ -444,7 +444,7 @@ int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC) xmlDocPtr docp; int ret; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { ALLOC_ZVAL(*retval); @@ -480,7 +480,7 @@ int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep; char *str = NULL; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); switch (nodep->type) { case XML_ELEMENT_NODE: @@ -520,7 +520,7 @@ int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNsPtr ns; char *str = NULL; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); switch (nodep->type) { case XML_ELEMENT_NODE: @@ -556,7 +556,7 @@ int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC) char *strURI; char *prefix; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); switch (nodep->type) { case XML_ELEMENT_NODE: @@ -617,7 +617,8 @@ Since: DOM Level 2 int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlNode *nodep; - nodep = obj->ptr; + + nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); @@ -661,7 +662,7 @@ int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNode *nodep; char *str = NULL; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); str = xmlNodeGetContent(nodep); @@ -767,7 +768,8 @@ PHP_FUNCTION(dom_node_insert_before) if (lastattr != (xmlAttrPtr) child) { xmlUnlinkNode((xmlNodePtr) lastattr); node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); - xmlFreeProp(lastattr); + /* Freed above + xmlFreeProp(lastattr); */ } else { DOM_RET_OBJ(rv, child, &ret, intern); return; @@ -808,7 +810,8 @@ PHP_FUNCTION(dom_node_insert_before) if (lastattr != (xmlAttrPtr) child) { xmlUnlinkNode((xmlNodePtr) lastattr); node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); - xmlFreeProp(lastattr); + /* Freed above + xmlFreeProp(lastattr); */ } else { DOM_RET_OBJ(rv, child, &ret, intern); return; @@ -1012,7 +1015,8 @@ PHP_FUNCTION(dom_node_append_child) if (lastattr != (xmlAttrPtr) child) { xmlUnlinkNode((xmlNodePtr) lastattr); node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); - xmlFreeProp(lastattr); + /* Freed above + xmlFreeProp(lastattr); */ } } } else if (child->type == XML_DOCUMENT_FRAG_NODE) { diff --git a/ext/dom/notation.c b/ext/dom/notation.c index b50765f3c9..754eb835e8 100644 --- a/ext/dom/notation.c +++ b/ext/dom/notation.c @@ -49,7 +49,7 @@ int dom_notation_public_id_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlNotationPtr nodep; - nodep = obj->ptr; + nodep = (xmlNotationPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); if (nodep->PublicID) { ZVAL_STRING(*retval, (char *) (nodep->PublicID), 1); @@ -73,7 +73,7 @@ int dom_notation_system_id_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlNotationPtr nodep; - nodep = obj->ptr; + nodep = (xmlNotationPtr) dom_object_get_node(obj); ALLOC_ZVAL(*retval); if (nodep->SystemID) { ZVAL_STRING(*retval, (char *) (nodep->PublicID), 1); diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index f811ef892d..78ee524f61 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -74,7 +74,7 @@ static zend_function_entry dom_functions[] = { }; -/* {{{ void increment_document_reference(dom_object *object) */ +/* {{{ int increment_document_reference(dom_object *object) */ int increment_document_reference(dom_object *object, xmlDocPtr docp TSRMLS_DC) { int ret_refcount = -1; @@ -82,16 +82,17 @@ int increment_document_reference(dom_object *object, xmlDocPtr docp TSRMLS_DC) { 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 = 1; + object->document->refcount = ret_refcount; } return ret_refcount; } /* }}} end increment_document_reference */ -/* {{{ void decrement_document_reference(dom_object *object) */ +/* {{{ int decrement_document_reference(dom_object *object) */ int decrement_document_reference(dom_object *object TSRMLS_DC) { int ret_refcount = -1; @@ -104,46 +105,93 @@ int decrement_document_reference(dom_object *object TSRMLS_DC) { object->document->ptr = NULL; } efree(object->document); - object->document = NULL; } + 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; + + if (object != NULL && object->ptr != NULL) { + ret_refcount = --object->ptr->refcount; + if (ret_refcount == 0) { + if (object->ptr->node != NULL) { + object->ptr->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 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) { - - obj->_private = wrapper; + if (wrapper == NULL) { + obj->_private = NULL; + } else { + obj->_private = wrapper->ptr; + } } /* }}} end dom_object_set_data */ -/* {{{ dom_object_get_data */ +/* {{{ dom_object *dom_object_get_data(xmlNodePtr obj) */ dom_object *dom_object_get_data(xmlNodePtr obj) { - return (dom_object *) obj->_private; + if (obj->_private != NULL) { + return (dom_object *) ((node_ptr *) obj->_private)->_private; + } else { + return NULL; + } } /* }}} end dom_object_get_data */ /* {{{ php_dom_clear_object */ static void php_dom_clear_object(dom_object *object TSRMLS_DC) { - object->ptr = NULL; if (object->prop_handler) { object->prop_handler = NULL; } + decrement_node_ptr(object TSRMLS_CC); decrement_document_reference(object TSRMLS_CC); - object->document = NULL; } -/* }}} end dom_object_get_data */ +/* }}} end php_dom_clear_object */ -/* {{{ php_dom_set_object */ -void php_dom_set_object(dom_object *object, void *obj TSRMLS_DC) +/* {{{ void php_dom_set_object(dom_object *object, xmlNodePtr obj TSRMLS_DC) */ +void php_dom_set_object(dom_object *object, xmlNodePtr obj TSRMLS_DC) { - object->ptr = obj; - dom_object_set_data(obj, object TSRMLS_CC); + if (obj->_private == NULL) { + object->ptr = emalloc(sizeof(node_ptr)); + object->ptr->node = obj; + object->ptr->refcount = 1; + object->ptr->_private = object; + dom_object_set_data(obj, object TSRMLS_CC); + } else if (object->ptr == NULL) { + object->ptr = obj->_private; + object->ptr->refcount++; + if (object->ptr->_private == NULL) { + object->ptr->_private = object; + } + } } /* }}} end php_dom_set_object */ @@ -154,7 +202,6 @@ void dom_unregister_node(xmlNodePtr nodep TSRMLS_DC) wrapper = dom_object_get_data(nodep); if (wrapper != NULL ) { - dom_object_set_data(nodep, NULL TSRMLS_CC); php_dom_clear_object(wrapper TSRMLS_CC); } } @@ -635,6 +682,9 @@ void node_list_unlink(xmlNodePtr node TSRMLS_DC) 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); @@ -686,9 +736,6 @@ void node_free_list(xmlNodePtr node TSRMLS_DC) /* {{{ node_free_resource */ void node_free_resource(xmlNodePtr node TSRMLS_DC) { - xmlDtdPtr extSubset, intSubset; - xmlDocPtr docp; - if (!node) { return; } @@ -696,34 +743,7 @@ void node_free_resource(xmlNodePtr node TSRMLS_DC) switch (node->type) { case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: - { - docp = (xmlDocPtr) node; - if (docp->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) docp->ids); - docp->ids = NULL; - if (docp->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) docp->refs); - docp->refs = NULL; - extSubset = docp->extSubset; - intSubset = docp->intSubset; - if (intSubset == extSubset) - extSubset = NULL; - if (extSubset != NULL) { - node_free_list((xmlNodePtr) extSubset->children TSRMLS_CC); - xmlUnlinkNode((xmlNodePtr) docp->extSubset); - docp->extSubset = NULL; - xmlFreeDtd(extSubset); - } - if (intSubset != NULL) { - node_free_list((xmlNodePtr) intSubset->children TSRMLS_CC); - xmlUnlinkNode((xmlNodePtr) docp->intSubset); - docp->intSubset = NULL; - xmlFreeDtd(intSubset); - } - - node_free_list(node->children TSRMLS_CC); - node_free_list((xmlNodePtr) node->properties TSRMLS_CC); - xmlFreeDoc((xmlDoc *) node); break; - } default: if (node->parent == NULL) { node_free_list((xmlNodePtr) node->children TSRMLS_CC); @@ -739,13 +759,7 @@ void node_free_resource(xmlNodePtr node TSRMLS_DC) node_free_list((xmlNodePtr) node->properties TSRMLS_CC); } dom_unregister_node(node TSRMLS_CC); - switch (node->type) { - case XML_ATTRIBUTE_NODE: - xmlFreeProp((xmlAttrPtr) node); - break; - default: - xmlFreeNode((xmlNode *) node); - } + dom_node_free(node); } else { dom_unregister_node(node TSRMLS_CC); } @@ -769,15 +783,12 @@ 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) { - if (((xmlNodePtr) intern->ptr)->type != XML_DOCUMENT_NODE && ((xmlNodePtr) intern->ptr)->type != XML_HTML_DOCUMENT_NODE) { - node_free_resource(intern->ptr TSRMLS_CC); + if (intern->ptr != NULL && intern->ptr->node != NULL) { + if (((xmlNodePtr) intern->ptr->node)->type != XML_DOCUMENT_NODE && ((xmlNodePtr) intern->ptr->node)->type != XML_HTML_DOCUMENT_NODE) { + node_free_resource(dom_object_get_node(intern) TSRMLS_CC); } else { + decrement_node_ptr(intern TSRMLS_CC); retcount = decrement_document_reference(intern TSRMLS_CC); - if (retcount != 0) { - dom_object_set_data(intern->ptr, NULL TSRMLS_CC); - } - intern->document = NULL; } intern->ptr = NULL; } diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 3bc6a3875c..9160d10958 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -64,12 +64,14 @@ extern zend_module_entry dom_module_entry; #include "dom_fe.h" -void php_dom_set_object(dom_object *wrapper, void *obj TSRMLS_DC); +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); zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC); void php_dom_throw_error(int error_code, zval **retval 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); xmlNsPtr dom_get_ns(char *uri, char *qName, int uri_len, int qName_len, int *errorcode, char **localname); @@ -88,7 +90,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 (!(__ptr = (__prtype)__intern->ptr)) { \ + if (__intern->ptr == NULL || !(__ptr = (__prtype)__intern->ptr->node)) { \ php_error(E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\ RETURN_NULL();\ } \ diff --git a/ext/dom/processinginstruction.c b/ext/dom/processinginstruction.c index b051da30bc..004bfbf5aa 100644 --- a/ext/dom/processinginstruction.c +++ b/ext/dom/processinginstruction.c @@ -85,7 +85,7 @@ int dom_processinginstruction_target_read(dom_object *obj, zval **retval TSRMLS_ { xmlNodePtr nodep; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); ZVAL_STRING(*retval, (char *) (nodep->name), 1); @@ -107,7 +107,7 @@ int dom_processinginstruction_data_read(dom_object *obj, zval **retval TSRMLS_DC xmlNodePtr nodep; xmlChar *content; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); @@ -127,7 +127,7 @@ int dom_processinginstruction_data_write(dom_object *obj, zval *newval TSRMLS_DC { xmlNode *nodep; - nodep = obj->ptr; + nodep = dom_object_get_node(obj); xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); return SUCCESS; diff --git a/ext/dom/text.c b/ext/dom/text.c index 68461ccd5d..4995eb6d87 100644 --- a/ext/dom/text.c +++ b/ext/dom/text.c @@ -84,7 +84,7 @@ int dom_text_whole_text_read(dom_object *obj, zval **retval TSRMLS_DC) xmlNodePtr node; xmlChar *wholetext; - node = obj->ptr; + node = dom_object_get_node(obj); ALLOC_ZVAL(*retval); wholetext = xmlNodeListGetString(node->doc, node, 1); diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h index a2e6b2c5a0..c16aef5ab0 100644 --- a/ext/dom/xml_common.h +++ b/ext/dom/xml_common.h @@ -27,15 +27,21 @@ typedef struct _dom_ref_obj { int refcount; } dom_ref_obj; +typedef struct _node_ptr { + xmlNodePtr node; + int refcount; + void *_private; +} node_ptr; + typedef struct _node_object { zend_object std; - xmlNodePtr node; + node_ptr *node; dom_ref_obj *document; } node_object; typedef struct _dom_object { zend_object std; - void *ptr; + node_ptr *ptr; dom_ref_obj *document; HashTable *prop_handler; zend_object_handle handle; @@ -63,7 +69,7 @@ PHP_DOM_EXPORT(void) dom_write_property(zval *object, zval *member, zval *value #define NODE_GET_OBJ(__ptr, __id, __prtype, __intern) { \ __intern = (node_object *)zend_object_store_get_object(__id TSRMLS_CC); \ - if (!(__ptr = (__prtype)__intern->node)) { \ + if (__intern->ptr == NULL || !(__ptr = (__prtype)__intern->ptr->node)) { \ php_error(E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\ RETURN_NULL();\ } \ |