diff options
Diffstat (limited to 'ext/spl/spl_iterators.c')
| -rwxr-xr-x | ext/spl/spl_iterators.c | 37 |
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); |
