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