helly Sun Oct 31 13:43:00 2004 EDT Added files: /php-src/ext/spl/internal iteratoriterator.inc norewinditerator.inc /php-src/ext/spl/tests iterator_005.phpt iterator_006.phpt iterator_007.phpt
Removed files: /php-src/ext/spl/examples iteratoriterator.inc norewinditerator.inc Modified files: /php-src/ext/spl php_spl.c spl_iterators.c spl_iterators.h /php-src/ext/spl/tests array_014.phpt Log: - Implement classes IteratorIterator and NoRewindIterator in C
http://cvs.php.net/diff.php/php-src/ext/spl/php_spl.c?r1=1.30&r2=1.31&ty=u Index: php-src/ext/spl/php_spl.c diff -u php-src/ext/spl/php_spl.c:1.30 php-src/ext/spl/php_spl.c:1.31 --- php-src/ext/spl/php_spl.c:1.30 Fri Oct 29 16:12:54 2004 +++ php-src/ext/spl/php_spl.c Sun Oct 31 13:43:00 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_spl.c,v 1.30 2004/10/29 20:12:54 helly Exp $ */ +/* $Id: php_spl.c,v 1.31 2004/10/31 18:43:00 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -167,7 +167,9 @@ 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(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); \ SPL_ADD_CLASS(OuterIterator, z_list, sub, allow, ce_flags); \ SPL_ADD_CLASS(ParentIterator, z_list, sub, allow, ce_flags); \ SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, sub, allow, ce_flags); \ http://cvs.php.net/diff.php/php-src/ext/spl/spl_iterators.c?r1=1.44&r2=1.45&ty=u Index: php-src/ext/spl/spl_iterators.c diff -u php-src/ext/spl/spl_iterators.c:1.44 php-src/ext/spl/spl_iterators.c:1.45 --- php-src/ext/spl/spl_iterators.c:1.44 Sat Oct 30 15:12:14 2004 +++ php-src/ext/spl/spl_iterators.c Sun Oct 31 13:43:00 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.c,v 1.44 2004/10/30 19:12:14 helly Exp $ */ +/* $Id: spl_iterators.c,v 1.45 2004/10/31 18:43:00 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -45,6 +45,8 @@ 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) @@ -565,6 +567,8 @@ } #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; @@ -605,6 +609,22 @@ 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); @@ -728,6 +748,7 @@ } /* {{{ proto void ParentIterator::rewind() + proto void IteratorIterator::rewind() Rewind the iterator */ SPL_METHOD(dual_it, rewind) @@ -741,6 +762,8 @@ /* {{{ 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) { @@ -755,6 +778,8 @@ 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) { @@ -776,6 +801,8 @@ 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) { @@ -791,6 +818,8 @@ } /* }}} */ /* {{{ proto void ParentIterator::next() + proto void IteratorIterator::next() + proto void NoRewindIterator::next() Move the iterator forward */ SPL_METHOD(dual_it, next) { @@ -1273,7 +1302,7 @@ 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[] = { @@ -1325,8 +1354,7 @@ 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[] = { @@ -1336,6 +1364,65 @@ {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) @@ -1452,6 +1539,12 @@ 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); @@ -1459,6 +1552,8 @@ 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; } http://cvs.php.net/diff.php/php-src/ext/spl/spl_iterators.h?r1=1.11&r2=1.12&ty=u Index: php-src/ext/spl/spl_iterators.h diff -u php-src/ext/spl/spl_iterators.h:1.11 php-src/ext/spl/spl_iterators.h:1.12 --- php-src/ext/spl/spl_iterators.h:1.11 Fri Oct 29 16:12:55 2004 +++ php-src/ext/spl/spl_iterators.h Sun Oct 31 13:43:00 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.h,v 1.11 2004/10/29 20:12:55 helly Exp $ */ +/* $Id: spl_iterators.h,v 1.12 2004/10/31 18:43:00 helly Exp $ */ #ifndef SPL_ITERATORS_H #define SPL_ITERATORS_H @@ -33,6 +33,8 @@ extern zend_class_entry *spl_ce_CachingIterator; 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; PHP_MINIT_FUNCTION(spl_iterators); @@ -43,7 +45,9 @@ DIT_Default = 0, DIT_LimitIterator, DIT_CachingIterator, - DIT_CachingRecursiveIterator + DIT_CachingRecursiveIterator, + DIT_IteratorIterator, + DIT_NoRewindIterator, } dual_it_type; enum { http://cvs.php.net/diff.php/php-src/ext/spl/tests/array_014.phpt?r1=1.2&r2=1.3&ty=u Index: php-src/ext/spl/tests/array_014.phpt diff -u php-src/ext/spl/tests/array_014.phpt:1.2 php-src/ext/spl/tests/array_014.phpt:1.3 --- php-src/ext/spl/tests/array_014.phpt:1.2 Wed Sep 29 15:36:30 2004 +++ php-src/ext/spl/tests/array_014.phpt Sun Oct 31 13:43:00 2004 @@ -1,25 +1,21 @@ --TEST-- -SPL: ArrayIterator::seek() +SPL: ArrayItaerator/Object and IteratorIterator --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php -$it = new ArrayIterator(range(0,10)); -var_dump($it->count()); -$it->seek(5); -var_dump($it->current()); -$it->seek(4); -var_dump($it->current()); -$it->seek(-1); -var_dump($it->current()); -$it->seek(12); -var_dump($it->current()); +$it = new ArrayIterator(range(0,3)); -$pos = 0; -foreach($it as $v) +foreach(new IteratorIterator($it) as $v) +{ + var_dump($v); +} + +$it = new ArrayObject(range(0,3)); + +foreach(new IteratorIterator($it) as $v) { - $it->seek($pos++); var_dump($v); } @@ -27,20 +23,12 @@ ===DONE=== <?php exit(0); ?> --EXPECTF-- -int(11) -int(5) -int(4) int(0) -NULL +int(1) +int(2) +int(3) int(0) int(1) int(2) int(3) -int(4) -int(5) -int(6) -int(7) -int(8) -int(9) -int(10) ===DONE=== http://cvs.php.net/co.php/php-src/ext/spl/internal/iteratoriterator.inc?r=1.1&p=1 Index: php-src/ext/spl/internal/iteratoriterator.inc +++ php-src/ext/spl/internal/iteratoriterator.inc <?php /** @file iteratoriterator.inc * @ingroup SPL * @brief class IteratorIterator * @author Marcus Boerger * @date 2003 - 2004 * * SPL - Standard PHP Library */ /** @ingroup SPL * @brief Basic Iterator wrapper */ class IteratorIterator implements OuterIterator { /** Construct an IteratorIterator from an Iterator or an IteratorAggregate. * * Classes that only implement Traversable can be wrapped only after * converting class IteratorIterator into c code. */ function __construct(Traversable $iterator) { if ($iterator instanceof IteratorAggregate) { $iterator = $iterator->getIterator(); } if ($iterator instanceof Iterator) { $this->iterator = $iterator; } else { throw new Exception("Classes that only implement Traversable can be wrapped only after converting class IteratorItaerator into c code"); } } /** \return the inner iterator as passed to the constructor */ function getInnerIterator() { return $this->iterator; } /** \return whether the iterator is valid */ function valid() { return $this->iterator->valid(); } /** \return current key */ function key() { return $this->iterator->key(); } /** \return current value */ function current() { return $this->iterator->current(); } /** forward to next element */ function next() { return $this->iterator->next(); } /** rewind to the first element */ function rewind() { return $this->iterator->rewind(); } /** The inner iterator must be private because when this class will be * converted to c code it won't no longer be available. */ private $iterator; } ?> http://cvs.php.net/co.php/php-src/ext/spl/internal/norewinditerator.inc?r=1.1&p=1 Index: php-src/ext/spl/internal/norewinditerator.inc +++ php-src/ext/spl/internal/norewinditerator.inc <?php /** @file norewinditerator.inc * @ingroup SPL * @brief class NoRewindIterator * @author Marcus Boerger * @date 2003 - 2004 * * SPL - Standard PHP Library */ /** @ingroup Examples * @brief An Iterator wrapper that doesn't call rewind * @author Marcus Boerger * @version 1.1 * */ class NoRewindIterator extends IteratorIterator { /** Simply prevent execution of inner iterators rewind(). */ function rewind() { // nothing to do } } ?> http://cvs.php.net/co.php/php-src/ext/spl/tests/iterator_005.phpt?r=1.1&p=1 Index: php-src/ext/spl/tests/iterator_005.phpt +++ php-src/ext/spl/tests/iterator_005.phpt --TEST-- SPL: IteratorIterator and ArrayIterator/Object --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php class ArrayIteratorEx extends ArrayIterator { function rewind() { echo __METHOD__ . "\n"; return parent::rewind(); } } $it = new ArrayIteratorEx(range(0,3)); foreach(new IteratorIterator($it) as $v) { var_dump($v); } class ArrayObjectEx extends ArrayObject { function getIterator() { echo __METHOD__ . "\n"; return parent::getIterator(); } } $it = new ArrayObjectEx(range(0,3)); foreach(new IteratorIterator($it) as $v) { var_dump($v); } ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- ArrayIteratorEx::rewind int(0) int(1) int(2) int(3) ArrayObjectEx::getIterator int(0) int(1) int(2) int(3) ===DONE=== http://cvs.php.net/co.php/php-src/ext/spl/tests/iterator_006.phpt?r=1.1&p=1 Index: php-src/ext/spl/tests/iterator_006.phpt +++ php-src/ext/spl/tests/iterator_006.phpt --TEST-- SPL: IteratorIterator and SimpleXMlElement --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php $root = simplexml_load_string('<?xml version="1.0"?> <root> <child>Hello</child> <child>World</child> </root> '); foreach (new IteratorIterator($root->child) as $child) { echo $child."\n"; } ?> ===DONE=== <?php exit(0); ?> --EXPECT-- Hello World ===DONE=== http://cvs.php.net/co.php/php-src/ext/spl/tests/iterator_007.phpt?r=1.1&p=1 Index: php-src/ext/spl/tests/iterator_007.phpt +++ php-src/ext/spl/tests/iterator_007.phpt --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===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php