From: Marcus Boerger Date: Fri, 26 May 2006 00:37:33 +0000 (+0000) Subject: - Add function iterator_apply() X-Git-Tag: BEFORE_NEW_OUTPUT_API~75 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f0e9f6e4f97fa48f910f52048814bb961d4fb2ea;p=php - Add function iterator_apply() --- diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index 98521f5376..3a046c1a00 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -621,7 +621,14 @@ PHP_MINFO_FUNCTION(spl) static ZEND_BEGIN_ARG_INFO(arginfo_iterator, 0) - ZEND_ARG_INFO(0, iterator) + ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) +ZEND_END_ARG_INFO(); + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_iterator_apply, 0, 0, 2) + ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) + ZEND_ARG_INFO(0, function) + ZEND_ARG_ARRAY_INFO(0, args, 0) ZEND_END_ARG_INFO(); /* {{{ spl_functions @@ -639,6 +646,7 @@ zend_function_entry spl_functions[] = { #ifdef SPL_ITERATORS_H PHP_FE(iterator_to_array, arginfo_iterator) PHP_FE(iterator_count, arginfo_iterator) + PHP_FE(iterator_apply, arginfo_iterator_apply) #endif /* SPL_ITERATORS_H */ {NULL, NULL, NULL} }; diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index d8694279ca..17d4be3eea 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -2612,7 +2612,7 @@ static int spl_iterator_to_array_apply(zend_object_iterator *iter, void *puser T Copy the iterator into an array */ PHP_FUNCTION(iterator_to_array) { - zval *obj; + zval *obj; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &obj, zend_ce_traversable) == FAILURE) { RETURN_FALSE; @@ -2637,8 +2637,8 @@ static int spl_iterator_count_apply(zend_object_iterator *iter, void *puser TSRM Count the elements in an iterator */ PHP_FUNCTION(iterator_count) { - zval *obj; - long count = 0; + zval *obj; + long count = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &obj, zend_ce_traversable) == FAILURE) { RETURN_FALSE; @@ -2650,6 +2650,53 @@ PHP_FUNCTION(iterator_count) } /* }}} */ +typedef struct { + zval *obj; + zval *args; + long count; + zend_fcall_info fci; + zend_fcall_info_cache fcc; +} spl_iterator_apply_info; + +static int spl_iterator_func_apply(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */ +{ + zval *retval; + spl_iterator_apply_info *apply_info = (spl_iterator_apply_info*)puser; + int result; + + apply_info->count++; + zend_fcall_info_call(&apply_info->fci, &apply_info->fcc, &retval, NULL TSRMLS_CC); + if (retval) { + result = zend_is_true(retval) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_STOP; + zval_ptr_dtor(&retval); + } else { + result = ZEND_HASH_APPLY_STOP; + } + return result; +} +/* }}} */ + +/* {{{ proto int iterator_apply(Traversable it, mixed function [, mixed params]) + Calls a function for every element in an iterator */ +PHP_FUNCTION(iterator_apply) +{ + spl_iterator_apply_info apply_info; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Of|a", &apply_info.obj, zend_ce_traversable, &apply_info.fci, &apply_info.fcc, &apply_info.args) == FAILURE) { + RETURN_FALSE; + } + + apply_info.count = 0; + zend_fcall_info_args(&apply_info.fci, apply_info.args TSRMLS_CC); + if (spl_iterator_apply(apply_info.obj, spl_iterator_func_apply, (void*)&apply_info TSRMLS_CC) == SUCCESS) { + RETVAL_LONG(apply_info.count); + } else { + RETVAL_FALSE; + } + zend_fcall_info_args(&apply_info.fci, NULL TSRMLS_CC); +} +/* }}} */ + static zend_function_entry spl_funcs_OuterIterator[] = { SPL_ABSTRACT_ME(OuterIterator, getInnerIterator, NULL) {NULL, NULL, NULL} diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index dc03fd73da..321b28fc52 100755 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -55,6 +55,7 @@ PHP_MINIT_FUNCTION(spl_iterators); PHP_FUNCTION(iterator_to_array); PHP_FUNCTION(iterator_count); +PHP_FUNCTION(iterator_apply); typedef enum { DIT_Default = 0,