zend_class_entry *spl_ce_CachingIterator;
zend_class_entry *spl_ce_CachingRecursiveIterator;
zend_class_entry *spl_ce_OuterIterator;
+zend_class_entry *spl_ce_IteratorIterator;
+zend_class_entry *spl_ce_NoRewindIterator;
function_entry spl_funcs_RecursiveIterator[] = {
SPL_ABSTRACT_ME(RecursiveIterator, hasChildren, NULL)
}
#endif
+static INLINE int spl_dual_it_fetch(spl_dual_it_object *intern, int check_more TSRMLS_DC);
+
static INLINE spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_inner, dual_it_type dit_type)
{
zval *zobject;
intern->u.caching.flags |= flags & CIT_PUBLIC;
break;
}
+ case DIT_IteratorIterator: {
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zobject, ce_inner) == FAILURE) {
+ php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
+ return NULL;
+ }
+ ce = Z_OBJCE_P(zobject);
+ if (!instanceof_function(ce, zend_ce_iterator TSRMLS_CC)) {
+ if (instanceof_function(ce, zend_ce_aggregate TSRMLS_CC)) {
+ zval *retval;
+ zobject = zend_call_method_with_0_params(&zobject, ce, &ce->iterator_funcs.zf_new_iterator, "getiterator", &retval);
+ }
+ }
+ break;
+ }
default:
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zobject, ce_inner) == FAILURE) {
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
}
/* {{{ proto void ParentIterator::rewind()
+ proto void IteratorIterator::rewind()
Rewind the iterator
*/
SPL_METHOD(dual_it, rewind)
/* {{{ proto boolean FilterIterator::valid()
proto boolean ParentIterator::valid()
+ proto boolean IteratorIterator::valid()
+ proto boolean NoRewindIterator::valid()
Check whether the current element is valid */
SPL_METHOD(dual_it, valid)
{
proto mixed CachingIterator::key()
proto mixed LimitIterator::key()
proto mixed ParentIterator::key()
+ proto mixed IteratorIterator::key()
+ proto mixed NoRewindIterator::key()
Get the current key */
SPL_METHOD(dual_it, key)
{
proto mixed CachingIterator::current()
proto mixed LimitIterator::current()
proto mixed ParentIterator::current()
+ proto mixed IteratorIterator::current()
+ proto mixed NoRewindIterator::current()
Get the current element value */
SPL_METHOD(dual_it, current)
{
} /* }}} */
/* {{{ proto void ParentIterator::next()
+ proto void IteratorIterator::next()
+ proto void NoRewindIterator::next()
Move the iterator forward */
SPL_METHOD(dual_it, next)
{
static
ZEND_BEGIN_ARG_INFO(arginfo_caching_it___construct, 0)
ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0)
- ZEND_ARG_INFO(0, getStrVal)
+ ZEND_ARG_INFO(0, flags)
ZEND_END_ARG_INFO();
static zend_function_entry spl_funcs_CachingIterator[] = {
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_rec_it___construct, 0, ZEND_RETURN_REFERENCE_AGNOSTIC, 2)
ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0)
- ZEND_ARG_INFO(0, getStrVal)
- ZEND_ARG_INFO(0, catch_getChildren)
+ ZEND_ARG_INFO(0, flags)
ZEND_END_ARG_INFO();
static zend_function_entry spl_funcs_CachingRecursiveIterator[] = {
{NULL, NULL, NULL}
};
+/* {{{ proto IteratorIterator::__construct(Traversable it)
+ Create an iterator from anything that is traversable */
+SPL_METHOD(IteratorIterator, __construct)
+{
+ spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_traversable, DIT_IteratorIterator);
+} /* }}} */
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_iterator_it___construct, 0)
+ ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0)
+ZEND_END_ARG_INFO();
+
+static zend_function_entry spl_funcs_IteratorIterator[] = {
+ SPL_ME(IteratorIterator, __construct, arginfo_iterator_it___construct, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, rewind, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, valid, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, key, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, current, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, next, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+/* {{{ proto NoRewindIterator::__construct(Iterator it)
+ Create an iterator from another iterator */
+SPL_METHOD(NoRewindIterator, __construct)
+{
+ spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_iterator, DIT_NoRewindIterator);
+} /* }}} */
+
+/* {{{ proto NoRewindIterator::rewind()
+ Prevent a call to inner iterators rewind() (internally the current data will be fetched if valid()) */
+SPL_METHOD(NoRewindIterator, rewind)
+{
+ spl_dual_it_object *intern;
+
+ intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ spl_dual_it_fetch(intern, 1 TSRMLS_CC);
+} /* }}} */
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_norewind_it___construct, 0)
+ ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0)
+ZEND_END_ARG_INFO();
+
+static zend_function_entry spl_funcs_NoRewindIterator[] = {
+ SPL_ME(NoRewindIterator, __construct, arginfo_norewind_it___construct, ZEND_ACC_PUBLIC)
+ SPL_ME(NoRewindIterator, rewind, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, valid, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, key, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, current, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, next, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_object_iterator_funcs spl_norewind_it_iterator_funcs;
+
/* {{{ array iterator_to_array(IteratorAggregate it)
Copy the iterator into an array */
PHP_FUNCTION(iterator_to_array)
REGISTER_SPL_SUB_CLASS_EX(CachingRecursiveIterator, CachingIterator, spl_dual_it_new, spl_funcs_CachingRecursiveIterator);
REGISTER_SPL_IMPLEMENTS(CachingRecursiveIterator, RecursiveIterator);
+ REGISTER_SPL_STD_CLASS_EX(IteratorIterator, spl_dual_it_new, spl_funcs_IteratorIterator);
+ REGISTER_SPL_ITERATOR(IteratorIterator);
+
+ REGISTER_SPL_STD_CLASS_EX(NoRewindIterator, spl_dual_it_new, spl_funcs_NoRewindIterator);
+ REGISTER_SPL_ITERATOR(NoRewindIterator);
+
REGISTER_SPL_INTERFACE(OuterIterator);
REGISTER_SPL_ITERATOR(OuterIterator);
REGISTER_SPL_IMPLEMENTS(CachingIterator, OuterIterator);
REGISTER_SPL_IMPLEMENTS(FilterIterator, OuterIterator);
REGISTER_SPL_IMPLEMENTS(LimitIterator, OuterIterator);
+ REGISTER_SPL_IMPLEMENTS(IteratorIterator, OuterIterator);
+ REGISTER_SPL_IMPLEMENTS(NoRewindIterator, OuterIterator);
return SUCCESS;
}
--- /dev/null
+--TEST--
+SPL: NoRewindIterator
+--SKIPIF--
+<?php if (!extension_loaded("spl")) print "skip"; ?>
+--FILE--
+<?php
+
+class ArrayIteratorEx extends ArrayIterator
+{
+ function rewind()
+ {
+ echo __METHOD__ . "\n";
+ parent::rewind();
+ }
+ function valid()
+ {
+ echo __METHOD__ . "\n";
+ return parent::valid();
+ }
+ function current()
+ {
+ echo __METHOD__ . "\n";
+ return parent::current();
+ }
+ function key()
+ {
+ echo __METHOD__ . "\n";
+ return parent::key();
+ }
+ function next()
+ {
+ echo __METHOD__ . "\n";
+ parent::next();
+ }
+}
+
+class NoRewindIteratorEx extends NoRewindIterator
+{
+ function rewind()
+ {
+ echo __METHOD__ . "\n";
+ parent::rewind();
+ }
+ function valid()
+ {
+ echo __METHOD__ . "\n";
+ return parent::valid();
+ }
+ function current()
+ {
+ echo __METHOD__ . "\n";
+ return parent::current();
+ }
+ function key()
+ {
+ echo __METHOD__ . "\n";
+ return parent::key();
+ }
+ function next()
+ {
+ echo __METHOD__ . "\n";
+ parent::next();
+ }
+}
+
+$it = new NoRewindIteratorEx(new ArrayIteratorEx(range(0,3)));
+
+echo "===0===\n";
+foreach ($it->getInnerIterator() as $v) {
+ var_dump($v);
+}
+
+echo "===1===\n";
+foreach ($it as $v) {
+ var_dump($v);
+}
+
+$pos =0;
+
+$it = new NoRewindIteratorEx(new ArrayIteratorEx(range(0,3)));
+
+echo "===2===\n";
+foreach ($it as $v) {
+ var_dump($v);
+ if ($pos++ > 1) {
+ break;
+ }
+}
+
+echo "===3===\n";
+foreach ($it as $v) {
+ var_dump($v);
+}
+
+echo "===4===\n";
+foreach ($it as $v) {
+ var_dump($v);
+}
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+===0===
+ArrayIteratorEx::rewind
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+int(0)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+int(1)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+int(2)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+int(3)
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+===1===
+NoRewindIteratorEx::rewind
+ArrayIteratorEx::valid
+NoRewindIteratorEx::valid
+===2===
+NoRewindIteratorEx::rewind
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+NoRewindIteratorEx::valid
+NoRewindIteratorEx::current
+int(0)
+NoRewindIteratorEx::next
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+NoRewindIteratorEx::valid
+NoRewindIteratorEx::current
+int(1)
+NoRewindIteratorEx::next
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+NoRewindIteratorEx::valid
+NoRewindIteratorEx::current
+int(2)
+===3===
+NoRewindIteratorEx::rewind
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+NoRewindIteratorEx::valid
+NoRewindIteratorEx::current
+int(2)
+NoRewindIteratorEx::next
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+ArrayIteratorEx::current
+ArrayIteratorEx::key
+NoRewindIteratorEx::valid
+NoRewindIteratorEx::current
+int(3)
+NoRewindIteratorEx::next
+ArrayIteratorEx::next
+ArrayIteratorEx::valid
+NoRewindIteratorEx::valid
+===4===
+NoRewindIteratorEx::rewind
+ArrayIteratorEx::valid
+NoRewindIteratorEx::valid
+===DONE===