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