|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 using System; |
|
18 using System.Collections; |
|
19 using System.Collections.Generic; |
|
20 |
|
21 namespace SymbianTree |
|
22 { |
|
23 #region SymNodeEnumeratorSiblings |
|
24 public class SymNodeEnumeratorSiblings : IEnumerator<SymNode>, IEnumerable<SymNode> |
|
25 { |
|
26 #region Constructors |
|
27 public SymNodeEnumeratorSiblings( SymNode aNodeToEnumerate ) |
|
28 { |
|
29 iNode = aNodeToEnumerate; |
|
30 } |
|
31 #endregion |
|
32 |
|
33 #region From IEnumerable<SymNode> |
|
34 IEnumerator<SymNode> IEnumerable<SymNode>.GetEnumerator() |
|
35 { |
|
36 return this; |
|
37 } |
|
38 |
|
39 IEnumerator IEnumerable.GetEnumerator() |
|
40 { |
|
41 return this; |
|
42 } |
|
43 #endregion |
|
44 |
|
45 #region IEnumerator Members |
|
46 void IEnumerator.Reset() |
|
47 { |
|
48 iCurrentNode = null; |
|
49 } |
|
50 |
|
51 object IEnumerator.Current |
|
52 { |
|
53 get |
|
54 { |
|
55 return iCurrentNode; |
|
56 } |
|
57 } |
|
58 |
|
59 bool IEnumerator.MoveNext() |
|
60 { |
|
61 if ( iCurrentNode == null ) |
|
62 { |
|
63 iCurrentNode = iNode; |
|
64 } |
|
65 else |
|
66 { |
|
67 iCurrentNode = iCurrentNode.Next; |
|
68 } |
|
69 |
|
70 bool haveMoreNodes = ( iCurrentNode.Next != null ); |
|
71 return haveMoreNodes; |
|
72 } |
|
73 #endregion |
|
74 |
|
75 #region From IEnumerator<SymNode> |
|
76 SymNode IEnumerator<SymNode>.Current |
|
77 { |
|
78 get { return iCurrentNode; } |
|
79 } |
|
80 #endregion |
|
81 |
|
82 #region From IDisposable |
|
83 public void Dispose() |
|
84 { |
|
85 } |
|
86 #endregion |
|
87 |
|
88 #region Data members |
|
89 private readonly SymNode iNode; |
|
90 private SymNode iCurrentNode = null; |
|
91 #endregion |
|
92 } |
|
93 #endregion |
|
94 |
|
95 #region SymNodeEnumeratorChildren |
|
96 public class SymNodeEnumeratorChildren : IEnumerator<SymNode>, IEnumerable<SymNode> |
|
97 { |
|
98 #region Constructors |
|
99 public SymNodeEnumeratorChildren( SymNode aNodeToEnumerate ) |
|
100 { |
|
101 iNode = aNodeToEnumerate; |
|
102 } |
|
103 #endregion |
|
104 |
|
105 #region From IEnumerable<SymNode> |
|
106 IEnumerator<SymNode> IEnumerable<SymNode>.GetEnumerator() |
|
107 { |
|
108 return this; |
|
109 } |
|
110 |
|
111 IEnumerator IEnumerable.GetEnumerator() |
|
112 { |
|
113 return this; |
|
114 } |
|
115 #endregion |
|
116 |
|
117 #region IEnumerator Members |
|
118 void IEnumerator.Reset() |
|
119 { |
|
120 iEnumeratorIndex = -1; |
|
121 } |
|
122 |
|
123 object IEnumerator.Current |
|
124 { |
|
125 get |
|
126 { |
|
127 return iNode.Children[ iEnumeratorIndex ]; |
|
128 } |
|
129 } |
|
130 |
|
131 bool IEnumerator.MoveNext() |
|
132 { |
|
133 return ( ++iEnumeratorIndex < iNode.ChildCount ); |
|
134 } |
|
135 #endregion |
|
136 |
|
137 #region From IEnumerator<SymNode> |
|
138 SymNode IEnumerator<SymNode>.Current |
|
139 { |
|
140 get { return iNode.Children[ iEnumeratorIndex ]; } |
|
141 } |
|
142 #endregion |
|
143 |
|
144 #region From IDisposable |
|
145 public void Dispose() |
|
146 { |
|
147 } |
|
148 #endregion |
|
149 |
|
150 #region Data members |
|
151 private readonly SymNode iNode; |
|
152 private int iEnumeratorIndex = -1; |
|
153 #endregion |
|
154 } |
|
155 #endregion |
|
156 |
|
157 #region SymNodeEnumeratorTreeChildrenFirst |
|
158 public class SymNodeEnumeratorTreeChildrenFirst : IEnumerator<SymNode>, IEnumerable<SymNode> |
|
159 { |
|
160 #region Constructors |
|
161 public SymNodeEnumeratorTreeChildrenFirst( SymNode aStartingNode ) |
|
162 { |
|
163 iStartingNode = aStartingNode; |
|
164 } |
|
165 #endregion |
|
166 |
|
167 #region From IEnumerable<SymNode> |
|
168 IEnumerator<SymNode> IEnumerable<SymNode>.GetEnumerator() |
|
169 { |
|
170 return this; |
|
171 } |
|
172 |
|
173 IEnumerator IEnumerable.GetEnumerator() |
|
174 { |
|
175 return this; |
|
176 } |
|
177 #endregion |
|
178 |
|
179 #region IEnumerator Members |
|
180 void IEnumerator.Reset() |
|
181 { |
|
182 iCurrentNode = null; |
|
183 } |
|
184 |
|
185 object IEnumerator.Current |
|
186 { |
|
187 get |
|
188 { |
|
189 return iCurrentNode; |
|
190 } |
|
191 } |
|
192 |
|
193 bool IEnumerator.MoveNext() |
|
194 { |
|
195 iCurrentNode = NextNode( iCurrentNode ); |
|
196 |
|
197 bool haveMoreNodes = ( NextNode( iCurrentNode ) != null ); |
|
198 return haveMoreNodes; |
|
199 } |
|
200 #endregion |
|
201 |
|
202 #region From IEnumerator<SymNode> |
|
203 SymNode IEnumerator<SymNode>.Current |
|
204 { |
|
205 get { return iCurrentNode; } |
|
206 } |
|
207 #endregion |
|
208 |
|
209 #region From IDisposable |
|
210 public void Dispose() |
|
211 { |
|
212 } |
|
213 #endregion |
|
214 |
|
215 #region Internal methods |
|
216 private SymNode NextNode( SymNode aCurrentNode ) |
|
217 { |
|
218 SymNode nextNode = null; |
|
219 // |
|
220 if ( aCurrentNode == null ) |
|
221 { |
|
222 nextNode = iStartingNode; |
|
223 } |
|
224 else |
|
225 { |
|
226 #region Example |
|
227 // |
|
228 // [A] |
|
229 // / |
|
230 // / |
|
231 // [B] |
|
232 // / | \ |
|
233 // / | \ |
|
234 // [C] [E] [I] |
|
235 // / / \ \ |
|
236 // / / \ \ |
|
237 // [D] [F] [H] [J] |
|
238 // / |
|
239 // / |
|
240 // [G] |
|
241 // |
|
242 // Navigation plan: |
|
243 // |
|
244 // [A] -> [B] -> [C] -> [D] -> [E] -> [F] -> [G] -> [H] -> [I] -> [J] |
|
245 // |
|
246 #endregion |
|
247 |
|
248 if ( aCurrentNode.HasChildren ) |
|
249 { |
|
250 // Try to visit the node's children first. |
|
251 nextNode = aCurrentNode.FirstChild; |
|
252 } |
|
253 else |
|
254 { |
|
255 // No children... |
|
256 if ( aCurrentNode.HasNext ) |
|
257 { |
|
258 // Go to next sibling |
|
259 nextNode = aCurrentNode.Next; |
|
260 } |
|
261 else |
|
262 { |
|
263 // No (more) siblings - go to parent's next sibling. |
|
264 // For example, in the case of the current node being [G] |
|
265 // we need to traverse seemlessly to [H]. Therefore |
|
266 // we go from [G] -> [F] -> [H] |
|
267 nextNode = aCurrentNode.Parent; // [F] |
|
268 while( nextNode != null && nextNode.HasNext == false ) |
|
269 { |
|
270 nextNode = nextNode.Parent; |
|
271 } |
|
272 |
|
273 // We'll now be at [F] |
|
274 if ( nextNode != null ) |
|
275 { |
|
276 // Now we'll be at [H] |
|
277 nextNode = nextNode.Next; |
|
278 } |
|
279 } |
|
280 } |
|
281 } |
|
282 // |
|
283 return nextNode; |
|
284 } |
|
285 #endregion |
|
286 |
|
287 #region Data members |
|
288 private readonly SymNode iStartingNode; |
|
289 private SymNode iCurrentNode = null; |
|
290 #endregion |
|
291 } |
|
292 #endregion |
|
293 |
|
294 #region SymNodeEnumeratorUpTreeSiblingsFirst |
|
295 public class SymNodeEnumeratorUpTreeSiblingsFirst : IEnumerator<SymNode>, IEnumerable<SymNode> |
|
296 { |
|
297 #region Constructors |
|
298 public SymNodeEnumeratorUpTreeSiblingsFirst( SymNode aStartingNode ) |
|
299 { |
|
300 iStartingNode = aStartingNode.FirstSibling; |
|
301 } |
|
302 #endregion |
|
303 |
|
304 #region From IEnumerable<SymNode> |
|
305 IEnumerator<SymNode> IEnumerable<SymNode>.GetEnumerator() |
|
306 { |
|
307 return this; |
|
308 } |
|
309 |
|
310 IEnumerator IEnumerable.GetEnumerator() |
|
311 { |
|
312 return this; |
|
313 } |
|
314 #endregion |
|
315 |
|
316 #region IEnumerator Members |
|
317 void IEnumerator.Reset() |
|
318 { |
|
319 iCurrentNode = null; |
|
320 } |
|
321 |
|
322 object IEnumerator.Current |
|
323 { |
|
324 get |
|
325 { |
|
326 return iCurrentNode; |
|
327 } |
|
328 } |
|
329 |
|
330 bool IEnumerator.MoveNext() |
|
331 { |
|
332 if ( iCurrentNode == null ) |
|
333 { |
|
334 iCurrentNode = iStartingNode; |
|
335 } |
|
336 else |
|
337 { |
|
338 if ( iCurrentNode.HasNext ) |
|
339 { |
|
340 iCurrentNode = iCurrentNode.Next; |
|
341 } |
|
342 else |
|
343 { |
|
344 iCurrentNode = iCurrentNode.Parent.FirstSibling; |
|
345 } |
|
346 |
|
347 System.Diagnostics.Debug.Assert( iCurrentNode != null ); |
|
348 } |
|
349 |
|
350 bool haveMoreNodes = iCurrentNode.HasNext; |
|
351 if ( haveMoreNodes == false ) |
|
352 { |
|
353 haveMoreNodes = iCurrentNode.HasParent; |
|
354 } |
|
355 return haveMoreNodes; |
|
356 } |
|
357 #endregion |
|
358 |
|
359 #region From IEnumerator<SymNode> |
|
360 SymNode IEnumerator<SymNode>.Current |
|
361 { |
|
362 get { return iCurrentNode; } |
|
363 } |
|
364 #endregion |
|
365 |
|
366 #region From IDisposable |
|
367 public void Dispose() |
|
368 { |
|
369 } |
|
370 #endregion |
|
371 |
|
372 #region Data members |
|
373 private readonly SymNode iStartingNode; |
|
374 private SymNode iCurrentNode = null; |
|
375 #endregion |
|
376 } |
|
377 #endregion |
|
378 } |