summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2015-05-05 17:23:54 +0800
committerXinchen Hui <laruence@php.net>2015-05-05 17:23:54 +0800
commit8c0ebb4c5d869671bcf44805ed497eefd9dd712c (patch)
tree5cf498725d28465bd995e720f05b947c6e13275c
parentb6e893c143cf3e7ca1e1b3b3b31b4f5b20e4ebd3 (diff)
downloadphp-git-8c0ebb4c5d869671bcf44805ed497eefd9dd712c.tar.gz
Optimize cast simplexml to IS_BOOL
-rw-r--r--ext/simplexml/simplexml.c101
1 files changed, 96 insertions, 5 deletions
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index a0b0c1310d..b76e3ca167 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -1041,6 +1041,97 @@ static void sxe_properties_add(HashTable *rv, char *name, int namelen, zval *val
}
/* }}} */
+static int sxe_prop_is_empty(zval *object) /* {{{ */
+{
+ php_sxe_object *sxe;
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ zval iter_data;
+ int test;
+ int is_empty;
+
+ sxe = Z_SXEOBJ_P(object);
+
+ GET_NODE(sxe, node);
+ if (!node) {
+ return 1;
+ }
+
+ if (sxe->iter.type == SXE_ITER_ELEMENT) {
+ node = php_sxe_get_first_node(sxe, node);
+ }
+ if (!node || node->type != XML_ENTITY_DECL) {
+ attr = node ? (xmlAttrPtr)node->properties : NULL;
+ test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST;
+ while (attr) {
+ if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
+ return 0;
+ }
+ attr = attr->next;
+ }
+ }
+
+ GET_NODE(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
+ is_empty = 1;
+ ZVAL_UNDEF(&iter_data);
+ if (node && sxe->iter.type != SXE_ITER_ATTRLIST) {
+ if (node->type == XML_ATTRIBUTE_NODE) {
+ return 0;
+ } else if (sxe->iter.type != SXE_ITER_CHILD) {
+ if (!node->children || !node->parent || !node->next || node->children->next || node->children->children || node->parent->children == node->parent->last) {
+ node = node->children;
+ } else {
+ ZVAL_COPY_VALUE(&iter_data, &sxe->iter.data);
+ ZVAL_UNDEF(&sxe->iter.data);
+ node = php_sxe_reset_iterator(sxe, 0);
+ }
+ }
+
+ while (node) {
+ if (node->children != NULL || node->prev != NULL || node->next != NULL) {
+ SKIP_TEXT(node);
+ } else {
+ if (node->type == XML_TEXT_NODE) {
+ const xmlChar *cur = node->content;
+ if (*cur != 0) {
+ is_empty = 0;
+ break;
+ }
+ goto next_iter;
+ }
+ }
+
+ if (node->type == XML_ELEMENT_NODE && (! match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix))) {
+ goto next_iter;
+ }
+
+ if (!node->name) {
+ goto next_iter;
+ }
+
+ is_empty = 0;
+ break;
+next_iter:
+ if (!Z_ISUNDEF(iter_data)) {
+ node = php_sxe_iterator_fetch(sxe, node->next, 0);
+ } else {
+ node = node->next;
+ }
+ }
+ }
+
+ if (!Z_ISUNDEF(iter_data)) {
+ if (!Z_ISUNDEF(sxe->iter.data)) {
+ zval_ptr_dtor(&sxe->iter.data);
+ }
+ ZVAL_COPY_VALUE(&sxe->iter.data, &iter_data);
+ }
+
+ return is_empty;
+}
+/* }}} */
+
static HashTable *sxe_get_prop_hash(zval *object, int is_debug) /* {{{ */
{
zval value;
@@ -1784,16 +1875,16 @@ static int sxe_object_cast_ex(zval *readobj, zval *writeobj, int type)
xmlChar *contents = NULL;
xmlNodePtr node;
int rv;
- HashTable *prop_hash;
sxe = Z_SXEOBJ_P(readobj);
if (type == _IS_BOOL) {
node = php_sxe_get_first_node(sxe, NULL);
- prop_hash = sxe_get_prop_hash(readobj, 1);
- ZVAL_BOOL(writeobj, node != NULL || zend_hash_num_elements(prop_hash) > 0);
- zend_hash_destroy(prop_hash);
- efree(prop_hash);
+ if (node) {
+ ZVAL_TRUE(writeobj);
+ } else {
+ ZVAL_BOOL(writeobj, !sxe_prop_is_empty(readobj));
+ }
return SUCCESS;
}