iteratoriterator.inc 2.9 KB

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