]> granicus.if.org Git - php/commitdiff
- Implement InfiniteIterator in C
authorMarcus Boerger <helly@php.net>
Sun, 31 Oct 2004 19:49:18 +0000 (19:49 +0000)
committerMarcus Boerger <helly@php.net>
Sun, 31 Oct 2004 19:49:18 +0000 (19:49 +0000)
ext/spl/examples/infiniteiterator.inc [deleted file]
ext/spl/internal/infiniteiterator.inc [new file with mode: 0755]
ext/spl/php_spl.c
ext/spl/spl_iterators.c
ext/spl/spl_iterators.h
ext/spl/tests/iterator_008.phpt [new file with mode: 0755]

diff --git a/ext/spl/examples/infiniteiterator.inc b/ext/spl/examples/infiniteiterator.inc
deleted file mode 100755 (executable)
index 7ff9d44..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-
-/** @file infiniteiterator.inc
- * @ingroup Examples
- * @brief class InfiniteIterator
- * @author  Marcus Boerger
- * @date    2003 - 2004
- *
- * SPL - Standard PHP Library
- */
-
-/** @ingroup Examples
- * @brief   An infinite Iterator
- * @author  Marcus Boerger
- * @version 1.0
- *
- * This Iterator takes another Iterator and infinitvely iterates it by
- * rewinding it when its end is reached.
- *
- * \note Even an InfiniteIterator stops if its inner Iterator is empty.
- *
- \verbatim
- $it       = new ArrayIterator(array(1,2,3));
- $infinite = new InfiniteIterator($it);
- $limit    = new LimitIterator($infinite, 0, 5);
- foreach($limit as $val=>$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 (executable)
index 0000000..aaece36
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+
+/** @file infiniteiterator.inc
+ * @ingroup SPL
+ * @brief class InfiniteIterator
+ * @author  Marcus Boerger
+ * @date    2003 - 2004
+ *
+ * SPL - Standard PHP Library
+ */
+
+/** @ingroup Examples
+ * @brief   An infinite Iterator
+ * @author  Marcus Boerger
+ * @version 1.1
+ *
+ * This Iterator takes another Iterator and infinitvely iterates it by
+ * rewinding it when its end is reached.
+ *
+ * \note Even an InfiniteIterator stops if its inner Iterator is empty.
+ *
+ \verbatim
+ $it       = new ArrayIterator(array(1,2,3));
+ $infinite = new InfiniteIterator($it);
+ $limit    = new LimitIterator($infinite, 0, 5);
+ foreach($limit as $val=>$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
index b0011106b196194c7f20864c67c70640436a71f9..3fcdd49ef7682747b85e8e1614ee16d43bdb6285 100755 (executable)
@@ -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); \
index 8f5d9c2afa3b2223d9c417460d8232efff6dc95e..410bbb6d8ddb46064daca5dfcfc8401867768286 100755 (executable)
@@ -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;
 }
 /* }}} */
index 22da632d55d9afd254aab8c88548cc9f42ea93bc..5a7391e520e49a680d719bc4094dabf6f9bf388a 100755 (executable)
@@ -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 (executable)
index 0000000..5f3c7d8
--- /dev/null
@@ -0,0 +1,91 @@
+--TEST--
+SPL: InfiniteIterator
+--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();
+       }
+}
+
+$it = new InfiniteIterator(new ArrayIteratorEx(range(0,2)));
+
+$pos =0;
+
+foreach ($it as $v) {
+       var_dump($v);
+       if ($pos++ > 5) {
+               break;
+       }
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--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===