Annotation of embedaddon/php/ext/spl/internal/recursiveiteratoriterator.inc, revision 1.1

1.1     ! misho       1: <?php
        !             2: 
        !             3: /** @file recursiveiteratoriterator.inc
        !             4:  * @ingroup SPL
        !             5:  * @brief class RecursiveIteratorIterator
        !             6:  * @author  Marcus Boerger
        !             7:  * @date    2003 - 2009
        !             8:  *
        !             9:  * SPL - Standard PHP Library
        !            10:  */
        !            11: 
        !            12: /**
        !            13:  * @brief   Iterates through recursive iterators
        !            14:  * @author  Marcus Boerger
        !            15:  * @version 1.2
        !            16:  * @since PHP 5.0
        !            17:  *
        !            18:  * The objects of this class are created by instances of RecursiveIterator. 
        !            19:  * Elements of those iterators may be traversable themselves. If so these 
        !            20:  * sub elements are recursed into.
        !            21:  */
        !            22: class RecursiveIteratorIterator implements OuterIterator
        !            23: {
        !            24:        /** Mode: Only show leaves */
        !            25:        const LEAVES_ONLY               = 0;
        !            26:        /** Mode: Show parents prior to their children */
        !            27:        const SELF_FIRST                = 1;
        !            28:        /** Mode: Show all children prior to their parent */
        !            29:        const CHILD_FIRST               = 2;
        !            30: 
        !            31:        /** Flag: Catches exceptions during getChildren() calls and simply jumps
        !            32:         * to the next element. */
        !            33:        const CATCH_GET_CHILD   = 0x00000002;
        !            34: 
        !            35:        private $ait = array();
        !            36:        private $count = 0;
        !            37:        private $mode  = self::LEAVES_ONLY;
        !            38:        private $flags = 0;
        !            39: 
        !            40:        /** Construct from RecursiveIterator
        !            41:         *
        !            42:         * @param it     RecursiveIterator to iterate
        !            43:         * @param mode   Operation mode (one of):
        !            44:         *               - LEAVES_ONLY only show leaves
        !            45:         *               - SELF_FIRST  show parents prior to their childs
        !            46:         *               - CHILD_FIRST show all children prior to their parent
        !            47:         * @param flags  Control flags, zero or any combination of the following
        !            48:         *               (since PHP 5.1).
        !            49:         *               - CATCH_GET_CHILD which catches exceptions during
        !            50:         *                 getChildren() calls and simply jumps to the next 
        !            51:         *                 element.
        !            52:         */
        !            53:        function __construct(RecursiveIterator $it, $mode = self::LEAVES_ONLY, $flags = 0)
        !            54:        {
        !            55:                $this->ait[0] = $it;
        !            56:                $this->mode   = $mode;
        !            57:                $this->flags  = $flags;
        !            58:        }
        !            59: 
        !            60:        /** Rewind to top iterator as set in constructor
        !            61:         */
        !            62:        function rewind()
        !            63:        {
        !            64:                while ($this->count) {
        !            65:                        unset($this->ait[$this->count--]);
        !            66:                        $this->endChildren();
        !            67:                }
        !            68:                $this->ait[0]->rewind();
        !            69:                $this->ait[0]->recursed = false;
        !            70:                callNextElement(true);
        !            71:        }
        !            72:        
        !            73:        /** @return whether iterator is valid
        !            74:         */
        !            75:        function valid()
        !            76:        {
        !            77:                $count = $this->count;
        !            78:                while ($count) {
        !            79:                        $it = $this->ait[$count];
        !            80:                        if ($it->valid()) {
        !            81:                                return true;
        !            82:                        }
        !            83:                        $count--;
        !            84:                        $this->endChildren();
        !            85:                }
        !            86:                return false;
        !            87:        }
        !            88:        
        !            89:        /** @return current key
        !            90:         */
        !            91:        function key()
        !            92:        {
        !            93:                $it = $this->ait[$this->count];
        !            94:                return $it->key();
        !            95:        }
        !            96:        
        !            97:        /** @return current element
        !            98:         */
        !            99:        function current()
        !           100:        {
        !           101:                $it = $this->ait[$this->count];
        !           102:                return $it->current();
        !           103:        }
        !           104:        
        !           105:        /** Forward to next element
        !           106:         */
        !           107:        function next()
        !           108:        {
        !           109:                while ($this->count) {
        !           110:                        $it = $this->ait[$this->count];
        !           111:                        if ($it->valid()) {
        !           112:                                if (!$it->recursed && callHasChildren()) {
        !           113:                                        $it->recursed = true;
        !           114:                                        try
        !           115:                                        {
        !           116:                                                $sub = callGetChildren();
        !           117:                                        }
        !           118:                                        catch (Exception $e)
        !           119:                                        {
        !           120:                                                if (!($this->flags & self::CATCH_GET_CHILD))
        !           121:                                                {
        !           122:                                                        throw $e;
        !           123:                                                }
        !           124:                                                $it->next();
        !           125:                                                continue;
        !           126:                                        }
        !           127:                                        $sub->recursed = false;
        !           128:                                        $sub->rewind();
        !           129:                                        if ($sub->valid()) {
        !           130:                                                $this->ait[++$this->count] = $sub;
        !           131:                                                if (!$sub instanceof RecursiveIterator) {
        !           132:                                                        throw new Exception(get_class($sub).'::getChildren() must return an object that implements RecursiveIterator');
        !           133:                                                }
        !           134:                                                $this->beginChildren();
        !           135:                                                return;
        !           136:                                        }
        !           137:                                        unset($sub);
        !           138:                                }
        !           139:                                $it->next();
        !           140:                                $it->recursed = false;
        !           141:                                if ($it->valid()) {
        !           142:                                        return;
        !           143:                                }
        !           144:                                $it->recursed = false;
        !           145:                        }
        !           146:                        if ($this->count) {
        !           147:                                unset($this->ait[$this->count--]);
        !           148:                                $it = $this->ait[$this->count];
        !           149:                                $this->endChildren();
        !           150:                                callNextElement(false);
        !           151:                        }
        !           152:                }
        !           153:                callNextElement(true);
        !           154:        }
        !           155: 
        !           156:        /** @return Sub Iterator at given level or if unspecified the current sub 
        !           157:         *          Iterator
        !           158:         */
        !           159:        function getSubIterator($level = NULL)
        !           160:        {
        !           161:                if (is_null($level)) {
        !           162:                        $level = $this->count;
        !           163:                }
        !           164:                return @$this->ait[$level];
        !           165:        }
        !           166: 
        !           167:        /**
        !           168:         * @return The inner iterator
        !           169:         */     
        !           170:        function getInnerIterator()
        !           171:        {
        !           172:                return $this->it;
        !           173:        }
        !           174: 
        !           175:        /** @return Current Depth (Number of parents)
        !           176:         */
        !           177:        function getDepth()
        !           178:        {
        !           179:                return $this->level;
        !           180:        }
        !           181: 
        !           182:        /** @return whether current sub iterators current element has children
        !           183:         * @since PHP 5.1
        !           184:         */
        !           185:        function callHasChildren()
        !           186:        {
        !           187:                return $this->ait[$this->count]->hasChildren();
        !           188:        }
        !           189: 
        !           190:        /** @return current sub iterators current children
        !           191:         * @since PHP 5.1
        !           192:         */
        !           193:        function callGetChildren()
        !           194:        {
        !           195:                return $this->ait[$this->count]->getChildren();
        !           196:        }
        !           197: 
        !           198:        /** Called right after calling getChildren() and its rewind().
        !           199:         * @since PHP 5.1
        !           200:         */
        !           201:        function beginChildren()
        !           202:        {
        !           203:        }
        !           204:        
        !           205:        /** Called after current child iterator is invalid and right before it
        !           206:         * gets destructed.
        !           207:         * @since PHP 5.1
        !           208:         */
        !           209:        function endChildren()
        !           210:        {
        !           211:        }
        !           212: 
        !           213:        private function callNextElement($after_move)
        !           214:        {
        !           215:                if ($this->valid())
        !           216:                {
        !           217:                        if ($after_move)
        !           218:                        {
        !           219:                                if (($this->mode == self::SELF_FIRST && $this->callHasChildren())
        !           220:                                ||   $this->mode == self::LEAVES_ONLY)
        !           221:                                $this->nextElement();
        !           222:                        }
        !           223:                        else
        !           224:                        {
        !           225:                                $this->nextElement();
        !           226:                        }
        !           227:                }
        !           228:        }
        !           229:        
        !           230:        /** Called when the next element is available
        !           231:         */
        !           232:        function nextElement()
        !           233:        {
        !           234:        }
        !           235: }
        !           236: 
        !           237: ?>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>