Annotation of embedaddon/php/ext/spl/internal/multipleiterator.inc, revision 1.1.1.2

1.1       misho       1: <?php
                      2: /** @file multipleiterator.inc
                      3:  * @ingroup SPL
                      4:  * @brief class MultipleIterator
                      5:  * @author  Johannes Schlueter
                      6:  * @author  Marcus Boerger
                      7:  * @date    2008 - 2009
                      8:  *
                      9:  * SPL - Standard PHP Library
                     10:  */
                     11: 
                     12: /** @ingroup SPL
                     13:  * @brief   Iterator that iterates over several iterators one after the other
                     14:  * @author  Johannes Schlueter
                     15:  * @author  Marcus Boerger
                     16:  * @version 1.0
                     17:  * @since PHP 5.3
                     18:  */
                     19: class MultipleIterator implements Iterator
                     20: {
                     21:        /** Inner Iterators */
                     22:        private $iterators;
                     23: 
                     24:        /** Flags: const MIT_* */
                     25:        private $flags;
                     26: 
                     27:        /** do not require all sub iterators to be valid in iteration */
                     28:        const MIT_NEED_ANY = 0;
                     29: 
                     30:        /** require all sub iterators to be valid in iteration */
                     31:        const MIT_NEED_ALL  = 1;
                     32: 
                     33:        /** keys are created from sub iterators position */
                     34:        const MIT_KEYS_NUMERIC  = 0;
                     35: 
                     36:        /** keys are created from sub iterators associated infromation */
                     37:        const MIT_KEYS_ASSOC  = 2;
                     38: 
                     39:        /** Construct a new empty MultipleIterator
                     40:        * @param flags MIT_* flags
                     41:        */
                     42:        public function __construct($flags = self::MIT_NEED_ALL|self::MIT_KEYS_NUMERIC)
                     43:        {
                     44:                $this->iterators = new SplObjectStorage();
                     45:                $this->flags = $flags;
                     46:        }
                     47: 
                     48:        /** @return current flags MIT_* */
                     49:        public function getFlags()
                     50:        {
                     51:                return $this->flags;
                     52:        }
                     53: 
                     54:        /** @param $flags new flags. */
                     55:        public function setFlags($flags)
                     56:        {
                     57:                $this->flags = $flags;
                     58:        }
                     59: 
                     60:        /** @param $iter new Iterator to attach.
                     61:        * @param $inf associative info forIteraotr, must be NULL, integer or string
                     62:        *
                     63:        * @throws IllegalValueException if a inf is none of NULL, integer or string
                     64:        * @throws IllegalValueException if a inf is already an associated info
                     65:        */
                     66:        public function attachIterator(Iterator $iter, $inf = NULL)
                     67:        {
                     68: 
                     69:                if (!is_null($inf))
                     70:                {
                     71:                        if (!is_int($inf) && !is_string($inf))
                     72:                        {
                     73:                                throw new IllegalValueException('Inf must be NULL, integer or string');
                     74:                        }
                     75:                        foreach($this->iterators as $iter)
                     76:                        {
                     77:                                if ($inf == $this->iterators->getInfo())
                     78:                                {
                     79:                                        throw new IllegalValueException('Key duplication error');
                     80:                                }
                     81:                        }
                     82:                }
                     83:                $this->iterators->attach($iter, $inf);
                     84:        }
                     85: 
                     86:        /** @param $iter attached Iterator that should be detached. */
                     87:        public function detachIterator(Iterator $iter)
                     88:        {
                     89:                $this->iterators->detach($iter);
                     90:        }
                     91: 
                     92:        /** @param $iter Iterator to check
                     93:        * @return whether $iter is attached or not
                     94:        */
                     95:        public function containsIterator(Iterator $iter)
                     96:        {
                     97:                return $this->iterator->contains($iter);
                     98:        }
                     99: 
                    100:        /** @return number of attached Iterator instances. */
                    101:        public function countIterators()
                    102:        {
                    103:                return $this->iterators->count();
                    104:        }
                    105: 
                    106:        /** Rewind all attached Iterator instances. */
                    107:        public function rewind()
                    108:        {
                    109:                foreach($this->iterators as $iter)
                    110:                {
                    111:                        $iter->rewind();
                    112:                }
                    113:        }
                    114: 
                    115:        /**
                    116:        * @return whether all or one sub iterator is valid depending on flags.
                    117:        * In mode MIT_NEED_ALL we expect all sub iterators to be valid and
                    118:        * return flase on the first non valid one. If that flag is not set we
                    119:        * return true on the first valid sub iterator found. If no Iterator
                    120:        * is attached, we always return false.
                    121:        */
                    122:        public function valid()
                    123:        {
                    124:                if (!sizeof($this->iterators)) {
                    125:                        return false;
                    126:                }
                    127:                // The following code is an optimized version that executes as few
                    128:                // valid() calls as necessary and that only checks the flags once.
                    129:                $expect = $this->flags & self::MIT_NEED_ALL ? true : false;
                    130:                foreach($this->iterators as $iter)
                    131:                {
                    132:                        if ($expect != $iter->valid())
                    133:                        {
                    134:                                return !$expect;
                    135:                        }
                    136:                }
                    137:                return $expect;
                    138:        }
                    139: 
                    140:        /** Move all attached Iterator instances forward. That is invoke
                    141:        * their next() method regardless of their state.
                    142:        */
                    143:        public function next()
                    144:        {
                    145:                foreach($this->iterators as $iter)
                    146:                {
                    147:                        $iter->next();
                    148:                }
                    149:        }
                    150: 
                    151:        /** @return false if no sub Iterator is attached and an array of
                    152:        * all registered Iterator instances current() result.
                    153:        * @throws RuntimeException      if mode MIT_NEED_ALL is set and at least one
                    154:        *                               attached Iterator is not valid().
                    155:        * @throws IllegalValueException if a key is NULL and MIT_KEYS_ASSOC is set.
                    156:        */
                    157:        public function current()
                    158:        {
                    159:                if (!sizeof($this->iterators))
                    160:                {
                    161:                        return false;
                    162:                }
                    163:                $retval = array();
                    164:                foreach($this->iterators as $iter)
                    165:                {
1.1.1.2 ! misho     166:                        if ($iter->valid())
1.1       misho     167:                        {
                    168:                                if ($this->flags & self::MIT_KEYS_ASSOC)
                    169:                                {
                    170:                                        $key = $this->iterators->getInfo();
                    171:                                        if (is_null($key))
                    172:                                        {
                    173:                                                throw new IllegalValueException('Sub-Iterator is associated with NULL');
                    174:                                        }
                    175:                                        $retval[$key] = $iter->current();
                    176:                                }
                    177:                                else
                    178:                                {
                    179:                                        $retval[] = $iter->current();
                    180:                                }
                    181:                        }
                    182:                        else if ($this->flags & self::MIT_NEED_ALL)
                    183:                        {
                    184:                                throw new RuntimeException('Called current() with non valid sub iterator');
                    185:                        }
                    186:                        else
                    187:                        {
                    188:                                $retval[] = NULL;
                    189:                        }
                    190:                }
                    191:                return $retval;
                    192:        }
                    193: 
                    194:        /** @return false if no sub Iterator is attached and an array of
                    195:        * all registered Iterator instances key() result.
                    196:        * @throws LogicException if mode MIT_NEED_ALL is set and at least one
                    197:        *         attached Iterator is not valid().
                    198:        */
                    199:        public function key()
                    200:        {
                    201:                if (!sizeof($this->iterators))
                    202:                {
                    203:                        return false;
                    204:                }
                    205:                $retval = array();
                    206:                foreach($this->iterators as $iter)
                    207:                {
1.1.1.2 ! misho     208:                        if ($iter->valid())
1.1       misho     209:                        {
                    210:                                $retval[] = $iter->key();
                    211:                        }
                    212:                        else if ($this->flags & self::MIT_NEED_ALL)
                    213:                        {
                    214:                                throw new LogicException('Called key() with non valid sub iterator');
                    215:                        }
                    216:                        else
                    217:                        {
                    218:                                $retval[] = NULL;
                    219:                        }
                    220:                }
                    221:                return $retval;
                    222:        }
                    223: }

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