1<?php 2 3/** @file iteratoriterator.inc 4 * @ingroup SPL 5 * @brief class IteratorIterator 6 * @author Marcus Boerger 7 * @date 2003 - 2009 8 * 9 * SPL - Standard PHP Library 10 */ 11 12/** @ingroup SPL 13 * @brief Basic Iterator wrapper 14 * @since PHP 5.1 15 * 16 * This iterator wrapper allows to convert anything that is traversable into 17 * an Iterator. It is very important to understand that most classes that do 18 * not implement Iterator have their reasone to. Most likely they do not allow 19 * the full Iterator feature set. If so you need to provide techniques to 20 * prevent missuse. If you do not you must expect exceptions or fatal errors. 21 * 22 * It is also possible to derive the class and implement IteratorAggregate by 23 * downcasting the instances returned in getIterator. See the following 24 * example (assuming BaseClass implements Traversable): 25 \code 26 class SomeClass extends BaseClass implements IteratorAggregate 27 { 28 function getIterator() 29 { 30 return new IteratorIterator($this, 'BaseClass'); 31 } 32 } 33 \endcode 34 * 35 * As you can see in the example this approach requires that the class to 36 * downcast to is actually a base class of the specified iterator to wrap. 37 * Omitting the downcast in the above example would result in an endless loop 38 * since IteratorIterator::__construct() would call SomeClass::getIterator(). 39 */ 40class IteratorIterator implements OuterIterator 41{ 42 /** Construct an IteratorIterator from an Iterator or an IteratorAggregate. 43 * 44 * @param iterator inner iterator 45 * @param classname optional class the iterator has to be downcasted to 46 */ 47 function __construct(Traversable $iterator, $classname = null) 48 { 49 if ($iterator instanceof IteratorAggregate) 50 { 51 $iterator = $iterator->getIterator(); 52 } 53 if ($iterator instanceof Iterator) 54 { 55 $this->iterator = $iterator; 56 } 57 else 58 { 59 throw new Exception("Classes that only implement Traversable can be wrapped only after converting class IteratorIterator into c code"); 60 } 61 } 62 63 /** \return the inner iterator as passed to the constructor 64 */ 65 function getInnerIterator() 66 { 67 return $this->iterator; 68 } 69 70 /** \return whether the iterator is valid 71 */ 72 function valid() 73 { 74 return $this->iterator->valid(); 75 } 76 77 /** \return current key 78 */ 79 function key() 80 { 81 return $this->iterator->key(); 82 } 83 84 /** \return current value 85 */ 86 function current() 87 { 88 return $this->iterator->current(); 89 } 90 91 /** forward to next element 92 */ 93 function next() 94 { 95 return $this->iterator->next(); 96 } 97 98 /** rewind to the first element 99 */ 100 function rewind() 101 { 102 return $this->iterator->rewind(); 103 } 104 105 /** Aggregate the inner iterator 106 * 107 * @param func Name of method to invoke 108 * @param params Array of parameters to pass to method 109 */ 110 function __call($func, $params) 111 { 112 return call_user_func_array(array($this->iterator, $func), $params); 113 } 114 115 /** The inner iterator must be private because when this class will be 116 * converted to c code it won't no longer be available. 117 */ 118 private $iterator; 119} 120 121?> 122