summaryrefslogtreecommitdiff
path: root/ext/spl/spl_iterators.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/spl/spl_iterators.c')
-rwxr-xr-xext/spl/spl_iterators.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c
index 3f3e386521..0ad559089a 100755
--- a/ext/spl/spl_iterators.c
+++ b/ext/spl/spl_iterators.c
@@ -93,6 +93,7 @@ typedef struct _spl_recursive_it_object {
zend_function *callGetChildren;
zend_function *beginChildren;
zend_function *endChildren;
+ zend_function *nextElement;
zend_class_entry *ce;
} spl_recursive_it_object;
@@ -209,9 +210,15 @@ next_step:
}
}
}
+ if (object->nextElement) {
+ zend_call_method_with_0_params(&zthis, object->ce, &object->nextElement, "nextelement", NULL);
+ }
object->iterators[object->level].state = RS_NEXT;
return /* self */;
case RS_SELF:
+ if (object->nextElement && (object->mode == RIT_SELF_FIRST || object->mode == RIT_CHILD_FIRST)) {
+ zend_call_method_with_0_params(&zthis, object->ce, &object->nextElement, "nextelement", NULL);
+ }
if (object->mode == RIT_SELF_FIRST) {
object->iterators[object->level].state = RS_CHILD;
} else {
@@ -381,6 +388,10 @@ SPL_METHOD(RecursiveIteratorIterator, __construct)
if (intern->endChildren->common.scope == U_CLASS_ENTRY(spl_ce_RecursiveIteratorIterator)) {
intern->endChildren = NULL;
}
+ zend_hash_find(&intern->ce->function_table, "nextelement", sizeof("nextElement"), (void **) &intern->nextElement);
+ if (intern->nextElement->common.scope == U_CLASS_ENTRY(spl_ce_RecursiveIteratorIterator)) {
+ intern->nextElement = NULL;
+ }
ce_iterator = Z_OBJCE_P(iterator); /* respect inheritance, don't use spl_ce_RecursiveIterator */
intern->iterators[0].iterator = ce_iterator->get_iterator(ce_iterator, iterator TSRMLS_CC);
iterator->refcount++;
@@ -516,7 +527,9 @@ SPL_METHOD(RecursiveIteratorIterator, callGetChildren)
return;
} else {
zend_call_method_with_0_params(&zobject, ce, NULL, "getchildren", &retval);
- RETURN_ZVAL(retval, 0, 1);
+ if (retval) {
+ RETURN_ZVAL(retval, 0, 1);
+ }
}
} /* }}} */
@@ -534,6 +547,13 @@ SPL_METHOD(RecursiveIteratorIterator, endChildren)
/* nothing to do */
} /* }}} */
+/* {{{ proto RecursiveIterator RecursiveIteratorIterator::nextElement()
+ Called when the next element is available */
+SPL_METHOD(RecursiveIteratorIterator, nextElement)
+{
+ /* nothing to do */
+} /* }}} */
+
static union _zend_function *spl_recursive_it_get_method(zval **object_ptr, char *method, int method_len TSRMLS_DC)
{
union _zend_function *function_handler;
@@ -621,6 +641,7 @@ static zend_function_entry spl_funcs_RecursiveIteratorIterator[] = {
SPL_ME(RecursiveIteratorIterator, callGetChildren, NULL, ZEND_ACC_PUBLIC)
SPL_ME(RecursiveIteratorIterator, beginChildren, NULL, ZEND_ACC_PUBLIC)
SPL_ME(RecursiveIteratorIterator, endChildren, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(RecursiveIteratorIterator, nextElement, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
@@ -1197,6 +1218,7 @@ static zend_function_entry spl_funcs_ParentIterator[] = {
SPL_MA(ParentIterator, accept, ParentIterator, hasChildren, NULL, ZEND_ACC_PUBLIC)
SPL_ME(ParentIterator, hasChildren, NULL, ZEND_ACC_PUBLIC)
SPL_ME(ParentIterator, getChildren, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
@@ -1988,13 +2010,14 @@ PHP_MINIT_FUNCTION(spl_iterators)
spl_ce_RecursiveIteratorIterator->get_iterator = spl_recursive_it_get_iterator;
spl_ce_RecursiveIteratorIterator->iterator_funcs.funcs = &spl_recursive_it_iterator_funcs;
- REGISTER_LONG_CONSTANT("RIT_LEAVES_ONLY", (long)RIT_LEAVES_ONLY, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("RIT_SELF_FIRST", (long)RIT_SELF_FIRST, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("RIT_CHILD_FIRST", (long)RIT_CHILD_FIRST, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("RIT_CATCH_GET_CHILD", (long)RIT_CATCH_GET_CHILD, CONST_CS | CONST_PERSISTENT);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveIteratorIterator, "LEAVES_ONLY", RIT_LEAVES_ONLY);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveIteratorIterator, "SELF_FIRST", RIT_SELF_FIRST);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveIteratorIterator, "CHILD_FIRST", RIT_CHILD_FIRST);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveIteratorIterator, "CATCH_GET_CHILD", RIT_CATCH_GET_CHILD);
REGISTER_SPL_STD_CLASS_EX(FilterIterator, spl_dual_it_new, spl_funcs_FilterIterator);
REGISTER_SPL_ITERATOR(FilterIterator);
+ spl_ce_FilterIterator->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
REGISTER_SPL_SUB_CLASS_EX(RecursiveFilterIterator, FilterIterator, spl_dual_it_new, spl_funcs_RecursiveFilterIterator);
REGISTER_SPL_IMPLEMENTS(RecursiveFilterIterator, RecursiveIterator);
@@ -2010,8 +2033,8 @@ PHP_MINIT_FUNCTION(spl_iterators)
REGISTER_SPL_STD_CLASS_EX(CachingIterator, spl_dual_it_new, spl_funcs_CachingIterator);
REGISTER_SPL_ITERATOR(CachingIterator);
- REGISTER_LONG_CONSTANT("CIT_CALL_TOSTRING", (long)CIT_CALL_TOSTRING, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("CIT_CATCH_GET_CHILD", (long)CIT_CATCH_GET_CHILD, CONST_CS | CONST_PERSISTENT);
+ REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CALL_TOSTRING", CIT_CALL_TOSTRING);
+ REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CATCH_GET_CHILD", CIT_CATCH_GET_CHILD);
REGISTER_SPL_SUB_CLASS_EX(CachingRecursiveIterator, CachingIterator, spl_dual_it_new, spl_funcs_CachingRecursiveIterator);
REGISTER_SPL_IMPLEMENTS(CachingRecursiveIterator, RecursiveIterator);