appenditerator.inc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. /** @file appenditerator.inc
  3. * @ingroup SPL
  4. * @brief class AppendIterator
  5. * @author Marcus Boerger
  6. * @date 2003 - 2009
  7. *
  8. * SPL - Standard PHP Library
  9. */
  10. /** @ingroup SPL
  11. * @brief Iterator that iterates over several iterators one after the other
  12. * @author Marcus Boerger
  13. * @version 1.0
  14. * @since PHP 5.1
  15. */
  16. class AppendIterator implements OuterIterator
  17. {
  18. /** @internal array of inner iterators */
  19. private $iterators;
  20. /** Construct an empty AppendIterator
  21. */
  22. function __construct()
  23. {
  24. $this->iterators = new ArrayIterator();
  25. }
  26. /** Append an Iterator
  27. * @param $it Iterator to append
  28. *
  29. * If the current state is invalid but the appended iterator is valid
  30. * the AppendIterator itself becomes valid. However there will be no
  31. * call to $it->rewind(). Also if the current state is invalid the inner
  32. * ArrayIterator will be rewound und forwarded to the appended element.
  33. */
  34. function append(Iterator $it)
  35. {
  36. $this->iterators->append($it);
  37. }
  38. /** @return the current inner Iterator
  39. */
  40. function getInnerIterator()
  41. {
  42. return $this->iterators->current();
  43. }
  44. /** Rewind to the first element of the first inner Iterator.
  45. * @return void
  46. */
  47. function rewind()
  48. {
  49. $this->iterators->rewind();
  50. if ($this->iterators->valid())
  51. {
  52. $this->getInnerIterator()->rewind();
  53. }
  54. }
  55. /** @return whether the current element is valid
  56. */
  57. function valid()
  58. {
  59. return $this->iterators->valid() && $this->getInnerIterator()->valid();
  60. }
  61. /** @return the current value if it is valid or \c NULL
  62. */
  63. function current()
  64. {
  65. /* Using $this->valid() would be exactly the same; it would omit
  66. * the access to a non valid element in the inner iterator. Since
  67. * the user didn't respect the valid() return value false this
  68. * must be intended hence we go on. */
  69. return $this->iterators->valid() ? $this->getInnerIterator()->current() : NULL;
  70. }
  71. /** @return the current key if it is valid or \c NULL
  72. */
  73. function key()
  74. {
  75. return $this->iterators->valid() ? $this->getInnerIterator()->key() : NULL;
  76. }
  77. /** Move to the next element. If this means to another Iterator that
  78. * rewind that Iterator.
  79. * @return void
  80. */
  81. function next()
  82. {
  83. if (!$this->iterators->valid())
  84. {
  85. return; /* done all */
  86. }
  87. $this->getInnerIterator()->next();
  88. if ($this->getInnerIterator()->valid())
  89. {
  90. return; /* found valid element in current inner iterator */
  91. }
  92. $this->iterators->next();
  93. while ($this->iterators->valid())
  94. {
  95. $this->getInnerIterator()->rewind();
  96. if ($this->getInnerIterator()->valid())
  97. {
  98. return; /* found element as first elemet in another iterator */
  99. }
  100. $this->iterators->next();
  101. }
  102. }
  103. /** Aggregates the inner iterator
  104. */
  105. function __call($func, $params)
  106. {
  107. return call_user_func_array(array($this->getInnerIterator(), $func), $params);
  108. }
  109. }
  110. ?>