From: Marcus Boerger Date: Sun, 31 Oct 2004 19:49:18 +0000 (+0000) Subject: - Implement InfiniteIterator in C X-Git-Tag: RELEASE_0_2~786 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=de3a8ea3e132db2c4edc0e2f4b4468fbcced26e8;p=php - Implement InfiniteIterator in C --- diff --git a/ext/spl/examples/infiniteiterator.inc b/ext/spl/examples/infiniteiterator.inc deleted file mode 100755 index 7ff9d4472b..0000000000 --- a/ext/spl/examples/infiniteiterator.inc +++ /dev/null @@ -1,102 +0,0 @@ -$key) - { - echo "$val=>$key\n"; - } - \endverbatim - */ -class InfiniteIterator implements OuterIterator -{ - /** @internal - * The inner Iterator. */ - private $it; - - /** Construct from another Iterator. - * @param $it the inner Iterator. - */ - function __construct(Iterator $it) - { - $this->it = $it; - } - - /** @return the inner iterator - */ - function getInnerIterator() - { - return $this->it; - } - - /** Rewind the inner iterator. - * @return void - */ - function rewind() - { - $this->getInnerIterator()->rewind(); - } - - /** @return whether the current element is valid - */ - function valid() - { - return $this->getInnerIterator()->valid(); - } - - /** @return the current value - */ - function current() - { - return $this->getInnerIterator()->current(); - } - - /** @return the current key - */ - function key() - { - return $this->getInnerIterator()->key(); - } - - /** Move the inner Iterator forward to its next element or rewind it. - * @return void - */ - function next() - { - $this->getInnerIterator()->next(); - if (!$this->getInnerIterator()->valid()) - { - $this->getInnerIterator()->rewind(); - } - } - - /** Aggregates the inner iterator - */ - function __call($func, $params) - { - return call_user_func_array(array($this->getInnerIterator(), $func), $params); - } -} - -?> \ No newline at end of file diff --git a/ext/spl/internal/infiniteiterator.inc b/ext/spl/internal/infiniteiterator.inc new file mode 100755 index 0000000000..aaece36e6f --- /dev/null +++ b/ext/spl/internal/infiniteiterator.inc @@ -0,0 +1,47 @@ +$key) + { + echo "$val=>$key\n"; + } + \endverbatim + */ +class InfiniteIterator extends IteratorIterator +{ + /** Move the inner Iterator forward to its next element or rewind it. + * @return void + */ + function next() + { + $this->getInnerIterator()->next(); + if (!$this->getInnerIterator()->valid()) + { + $this->getInnerIterator()->rewind(); + } + } +} + +?> \ No newline at end of file diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index b0011106b1..3fcdd49ef7 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -167,6 +167,7 @@ PHP_FUNCTION(class_implements) SPL_ADD_CLASS(CachingRecursiveIterator, z_list, sub, allow, ce_flags); \ SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags); \ SPL_ADD_CLASS(FilterIterator, z_list, sub, allow, ce_flags); \ + SPL_ADD_CLASS(InfiniteIterator, z_list, sub, allow, ce_flags); \ SPL_ADD_CLASS(IteratorIterator, z_list, sub, allow, ce_flags); \ SPL_ADD_CLASS(LimitIterator, z_list, sub, allow, ce_flags); \ SPL_ADD_CLASS(NoRewindIterator, z_list, sub, allow, ce_flags); \ diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 8f5d9c2afa..410bbb6d8d 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -47,6 +47,7 @@ zend_class_entry *spl_ce_CachingRecursiveIterator; zend_class_entry *spl_ce_OuterIterator; zend_class_entry *spl_ce_IteratorIterator; zend_class_entry *spl_ce_NoRewindIterator; +zend_class_entry *spl_ce_InfiniteIterator; function_entry spl_funcs_RecursiveIterator[] = { SPL_ABSTRACT_ME(RecursiveIterator, hasChildren, NULL) @@ -1440,7 +1441,37 @@ static zend_function_entry spl_funcs_NoRewindIterator[] = { {NULL, NULL, NULL} }; -zend_object_iterator_funcs spl_norewind_it_iterator_funcs; +/* {{{ proto InfiniteIterator::__construct(Iterator it) + Create an iterator from another iterator */ +SPL_METHOD(InfiniteIterator, __construct) +{ + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_iterator, DIT_InfiniteIterator); +} /* }}} */ + +/* {{{ proto InfiniteIterator::next() + Prevent a call to inner iterators rewind() (internally the current data will be fetched if valid()) */ +SPL_METHOD(InfiniteIterator, next) +{ + spl_dual_it_object *intern; + + intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + + spl_dual_it_next(intern, 1 TSRMLS_CC); + if (spl_dual_it_valid(intern TSRMLS_CC) == SUCCESS) { + spl_dual_it_fetch(intern, 0 TSRMLS_CC); + } else { + spl_dual_it_rewind(intern TSRMLS_CC); + if (spl_dual_it_valid(intern TSRMLS_CC) == SUCCESS) { + spl_dual_it_fetch(intern, 0 TSRMLS_CC); + } + } + +} /* }}} */ + +static zend_function_entry spl_funcs_InfiniteIterator[] = { + SPL_ME(InfiniteIterator, __construct, arginfo_norewind_it___construct, ZEND_ACC_PUBLIC) + SPL_ME(InfiniteIterator, next, NULL, ZEND_ACC_PUBLIC) +}; /* {{{ array iterator_to_array(IteratorAggregate it) Copy the iterator into an array */ @@ -1575,6 +1606,8 @@ PHP_MINIT_FUNCTION(spl_iterators) REGISTER_SPL_IMPLEMENTS(IteratorIterator, OuterIterator); REGISTER_SPL_IMPLEMENTS(NoRewindIterator, OuterIterator); + REGISTER_SPL_SUB_CLASS_EX(InfiniteIterator, IteratorIterator, spl_dual_it_new, spl_funcs_InfiniteIterator); + return SUCCESS; } /* }}} */ diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index 22da632d55..5a7391e520 100755 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -35,6 +35,7 @@ extern zend_class_entry *spl_ce_CachingRecursiveIterator; extern zend_class_entry *spl_ce_OuterIterator; extern zend_class_entry *spl_ce_IteratorIterator; extern zend_class_entry *spl_ce_NoRewindIterator; +extern zend_class_entry *spl_ce_InfiniteIterator; PHP_MINIT_FUNCTION(spl_iterators); @@ -48,6 +49,7 @@ typedef enum { DIT_CachingRecursiveIterator, DIT_IteratorIterator, DIT_NoRewindIterator, + DIT_InfiniteIterator, } dual_it_type; enum { diff --git a/ext/spl/tests/iterator_008.phpt b/ext/spl/tests/iterator_008.phpt new file mode 100755 index 0000000000..5f3c7d89df --- /dev/null +++ b/ext/spl/tests/iterator_008.phpt @@ -0,0 +1,91 @@ +--TEST-- +SPL: InfiniteIterator +--SKIPIF-- + +--FILE-- + 5) { + break; + } +} + +?> +===DONE=== + +--EXPECT-- +ArrayIteratorEx::rewind +ArrayIteratorEx::valid +ArrayIteratorEx::current +ArrayIteratorEx::key +int(0) +ArrayIteratorEx::next +ArrayIteratorEx::valid +ArrayIteratorEx::current +ArrayIteratorEx::key +int(1) +ArrayIteratorEx::next +ArrayIteratorEx::valid +ArrayIteratorEx::current +ArrayIteratorEx::key +int(2) +ArrayIteratorEx::next +ArrayIteratorEx::valid +ArrayIteratorEx::rewind +ArrayIteratorEx::valid +ArrayIteratorEx::current +ArrayIteratorEx::key +int(0) +ArrayIteratorEx::next +ArrayIteratorEx::valid +ArrayIteratorEx::current +ArrayIteratorEx::key +int(1) +ArrayIteratorEx::next +ArrayIteratorEx::valid +ArrayIteratorEx::current +ArrayIteratorEx::key +int(2) +ArrayIteratorEx::next +ArrayIteratorEx::valid +ArrayIteratorEx::rewind +ArrayIteratorEx::valid +ArrayIteratorEx::current +ArrayIteratorEx::key +int(0) +===DONE===