rrichards               Mon Jun  9 16:20:55 2003 EDT

  Modified files:              
    /php4/ext/dom       attr.c cdatasection.c characterdata.c comment.c 
                        document.c documentfragment.c documenttype.c 
                        domimplementation.c element.c entityreference.c 
                        node.c php_dom.c php_dom.h processinginstruction.c 
                        text.c xml_common.h 
  Log:
  implmentation of document ref counting for persistance
  re-work of internal object handling
  
Index: php4/ext/dom/attr.c
diff -u php4/ext/dom/attr.c:1.1 php4/ext/dom/attr.c:1.2
--- php4/ext/dom/attr.c:1.1     Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/attr.c Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: attr.c,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: attr.c,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -52,7 +52,8 @@
        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 @@
        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 @@
 */
 int dom_attr_owner_element_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-
-       zval *wrapper;
        xmlNodePtr nodep, nodeparent;
        int ret;
 
@@ -181,11 +179,9 @@
                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;
        }
Index: php4/ext/dom/cdatasection.c
diff -u php4/ext/dom/cdatasection.c:1.1 php4/ext/dom/cdatasection.c:1.2
--- php4/ext/dom/cdatasection.c:1.1     Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/cdatasection.c Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: cdatasection.c,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: cdatasection.c,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -67,7 +67,7 @@
                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 */
Index: php4/ext/dom/characterdata.c
diff -u php4/ext/dom/characterdata.c:1.1 php4/ext/dom/characterdata.c:1.2
--- php4/ext/dom/characterdata.c:1.1    Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/characterdata.c        Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: characterdata.c,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: characterdata.c,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -140,11 +140,12 @@
 {
        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;
Index: php4/ext/dom/comment.c
diff -u php4/ext/dom/comment.c:1.1 php4/ext/dom/comment.c:1.2
--- php4/ext/dom/comment.c:1.1  Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/comment.c      Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: comment.c,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: comment.c,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -66,7 +66,7 @@
                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 */
Index: php4/ext/dom/document.c
diff -u php4/ext/dom/document.c:1.3 php4/ext/dom/document.c:1.4
--- php4/ext/dom/document.c:1.3 Thu Jun  5 14:30:19 2003
+++ php4/ext/dom/document.c     Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: document.c,v 1.3 2003/06/05 18:30:19 sterling Exp $ */
+/* $Id: document.c,v 1.4 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -82,7 +82,6 @@
 */
 int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       zval *wrapper;
        xmlDoc *docp;
        xmlDtdPtr dtdptr;
        int ret;
@@ -95,11 +94,8 @@
                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 @@
 */
 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 @@
                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 @@
        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 @@
                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 @@
        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 @@
        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 @@
                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 @@
        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 @@
                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 @@
        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 @@
                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 @@
        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 @@
 
        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 @@
        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 @@
                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 @@
        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 @@
                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 @@
        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 @@
 
                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 @@
        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 @@
                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 @@
        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 @@
                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 @@
        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 @@
                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 @@
        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 @@
        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 @@
        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 @@
                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 @@
 {
        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 @@
        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 @@
        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 @@
        xmlDoc *docp = NULL, *newdoc;
        dom_object *intern;
        char *source;
-       int source_len;
+       int source_len, refcount;
 
        id = getThis();
        
@@ -996,11 +1006,16 @@
        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 @@
        xmlDoc *docp = NULL, *newdoc;
        dom_object *intern;
        char *buffer;
-       int buffer_len;
+       int buffer_len, refcount;
 
        id = getThis();
        
@@ -1032,11 +1047,17 @@
        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 @@
        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 @@
        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 @@
 
        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");
Index: php4/ext/dom/documentfragment.c
diff -u php4/ext/dom/documentfragment.c:1.1 php4/ext/dom/documentfragment.c:1.2
--- php4/ext/dom/documentfragment.c:1.1 Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/documentfragment.c     Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: documentfragment.c,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: documentfragment.c,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -60,7 +60,7 @@
                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 */
Index: php4/ext/dom/documenttype.c
diff -u php4/ext/dom/documenttype.c:1.1 php4/ext/dom/documenttype.c:1.2
--- php4/ext/dom/documenttype.c:1.1     Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/documenttype.c Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: documenttype.c,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: documenttype.c,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -108,13 +108,9 @@
                                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 @@
                                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);
                                }
                        }
Index: php4/ext/dom/domimplementation.c
diff -u php4/ext/dom/domimplementation.c:1.1 php4/ext/dom/domimplementation.c:1.2
--- php4/ext/dom/domimplementation.c:1.1        Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/domimplementation.c    Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: domimplementation.c,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: domimplementation.c,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -105,7 +105,7 @@
        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 @@
        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 @@
                xmlFree(localname);
        }
 
-       DOM_RET_OBJ(rv, (xmlNodePtr) docp, &ret);
+       DOM_RET_OBJ(rv, (xmlNodePtr) docp, &ret, NULL);
 }
 /* }}} end dom_domimplementation_create_document */
 
Index: php4/ext/dom/element.c
diff -u php4/ext/dom/element.c:1.2 php4/ext/dom/element.c:1.3
--- php4/ext/dom/element.c:1.2  Thu Jun  5 14:54:25 2003
+++ php4/ext/dom/element.c      Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: element.c,v 1.2 2003/06/05 18:54:25 sterling Exp $ */
+/* $Id: element.c,v 1.3 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -93,7 +93,7 @@
                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 @@
        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 @@
        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 @@
                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 @@
        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 @@
                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 @@
        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 @@
        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 @@
 */
 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 @@
        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 @@
                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 @@
        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 @@
 
                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 @@
        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 @@
        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 @@
                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 @@
        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 @@
                        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 @@
        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 @@
 */
 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 @@
     }
 
        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 @@
        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 @@
 
        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 @@
 {
        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 @@
        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;
Index: php4/ext/dom/entityreference.c
diff -u php4/ext/dom/entityreference.c:1.1 php4/ext/dom/entityreference.c:1.2
--- php4/ext/dom/entityreference.c:1.1  Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/entityreference.c      Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: entityreference.c,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: entityreference.c,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -71,7 +71,7 @@
                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);
        }
 }
 
Index: php4/ext/dom/node.c
diff -u php4/ext/dom/node.c:1.2 php4/ext/dom/node.c:1.3
--- php4/ext/dom/node.c:1.2     Thu Jun  5 14:54:25 2003
+++ php4/ext/dom/node.c Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: node.c,v 1.2 2003/06/05 18:54:25 sterling Exp $ */
+/* $Id: node.c,v 1.3 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -217,7 +217,6 @@
 */
 int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       zval *wrapper;
        xmlNode *nodep, *nodeparent;
        int ret;
 
@@ -228,11 +227,9 @@
                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 @@
        
        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 @@
 */
 int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       zval *wrapper;
        xmlNode *nodep, *first;
        int ret;
 
@@ -301,11 +293,9 @@
                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 @@
 */
 int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       zval *wrapper;
        xmlNode *nodep, *last;
        int ret;
 
@@ -334,11 +323,9 @@
                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 @@
 */
 int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       zval *wrapper;
        xmlNode *nodep, *prevsib;
        int ret;
 
@@ -367,11 +353,9 @@
                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 @@
 */
 int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       zval *wrapper;
        xmlNode *nodep, *nextsib;
        int ret;
 
@@ -400,11 +383,9 @@
                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 @@
                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 @@
 */
 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 @@
                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 @@
 {
        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 @@
                                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 @@
                                        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 @@
                        (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 @@
                        (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 @@
                                        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 @@
                        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 @@
                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 @@
 {
        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 @@
        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 @@
                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 @@
 {
        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 @@
                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 @@
 {
        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 @@
                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 @@
                (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 @@
                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 @@
 {
        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 @@
        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 @@
        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 @@
 {
        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 @@
 {
        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 @@
 {
        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;
Index: php4/ext/dom/php_dom.c
diff -u php4/ext/dom/php_dom.c:1.7 php4/ext/dom/php_dom.c:1.8
--- php4/ext/dom/php_dom.c:1.7  Sat Jun  7 11:09:24 2003
+++ php4/ext/dom/php_dom.c      Mon Jun  9 16:20:55 2003
@@ -13,12 +13,12 @@
    | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
    +----------------------------------------------------------------------+
    | Authors: Christian Stocker <[EMAIL PROTECTED]>                          |
-   |          Rob Richards <[EMAIL PROTECTED]>                                        
           |
+   |          Rob Richards <[EMAIL PROTECTED]>                            |
    |          Marcus Borger <[EMAIL PROTECTED]>                               |
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_dom.c,v 1.7 2003/06/07 15:09:24 sterling Exp $ */
+/* $Id: php_dom.c,v 1.8 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -75,81 +75,110 @@
        {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 @@
 /* }}} */
 
 /* {{{ 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 @@
 }
 
 /* {{{ 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 @@
 /* {{{ 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 @@
                                        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 @@
                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_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 @@
        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_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 @@
 /* }}} */
 
 /* {{{ 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 @@
                        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 @@
 /* }}} 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 @@
                                        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;
        }
 }
Index: php4/ext/dom/php_dom.h
diff -u php4/ext/dom/php_dom.h:1.1 php4/ext/dom/php_dom.h:1.2
--- php4/ext/dom/php_dom.h:1.1  Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/php_dom.h      Mon Jun  9 16:20:55 2003
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_dom.h,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: php_dom.h,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifndef PHP_DOM_H
 #define PHP_DOM_H
@@ -56,18 +56,21 @@
 
 #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);
 
Index: php4/ext/dom/processinginstruction.c
diff -u php4/ext/dom/processinginstruction.c:1.1 
php4/ext/dom/processinginstruction.c:1.2
--- php4/ext/dom/processinginstruction.c:1.1    Thu Jun  5 13:06:52 2003
+++ php4/ext/dom/processinginstruction.c        Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: processinginstruction.c,v 1.1 2003/06/05 17:06:52 rrichards Exp $ */
+/* $Id: processinginstruction.c,v 1.2 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -71,7 +71,7 @@
                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 */
Index: php4/ext/dom/text.c
diff -u php4/ext/dom/text.c:1.3 php4/ext/dom/text.c:1.4
--- php4/ext/dom/text.c:1.3     Sat Jun  7 11:03:45 2003
+++ php4/ext/dom/text.c Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: text.c,v 1.3 2003/06/07 15:03:45 sterling Exp $ */
+/* $Id: text.c,v 1.4 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -69,7 +69,7 @@
                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 @@
        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 @@
        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 */
 
Index: php4/ext/dom/xml_common.h
diff -u php4/ext/dom/xml_common.h:1.3 php4/ext/dom/xml_common.h:1.4
--- php4/ext/dom/xml_common.h:1.3       Sat Jun  7 09:30:58 2003
+++ php4/ext/dom/xml_common.h   Mon Jun  9 16:20:55 2003
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: xml_common.h,v 1.3 2003/06/07 13:30:58 rrichards Exp $ */
+/* $Id: xml_common.h,v 1.4 2003/06/09 20:20:55 rrichards Exp $ */
 
 #ifndef PHP_XML_COMMON_H
 #define PHP_XML_COMMON_H 
@@ -30,6 +30,7 @@
 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 @@
        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 @@
 
 #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 @@
 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 @@
                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

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to