From 6d0c676a592d4fcf402c2268d47d849b5d040532 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss Date: Wed, 9 Jul 2008 21:27:10 +0000 Subject: [PATCH] Move SXI::count to SXE::count and make it user-friendly --- ext/simplexml/php_simplexml.h | 1 + ext/simplexml/simplexml.c | 60 +++++++++++++++++++++++++++++++++-- ext/simplexml/tests/036.phpt | 22 +++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 ext/simplexml/tests/036.phpt diff --git a/ext/simplexml/php_simplexml.h b/ext/simplexml/php_simplexml.h index 8d97e836c28..01d8c7770c6 100644 --- a/ext/simplexml/php_simplexml.h +++ b/ext/simplexml/php_simplexml.h @@ -68,6 +68,7 @@ typedef struct { zval *data; } iter; zval *tmp; + zend_function *fptr_count; } php_sxe_object; #ifdef ZTS diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 8e2bdef2459..eeb214a215e 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1868,14 +1868,12 @@ SXE_METHOD(__toString) } /* }}} */ -static int sxe_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */ +static int php_sxe_count_elements_helper(php_sxe_object *sxe, long *count TSRMLS_DC) /* {{{ */ { - php_sxe_object *sxe; xmlNodePtr node; zval *data; *count = 0; - sxe = php_sxe_fetch_object(object TSRMLS_CC); data = sxe->iter.data; sxe->iter.data = NULL; @@ -1897,6 +1895,42 @@ static int sxe_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */ } /* }}} */ +static int sxe_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */ +{ + php_sxe_object *intern; + intern = php_sxe_fetch_object(object TSRMLS_CC); + if (intern->fptr_count) { + zval *rv; + zend_call_method_with_0_params(&object, intern->zo.ce, &intern->fptr_count, "count", &rv); + if (rv) { + if (intern->tmp) { + zval_ptr_dtor(&intern->tmp); + } + MAKE_STD_ZVAL(intern->tmp); + ZVAL_ZVAL(intern->tmp, rv, 1, 1); + convert_to_long(intern->tmp); + *count = (long) Z_LVAL_P(intern->tmp); + return SUCCESS; + } + return FAILURE; + } + return php_sxe_count_elements_helper(intern, count TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto int SimpleXMLIterator::count() + Get number of child elements */ +SXE_METHOD(count) +{ + long count = 0; + php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + + php_sxe_count_elements_helper(sxe, &count TSRMLS_CC); + + RETURN_LONG(count); +} +/* }}} */ + static zval *sxe_get_value(zval *z TSRMLS_DC) /* {{{ */ { zval *retval; @@ -2035,15 +2069,34 @@ static void sxe_object_free_storage(void *object TSRMLS_DC) static php_sxe_object* php_sxe_object_new(zend_class_entry *ce TSRMLS_DC) { php_sxe_object *intern; + zend_class_entry *parent = ce; + int inherited = 0; intern = ecalloc(1, sizeof(php_sxe_object)); intern->iter.type = SXE_ITER_NONE; intern->iter.nsprefix = NULL; intern->iter.name = NULL; + intern->fptr_count = NULL; zend_object_std_init(&intern->zo, ce TSRMLS_CC); + while (parent) { + if (parent == sxe_class_entry) { + break; + } + + parent = parent->parent; + inherited = 1; + } + + if (inherited) { + zend_hash_find(&ce->function_table, "count", sizeof("count"),(void **) &intern->fptr_count); + if (intern->fptr_count->common.scope == parent) { + intern->fptr_count = NULL; + } + } + return intern; } /* }}} */ @@ -2538,6 +2591,7 @@ static const zend_function_entry sxe_functions[] = { /* {{{ */ SXE_ME(addChild, NULL, ZEND_ACC_PUBLIC) SXE_ME(addAttribute, NULL, ZEND_ACC_PUBLIC) SXE_ME(__toString, NULL, ZEND_ACC_PUBLIC) + SXE_ME(count, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; /* }}} */ diff --git a/ext/simplexml/tests/036.phpt b/ext/simplexml/tests/036.phpt new file mode 100644 index 00000000000..24bfe60e7dc --- /dev/null +++ b/ext/simplexml/tests/036.phpt @@ -0,0 +1,22 @@ +--TEST-- +SimpleXML: overriden count() method +--SKIPIF-- + +--FILE-- +asdfghjk'; +$sxe = new SXE($str); +var_dump(count($sxe)); +?> +==Done== +--EXPECT-- +Called Count! +int(2) +==Done==