limititerator.inc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. /** @file limititerator.inc
  3. * @ingroup SPL
  4. * @brief class LimitIterator
  5. * @author Marcus Boerger
  6. * @date 2003 - 2009
  7. *
  8. * SPL - Standard PHP Library
  9. */
  10. /**
  11. * @brief Limited Iteration over another Iterator
  12. * @author Marcus Boerger
  13. * @version 1.1
  14. * @since PHP 5.0
  15. *
  16. * A class that starts iteration at a certain offset and only iterates over
  17. * a specified amount of elements.
  18. *
  19. * This class uses SeekableIterator::seek() if available and rewind() plus
  20. * a skip loop otehrwise.
  21. */
  22. class LimitIterator implements OuterIterator
  23. {
  24. private $it;
  25. private $offset;
  26. private $count;
  27. private $pos;
  28. /** Construct
  29. *
  30. * @param it Iterator to limit
  31. * @param offset Offset to first element
  32. * @param count Maximum number of elements to show or -1 for all
  33. */
  34. function __construct(Iterator $it, $offset = 0, $count = -1)
  35. {
  36. if ($offset < 0) {
  37. throw new exception('Parameter offset must be > 0');
  38. }
  39. if ($count < 0 && $count != -1) {
  40. throw new exception('Parameter count must either be -1 or a value greater than or equal to 0');
  41. }
  42. $this->it = $it;
  43. $this->offset = $offset;
  44. $this->count = $count;
  45. $this->pos = 0;
  46. }
  47. /** Seek to specified position
  48. * @param position offset to seek to (relative to beginning not offset
  49. * specified in constructor).
  50. * @throw exception when position is invalid
  51. */
  52. function seek($position) {
  53. if ($position < $this->offset) {
  54. throw new exception('Cannot seek to '.$position.' which is below offset '.$this->offset);
  55. }
  56. if ($position > $this->offset + $this->count && $this->count != -1) {
  57. throw new exception('Cannot seek to '.$position.' which is behind offset '.$this->offset.' plus count '.$this->count);
  58. }
  59. if ($this->it instanceof SeekableIterator) {
  60. $this->it->seek($position);
  61. $this->pos = $position;
  62. } else {
  63. while($this->pos < $position && $this->it->valid()) {
  64. $this->next();
  65. }
  66. }
  67. }
  68. /** Rewind to offset specified in constructor
  69. */
  70. function rewind()
  71. {
  72. $this->it->rewind();
  73. $this->pos = 0;
  74. $this->seek($this->offset);
  75. }
  76. /** @return whether iterator is valid
  77. */
  78. function valid() {
  79. return ($this->count == -1 || $this->pos < $this->offset + $this->count)
  80. && $this->it->valid();
  81. }
  82. /** @return current key
  83. */
  84. function key() {
  85. return $this->it->key();
  86. }
  87. /** @return current element
  88. */
  89. function current() {
  90. return $this->it->current();
  91. }
  92. /** Forward to nect element
  93. */
  94. function next() {
  95. $this->it->next();
  96. $this->pos++;
  97. }
  98. /** @return current position relative to zero (not to offset specified in
  99. * constructor).
  100. */
  101. function getPosition() {
  102. return $this->pos;
  103. }
  104. /**
  105. * @return The inner iterator
  106. */
  107. function getInnerIterator()
  108. {
  109. return $this->it;
  110. }
  111. /** Aggregate the inner iterator
  112. *
  113. * @param func Name of method to invoke
  114. * @param params Array of parameters to pass to method
  115. */
  116. function __call($func, $params)
  117. {
  118. return call_user_func_array(array($this->it, $func), $params);
  119. }
  120. }
  121. ?>