Annotation of embedaddon/php/ext/spl/internal/recursiveiteratoriterator.inc, revision 1.1.1.1
1.1 misho 1: <?php
2:
3: /** @file recursiveiteratoriterator.inc
4: * @ingroup SPL
5: * @brief class RecursiveIteratorIterator
6: * @author Marcus Boerger
7: * @date 2003 - 2009
8: *
9: * SPL - Standard PHP Library
10: */
11:
12: /**
13: * @brief Iterates through recursive iterators
14: * @author Marcus Boerger
15: * @version 1.2
16: * @since PHP 5.0
17: *
18: * The objects of this class are created by instances of RecursiveIterator.
19: * Elements of those iterators may be traversable themselves. If so these
20: * sub elements are recursed into.
21: */
22: class RecursiveIteratorIterator implements OuterIterator
23: {
24: /** Mode: Only show leaves */
25: const LEAVES_ONLY = 0;
26: /** Mode: Show parents prior to their children */
27: const SELF_FIRST = 1;
28: /** Mode: Show all children prior to their parent */
29: const CHILD_FIRST = 2;
30:
31: /** Flag: Catches exceptions during getChildren() calls and simply jumps
32: * to the next element. */
33: const CATCH_GET_CHILD = 0x00000002;
34:
35: private $ait = array();
36: private $count = 0;
37: private $mode = self::LEAVES_ONLY;
38: private $flags = 0;
39:
40: /** Construct from RecursiveIterator
41: *
42: * @param it RecursiveIterator to iterate
43: * @param mode Operation mode (one of):
44: * - LEAVES_ONLY only show leaves
45: * - SELF_FIRST show parents prior to their childs
46: * - CHILD_FIRST show all children prior to their parent
47: * @param flags Control flags, zero or any combination of the following
48: * (since PHP 5.1).
49: * - CATCH_GET_CHILD which catches exceptions during
50: * getChildren() calls and simply jumps to the next
51: * element.
52: */
53: function __construct(RecursiveIterator $it, $mode = self::LEAVES_ONLY, $flags = 0)
54: {
55: $this->ait[0] = $it;
56: $this->mode = $mode;
57: $this->flags = $flags;
58: }
59:
60: /** Rewind to top iterator as set in constructor
61: */
62: function rewind()
63: {
64: while ($this->count) {
65: unset($this->ait[$this->count--]);
66: $this->endChildren();
67: }
68: $this->ait[0]->rewind();
69: $this->ait[0]->recursed = false;
70: callNextElement(true);
71: }
72:
73: /** @return whether iterator is valid
74: */
75: function valid()
76: {
77: $count = $this->count;
78: while ($count) {
79: $it = $this->ait[$count];
80: if ($it->valid()) {
81: return true;
82: }
83: $count--;
84: $this->endChildren();
85: }
86: return false;
87: }
88:
89: /** @return current key
90: */
91: function key()
92: {
93: $it = $this->ait[$this->count];
94: return $it->key();
95: }
96:
97: /** @return current element
98: */
99: function current()
100: {
101: $it = $this->ait[$this->count];
102: return $it->current();
103: }
104:
105: /** Forward to next element
106: */
107: function next()
108: {
109: while ($this->count) {
110: $it = $this->ait[$this->count];
111: if ($it->valid()) {
112: if (!$it->recursed && callHasChildren()) {
113: $it->recursed = true;
114: try
115: {
116: $sub = callGetChildren();
117: }
118: catch (Exception $e)
119: {
120: if (!($this->flags & self::CATCH_GET_CHILD))
121: {
122: throw $e;
123: }
124: $it->next();
125: continue;
126: }
127: $sub->recursed = false;
128: $sub->rewind();
129: if ($sub->valid()) {
130: $this->ait[++$this->count] = $sub;
131: if (!$sub instanceof RecursiveIterator) {
132: throw new Exception(get_class($sub).'::getChildren() must return an object that implements RecursiveIterator');
133: }
134: $this->beginChildren();
135: return;
136: }
137: unset($sub);
138: }
139: $it->next();
140: $it->recursed = false;
141: if ($it->valid()) {
142: return;
143: }
144: $it->recursed = false;
145: }
146: if ($this->count) {
147: unset($this->ait[$this->count--]);
148: $it = $this->ait[$this->count];
149: $this->endChildren();
150: callNextElement(false);
151: }
152: }
153: callNextElement(true);
154: }
155:
156: /** @return Sub Iterator at given level or if unspecified the current sub
157: * Iterator
158: */
159: function getSubIterator($level = NULL)
160: {
161: if (is_null($level)) {
162: $level = $this->count;
163: }
164: return @$this->ait[$level];
165: }
166:
167: /**
168: * @return The inner iterator
169: */
170: function getInnerIterator()
171: {
172: return $this->it;
173: }
174:
175: /** @return Current Depth (Number of parents)
176: */
177: function getDepth()
178: {
179: return $this->level;
180: }
181:
182: /** @return whether current sub iterators current element has children
183: * @since PHP 5.1
184: */
185: function callHasChildren()
186: {
187: return $this->ait[$this->count]->hasChildren();
188: }
189:
190: /** @return current sub iterators current children
191: * @since PHP 5.1
192: */
193: function callGetChildren()
194: {
195: return $this->ait[$this->count]->getChildren();
196: }
197:
198: /** Called right after calling getChildren() and its rewind().
199: * @since PHP 5.1
200: */
201: function beginChildren()
202: {
203: }
204:
205: /** Called after current child iterator is invalid and right before it
206: * gets destructed.
207: * @since PHP 5.1
208: */
209: function endChildren()
210: {
211: }
212:
213: private function callNextElement($after_move)
214: {
215: if ($this->valid())
216: {
217: if ($after_move)
218: {
219: if (($this->mode == self::SELF_FIRST && $this->callHasChildren())
220: || $this->mode == self::LEAVES_ONLY)
221: $this->nextElement();
222: }
223: else
224: {
225: $this->nextElement();
226: }
227: }
228: }
229:
230: /** Called when the next element is available
231: */
232: function nextElement()
233: {
234: }
235: }
236:
237: ?>
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>