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