From: Marcus Boerger Date: Sun, 31 Oct 2004 18:43:00 +0000 (+0000) Subject: - Implement classes IteratorIterator and NoRewindIterator in C X-Git-Tag: RELEASE_0_2~789 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=90012aa3cc2b95a05a2e9f780823c8d217186aea;p=php - Implement classes IteratorIterator and NoRewindIterator in C --- diff --git a/ext/spl/examples/iteratoriterator.inc b/ext/spl/internal/iteratoriterator.inc similarity index 86% rename from ext/spl/examples/iteratoriterator.inc rename to ext/spl/internal/iteratoriterator.inc index 8ed8c6fcd7..03cbc9f876 100755 --- a/ext/spl/examples/iteratoriterator.inc +++ b/ext/spl/internal/iteratoriterator.inc @@ -1,7 +1,16 @@ 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 @@ static INLINE void spl_dual_it_next(spl_dual_it_object *intern, int do_free TSRM } /* {{{ proto void ParentIterator::rewind() + proto void IteratorIterator::rewind() Rewind the iterator */ SPL_METHOD(dual_it, rewind) @@ -741,6 +762,8 @@ 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) { @@ -755,6 +778,8 @@ 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) { @@ -776,6 +801,8 @@ 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) { @@ -791,6 +818,8 @@ 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) { @@ -1273,7 +1302,7 @@ SPL_METHOD(CachingIterator, __toString) 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 @@ SPL_METHOD(CachingRecursiveIterator, getChildren) 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 @@ 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) @@ -1452,6 +1539,12 @@ PHP_MINIT_FUNCTION(spl_iterators) 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 @@ PHP_MINIT_FUNCTION(spl_iterators) 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; } diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index 3459b0f94b..22da632d55 100755 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -33,6 +33,8 @@ extern zend_class_entry *spl_ce_LimitIterator; 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 @@ typedef enum { DIT_Default = 0, DIT_LimitIterator, DIT_CachingIterator, - DIT_CachingRecursiveIterator + DIT_CachingRecursiveIterator, + DIT_IteratorIterator, + DIT_NoRewindIterator, } dual_it_type; enum { diff --git a/ext/spl/tests/array_014.phpt b/ext/spl/tests/array_014.phpt index 6cd560fe30..d4ea0ab39a 100755 --- a/ext/spl/tests/array_014.phpt +++ b/ext/spl/tests/array_014.phpt @@ -1,25 +1,21 @@ --TEST-- -SPL: ArrayIterator::seek() +SPL: ArrayItaerator/Object and IteratorIterator --SKIPIF-- --FILE-- 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 @@ foreach($it as $v) ===DONE=== --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=== diff --git a/ext/spl/tests/iterator_005.phpt b/ext/spl/tests/iterator_005.phpt new file mode 100755 index 0000000000..4aae600169 --- /dev/null +++ b/ext/spl/tests/iterator_005.phpt @@ -0,0 +1,54 @@ +--TEST-- +SPL: IteratorIterator and ArrayIterator/Object +--SKIPIF-- + +--FILE-- + +===DONE=== + +--EXPECTF-- +ArrayIteratorEx::rewind +int(0) +int(1) +int(2) +int(3) +ArrayObjectEx::getIterator +int(0) +int(1) +int(2) +int(3) +===DONE=== diff --git a/ext/spl/tests/iterator_006.phpt b/ext/spl/tests/iterator_006.phpt new file mode 100755 index 0000000000..855741c711 --- /dev/null +++ b/ext/spl/tests/iterator_006.phpt @@ -0,0 +1,24 @@ +--TEST-- +SPL: IteratorIterator and SimpleXMlElement +--SKIPIF-- + +--FILE-- + + + Hello + World + +'); + +foreach (new IteratorIterator($root->child) as $child) { + echo $child."\n"; +} +?> +===DONE=== + +--EXPECT-- +Hello +World +===DONE=== diff --git a/ext/spl/tests/iterator_007.phpt b/ext/spl/tests/iterator_007.phpt new file mode 100755 index 0000000000..e40e2a245a --- /dev/null +++ b/ext/spl/tests/iterator_007.phpt @@ -0,0 +1,174 @@ +--TEST-- +SPL: NoRewindIterator +--SKIPIF-- + +--FILE-- +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=== + +--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===