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
#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}
};
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;
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;
}
/* }}} */
+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}