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