]> granicus.if.org Git - php/commitdiff
- Before we later run into BC trouble we split flags into two params mode
authorMarcus Boerger <helly@php.net>
Thu, 28 Jul 2005 21:09:02 +0000 (21:09 +0000)
committerMarcus Boerger <helly@php.net>
Thu, 28 Jul 2005 21:09:02 +0000 (21:09 +0000)
  and flags now before branching for 5.1.

ext/spl/internal/recursiveiteratoriterator.inc
ext/spl/spl_iterators.c
ext/spl/tests/iterator_023.phpt [new file with mode: 0755]

index 66cffc48752f804a42f70e0c0cce2d6c36672d36..d77f9850da401190f1f3d6c312a39c769c81b924 100755 (executable)
@@ -12,7 +12,7 @@
 define('RIT_LEAVES_ONLY', 0);
 define('RIT_SELF_FIRST',  1);
 define('RIT_CHILD_FIRST', 2);
-define('RIT_CATCH_GET_CHILD', 256);
+define('RIT_CATCH_GET_CHILD', 2);
 
 /**
  * @brief   Iterates through recursive iterators
@@ -34,20 +34,20 @@ class RecursiveIteratorIterator implements OuterIterator
        /** Construct from RecursiveIterator
         *
         * @param it     RecursiveIterator to iterate
-        * @param flags  Operation mode (one of):
+        * @param mode   Operation mode (one of):
         *               - RIT_LEAVES_ONLY only show leaves
         *               - RIT_SELF_FIRST  show parents prior to their childs
         *               - RIT_CHILD_FIRST show all childs prior to their parent
-        *               or'ed with the following flags:
+        * @param flags  Control flags, zero or any combination of the following
         *               - RIT_CATCH_GET_CHILD which catches exceptions during
         *                 getChildren() calls and simply jumps to the next 
         *                 element.
         */
-       function __construct(RecursiveIterator $it, $flags)
+       function __construct(RecursiveIterator $it, $mode = RIT_LEAVES_ONLY, $flags = 0)
        {
                $this->ait[0] = $it;
-               $this->mode   = $flags & 0xFF;
-               $this->flags  = $flags & ~0xFF;
+               $this->mode   = $mode;
+               $this->flags  = $flags;
        }
 
        /** Rewind to top iterator as set in constructor
index 2924b909666ffbfb5a4e6e7f2def74266b6b2807..34e6886d9725a500d98e8f87399366ce04d82a36 100755 (executable)
@@ -65,8 +65,7 @@ typedef enum {
        RIT_CHILD_FIRST = 2
 } RecursiveIteratorMode;
 
-#define RIT_MODE_MASK       0x000000FF
-#define RIT_CATCH_GET_CHILD 0x00000100
+#define RIT_CATCH_GET_CHILD CIT_CATCH_GET_CHILD
 
 typedef enum {
        RS_NEXT  = 0,
@@ -333,7 +332,7 @@ zend_object_iterator_funcs spl_recursive_it_iterator_funcs = {
        spl_recursive_it_rewind
 };
 
-/* {{{ proto RecursiveIteratorIterator::__construct(RecursiveIterator|IteratorAggregate it [, int flags = RIT_LEAVES_ONLY]) throws InvalidArgumentException
+/* {{{ proto RecursiveIteratorIterator::__construct(RecursiveIterator|IteratorAggregate it [, int mode = RIT_LEAVES_ONLY [, int flags = 0]]) throws InvalidArgumentException
    Creates a RecursiveIteratorIterator from a RecursiveIterator. */
 SPL_METHOD(RecursiveIteratorIterator, __construct)
 {
@@ -341,11 +340,11 @@ SPL_METHOD(RecursiveIteratorIterator, __construct)
        spl_recursive_it_object   *intern;
        zval                      *iterator;
        zend_class_entry          *ce_iterator;
-       long                       mode = RIT_LEAVES_ONLY;
+       long                       mode = RIT_LEAVES_ONLY, flags = 0;
 
        php_set_error_handling(EH_THROW, spl_ce_InvalidArgumentException TSRMLS_CC);
 
-       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "o|l", &iterator, &mode) == SUCCESS) {
+       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "o|ll", &iterator, &mode, &flags) == SUCCESS) {
                if (instanceof_function(Z_OBJCE_P(iterator), zend_ce_aggregate TSRMLS_CC)) {
                        zval *aggregate = iterator;
                        zend_call_method_with_0_params(&aggregate, Z_OBJCE_P(aggregate), &Z_OBJCE_P(aggregate)->iterator_funcs.zf_new_iterator, "getiterator", &iterator);
@@ -362,8 +361,8 @@ SPL_METHOD(RecursiveIteratorIterator, __construct)
        intern = (spl_recursive_it_object*)zend_object_store_get_object(object TSRMLS_CC);
        intern->iterators = emalloc(sizeof(spl_sub_iterator));
        intern->level = 0;
-       intern->mode = mode & RIT_MODE_MASK;
-       intern->flags = mode & ~RIT_MODE_MASK;
+       intern->mode = mode;
+       intern->flags = flags;
        intern->ce = Z_OBJCE_P(object);
        zend_hash_find(&intern->ce->function_table, "callhaschildren", sizeof("callHasChildren"), (void **) &intern->callHasChildren);
        if (intern->callHasChildren->common.scope == spl_ce_RecursiveIteratorIterator) {
diff --git a/ext/spl/tests/iterator_023.phpt b/ext/spl/tests/iterator_023.phpt
new file mode 100755 (executable)
index 0000000..46aa26a
--- /dev/null
@@ -0,0 +1,198 @@
+--TEST--
+SPL: RecursiveIteratorIterator and catch getChildren
+--FILE--
+<?php
+
+class RecursiveArrayIterator extends ArrayIterator implements RecursiveIterator
+{
+       function hasChildren()
+       {
+               return is_array($this->current());
+       }
+       
+       function getChildren()
+       {
+               echo __METHOD__ . "\n";
+               return $this->current();
+       }
+
+       function valid()
+       {
+               if (!parent::valid())
+               {
+                       echo __METHOD__ . " = false\n";
+                       return false;
+               }
+               else
+               {
+                       return true;
+               }
+       }
+}
+
+class RecursiveArrayIteratorIterator extends RecursiveIteratorIterator
+{
+       private $max_depth;
+       private $over = 0;
+       private $skip = false;
+
+       function __construct($it, $max_depth)
+       {
+               $this->max_depth = $max_depth;
+               parent::__construct($it, RIT_LEAVES_ONLY, RIT_CATCH_GET_CHILD);
+       }
+
+       function rewind()
+       {
+               echo __METHOD__ . "\n";
+               $this->skip = false;
+               parent::rewind();
+       }
+
+       function valid()
+       {
+               echo __METHOD__ . "\n";
+               if ($this->skip)
+               {
+                       $this->skip = false;
+                       $this->next();
+               }
+               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();
+       }
+
+       function callHasChildren()
+       {
+               $this->skip = false;
+               $has = parent::callHasChildren();
+               $res = $this->getDepth() < $this->max_depth && $has;
+               echo __METHOD__ . "(".$this->getDepth().") = ".($res?"yes":"no")."/".($has?"yes":"no")."\n";
+               if ($has && !$res)
+               {
+                       $this->over++;
+                       if ($this->over == 2) {
+                               $this->skip = true;
+                       }
+               }
+               return $res;
+       }
+       
+       function callGetChildren()
+       {
+               if ($this->over == 2)
+               {
+                       echo __METHOD__ . "(throw)\n";
+                       throw new Exception("Thrown in callGetChildren()");
+               }
+               echo __METHOD__ . "(ok:{$this->over})\n";
+               return new RecursiveArrayIterator($this->current());
+       }
+
+       function beginChildren()
+       {
+               echo __METHOD__ . "(".$this->getDepth().")\n";
+       }
+
+       function endChildren()
+       {
+               echo __METHOD__ . "(".$this->getDepth().")\n";
+       }
+}
+
+try
+{
+       foreach(new RecursiveArrayIteratorIterator(new RecursiveArrayIterator(array("a", array("ba", array("bba", "bbb"), array(array("bcaa"), array("bcba"))), array("ca"), "d")), 2) as $k=>$v)
+       {
+               if (is_array($v)) $v = join('',$v);
+               echo "$k=>$v\n";
+       }
+}
+catch(UnexpectedValueException $e)
+{
+       echo $e->getMessage() . "\n";
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+RecursiveArrayIteratorIterator::rewind
+RecursiveArrayIteratorIterator::callHasChildren(0) = no/no
+RecursiveArrayIteratorIterator::valid
+RecursiveArrayIteratorIterator::current
+RecursiveArrayIteratorIterator::key
+0=>a
+RecursiveArrayIteratorIterator::next
+RecursiveArrayIteratorIterator::callHasChildren(0) = yes/yes
+RecursiveArrayIteratorIterator::callGetChildren(ok:0)
+RecursiveArrayIteratorIterator::current
+RecursiveArrayIteratorIterator::beginChildren(1)
+RecursiveArrayIteratorIterator::callHasChildren(1) = no/no
+RecursiveArrayIteratorIterator::valid
+RecursiveArrayIteratorIterator::current
+RecursiveArrayIteratorIterator::key
+0=>ba
+RecursiveArrayIteratorIterator::next
+RecursiveArrayIteratorIterator::callHasChildren(1) = yes/yes
+RecursiveArrayIteratorIterator::callGetChildren(ok:0)
+RecursiveArrayIteratorIterator::current
+RecursiveArrayIteratorIterator::beginChildren(2)
+RecursiveArrayIteratorIterator::callHasChildren(2) = no/no
+RecursiveArrayIteratorIterator::valid
+RecursiveArrayIteratorIterator::current
+RecursiveArrayIteratorIterator::key
+0=>bba
+RecursiveArrayIteratorIterator::next
+RecursiveArrayIteratorIterator::callHasChildren(2) = no/no
+RecursiveArrayIteratorIterator::valid
+RecursiveArrayIteratorIterator::current
+RecursiveArrayIteratorIterator::key
+1=>bbb
+RecursiveArrayIteratorIterator::next
+RecursiveArrayIterator::valid = false
+RecursiveArrayIteratorIterator::endChildren(2)
+RecursiveArrayIteratorIterator::callHasChildren(1) = yes/yes
+RecursiveArrayIteratorIterator::callGetChildren(ok:0)
+RecursiveArrayIteratorIterator::current
+RecursiveArrayIteratorIterator::beginChildren(2)
+RecursiveArrayIteratorIterator::callHasChildren(2) = no/yes
+RecursiveArrayIteratorIterator::valid
+RecursiveArrayIteratorIterator::current
+RecursiveArrayIteratorIterator::key
+0=>bcaa
+RecursiveArrayIteratorIterator::next
+RecursiveArrayIteratorIterator::callHasChildren(2) = no/yes
+RecursiveArrayIteratorIterator::valid
+RecursiveArrayIteratorIterator::next
+RecursiveArrayIterator::valid = false
+RecursiveArrayIteratorIterator::endChildren(2)
+RecursiveArrayIterator::valid = false
+RecursiveArrayIteratorIterator::endChildren(1)
+RecursiveArrayIteratorIterator::callHasChildren(0) = yes/yes
+RecursiveArrayIteratorIterator::callGetChildren(throw)
+RecursiveArrayIteratorIterator::callHasChildren(0) = no/no
+RecursiveArrayIteratorIterator::current
+RecursiveArrayIteratorIterator::key
+3=>d
+RecursiveArrayIteratorIterator::next
+RecursiveArrayIterator::valid = false
+RecursiveArrayIteratorIterator::valid
+RecursiveArrayIterator::valid = false
+===DONE===