helly           Thu May 25 17:44:59 2006 UTC

  Added files:                 
    /php-src/ext/spl/examples   dualiterator.inc 
                                recursivedualiterator.inc 
    /php-src/ext/spl/examples/tests     dualiterator_001.phpt 
  Log:
  - Add DualIterator and RecursiveDualIterator to examples including a test
  
  

http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/examples/dualiterator.inc?view=markup&rev=1.1
Index: php-src/ext/spl/examples/dualiterator.inc
+++ php-src/ext/spl/examples/dualiterator.inc
<?php

/** @file DualIterator.inc
 * @ingroup Examples
 * @brief class DualIterator
 * @author  Marcus Boerger
 * @date    2003 - 2006
 *
 * SPL - Standard PHP Library
 */

/** @ingroup Examples
 * @brief   Synchronous iteration over two iterators
 * @author  Marcus Boerger
 * @version 1.1
 */
class DualIterator implements Iterator
{
        const CURRENT_LHS   = 0x01;
        const CURRENT_RHS   = 0x02;
        const CURRENT_ARRAY = 0x03;
        const CURRENT_0     = 0x00;

        const KEY_LHS   = 0x10;
        const KEY_RHS   = 0x20;
        const KEY_ARRAY = 0x30;
        const KEY_0     = 0x00;
        
        const DEFAULT_FLAGS = 0x33;
        
        private $lhs;
        private $rhs;
        private $flags;

        /** construct iterator from two iterators
         *
         * @param lhs   Left  Hand Side Iterator
         * @param rhs   Right Hand Side Iterator
         * @param flags iteration flags
         */
        function __construct(Iterator $lhs, Iterator $rhs, 
                                        $flags = 0x33 
/*DualIterator::DEFAULT_FLAGS*/)
        {
                $this->lhs   = $lhs;
                $this->rhs   = $rhs;
                $this->flags = $flags;
        }

        /** @return Left Hand Side Iterator
         */
        function getLHS()
        {
                return $this->lhs;
        }

        /** @return Right Hand Side Iterator
         */
        function getRHS()
        {
                return $this->rhs;
        }

        /** @param flags new flags
         */
        function setFlags($flags)
        {
                $this->flags = $flags;
        }

        /** @return current flags
         */
        function getFlags()
        {
                return $this->flags;
        }

        /** rewind both inner iterators
         */     
        function rewind()
        {
                $this->lhs->rewind();
                $this->rhs->rewind();   
        }

        /** @return whether both inner iterators are valid
         */     
        function valid()
        {
                return $this->lhs->valid() && $this->rhs->valid();      
        }

        /** @return current value depending on CURRENT_* flags
         */     
        function current()
        {
                switch($this->flags & 0x0F)
                {
                default:
                case self::CURRENT_ARRAY:
                        return array($this->lhs->current(), 
$this->rhs->current());
                case self::CURRENT_LHS:
                        return $this->lhs->current();
                case self::CURRENT_RHS:
                        return $this->rhs->current();
                case self::CURRENT_0:
                        return NULL;
                }
        }

        /** @return current value depending on KEY_* flags
         */     
        function key()
        {
                switch($this->flags & 0xF0)
                {
                default:
                case self::CURRENT_ARRAY:
                        return array($this->lhs->key(), $this->rhs->key());
                case self::CURRENT_LHS:
                        return $this->lhs->key();
                case self::CURRENT_RHS:
                        return $this->rhs->key();
                case self::CURRENT_0:
                        return NULL;
                }
        }

        /** move both inner iterators forward
         */     
        function next()
        {
                $this->lhs->next();
                $this->rhs->next();
        }

        /** @return whether both inner iterators are valid and have identical 
         * current and key values or both are non valid.
         */
        function areIdentical()
        {
                return $this->valid()
                     ? $this->lhs->current() === $this->rhs->current()
                        && $this->lhs->key()     === $this->rhs->key()
                         : $this->lhs->valid()   ==  $this->rhs->valid();
        }

        /** @return whether both inner iterators are valid and have equal 
current 
         * and key values or both are non valid.
         */
        function areEqual()
        {
                return $this->valid()
                     ? $this->lhs->current() ==  $this->rhs->current()
                        && $this->lhs->key()     ==  $this->rhs->key()
                         : $this->lhs->valid()   ==  $this->rhs->valid();
        }

        /** Compare two iterators
         *
         * @param lhs   Left  Hand Side Iterator
         * @param rhs   Right Hand Side Iterator
         * @param identical whether to use areEqual() or areIdentical()
         * @return whether both iterators are equal/identical
         *
         * @note If one implements RecursiveIterator the other must do as well.
         *       And if both do then a recursive comparison is being used.
         */
        static function compareIterators(Iterator $lhs, Iterator $rhs, 
                                         $identical = false)
        {
                if ($lhs instanceof RecursiveIterator)
                {
                        if ($rhs instanceof RecursiveIterator)
                        {
                                $it = new RecursiveDualIterator($lhs, $rhs, 
                                                                self::CURRENT_0 
| self::KEY_0);
                        }
                        else
                        {
                                return false;
                        }
                }
                else
                {
                        $it = new DualIterator($lhs, $rhs, self::CURRENT_0 | 
self::KEY_0);
                }

                if ($identical)
                {
                        foreach(new RecursiveIteratorIterator($it) as $n)
                        {
                                if (!$it->areIdentical())
                                {
                                        return false;
                                }
                        }
                }
                else
                {
                        foreach($it as $n)
                        {
                                if (!$it->areEqual())
                                {
                                        return false;
                                }
                        }
                }
                return $identical ? $it->areIdentical() : $it->areEqual();
        }
}

?>

http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/examples/recursivedualiterator.inc?view=markup&rev=1.1
Index: php-src/ext/spl/examples/recursivedualiterator.inc
+++ php-src/ext/spl/examples/recursivedualiterator.inc
<?php

/** @file recursivedualiterator.inc
 * @ingroup Examples
 * @brief class RecursiveDualIterator
 * @author  Marcus Boerger
 * @date    2003 - 2006
 *
 * SPL - Standard PHP Library
 */

/** @ingroup Examples
 * @brief   Synchronous iteration over two recursive iterators
 * @author  Marcus Boerger
 * @version 1.0
 */
class RecursiveDualIterator extends DualIterator implements RecursiveIterator
{
        private $ref;

        /** construct iterator from two iterators
         *
         * @param lhs   Left  Hand Side Iterator
         * @param rhs   Right Hand Side Iterator
         * @param flags iteration flags
         */
        function __construct(RecursiveIterator $lhs, RecursiveIterator $rhs, 
                                $flags = 0x33 /*DualIterator::DEFAULT_FLAGS*/)
        {
                parent::__construct($lhs, $rhs, $flags);
        }

        /** @return whether both LHS and RHS have children
         */
        function hasChildren()
        {
                return $this->getLHS()->hasChildren() && 
$this->getRHS()->hasChildren();        
        }

        /** @return new RecursiveDualIterator (late binding) for the two inner 
         * iterators current children.
         */
        function getChildren()
        {
                if (empty($this->ref))
                {
                        $this->ref = new ReflectionClass($this);
                }
                return $this->ref->newInstance(
                                        $this->getLHS()->current(), 
$this->getRHS()->current(), $this->flags);
        }

        /** @return whether both inner iterators are valid, have same 
hasChildren()
         * state and identical current and key values or both are non valid.
         */
        function areIdentical()
        {
                return $this->getLHS()->hasChildren() === 
$this->getRHS()->hasChildren()
                        && parent::areIdentical();
        }

        /** @return whether both inner iterators are valid, have same 
hasChildren()
         * state and equal current and key values or both are invalid.
         */
        function areEqual()
        {
                return $this->getLHS()->hasChildren() === 
$this->getRHS()->hasChildren()
                        && parent::areEqual();
        }
}

?>

http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/examples/tests/dualiterator_001.phpt?view=markup&rev=1.1
Index: php-src/ext/spl/examples/tests/dualiterator_001.phpt
+++ php-src/ext/spl/examples/tests/dualiterator_001.phpt
--TEST--
SPL: DualIterator
--SKIPIF--
<?php if (!extension_loaded("spl")) print "skip"; ?>
--FILE--
<?php

function spl_examples_autoload($classname)
{
        include(dirname(__FILE__) . '/../' . strtolower($classname) . '.inc');
}

spl_autoload_register('spl_examples_autoload');

function test($a, $b, $identical = false)
{
        var_dump(DualIterator::compareIterators(
                                        new RecursiveArrayIterator($a), 
                                        new RecursiveArrayIterator($b), 
                                        $identical));
}

test(array(1,2,3), array(1,2,3));
test(array(1,2,3), array(1,2));
test(array(1,array(21,22),3), array(1,array(21,22),3));
test(array(1,array(21,22),3), array(1,array(21,22,23),3));
test(array(1,array(21,22),3), array(1,array(21,22,3)));
test(array(1,array(21,22),3), array(1,array(21),array(22),3));

?>
===DONE===
--EXPECT--
bool(true)
bool(false)
bool(true)
bool(false)
bool(false)
bool(false)
===DONE===

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to