From e0844e09bd9a64c59b765dbc16b1c6834821a979 Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Wed, 7 Jun 2006 09:44:42 +0000 Subject: [PATCH] - MFH iterator_apply() --- ext/spl/php_spl.c | 10 ++++- ext/spl/spl_iterators.c | 54 ++++++++++++++++++++++-- ext/spl/spl_iterators.h | 1 + ext/spl/tests/spl_004.phpt | 86 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 4 deletions(-) create mode 100755 ext/spl/tests/spl_004.phpt diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index 2b61aa568e..fce87de40c 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -610,7 +610,14 @@ PHP_MINFO_FUNCTION(spl) static ZEND_BEGIN_ARG_INFO(arginfo_iterator, 0) - ZEND_ARG_INFO(0, iterator) + ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0) +ZEND_END_ARG_INFO(); + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_iterator_apply, 0, 0, 2) + ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0) + ZEND_ARG_INFO(0, function) + ZEND_ARG_ARRAY_INFO(0, args, 1) ZEND_END_ARG_INFO(); /* {{{ spl_functions @@ -628,6 +635,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 1caf3aa3cf..294bc12126 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -2575,7 +2575,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; @@ -2600,8 +2600,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; @@ -2613,6 +2613,54 @@ 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; + + apply_info.args = NULL; + 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; + } + + 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 8a608def63..af4eccd8ff 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, diff --git a/ext/spl/tests/spl_004.phpt b/ext/spl/tests/spl_004.phpt new file mode 100755 index 0000000000..60da28042a --- /dev/null +++ b/ext/spl/tests/spl_004.phpt @@ -0,0 +1,86 @@ +--TEST-- +SPL: iterator_apply() +--SKIPIF-- + +--FILE-- +key()); + var_dump($arg->current()); + } + else + { + var_dump($arg); + } + return true; +} + +function test() +{ + static $arg = 0; + var_dump($arg++); + return true; +} + +$it = new RecursiveArrayIterator(array(1, array(21, 22), 3)); + +var_dump(iterator_apply($it, 'test', NULL)); + +echo "===ARGS===\n"; +var_dump(iterator_apply($it, 'test_arg', array($it))); + +echo "===RECURSIVE===\n"; +$it = new RecursiveIteratorIterator($it); +var_dump(iterator_apply($it, 'test')); + +echo "===ERRORS===\n"; +var_dump(iterator_apply($it, 'test', 1)); +var_dump(iterator_apply($it, 'non_existing_functon')); +var_dump(iterator_apply($it, 'non_existing_functon', NULL, 2)); + +?> +===DONE=== + +--EXPECTF-- +int(0) +int(1) +int(2) +int(3) +===ARGS=== +int(0) +int(1) +int(1) +array(2) { + [0]=> + int(21) + [1]=> + int(22) +} +int(2) +int(3) +int(3) +===RECURSIVE=== +int(3) +int(4) +int(5) +int(6) +int(4) +===ERRORS=== +Error: Argument 3 passed to iterator_apply() must be an array, integer given +Error: iterator_apply() expects parameter 3 to be array, integer given +NULL +Error: iterator_apply() expects parameter 2 to be function,%sstring given +NULL +Error: iterator_apply() expects at most 3 parameters, 4 given +NULL +===DONE=== -- 2.40.0