crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianTree/Nodes/SymNodeEnumerators.cs
author Matti Laitinen <matti.t.laitinen@nokia.com>
Thu, 11 Feb 2010 15:50:58 +0200
changeset 0 818e61de6cd1
permissions -rw-r--r--
Add initial version of Crash Analyser cmdline under EPL

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
* 
* Description:
*
*/
using System;
using System.Collections;
using System.Collections.Generic;

namespace SymbianTree
{
	#region SymNodeEnumeratorSiblings 
	public class SymNodeEnumeratorSiblings : IEnumerator<SymNode>, IEnumerable<SymNode>
	{
		#region Constructors
		public SymNodeEnumeratorSiblings( SymNode aNodeToEnumerate )
		{
			iNode = aNodeToEnumerate;
		}
		#endregion

        #region From IEnumerable<SymNode>
        IEnumerator<SymNode> IEnumerable<SymNode>.GetEnumerator()
        {
            return this;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
        #endregion

		#region IEnumerator Members
		void IEnumerator.Reset()
		{
			iCurrentNode = null;
		}

		object IEnumerator.Current
		{
			get
			{
				return iCurrentNode;
			}
		}

		bool IEnumerator.MoveNext()
		{
			if	( iCurrentNode == null )
			{
				iCurrentNode = iNode;
			}
			else
			{
				iCurrentNode = iCurrentNode.Next;
			}

			bool haveMoreNodes = ( iCurrentNode.Next != null );
			return haveMoreNodes;
		}
		#endregion

        #region From IEnumerator<SymNode>
        SymNode IEnumerator<SymNode>.Current
        {
            get { return iCurrentNode; }
        }
        #endregion

        #region From IDisposable
        public void Dispose()
        {
        }
        #endregion

		#region Data members
		private readonly SymNode iNode;
		private SymNode iCurrentNode = null;
		#endregion
    }
	#endregion

	#region SymNodeEnumeratorChildren 
    public class SymNodeEnumeratorChildren : IEnumerator<SymNode>, IEnumerable<SymNode>
	{
		#region Constructors
		public SymNodeEnumeratorChildren( SymNode aNodeToEnumerate )
		{
			iNode = aNodeToEnumerate;
		}
		#endregion

        #region From IEnumerable<SymNode>
        IEnumerator<SymNode> IEnumerable<SymNode>.GetEnumerator()
        {
            return this;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
        #endregion

		#region IEnumerator Members
		void IEnumerator.Reset()
		{
			iEnumeratorIndex = -1;
		}

		object IEnumerator.Current
		{
			get
			{
				return iNode.Children[ iEnumeratorIndex ];
			}
		}

		bool IEnumerator.MoveNext()
		{
			return ( ++iEnumeratorIndex < iNode.ChildCount );
		}
		#endregion

        #region From IEnumerator<SymNode>
        SymNode IEnumerator<SymNode>.Current
        {
            get { return iNode.Children[ iEnumeratorIndex ]; }
        }
        #endregion

        #region From IDisposable
        public void Dispose()
        {
        }
        #endregion

		#region Data members
		private readonly SymNode iNode;
		private int iEnumeratorIndex = -1;
		#endregion
	}
	#endregion

	#region SymNodeEnumeratorTreeChildrenFirst 
    public class SymNodeEnumeratorTreeChildrenFirst : IEnumerator<SymNode>, IEnumerable<SymNode>
	{
		#region Constructors
		public SymNodeEnumeratorTreeChildrenFirst( SymNode aStartingNode )
		{
			iStartingNode = aStartingNode;
		}
		#endregion

        #region From IEnumerable<SymNode>
        IEnumerator<SymNode> IEnumerable<SymNode>.GetEnumerator()
        {
            return this;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
        #endregion

		#region IEnumerator Members
		void IEnumerator.Reset()
		{
			iCurrentNode = null;
		}

		object IEnumerator.Current
		{
			get
			{
				return iCurrentNode;
			}
		}

		bool IEnumerator.MoveNext()
		{
			iCurrentNode = NextNode( iCurrentNode );

			bool haveMoreNodes = ( NextNode( iCurrentNode ) != null );
			return haveMoreNodes;
		}
		#endregion

        #region From IEnumerator<SymNode>
        SymNode IEnumerator<SymNode>.Current
        {
            get { return iCurrentNode; }
        }
        #endregion

        #region From IDisposable
        public void Dispose()
        {
        }
        #endregion

		#region Internal methods
		private SymNode NextNode( SymNode aCurrentNode )
		{
			SymNode nextNode = null;
			//
			if	( aCurrentNode == null )
			{
				nextNode = iStartingNode;
			}
			else
			{
				#region Example
				//
				//                [A]
				//               /
				//              /
				//            [B]
				//           / | \
				//          /  |  \
				//        [C] [E] [I]
				//       /    / \   \
				//      /    /   \   \
				//    [D]  [F]   [H]  [J]
				//        / 
				//       /
				//     [G]
				//
				// Navigation plan:
				//
				//    [A] -> [B] -> [C] -> [D] -> [E] -> [F] -> [G] -> [H] -> [I] -> [J]
				// 
				#endregion

				if	( aCurrentNode.HasChildren )
				{
					// Try to visit the node's children first.
					nextNode = aCurrentNode.FirstChild;
				}
				else
				{
					// No children...
					if	( aCurrentNode.HasNext )
					{
						// Go to next sibling
						nextNode = aCurrentNode.Next;
					}
					else
					{
						// No (more) siblings - go to parent's next sibling.
						// For example, in the case of the current node being [G]
						// we need to traverse seemlessly to [H]. Therefore
						// we go from [G] -> [F] -> [H]
						nextNode = aCurrentNode.Parent; // [F]
						while( nextNode != null && nextNode.HasNext == false )
						{
							nextNode = nextNode.Parent;
						}

						// We'll now be at [F]
						if	( nextNode != null )
						{
							// Now we'll be at [H]
							nextNode = nextNode.Next;
						}
					}
				}
			}
			//
			return nextNode;
		}
		#endregion

		#region Data members
		private readonly SymNode iStartingNode;
		private SymNode iCurrentNode = null;
		#endregion
	}
	#endregion

	#region SymNodeEnumeratorUpTreeSiblingsFirst
    public class SymNodeEnumeratorUpTreeSiblingsFirst : IEnumerator<SymNode>, IEnumerable<SymNode>
	{
		#region Constructors
		public SymNodeEnumeratorUpTreeSiblingsFirst( SymNode aStartingNode )
		{
			iStartingNode = aStartingNode.FirstSibling;
		}
		#endregion

        #region From IEnumerable<SymNode>
        IEnumerator<SymNode> IEnumerable<SymNode>.GetEnumerator()
        {
            return this;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
        #endregion

		#region IEnumerator Members
		void IEnumerator.Reset()
		{
			iCurrentNode = null;
		}

		object IEnumerator.Current
		{
			get
			{
				return iCurrentNode;
			}
		}

		bool IEnumerator.MoveNext()
		{
			if	( iCurrentNode == null )
			{
				iCurrentNode = iStartingNode;
			}
			else
			{
				if	( iCurrentNode.HasNext )
				{
					iCurrentNode = iCurrentNode.Next;
				}
				else
				{
					iCurrentNode = iCurrentNode.Parent.FirstSibling;
				}

				System.Diagnostics.Debug.Assert( iCurrentNode != null );
			}

			bool haveMoreNodes = iCurrentNode.HasNext;
			if	( haveMoreNodes == false )
			{
				haveMoreNodes = iCurrentNode.HasParent;
			}
			return haveMoreNodes;
		}
		#endregion

        #region From IEnumerator<SymNode>
        SymNode IEnumerator<SymNode>.Current
        {
            get { return iCurrentNode; }
        }
        #endregion

        #region From IDisposable
        public void Dispose()
        {
        }
        #endregion

		#region Data members
		private readonly SymNode iStartingNode;
		private SymNode iCurrentNode = null;
		#endregion
	}
	#endregion
}