From: Rob Richards Date: Mon, 9 Jun 2003 20:20:55 +0000 (+0000) Subject: implmentation of document ref counting for persistance X-Git-Tag: RELEASE_1_0_2~336 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6d72c89408234b954e7440e132b50474b9872d72;p=php implmentation of document ref counting for persistance re-work of internal object handling --- diff --git a/ext/dom/attr.c b/ext/dom/attr.c index 2136b2a651..d3d584c0db 100644 --- a/ext/dom/attr.c +++ b/ext/dom/attr.c @@ -52,7 +52,8 @@ PHP_FUNCTION(dom_attr_attr) int name_len, value_len; id = getThis(); - + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name, &name_len, &value, &value_len) == FAILURE) { return; } @@ -67,13 +68,12 @@ PHP_FUNCTION(dom_attr_attr) if (!nodep) RETURN_FALSE; - intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); if (intern != NULL) { oldnode = (xmlNodePtr)intern->ptr; if (oldnode != NULL) { node_free_resource(oldnode TSRMLS_CC); } - php_dom_set_object(id, (xmlNodePtr) nodep TSRMLS_CC); + php_dom_set_object(intern, (xmlNodePtr) nodep TSRMLS_CC); } } @@ -169,8 +169,6 @@ Since: DOM Level 2 */ int dom_attr_owner_element_read(dom_object *obj, zval **retval TSRMLS_DC) { - - zval *wrapper; xmlNodePtr nodep, nodeparent; int ret; @@ -181,11 +179,9 @@ int dom_attr_owner_element_read(dom_object *obj, zval **retval TSRMLS_DC) return FAILURE; } - wrapper = dom_object_get_data(nodeparent); - if (wrapper == NULL) { - ALLOC_ZVAL(*retval); - } - if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, wrapper, *retval TSRMLS_CC))) { + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, NULL, *retval, obj TSRMLS_CC))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); return FAILURE; } diff --git a/ext/dom/cdatasection.c b/ext/dom/cdatasection.c index 21ccefea1f..2622e070a9 100644 --- a/ext/dom/cdatasection.c +++ b/ext/dom/cdatasection.c @@ -67,7 +67,7 @@ PHP_FUNCTION(dom_cdatasection_cdatasection) if (oldnode != NULL) { node_free_resource(oldnode TSRMLS_CC); } - php_dom_set_object(id, nodep TSRMLS_CC); + php_dom_set_object(intern, nodep TSRMLS_CC); } } /* }}} end dom_cdatasection_cdatasection */ diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c index 4bc656a3bc..62ac3b3f73 100644 --- a/ext/dom/characterdata.c +++ b/ext/dom/characterdata.c @@ -140,11 +140,12 @@ PHP_FUNCTION(dom_characterdata_append_data) { zval *id; xmlNode *nodep; + dom_object *intern; char *arg; int arg_len; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { return; diff --git a/ext/dom/comment.c b/ext/dom/comment.c index 7d6c6e9783..b32555bd1f 100644 --- a/ext/dom/comment.c +++ b/ext/dom/comment.c @@ -66,7 +66,7 @@ PHP_FUNCTION(dom_comment_comment) if (oldnode != NULL) { node_free_resource(oldnode TSRMLS_CC); } - php_dom_set_object(id, nodep TSRMLS_CC); + php_dom_set_object(intern, nodep TSRMLS_CC); } } /* }}} end dom_comment_comment */ diff --git a/ext/dom/document.c b/ext/dom/document.c index a92a33efe4..298d9a405d 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -82,7 +82,6 @@ Since: */ int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC) { - zval *wrapper; xmlDoc *docp; xmlDtdPtr dtdptr; int ret; @@ -95,11 +94,8 @@ int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC) return FAILURE; } - wrapper = dom_object_get_data((xmlNodePtr) dtdptr); - if (wrapper == NULL) { - ALLOC_ZVAL(*retval); - } - if (NULL == (*retval = php_dom_create_object((xmlNodePtr) dtdptr, &ret, wrapper, *retval TSRMLS_CC))) { + ALLOC_ZVAL(*retval); + if (NULL == (*retval = php_dom_create_object((xmlNodePtr) dtdptr, &ret, NULL, *retval, obj TSRMLS_CC))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); return FAILURE; } @@ -134,7 +130,6 @@ Since: */ int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC) { - zval *wrapper; xmlDoc *docp; xmlNode *root; int ret; @@ -146,11 +141,8 @@ int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC) return FAILURE; } - wrapper = dom_object_get_data(root); - if (wrapper == NULL) { - ALLOC_ZVAL(*retval); - } - if (NULL == (*retval = php_dom_create_object(root, &ret, wrapper, *retval TSRMLS_CC))) { + ALLOC_ZVAL(*retval); + if (NULL == (*retval = php_dom_create_object(root, &ret, NULL, *retval, obj TSRMLS_CC))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); return FAILURE; } @@ -400,10 +392,11 @@ PHP_FUNCTION(dom_document_create_element) zval *id, *rv = NULL; xmlNode *node; xmlDocPtr docp; + dom_object *intern; int ret, name_len; char *name; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name, &name_len) == FAILURE) { return; @@ -414,8 +407,8 @@ PHP_FUNCTION(dom_document_create_element) RETURN_FALSE; } - dom_add_to_list(node, docp TSRMLS_CC); - DOM_RET_OBJ(rv, node, &ret); + dom_add_to_list(node, intern TSRMLS_CC); + DOM_RET_OBJ(rv, node, &ret, intern); } /* }}} end dom_document_create_element */ @@ -429,17 +422,18 @@ PHP_FUNCTION(dom_document_create_document_fragment) zval *id, *rv = NULL; xmlNode *node; xmlDocPtr docp; + dom_object *intern; int ret; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); node = xmlNewDocFragment(docp); if (!node) { RETURN_FALSE; } - dom_add_to_list(node, docp TSRMLS_CC); - DOM_RET_OBJ(rv, node, &ret); + dom_add_to_list(node, intern TSRMLS_CC); + DOM_RET_OBJ(rv, node, &ret, intern); } /* }}} end dom_document_create_document_fragment */ @@ -454,9 +448,10 @@ PHP_FUNCTION(dom_document_create_text_node) xmlNode *node; xmlDocPtr docp; int ret, value_len; + dom_object *intern; char *value; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) { return; @@ -467,8 +462,8 @@ PHP_FUNCTION(dom_document_create_text_node) RETURN_FALSE; } - dom_add_to_list(node, docp TSRMLS_CC); - DOM_RET_OBJ(rv, node, &ret); + dom_add_to_list(node, intern TSRMLS_CC); + DOM_RET_OBJ(rv, node, &ret, intern); } /* }}} end dom_document_create_text_node */ @@ -483,9 +478,10 @@ PHP_FUNCTION(dom_document_create_comment) xmlNode *node; xmlDocPtr docp; int ret, value_len; + dom_object *intern; char *value; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) { return; @@ -496,8 +492,8 @@ PHP_FUNCTION(dom_document_create_comment) RETURN_FALSE; } - dom_add_to_list(node, docp TSRMLS_CC); - DOM_RET_OBJ(rv, node, &ret); + dom_add_to_list(node, intern TSRMLS_CC); + DOM_RET_OBJ(rv, node, &ret, intern); } /* }}} end dom_document_create_comment */ @@ -512,9 +508,10 @@ PHP_FUNCTION(dom_document_create_cdatasection) xmlNode *node; xmlDocPtr docp; int ret, value_len; + dom_object *intern; char *value; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) { return; @@ -525,8 +522,8 @@ PHP_FUNCTION(dom_document_create_cdatasection) RETURN_FALSE; } - dom_add_to_list(node, docp TSRMLS_CC); - DOM_RET_OBJ(rv, node, &ret); + dom_add_to_list(node, intern TSRMLS_CC); + DOM_RET_OBJ(rv, node, &ret, intern); } /* }}} end dom_document_create_cdatasection */ @@ -541,9 +538,10 @@ PHP_FUNCTION(dom_document_create_processing_instruction) xmlNode *node; xmlDocPtr docp; int ret, value_len, name_len; + dom_object *intern; char *name, *value = NULL; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name, &name_len, &value, &value_len) == FAILURE) { return; @@ -556,8 +554,8 @@ PHP_FUNCTION(dom_document_create_processing_instruction) node->doc = docp; - dom_add_to_list(node, docp TSRMLS_CC); - DOM_RET_OBJ(rv, node, &ret); + dom_add_to_list(node, intern TSRMLS_CC); + DOM_RET_OBJ(rv, node, &ret, intern); } /* }}} end dom_document_create_processing_instruction */ @@ -572,9 +570,10 @@ PHP_FUNCTION(dom_document_create_attribute) xmlAttrPtr node; xmlDocPtr docp; int ret, name_len; + dom_object *intern; char *name; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; @@ -590,8 +589,8 @@ PHP_FUNCTION(dom_document_create_attribute) RETURN_FALSE; } - dom_add_to_list((xmlNodePtr) node, docp TSRMLS_CC); - DOM_RET_OBJ(rv, (xmlNodePtr) node, &ret); + dom_add_to_list((xmlNodePtr) node, intern TSRMLS_CC); + DOM_RET_OBJ(rv, (xmlNodePtr) node, &ret, intern); } /* }}} end dom_document_create_attribute */ @@ -606,10 +605,11 @@ PHP_FUNCTION(dom_document_create_entity_reference) zval *id, *rv = NULL; xmlNode *node; xmlDocPtr docp = NULL; + dom_object *intern; int ret, name_len; char *name; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; @@ -620,8 +620,8 @@ PHP_FUNCTION(dom_document_create_entity_reference) RETURN_FALSE; } - dom_add_to_list((xmlNodePtr) node, docp TSRMLS_CC); - DOM_RET_OBJ(rv, (xmlNodePtr) node, &ret); + dom_add_to_list((xmlNodePtr) node, intern TSRMLS_CC); + DOM_RET_OBJ(rv, (xmlNodePtr) node, &ret, intern); } /* }}} end dom_document_create_entity_reference */ @@ -636,10 +636,12 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name) xmlXPathContextPtr ctxp; xmlDocPtr docp; xmlXPathObjectPtr xpathobjp; + dom_object *intern; + int name_len, ret; char *str,*name; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; @@ -673,14 +675,10 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name) for (i = 0; i < nodesetp->nodeNr; i++) { xmlNodePtr node = nodesetp->nodeTab[i]; - zval *child=NULL; - zval *wrapper; - wrapper = dom_object_get_data(node); - if (wrapper == NULL) { - MAKE_STD_ZVAL(child); - } + zval *child; + MAKE_STD_ZVAL(child); - child = php_dom_create_object(node, &ret, wrapper, child TSRMLS_CC); + child = php_dom_create_object(node, &ret, NULL, child, intern TSRMLS_CC); add_next_index_zval(return_value, child); } } @@ -701,16 +699,17 @@ PHP_FUNCTION(dom_document_import_node) zval *id, *node; xmlDocPtr docp; xmlNodePtr nodep, retnodep; + dom_object *intern, *nodeobj; int ret; long recursive = 0; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|l", &node, &recursive) == FAILURE) { return; } - DOM_GET_OBJ(nodep, node, xmlNodePtr); + DOM_GET_OBJ(nodep, node, xmlNodePtr, nodeobj); if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_TYPE_NODE) { @@ -725,10 +724,10 @@ PHP_FUNCTION(dom_document_import_node) if (!retnodep) { RETURN_FALSE; } - dom_add_to_list((xmlNodePtr) retnodep, docp TSRMLS_CC); + dom_add_to_list((xmlNodePtr) retnodep, intern TSRMLS_CC); } - DOM_RET_OBJ(rv, (xmlNodePtr) retnodep, &ret); + DOM_RET_OBJ(rv, (xmlNodePtr) retnodep, &ret, intern); } /* }}} end dom_document_import_node */ @@ -747,8 +746,9 @@ PHP_FUNCTION(dom_document_create_element_ns) char *uri, *name; xmlChar *localname = NULL; int errorcode; + dom_object *intern; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; @@ -777,8 +777,8 @@ PHP_FUNCTION(dom_document_create_element_ns) RETURN_FALSE; } - dom_add_to_list(nodep, docp TSRMLS_CC); - DOM_RET_OBJ(rv, nodep, &ret); + dom_add_to_list(nodep, intern TSRMLS_CC); + DOM_RET_OBJ(rv, nodep, &ret, intern); } /* }}} end dom_document_create_element_ns */ @@ -796,9 +796,10 @@ PHP_FUNCTION(dom_document_create_attribute_ns) int ret, uri_len = 0, name_len = 0; char *uri, *name; xmlChar *localname = NULL; + dom_object *intern; int errorcode; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; @@ -830,8 +831,8 @@ PHP_FUNCTION(dom_document_create_attribute_ns) RETURN_FALSE; } - dom_add_to_list(nodep, docp TSRMLS_CC); - DOM_RET_OBJ(rv, nodep, &ret); + dom_add_to_list(nodep, intern TSRMLS_CC); + DOM_RET_OBJ(rv, nodep, &ret, intern); } /* }}} end dom_document_create_attribute_ns */ @@ -846,9 +847,10 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns) xmlDocPtr docp; xmlNodePtr elemp; int uri_len, name_len; + dom_object *intern; char *uri, *name; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; @@ -857,7 +859,7 @@ PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns) array_init(return_value); elemp = xmlDocGetRootElement(docp); - dom_get_elements_by_tag_name_ns_raw(elemp, uri, name, &return_value TSRMLS_CC); + dom_get_elements_by_tag_name_ns_raw(elemp, uri, name, &return_value, intern TSRMLS_CC); } /* }}} end dom_document_get_elements_by_tag_name_ns */ @@ -873,9 +875,10 @@ PHP_FUNCTION(dom_document_get_element_by_id) idsIterator iter; xmlHashTable *ids = NULL; int ret,idname_len; + dom_object *intern; char *idname; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &idname, &idname_len) == FAILURE) { return; @@ -886,7 +889,7 @@ PHP_FUNCTION(dom_document_get_element_by_id) iter.elementId = (xmlChar *) idname; iter.element = NULL; xmlHashScan(ids, (void *)idsHashScanner, &iter); - DOM_RET_OBJ(rv, (xmlNodePtr) iter.element, &ret); + DOM_RET_OBJ(rv, (xmlNodePtr) iter.element, &ret, intern); } else { RETVAL_NULL(); } @@ -913,8 +916,9 @@ PHP_FUNCTION(dom_document_normalize_document) { zval *id; xmlDocPtr docp; + dom_object *intern; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); DOM_NO_ARGS(); @@ -941,7 +945,7 @@ PHP_FUNCTION(dom_document_document) xmlDoc *docp = NULL, *olddoc; dom_object *intern; char *encoding, *version = NULL; - int encoding_len = 0, version_len = 0; + int encoding_len = 0, version_len = 0, refcount; id = getThis(); @@ -961,9 +965,15 @@ PHP_FUNCTION(dom_document_document) if (intern != NULL) { olddoc = (xmlDocPtr)intern->ptr; if (olddoc != NULL) { - node_free_resource((xmlNode *) olddoc TSRMLS_CC); + refcount = decrement_document_reference(intern TSRMLS_CC); + if (refcount != 0) { + olddoc->_private = NULL; + } } - php_dom_set_object(id, docp TSRMLS_CC); + intern->document = NULL; + increment_document_reference(intern, docp TSRMLS_CC); + + php_dom_set_object(intern, docp TSRMLS_CC); } } @@ -979,7 +989,7 @@ PHP_FUNCTION(dom_document_load) xmlDoc *docp = NULL, *newdoc; dom_object *intern; char *source; - int source_len; + int source_len, refcount; id = getThis(); @@ -996,11 +1006,16 @@ PHP_FUNCTION(dom_document_load) if (intern != NULL) { docp = (xmlDocPtr)intern->ptr; if (docp != NULL) { - node_free_resource((xmlNode *) docp TSRMLS_CC); + refcount = decrement_document_reference(intern TSRMLS_CC); + if (refcount != 0) { + docp->_private = NULL; + } } + intern->document = NULL; + increment_document_reference(intern, newdoc TSRMLS_CC); } - php_dom_set_object(id, newdoc TSRMLS_CC); + php_dom_set_object(intern, newdoc TSRMLS_CC); RETURN_TRUE; } @@ -1016,7 +1031,7 @@ PHP_FUNCTION(dom_document_loadxml) xmlDoc *docp = NULL, *newdoc; dom_object *intern; char *buffer; - int buffer_len; + int buffer_len, refcount; id = getThis(); @@ -1032,11 +1047,17 @@ PHP_FUNCTION(dom_document_loadxml) if (intern != NULL) { docp = (xmlDocPtr)intern->ptr; if (docp != NULL) { - node_free_resource((xmlNode *) docp TSRMLS_CC); + refcount = decrement_document_reference(intern TSRMLS_CC); + if (refcount != 0) { + docp->_private = NULL; + } + intern->document = NULL; } + intern->document = NULL; + increment_document_reference(intern, newdoc TSRMLS_CC); } - php_dom_set_object(id, newdoc TSRMLS_CC); + php_dom_set_object(intern, newdoc TSRMLS_CC); RETURN_TRUE; } @@ -1050,9 +1071,10 @@ PHP_FUNCTION(dom_document_save) zval *id; xmlDoc *docp; int file_len, bytes; + dom_object *intern; char *file; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) { return; @@ -1082,9 +1104,10 @@ PHP_FUNCTION(dom_document_savexml) xmlNode *node; xmlBufferPtr buf; xmlChar *mem; + dom_object *intern, *nodeobj; int size; - DOM_GET_THIS_OBJ(docp, id, xmlDocPtr); + DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o", &nodep) == FAILURE) { return; @@ -1092,7 +1115,7 @@ PHP_FUNCTION(dom_document_savexml) if (nodep != NULL) { /* Dump contents of Node */ - DOM_GET_OBJ(node, nodep, xmlNodePtr); + DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj); if (node->doc != docp) { php_dom_throw_error(WRONG_DOCUMENT_ERR, &return_value TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node not from same document"); diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c index e9039d9385..e59e80499d 100644 --- a/ext/dom/documentfragment.c +++ b/ext/dom/documentfragment.c @@ -60,7 +60,7 @@ PHP_FUNCTION(dom_documentfragment_documentfragment) if (oldnode != NULL) { node_free_resource(oldnode TSRMLS_CC); } - php_dom_set_object(id, nodep TSRMLS_CC); + php_dom_set_object(intern, nodep TSRMLS_CC); } } /* }}} end dom_documentfragment_documentfragment */ diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c index a3715b85d5..363cd552c1 100644 --- a/ext/dom/documenttype.c +++ b/ext/dom/documenttype.c @@ -108,13 +108,9 @@ int dom_documenttype_entities_read(dom_object *obj, zval **retval TSRMLS_DC) index++; nodep = iter->node; if (nodep != NULL) { - zval *child = NULL; - zval *wrapper; - wrapper = dom_object_get_data(nodep); - if (wrapper == NULL) { - MAKE_STD_ZVAL(child); - } - child = php_dom_create_object(nodep, &ret, wrapper, child TSRMLS_CC); + zval *child; + MAKE_STD_ZVAL(child); + child = php_dom_create_object(nodep, &ret, NULL, child, obj TSRMLS_CC); add_assoc_zval(*retval, (char *) nodep->name, child); } } @@ -158,13 +154,9 @@ int dom_documenttype_notations_read(dom_object *obj, zval **retval TSRMLS_DC) index++; nodep = iter->node; if (nodep != NULL) { - zval *child = NULL; - zval *wrapper; - wrapper = dom_object_get_data(nodep); - if (wrapper == NULL) { - MAKE_STD_ZVAL(child); - } - child = php_dom_create_object(nodep, &ret, wrapper, child TSRMLS_CC); + zval *child; + MAKE_STD_ZVAL(child); + child = php_dom_create_object(nodep, &ret, NULL, child, obj TSRMLS_CC); add_assoc_zval(*retval, (char *) nodep->name, child); } } diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c index 6654d6d82e..b434cae288 100644 --- a/ext/dom/domimplementation.c +++ b/ext/dom/domimplementation.c @@ -105,7 +105,7 @@ PHP_FUNCTION(dom_domimplementation_create_document_type) doctype = xmlCreateIntSubset(NULL, localname, pch1, pch2); xmlFree(localname); - DOM_RET_OBJ(rv, (xmlNodePtr) doctype, &ret); + DOM_RET_OBJ(rv, (xmlNodePtr) doctype, &ret, NULL); } /* }}} end dom_domimplementation_create_document_type */ @@ -125,13 +125,14 @@ PHP_FUNCTION(dom_domimplementation_create_document) char *uri, *name; xmlChar *prefix = NULL, *localname = NULL; xmlURIPtr uristruct; + dom_object *doctobj; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sso", &uri, &uri_len, &name, &name_len, &node) == FAILURE) { return; } if (doctype != NULL) { - DOM_GET_OBJ(doctype, node, xmlDtdPtr); + DOM_GET_OBJ(doctype, node, xmlDtdPtr, doctobj); if (doctype->type == XML_DOCUMENT_TYPE_NODE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid DocumentType object"); RETURN_FALSE; @@ -228,7 +229,7 @@ PHP_FUNCTION(dom_domimplementation_create_document) xmlFree(localname); } - DOM_RET_OBJ(rv, (xmlNodePtr) docp, &ret); + DOM_RET_OBJ(rv, (xmlNodePtr) docp, &ret, NULL); } /* }}} end dom_domimplementation_create_document */ diff --git a/ext/dom/element.c b/ext/dom/element.c index 4717465cf7..4c236631e1 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -93,7 +93,7 @@ PHP_FUNCTION(dom_element_element) if (oldnode != NULL) { node_free_resource(oldnode TSRMLS_CC); } - php_dom_set_object(id, nodep TSRMLS_CC); + php_dom_set_object(intern, nodep TSRMLS_CC); } } /* }}} end dom_element_element */ @@ -142,10 +142,11 @@ PHP_FUNCTION(dom_element_get_attribute) zval *id; xmlNode *nodep; char *name, *value; + dom_object *intern; int name_len; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; @@ -172,10 +173,11 @@ PHP_FUNCTION(dom_element_set_attribute) xmlNode *nodep; xmlAttr *attr; int ret, name_len, value_len; + dom_object *intern; char *name, *value; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &value, &value_len) == FAILURE) { return; @@ -191,7 +193,7 @@ PHP_FUNCTION(dom_element_set_attribute) RETURN_FALSE; } - DOM_RET_OBJ(rv, (xmlNodePtr) attr, &ret); + DOM_RET_OBJ(rv, (xmlNodePtr) attr, &ret, intern); } /* }}} end dom_element_set_attribute */ @@ -206,10 +208,11 @@ PHP_FUNCTION(dom_element_remove_attribute) zval *id; xmlNode *nodep; xmlAttr *attrp; + dom_object *intern; int name_len; char *name; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; @@ -226,7 +229,7 @@ PHP_FUNCTION(dom_element_remove_attribute) xmlUnlinkNode((xmlNodePtr) attrp); xmlFreeProp(attrp); } else { - dom_add_to_list((xmlNodePtr) attrp, attrp->doc TSRMLS_CC); + dom_add_to_list((xmlNodePtr) attrp, intern TSRMLS_CC); xmlUnlinkNode((xmlNodePtr) attrp); } @@ -245,9 +248,10 @@ PHP_FUNCTION(dom_element_get_attribute_node) xmlNode *nodep; xmlAttr *attrp; int name_len, ret; + dom_object *intern; char *name; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; @@ -257,7 +261,8 @@ PHP_FUNCTION(dom_element_get_attribute_node) if (attrp == NULL) { RETURN_FALSE; } - DOM_RET_OBJ(rv, (xmlNodePtr) attrp, &ret); + + DOM_RET_OBJ(rv, (xmlNodePtr) attrp, &ret, intern); } /* }}} end dom_element_get_attribute_node */ @@ -268,44 +273,50 @@ Since: */ PHP_FUNCTION(dom_element_set_attribute_node) { - zval *id, *node, *oldzval, *rv = NULL; + zval *id, *node, *rv = NULL; xmlNode *nodep; xmlAttr *attrp, *existattrp = NULL; + dom_object *intern, *attrobj, *oldobj; int ret; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { return; } - DOM_GET_OBJ(attrp, node, xmlAttrPtr); + DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj); if (attrp->type != XML_ATTRIBUTE_NODE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required"); RETURN_FALSE; } - existattrp = xmlHasProp(nodep,attrp->name); + existattrp = xmlHasProp(nodep, attrp->name); if (existattrp != NULL) { - if ((oldzval = dom_object_get_data((xmlNodePtr) existattrp)) == NULL) { - dom_add_to_list((xmlNodePtr) existattrp, existattrp->doc TSRMLS_CC); + if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) == NULL) { + dom_add_to_list((xmlNodePtr) existattrp, intern TSRMLS_CC); xmlUnlinkNode((xmlNodePtr) existattrp); } else { - if (oldzval == node) { + if (oldobj->ptr == attrp) { RETURN_NULL(); } - dom_add_to_list((xmlNodePtr) existattrp, existattrp->doc TSRMLS_CC); + dom_add_to_list((xmlNodePtr) existattrp, intern TSRMLS_CC); xmlUnlinkNode((xmlNodePtr) existattrp); } } + if (attrp->doc == NULL && nodep->doc != NULL) { + attrobj->document = intern->document; + increment_document_reference(attrobj, NULL TSRMLS_CC); + } + xmlAddChild(nodep, (xmlNodePtr) attrp); - dom_del_from_list((xmlNodePtr) attrp, attrp->doc TSRMLS_CC); + dom_del_from_list((xmlNodePtr) attrp, intern TSRMLS_CC); /* Returns old property if removed otherwise NULL */ if (existattrp != NULL) { - DOM_RET_OBJ(rv, (xmlNodePtr) existattrp, &ret); + DOM_RET_OBJ(rv, (xmlNodePtr) existattrp, &ret, intern); } else { RETVAL_NULL(); } @@ -323,10 +334,11 @@ PHP_FUNCTION(dom_element_remove_attribute_node) zval *id; xmlNode *nodep; xmlAttr *attrp; + dom_object *intern; int name_len; char *name; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; @@ -344,7 +356,7 @@ PHP_FUNCTION(dom_element_remove_attribute_node) xmlUnlinkNode((xmlNodePtr) attrp); xmlFreeProp(attrp); } else { - dom_add_to_list((xmlNodePtr) attrp, attrp->doc TSRMLS_CC); + dom_add_to_list((xmlNodePtr) attrp, intern TSRMLS_CC); xmlUnlinkNode((xmlNodePtr) attrp); } @@ -366,9 +378,10 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name) xmlDocPtr docp; xmlXPathObjectPtr xpathobjp; int name_len, ret; + dom_object *intern; char *str,*name; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; @@ -403,14 +416,10 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name) for (i = 0; i < nodesetp->nodeNr; i++) { xmlNodePtr node = nodesetp->nodeTab[i]; - zval *child = NULL; - zval *wrapper; - wrapper = dom_object_get_data(node); - if (wrapper == NULL) { - MAKE_STD_ZVAL(child); - } + zval *child; + MAKE_STD_ZVAL(child); - child = php_dom_create_object(node, &ret, wrapper, child TSRMLS_CC); + child = php_dom_create_object(node, &ret, NULL, child, intern TSRMLS_CC); add_next_index_zval(return_value, child); } } @@ -430,10 +439,11 @@ PHP_FUNCTION(dom_element_get_attribute_ns) zval *id; xmlNodePtr elemp; xmlNsPtr nsptr; + dom_object *intern; int uri_len = 0, name_len = 0; char *uri, *name, *strattr; - DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr); + DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; @@ -472,9 +482,10 @@ PHP_FUNCTION(dom_element_set_attribute_ns) int ret, uri_len = 0, name_len = 0; char *uri, *name; xmlChar *localname = NULL; + dom_object *intern; int errorcode = 0; - DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr); + DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; @@ -507,7 +518,7 @@ PHP_FUNCTION(dom_element_set_attribute_ns) RETURN_FALSE; } - DOM_RET_OBJ(rv, nodep, &ret); + DOM_RET_OBJ(rv, nodep, &ret, intern); } /* }}} end dom_element_set_attribute_ns */ @@ -521,10 +532,11 @@ PHP_FUNCTION(dom_element_remove_attribute_ns) zval *id; xmlNode *nodep; xmlAttr *attrp; + dom_object *intern; int name_len, uri_len; char *name, *uri; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; @@ -543,7 +555,7 @@ PHP_FUNCTION(dom_element_remove_attribute_ns) xmlUnlinkNode((xmlNodePtr) attrp); xmlFreeProp(attrp); } else { - dom_add_to_list((xmlNodePtr) attrp, attrp->doc TSRMLS_CC); + dom_add_to_list((xmlNodePtr) attrp, intern TSRMLS_CC); xmlUnlinkNode((xmlNodePtr) attrp); } } @@ -562,10 +574,11 @@ PHP_FUNCTION(dom_element_get_attribute_node_ns) zval *id; xmlNodePtr elemp; xmlNs *nsp; + dom_object *intern; int uri_len, name_len; char *uri, *name, *value; - DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr); + DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; @@ -599,19 +612,20 @@ Since: DOM Level 2 */ PHP_FUNCTION(dom_element_set_attribute_node_ns) { - zval *id, *node, *oldzval, *rv = NULL; + zval *id, *node, *rv = NULL; xmlNode *nodep; xmlNs *nsp; xmlAttr *attrp, *existattrp = NULL; + dom_object *intern, *attrobj, *oldobj; int ret; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { return; } - DOM_GET_OBJ(attrp, node, xmlAttrPtr); + DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj); if (attrp->type != XML_ATTRIBUTE_NODE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required"); @@ -626,28 +640,33 @@ PHP_FUNCTION(dom_element_set_attribute_node_ns) } if (existattrp != NULL) { - if ((oldzval = dom_object_get_data((xmlNodePtr) existattrp)) == NULL) { - dom_add_to_list((xmlNodePtr) existattrp, existattrp->doc TSRMLS_CC); + if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) == NULL) { + dom_add_to_list((xmlNodePtr) existattrp, intern TSRMLS_CC); xmlUnlinkNode((xmlNodePtr) existattrp); } else { - if (oldzval == node) { + if (oldobj->ptr == attrp) { RETURN_NULL(); } - dom_add_to_list((xmlNodePtr) existattrp, existattrp->doc TSRMLS_CC); + dom_add_to_list((xmlNodePtr) existattrp, intern TSRMLS_CC); xmlUnlinkNode((xmlNodePtr) existattrp); } } + if (attrp->doc == NULL && nodep->doc != NULL) { + attrobj->document = intern->document; + increment_document_reference(attrobj, NULL TSRMLS_CC); + } + xmlAddChild(nodep, (xmlNodePtr) attrp); if (existattrp == NULL) { xmlReconciliateNs(nodep->doc, nodep); } - dom_del_from_list((xmlNodePtr) attrp, attrp->doc TSRMLS_CC); + dom_del_from_list((xmlNodePtr) attrp, intern TSRMLS_CC); /* Returns old property if removed otherwise NULL */ if (existattrp != NULL) { - DOM_RET_OBJ(rv, (xmlNodePtr) existattrp, &ret); + DOM_RET_OBJ(rv, (xmlNodePtr) existattrp, &ret, intern); } else { RETVAL_NULL(); } @@ -666,9 +685,10 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns) zval *id; xmlNodePtr elemp; int uri_len, name_len; + dom_object *intern; char *uri, *name; - DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr); + DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; @@ -676,7 +696,7 @@ PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns) array_init(return_value); - dom_get_elements_by_tag_name_ns_raw(elemp->children, uri, name, &return_value TSRMLS_CC); + dom_get_elements_by_tag_name_ns_raw(elemp->children, uri, name, &return_value, intern TSRMLS_CC); } /* }}} end dom_element_get_elements_by_tag_name_ns */ @@ -689,10 +709,11 @@ PHP_FUNCTION(dom_element_has_attribute) { zval *id; xmlNode *nodep; + dom_object *intern; char *name, *value; int name_len; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; @@ -718,10 +739,11 @@ PHP_FUNCTION(dom_element_has_attribute_ns) zval *id; xmlNodePtr elemp; xmlNs *nsp; + dom_object *intern; int uri_len, name_len; char *uri, *name, *value; - DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr); + DOM_GET_THIS_OBJ(elemp, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; diff --git a/ext/dom/entityreference.c b/ext/dom/entityreference.c index d4927801ad..892d2a1a46 100644 --- a/ext/dom/entityreference.c +++ b/ext/dom/entityreference.c @@ -71,7 +71,7 @@ PHP_FUNCTION(dom_entityreference_entityreference) if (oldnode != NULL) { node_free_resource(oldnode TSRMLS_CC); } - php_dom_set_object(id, node TSRMLS_CC); + php_dom_set_object(intern, node TSRMLS_CC); } } diff --git a/ext/dom/node.c b/ext/dom/node.c index e200d91416..7563197cf3 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -217,7 +217,6 @@ Since: */ int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC) { - zval *wrapper; xmlNode *nodep, *nodeparent; int ret; @@ -228,11 +227,9 @@ int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC) return FAILURE; } - wrapper = dom_object_get_data(nodeparent); - if (wrapper == NULL) { - ALLOC_ZVAL(*retval); - } - if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, wrapper, *retval TSRMLS_CC))) { + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, NULL, *retval, obj TSRMLS_CC))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); return FAILURE; } @@ -264,13 +261,9 @@ int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC) if (last) { while (last) { - zval *child = NULL; - zval *wrapper; - wrapper = dom_object_get_data(last); - if (wrapper == NULL) { - MAKE_STD_ZVAL(child); - } - child = php_dom_create_object(last, &ret, wrapper, child TSRMLS_CC); + zval *child; + MAKE_STD_ZVAL(child); + child = php_dom_create_object(last, &ret, NULL, child, obj TSRMLS_CC); add_next_index_zval(*retval, child); last = last->next; } @@ -289,7 +282,6 @@ Since: */ int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC) { - zval *wrapper; xmlNode *nodep, *first; int ret; @@ -301,11 +293,9 @@ int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC) return FAILURE; } - wrapper = dom_object_get_data(first); - if (wrapper == NULL) { - ALLOC_ZVAL(*retval); - } - if (NULL == (*retval = php_dom_create_object(first, &ret, wrapper, *retval TSRMLS_CC))) { + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(first, &ret, NULL, *retval, obj TSRMLS_CC))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); return FAILURE; } @@ -323,7 +313,6 @@ Since: */ int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC) { - zval *wrapper; xmlNode *nodep, *last; int ret; @@ -334,11 +323,9 @@ int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC) return FAILURE; } - wrapper = dom_object_get_data(last); - if (wrapper == NULL) { - ALLOC_ZVAL(*retval); - } - if (NULL == (*retval = php_dom_create_object(last, &ret, wrapper, *retval TSRMLS_CC))) { + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(last, &ret, NULL, *retval, obj TSRMLS_CC))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); return FAILURE; } @@ -356,7 +343,6 @@ Since: */ int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC) { - zval *wrapper; xmlNode *nodep, *prevsib; int ret; @@ -367,11 +353,9 @@ int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC) return FAILURE; } - wrapper = dom_object_get_data(prevsib); - if (wrapper == NULL) { - ALLOC_ZVAL(*retval); - } - if (NULL == (*retval = php_dom_create_object(prevsib, &ret, wrapper, *retval TSRMLS_CC))) { + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(prevsib, &ret, NULL, *retval, obj TSRMLS_CC))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); return FAILURE; } @@ -389,7 +373,6 @@ Since: */ int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC) { - zval *wrapper; xmlNode *nodep, *nextsib; int ret; @@ -400,11 +383,9 @@ int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC) return FAILURE; } - wrapper = dom_object_get_data(nextsib); - if (wrapper == NULL) { - ALLOC_ZVAL(*retval); - } - if (NULL == (*retval = php_dom_create_object(nextsib, &ret, wrapper, *retval TSRMLS_CC))) { + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(nextsib, &ret, NULL, *retval, obj TSRMLS_CC))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); return FAILURE; } @@ -435,13 +416,9 @@ int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC) array_init(*retval); while (attr) { - zval *curattr = NULL; - zval *wrapper; - wrapper = dom_object_get_data((xmlNodePtr) attr); - if (wrapper == NULL) { - MAKE_STD_ZVAL(curattr); - } - curattr = php_dom_create_object((xmlNodePtr) attr, &ret, wrapper, curattr TSRMLS_CC); + zval *curattr; + MAKE_STD_ZVAL(curattr); + curattr = php_dom_create_object((xmlNodePtr) attr, &ret, NULL, curattr, obj TSRMLS_CC); add_assoc_zval(*retval, (char *) attr->name, curattr); attr = attr->next; } @@ -463,7 +440,6 @@ Since: */ int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC) { - zval *wrapper; xmlNode *nodep; xmlDocPtr docp; int ret; @@ -481,11 +457,9 @@ int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC) return FAILURE; } - wrapper = dom_object_get_data((xmlNodePtr) docp); - if (wrapper == NULL) { - ALLOC_ZVAL(*retval); - } - if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, wrapper, *retval TSRMLS_CC))) { + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, NULL, *retval, obj TSRMLS_CC))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); return FAILURE; } @@ -721,31 +695,38 @@ PHP_FUNCTION(dom_node_insert_before) { zval *id, *node, *ref, *rv = NULL; xmlNodePtr child, new_child, parentp, refp; + dom_object *intern, *childobj, *refpobj; int ret; - DOM_GET_THIS_OBJ(parentp, id, xmlNodePtr); + DOM_GET_THIS_OBJ(parentp, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo!", &node, &ref) == FAILURE) { return; } - DOM_GET_OBJ(child, node, xmlNodePtr); + DOM_GET_OBJ(child, node, xmlNodePtr, childobj); new_child = NULL; if (dom_hierarchy(parentp, child) == FAILURE) { php_dom_throw_error(HIERARCHY_REQUEST_ERR, &return_value TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hierarchy Request Error"); + RETURN_FALSE; } - + if (child->doc != parentp->doc && child->doc != NULL) { php_dom_throw_error(WRONG_DOCUMENT_ERR, &return_value TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as it was created from a different document"); RETURN_FALSE; } + if (child->doc == NULL && parentp->doc != NULL) { + childobj->document = intern->document; + increment_document_reference(childobj, NULL TSRMLS_CC); + } + if (ref != NULL) { - DOM_GET_OBJ(refp, ref, xmlNodePtr); + DOM_GET_OBJ(refp, ref, xmlNodePtr, refpobj); if (refp->parent != parentp) { php_dom_throw_error(NOT_FOUND_ERR, &return_value TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as refnode is not child of node"); @@ -765,14 +746,14 @@ PHP_FUNCTION(dom_node_insert_before) xmlNodeSetContent(refp, tmp); xmlFree(tmp); node_free_resource(child TSRMLS_CC); - DOM_RET_OBJ(rv, refp, &ret); + 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); - DOM_RET_OBJ(rv, refp->prev, &ret); + DOM_RET_OBJ(rv, refp->prev, &ret, intern); return; } } else if (child->type == XML_ATTRIBUTE_NODE) { @@ -788,7 +769,7 @@ PHP_FUNCTION(dom_node_insert_before) node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); xmlFreeProp(lastattr); } else { - DOM_RET_OBJ(rv, child, &ret); + DOM_RET_OBJ(rv, child, &ret, intern); return; } } @@ -805,7 +786,7 @@ PHP_FUNCTION(dom_node_insert_before) (parentp != child)) { xmlNodeAddContent(parentp, child->content); node_free_resource(child TSRMLS_CC); - DOM_RET_OBJ(rv, parentp, &ret); + DOM_RET_OBJ(rv, parentp, &ret, intern); return; } if ((parentp->last != NULL) && (parentp->last->type == XML_TEXT_NODE) && @@ -813,7 +794,7 @@ PHP_FUNCTION(dom_node_insert_before) (parentp->last != child)) { xmlNodeAddContent(parentp->last, child->content); node_free_resource(child TSRMLS_CC); - DOM_RET_OBJ(rv, parentp->last, &ret); + DOM_RET_OBJ(rv, parentp->last, &ret, intern); return; } } else if (child->type == XML_ATTRIBUTE_NODE) { @@ -829,7 +810,7 @@ PHP_FUNCTION(dom_node_insert_before) node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); xmlFreeProp(lastattr); } else { - DOM_RET_OBJ(rv, child, &ret); + DOM_RET_OBJ(rv, child, &ret, intern); return; } } @@ -838,8 +819,8 @@ PHP_FUNCTION(dom_node_insert_before) if (new_child != NULL) { child->children = NULL; } - dom_add_to_list(child, (xmlDocPtr) child->doc TSRMLS_CC); - DOM_RET_OBJ(rv, new_child, &ret); + dom_add_to_list(child, intern TSRMLS_CC); + DOM_RET_OBJ(rv, new_child, &ret, intern); return; } new_child = xmlAddChild(parentp, child); @@ -850,9 +831,9 @@ PHP_FUNCTION(dom_node_insert_before) RETURN_FALSE; } - dom_del_from_list(child, (xmlDocPtr) child->doc TSRMLS_CC); + dom_del_from_list(child, intern TSRMLS_CC); - DOM_RET_OBJ(rv, new_child, &ret); + DOM_RET_OBJ(rv, new_child, &ret, intern); } /* }}} end dom_node_insert_before */ @@ -866,17 +847,19 @@ PHP_FUNCTION(dom_node_replace_child) { zval *id, *newnode, *oldnode; xmlNodePtr children, newchild, oldchild, nodep; + dom_object *intern, *newchildobj, *oldchildobj; int foundoldchild = 0; + int ret; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo", &newnode, &oldnode) == FAILURE) { return; } - DOM_GET_OBJ(newchild, newnode, xmlNodePtr); - DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr); + DOM_GET_OBJ(newchild, newnode, xmlNodePtr, newchildobj); + DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr, oldchildobj); children = nodep->children; if (!children) { @@ -892,6 +875,7 @@ PHP_FUNCTION(dom_node_replace_child) if (dom_hierarchy(nodep, newchild) == FAILURE) { php_dom_throw_error(HIERARCHY_REQUEST_ERR, &return_value TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hierarchy Request Error"); + RETURN_FALSE; } /* check for the old child and wether the new child is already a child */ @@ -908,13 +892,17 @@ PHP_FUNCTION(dom_node_replace_child) if (oldchild != newchild) { xmlNodePtr node; if (newchild->parent == NULL && newchild->doc != NULL) { - dom_del_from_list(newchild, (xmlDocPtr) newchild->doc TSRMLS_CC); + dom_del_from_list(newchild, intern TSRMLS_CC); + } + if (newchild->doc == NULL && nodep->doc != NULL) { + newchildobj->document = intern->document; + increment_document_reference(newchildobj, NULL TSRMLS_CC); } if((node = xmlReplaceNode(oldchild, newchild)) != NULL) { - dom_add_to_list(node, (xmlDocPtr) node->doc TSRMLS_CC); + dom_add_to_list(node, intern TSRMLS_CC); } } - DOM_RET_OBJ(rv, oldchild, &ret); + DOM_RET_OBJ(rv, oldchild, &ret, intern); return; } else { php_dom_throw_error(NOT_FOUND_ERR, &return_value TSRMLS_CC); @@ -933,15 +921,16 @@ PHP_FUNCTION(dom_node_remove_child) { zval *id, *node; xmlNodePtr children, child, nodep; + dom_object *intern, *childobj; int ret; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { return; } - DOM_GET_OBJ(child, node, xmlNodePtr); + DOM_GET_OBJ(child, node, xmlNodePtr, childobj); children = nodep->children; if (!children) { @@ -953,8 +942,8 @@ PHP_FUNCTION(dom_node_remove_child) if (children == child) { zval *rv = NULL; xmlUnlinkNode(child); - dom_add_to_list(child, (xmlDocPtr) child->doc TSRMLS_CC); - DOM_RET_OBJ(rv, child, &ret); + dom_add_to_list(child, intern TSRMLS_CC); + DOM_RET_OBJ(rv, child, &ret, intern); return; } children = children->next; @@ -974,23 +963,21 @@ PHP_FUNCTION(dom_node_append_child) { zval *id, *node, *rv = NULL; xmlNodePtr child, nodep, new_child = NULL; + dom_object *intern, *childobj; int ret; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { return; } - if (!PZVAL_IS_REF(node)) { - zval_add_ref(&node); - } - - DOM_GET_OBJ(child, node, xmlNodePtr); + DOM_GET_OBJ(child, node, xmlNodePtr, childobj); if (dom_hierarchy(nodep, child) == FAILURE) { php_dom_throw_error(HIERARCHY_REQUEST_ERR, &return_value TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hierarchy Request Error"); + RETURN_FALSE; } if (!(child->doc == NULL || child->doc == nodep->doc)) { @@ -999,6 +986,11 @@ PHP_FUNCTION(dom_node_append_child) RETURN_FALSE; } + if (child->doc == NULL && nodep->doc != NULL) { + childobj->document = intern->document; + increment_document_reference(childobj, NULL TSRMLS_CC); + } + if (child->parent != NULL){ xmlUnlinkNode(child); } @@ -1008,14 +1000,14 @@ PHP_FUNCTION(dom_node_append_child) (nodep->content != NULL)) { xmlNodeAddContent(nodep, child->content); node_free_resource(child TSRMLS_CC); - DOM_RET_OBJ(rv, nodep, &ret); + 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); - DOM_RET_OBJ(rv, nodep->last, &ret); + DOM_RET_OBJ(rv, nodep->last, &ret, intern); return; } } else if (child->type == XML_ATTRIBUTE_NODE) { @@ -1037,22 +1029,21 @@ PHP_FUNCTION(dom_node_append_child) if (new_child != NULL) { child->children = NULL; } - dom_add_to_list(child, (xmlDocPtr) child->doc TSRMLS_CC); - DOM_RET_OBJ(rv, new_child, &ret); + dom_add_to_list(child, intern TSRMLS_CC); + DOM_RET_OBJ(rv, new_child, &ret, intern); return; } new_child = xmlAddChild(nodep, child); if (new_child == NULL) { - dom_add_to_list(child, (xmlDocPtr) child->doc TSRMLS_CC); + dom_add_to_list(child, intern TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't append node"); RETURN_FALSE; } - dom_del_from_list(child, (xmlDocPtr) child->doc TSRMLS_CC); - - DOM_RET_OBJ(rv, new_child, &ret); + dom_del_from_list(child, intern TSRMLS_CC); + DOM_RET_OBJ(rv, new_child, &ret, intern); } /* }}} end dom_node_append_child */ @@ -1065,8 +1056,9 @@ PHP_FUNCTION(dom_node_has_child_nodes) { zval *id; xmlNode *nodep; + dom_object *intern; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); DOM_NO_ARGS(); @@ -1088,10 +1080,11 @@ PHP_FUNCTION(dom_node_clone_node) zval *rv = NULL; zval *id; xmlNode *n, *node; - int ret; + int ret; + dom_object *intern; long recursive = 0; - DOM_GET_THIS_OBJ(n, id, xmlNodePtr); + DOM_GET_THIS_OBJ(n, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &recursive) == FAILURE) { return; @@ -1101,9 +1094,9 @@ PHP_FUNCTION(dom_node_clone_node) if (!node) { RETURN_FALSE; } - dom_add_to_list(node, (xmlDocPtr) node->doc TSRMLS_CC); + dom_add_to_list(node, intern TSRMLS_CC); - DOM_RET_OBJ(rv, node, &ret); + DOM_RET_OBJ(rv, node, &ret, intern); } /* }}} end dom_node_clone_node */ @@ -1117,8 +1110,9 @@ PHP_FUNCTION(dom_node_normalize) { zval *id; xmlNode *nodep; + dom_object *intern; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); DOM_NO_ARGS(); @@ -1147,8 +1141,9 @@ PHP_FUNCTION(dom_node_has_attributes) { zval *id; xmlNode *nodep; + dom_object *intern; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); DOM_NO_ARGS(); @@ -1183,14 +1178,15 @@ PHP_FUNCTION(dom_node_is_same_node) { zval *id, *node; xmlNodePtr nodeotherp, nodep; + dom_object *intern, *nodeotherobj; - DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { return; } - DOM_GET_OBJ(nodeotherp, node, xmlNodePtr); + DOM_GET_OBJ(nodeotherp, node, xmlNodePtr, nodeotherobj); if (nodep == nodeotherp) { RETURN_TRUE; diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 3dd6568ce5..d832663370 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -13,7 +13,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Christian Stocker | - | Rob Richards | + | Rob Richards | | Marcus Borger | +----------------------------------------------------------------------+ */ @@ -75,81 +75,110 @@ static zend_function_entry dom_functions[] = { {NULL, NULL, NULL} }; + +/* {{{ void increment_document_reference(dom_object *object) */ +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) { + object->document = emalloc(sizeof(dom_ref_obj)); + object->document->ptr = docp; + object->document->refcount = 1; + object->document->node_list = NULL; + } + + return ret_refcount; +} +/* }}} end increment_document_reference */ + +/* {{{ void 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) { + dom_clean_nodes(object TSRMLS_CC); + node_free_resource(object->document->ptr TSRMLS_CC); + efree(object->document); + object->document = NULL; + } + } + + return ret_refcount; +} +/* }}} end decrement_document_reference */ + /* {{{ dom_object_set_data */ -static void dom_object_set_data(xmlNodePtr obj, zval *wrapper TSRMLS_DC) +static void dom_object_set_data(xmlNodePtr obj, dom_object *wrapper TSRMLS_DC) { obj->_private = wrapper; } -/* }}} */ +/* }}} end dom_object_set_data */ /* {{{ dom_object_get_data */ -zval *dom_object_get_data(xmlNodePtr obj) +dom_object *dom_object_get_data(xmlNodePtr obj) { - return (zval *) obj->_private; + return (dom_object *) obj->_private; } -/* }}} */ +/* }}} end dom_object_get_data */ /* {{{ php_dom_clear_object */ -static void php_dom_clear_object(zval *wrapper TSRMLS_DC) +static void php_dom_clear_object(dom_object *object TSRMLS_DC) { - dom_object *object; - - object = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC); object->ptr = NULL; if (object->prop_handler) { object->prop_handler = NULL; } + decrement_document_reference(object TSRMLS_CC); + object->document = NULL; } -/* }}} */ +/* }}} end dom_object_get_data */ /* {{{ php_dom_set_object */ -void php_dom_set_object(zval *wrapper, void *obj TSRMLS_DC) +void php_dom_set_object(dom_object *object, void *obj TSRMLS_DC) { - dom_object *object; - - object = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC); object->ptr = obj; - dom_object_set_data(obj, wrapper TSRMLS_CC); + dom_object_set_data(obj, object TSRMLS_CC); } -/* }}} */ +/* }}} end php_dom_set_object */ /* {{{ dom_unregister_node */ void dom_unregister_node(xmlNodePtr nodep TSRMLS_DC) { - zval *wrapper; + dom_object *wrapper; wrapper = dom_object_get_data(nodep); if (wrapper != NULL ) { if (nodep->parent == NULL && nodep->doc != NULL && (xmlNodePtr) nodep->doc != nodep) { - dom_del_from_list(nodep, (xmlDocPtr) nodep->doc TSRMLS_CC); + dom_del_from_list(nodep, wrapper TSRMLS_CC); } dom_object_set_data(nodep, NULL TSRMLS_CC); php_dom_clear_object(wrapper TSRMLS_CC); } } -/* }}} */ +/* }}} end dom_unregister_node */ /* {{{ dom_del_from_list */ -void dom_del_from_list(xmlNodePtr nodep, xmlDocPtr docp TSRMLS_DC) +void dom_del_from_list(xmlNodePtr nodep, dom_object *object TSRMLS_DC) { - zval *wrapper; - dom_object *object; xmlNodePtr cur; node_list_pointer *cur_element, *prev; - if (docp != NULL && nodep != NULL) { - wrapper = dom_object_get_data((xmlNodePtr) docp); - - if (wrapper != NULL) { - object = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC); - cur_element = object->node_list; + if (object != NULL && nodep != NULL) { + if (object->document != NULL) { + cur_element = object->document->node_list; prev = NULL; while (cur_element != NULL) { cur = cur_element->nodep; if (cur == nodep) { if (prev == NULL) { - object->node_list = cur_element->next; + object->document->node_list = cur_element->next; } else { prev->next = cur_element->next; } @@ -166,25 +195,21 @@ void dom_del_from_list(xmlNodePtr nodep, xmlDocPtr docp TSRMLS_DC) /* }}} */ /* {{{ dom_add_to_list */ -void dom_add_to_list(xmlNodePtr nodep, xmlDocPtr docp TSRMLS_DC) +void dom_add_to_list(xmlNodePtr nodep, dom_object *object TSRMLS_DC) { - zval *wrapper; - dom_object *object; node_list_pointer *cur_element; - if (docp != NULL && nodep != NULL) { + if (object != NULL && nodep != NULL) { if (nodep->parent == NULL) { - wrapper = dom_object_get_data((xmlNodePtr) docp); - if (wrapper != NULL) { - object = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC); - dom_del_from_list(nodep, docp TSRMLS_CC); + if (object->document != NULL) { + dom_del_from_list(nodep, object TSRMLS_CC); cur_element = emalloc(sizeof(node_list_pointer)); cur_element->nodep = nodep; cur_element->next = NULL; - if (object->node_list != NULL) { - cur_element->next = object->node_list; + if (object->document->node_list != NULL) { + cur_element->next = object->document->node_list; } - object->node_list = cur_element; + object->document->node_list = cur_element; } } } @@ -615,21 +640,15 @@ PHP_MSHUTDOWN_FUNCTION(dom) } /* {{{ dom_clean_nodes */ -void dom_clean_nodes(xmlNodePtr nodep TSRMLS_DC) +void dom_clean_nodes(dom_object *object TSRMLS_DC) { node_list_pointer *l; - zval *wrapper; - dom_object *object; - - if (nodep != NULL) { - wrapper = dom_object_get_data(nodep); - if (wrapper != NULL) { - object = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC); - l = object->node_list; - while (l != NULL) { - node_free_resource(l->nodep TSRMLS_CC); - l = object->node_list; - } + + if (object != NULL && object->document != NULL) { + l = object->document->node_list; + while (l != NULL) { + node_free_resource(l->nodep TSRMLS_CC); + l = object->document->node_list; } } } @@ -638,14 +657,14 @@ void dom_clean_nodes(xmlNodePtr nodep TSRMLS_DC) /* {{{ node_list_unlink */ void node_list_unlink(xmlNodePtr node TSRMLS_DC) { - zval *wrapper; + dom_object *wrapper; while (node != NULL) { wrapper = dom_object_get_data(node); if (wrapper != NULL ) { - dom_add_to_list(node, node->doc TSRMLS_CC); + dom_add_to_list(node, wrapper TSRMLS_CC); xmlUnlinkNode(node); } else { node_list_unlink(node->children TSRMLS_CC); @@ -712,9 +731,9 @@ void node_free_list(xmlNodePtr node TSRMLS_DC) node_free_list((xmlNodePtr) node->properties TSRMLS_CC); } - dom_unregister_node(node TSRMLS_CC); curnode = node->next; xmlUnlinkNode(node); + dom_unregister_node(node TSRMLS_CC); dom_node_free(node); } } @@ -736,7 +755,6 @@ void node_free_resource(xmlNodePtr node TSRMLS_DC) case XML_HTML_DOCUMENT_NODE: { docp = (xmlDocPtr) node; - dom_clean_nodes(node TSRMLS_CC); if (docp->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) docp->ids); docp->ids = NULL; if (docp->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) docp->refs); @@ -803,14 +821,26 @@ void dom_objects_clone(void *object, void **object_clone TSRMLS_DC) void dom_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC) { dom_object *intern = (dom_object *)object; + int retcount; zend_hash_destroy(intern->std.properties); FREE_HASHTABLE(intern->std.properties); + + if (intern->ptr) { - node_free_resource(intern->ptr TSRMLS_CC); + if (((xmlNodePtr) intern->ptr)->type != XML_DOCUMENT_NODE && ((xmlNodePtr) intern->ptr)->type != XML_HTML_DOCUMENT_NODE) { + node_free_resource(intern->ptr TSRMLS_CC); + } else { + 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; } + efree(object); } /* }}} */ @@ -828,7 +858,6 @@ zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC) intern->std.in_get = 0; intern->std.in_set = 0; intern->ptr = NULL; - intern->node_list = NULL; intern->prop_handler = NULL; intern->document = NULL; @@ -844,6 +873,7 @@ zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC) zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); retval.handle = zend_objects_store_put(intern, dom_objects_dtor, dom_objects_clone TSRMLS_CC); + intern->handle = retval.handle; retval.handlers = &dom_object_handlers; return retval; @@ -851,41 +881,31 @@ zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC) /* }}} */ /* {{{ php_domobject_new */ -zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *wrapper_in, zval *return_value TSRMLS_DC) +zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *wrapper_in, zval *return_value, dom_object *domobj TSRMLS_DC) { zval *wrapper; zend_class_entry *ce; + dom_object *intern; *found = 0; if (!obj) { - if(!wrapper_in) { - ALLOC_ZVAL(wrapper); - } else { - wrapper = wrapper_in; - } + ALLOC_ZVAL(wrapper); ZVAL_NULL(wrapper); return wrapper; } - if ((wrapper = (zval *) dom_object_get_data((void *) obj))) { - if (wrapper_in) { - zval_add_ref(&wrapper); - *found = 1; - return wrapper; - } else { - *return_value = *wrapper; - zval_copy_ctor(return_value); - *found = 1; - return return_value; - } + if ((intern = (dom_object *) dom_object_get_data((void *) obj))) { + return_value->type = IS_OBJECT; + return_value->is_ref = 1; + return_value->value.obj.handle = intern->handle; + return_value->value.obj.handlers = &dom_object_handlers; + zval_copy_ctor(return_value); + *found = 1; + return return_value; } - if(!wrapper_in) { - wrapper = return_value; - } else { - wrapper = wrapper_in; - } + wrapper = return_value; switch (obj->type) { case XML_DOCUMENT_NODE: @@ -957,11 +977,17 @@ zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *wrapper_in, zval * return wrapper; } - if(!wrapper_in) { - object_init_ex(wrapper, ce); + + object_init_ex(wrapper, ce); + intern = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC); + if (obj->doc != NULL) { + if (domobj != NULL) { + intern->document = domobj->document; + } + increment_document_reference(intern, obj->doc TSRMLS_CC); } - php_dom_set_object(wrapper, (void *) obj TSRMLS_CC); + php_dom_set_object(intern, (void *) obj TSRMLS_CC); return (wrapper); } /* }}} end php_domobject_new */ @@ -994,9 +1020,9 @@ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) /* }}} end dom_hierarchy */ /* {{{ void dom_element_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, zval **retval TSRMLS_DC) */ -void dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, zval **retval TSRMLS_DC) +void dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, zval **retval, dom_object *intern TSRMLS_DC) { - zval *wrapper; + dom_object *wrapper; int ret; while (nodep != NULL) { @@ -1008,11 +1034,11 @@ void dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local MAKE_STD_ZVAL(child); } - child = php_dom_create_object(nodep, &ret, wrapper, child TSRMLS_CC); + child = php_dom_create_object(nodep, &ret, NULL, child, intern TSRMLS_CC); add_next_index_zval(*retval, child); } } - dom_get_elements_by_tag_name_ns_raw(nodep->children, ns, local, retval TSRMLS_CC); + dom_get_elements_by_tag_name_ns_raw(nodep->children, ns, local, retval, intern TSRMLS_CC); nodep = nodep->next; } } diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 17fe94a5ad..45497ae788 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -56,18 +56,21 @@ extern zend_module_entry dom_module_entry; #include "dom_fe.h" -void php_dom_set_object(zval *wrapper, void *obj TSRMLS_DC); -zval *dom_object_get_data(xmlNodePtr obj); +void php_dom_set_object(dom_object *wrapper, void *obj TSRMLS_DC); +dom_object *dom_object_get_data(xmlNodePtr obj); 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); -void dom_del_from_list(xmlNodePtr nodep, xmlDocPtr docp TSRMLS_DC); -void dom_add_to_list(xmlNodePtr nodep, xmlDocPtr docp TSRMLS_DC); +void dom_del_from_list(xmlNodePtr nodep, dom_object *intern TSRMLS_DC); +void dom_add_to_list(xmlNodePtr nodep, dom_object *intern TSRMLS_DC); +void dom_clean_nodes(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); void dom_set_old_ns(xmlDoc *doc, xmlNs *ns); xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName); void dom_normalize (xmlNodePtr nodep TSRMLS_DC); -void dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, zval **retval TSRMLS_DC); +void dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, zval **retval, dom_object *intern TSRMLS_DC); void php_dom_create_implementation(zval **retval TSRMLS_DC); int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child); diff --git a/ext/dom/processinginstruction.c b/ext/dom/processinginstruction.c index 7e83a37ae6..724be51641 100644 --- a/ext/dom/processinginstruction.c +++ b/ext/dom/processinginstruction.c @@ -71,7 +71,7 @@ PHP_FUNCTION(dom_processinginstruction_processinginstruction) if (oldnode != NULL) { node_free_resource(oldnode TSRMLS_CC); } - php_dom_set_object(id, nodep TSRMLS_CC); + php_dom_set_object(intern, nodep TSRMLS_CC); } } /* }}} end dom_processinginstruction_processinginstruction */ diff --git a/ext/dom/text.c b/ext/dom/text.c index 8c285c2e34..b497a817f8 100644 --- a/ext/dom/text.c +++ b/ext/dom/text.c @@ -69,7 +69,7 @@ PHP_FUNCTION(dom_text_text) if (oldnode != NULL) { node_free_resource(oldnode TSRMLS_CC); } - php_dom_set_object(id, nodep TSRMLS_CC); + php_dom_set_object(intern, nodep TSRMLS_CC); } } /* }}} end dom_text_text */ @@ -110,8 +110,9 @@ PHP_FUNCTION(dom_text_split_text) long offset; int ret; int length; + dom_object *intern; - DOM_GET_THIS_OBJ(node, getThis(), xmlNodePtr); + DOM_GET_THIS_OBJ(node, getThis(), xmlNodePtr, intern); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &offset) == FAILURE) { return; @@ -143,7 +144,7 @@ PHP_FUNCTION(dom_text_split_text) xmlAddNextSibling(node, nnode); nnode->type = XML_TEXT_NODE; - return_value = php_dom_create_object(nnode, &ret, NULL, return_value TSRMLS_CC); + return_value = php_dom_create_object(nnode, &ret, NULL, return_value, intern TSRMLS_CC); } /* }}} end dom_text_split_text */ diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h index 0c88bae040..b8b5df332e 100644 --- a/ext/dom/xml_common.h +++ b/ext/dom/xml_common.h @@ -30,6 +30,7 @@ typedef struct _node_list_pointer { typedef struct _dom_ref_obj { void *ptr; int refcount; + node_list_pointer *node_list; } dom_ref_obj; typedef struct _dom_object { @@ -37,7 +38,7 @@ typedef struct _dom_object { void *ptr; dom_ref_obj *document; HashTable *prop_handler; - node_list_pointer *node_list; + zend_object_handle handle; } dom_object; #ifdef PHP_WIN32 @@ -57,7 +58,7 @@ typedef struct _dom_object { #define PHP_DOM_EXPORT(__type) PHPAPI __type -PHP_DOM_EXPORT(zval *) php_dom_create_object(xmlNodePtr obj, int *found, zval* in, zval* return_value TSRMLS_DC); +PHP_DOM_EXPORT(zval *) php_dom_create_object(xmlNodePtr obj, int *found, zval *in, zval* return_value, dom_object *domobj TSRMLS_DC); PHP_DOM_EXPORT(void) dom_objects_clone(void *object, void **object_clone TSRMLS_DC); void dom_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC); PHP_DOM_EXPORT(zval *) dom_read_property(zval *object, zval *member TSRMLS_DC); @@ -78,22 +79,22 @@ INIT_CLASS_ENTRY(ce, name, funcs); \ ce.create_object = dom_objects_new; \ entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC); -#define DOM_GET_OBJ(__ptr, __id, __prtype) { \ - dom_object *intern = (dom_object *)zend_object_store_get_object(__id TSRMLS_CC); \ - if (!(__ptr = (__prtype)intern->ptr)) { \ - php_error(E_WARNING, "Couldn't fetch %s", intern->std.ce->name);\ +#define DOM_GET_OBJ(__ptr, __id, __prtype, __intern) { \ + __intern = (dom_object *)zend_object_store_get_object(__id TSRMLS_CC); \ + if (!(__ptr = (__prtype)__intern->ptr)) { \ + php_error(E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\ RETURN_NULL();\ } \ } -#define DOM_DOMOBJ_NEW(zval, obj, ret) \ - if (NULL == (zval = php_dom_create_object(obj, ret, zval, return_value TSRMLS_CC))) { \ +#define DOM_DOMOBJ_NEW(zval, obj, ret, domobject) \ + if (NULL == (zval = php_dom_create_object(obj, ret, zval, return_value, domobject TSRMLS_CC))) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); \ RETURN_FALSE; \ } -#define DOM_RET_OBJ(zval, obj, ret) \ - DOM_DOMOBJ_NEW(zval, obj, ret); +#define DOM_RET_OBJ(zval, obj, ret, domobject) \ + DOM_DOMOBJ_NEW(zval, obj, ret, domobject); #define DOM_GET_THIS(zval) \ if (NULL == (zval = getThis())) { \ @@ -101,8 +102,8 @@ entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC); RETURN_FALSE; \ } -#define DOM_GET_THIS_OBJ(__ptr, __id, __prtype) \ +#define DOM_GET_THIS_OBJ(__ptr, __id, __prtype, __intern) \ DOM_GET_THIS(__id); \ - DOM_GET_OBJ(__ptr, __id, __prtype); + DOM_GET_OBJ(__ptr, __id, __prtype, __intern); #endif