}
/* }}} */
-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;
}
/* }}} */
+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;
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;
#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
zend_object_std_init(&intern->zo, ce TSRMLS_CC);
intern->zo.guards = NULL;
#endif
+ 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;
}
/* }}} */
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}
};
/* }}} */
RETURN_ZVAL(sxe->iter.data, 1, 0);
}
-/* {{{ proto int SimpleXMLIterator::count()
- Get number of child elements */
-SPL_METHOD(SimpleXMLIterator, count)
-{
- long count = 0;
-
- Z_OBJ_HANDLER_P(getThis(), count_elements)(getThis(), &count TSRMLS_CC);
-
- RETURN_LONG(count);
-}
-
static const zend_function_entry spl_funcs_SimpleXMLIterator[] = {
SPL_ME(SimpleXMLIterator, rewind, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SimpleXMLIterator, valid, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SimpleXMLIterator, next, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SimpleXMLIterator, hasChildren, NULL, ZEND_ACC_PUBLIC)
SPL_ME(SimpleXMLIterator, getChildren, NULL, ZEND_ACC_PUBLIC)
- SPL_ME(SimpleXMLIterator, count, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
/* }}} */