Annotation of embedaddon/php/ext/spl/internal/recursiveiteratoriterator.inc, revision 1.1.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>