homescreenpluginsrv/hspsdom/src/hspsdomdepthiterator.cpp
changeset 0 79c6a41cd166
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/homescreenpluginsrv/hspsdom/src/hspsdomdepthiterator.cpp	Thu Dec 17 08:54:17 2009 +0200
@@ -0,0 +1,190 @@
+/*
+* Copyright (c) 2005,2006 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:  Depth iterator walks the dom tree using depth first principle.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include    "hspsdomdepthiterator.h"
+#include    "hspsdomlist.h"
+#include    "hspsdomnode.h"
+
+// ============================ LOCAL FUNCTIONS ===============================
+ 
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// ChspsDomDepthIterator::ChspsDomDepthIterator
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+ChspsDomDepthIterator::ChspsDomDepthIterator( ChspsDomNode& aRootNode  ):
+    iFirst(&aRootNode), iCurrent(&aRootNode)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// ChspsDomDepthIterator::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void ChspsDomDepthIterator::ConstructL()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// ChspsDomDepthIterator::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C ChspsDomDepthIterator* ChspsDomDepthIterator::NewL( ChspsDomNode& aRootNode )
+    {
+    ChspsDomDepthIterator* self = new( ELeave ) ChspsDomDepthIterator( aRootNode );
+    
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+    
+// Destructor
+EXPORT_C ChspsDomDepthIterator::~ChspsDomDepthIterator()
+    {
+    iDepthLevel.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// ChspsDomDepthIterator::First
+// -----------------------------------------------------------------------------
+//
+EXPORT_C ChspsDomNode* ChspsDomDepthIterator::First()
+    {
+    return iFirst;
+    }
+    
+// -----------------------------------------------------------------------------
+// ChspsDomDepthIterator::Next
+// -----------------------------------------------------------------------------
+//
+EXPORT_C ChspsDomNode* ChspsDomDepthIterator::NextL()
+    {
+    ChspsDomNode* sibling = NULL; 
+    ChspsDomNode* firstChild = NULL;     
+    
+    //Initialise iCurrent if the whole tree has been walked through 
+    if (!iCurrent) 
+        {
+        iCurrent = iFirst;
+        }
+        
+    firstChild = static_cast<ChspsDomNode*>( iCurrent->ChildNodes().First() );
+        
+    // Current node has childs left
+    if (firstChild)
+        {
+        //Keep count of depth level
+        PushL( *iCurrent );
+        iCurrent = firstChild;
+        }
+    else //If current node has siblings left
+        {
+        sibling = NextSibling(*iCurrent);
+        if(sibling)
+            {
+            iCurrent = sibling;    
+            }
+        else //Current node don't have any childs or siblings left
+            {
+            // Reverse the tree by moving up in hierarchy
+            // Move up one level in hierarchy and check if siblings exists or we are in a 
+            // root level
+            TBool stop( EFalse );
+            while( !stop && iDepthLevel.Count() )  
+                {
+                iCurrent = Pop();                   //Reach the previous level
+                sibling = NextSibling( *iCurrent ); //Check if siblings exist
+                if ( sibling && iDepthLevel.Count() )
+                    {
+                    iCurrent = sibling;
+                    stop = ETrue;
+                    }
+                else                                //We didn't find any siblings
+                    {
+                    iCurrent = NULL;
+                    }
+                }    
+            }
+        }
+    return iCurrent;
+    }
+
+// -----------------------------------------------------------------------------
+// NextSibling Find next sibling.
+// Returns NULL if there is no siblings left or there is no parent i.e this is a
+// root node
+// Returns: ChspsDomNode* Pointer to the node or NULL
+//          
+// -----------------------------------------------------------------------------
+//
+
+EXPORT_C ChspsDomNode* ChspsDomDepthIterator::NextSibling( ChspsDomNode& aNode )
+    {
+    ChspsDomNode* left = NULL;
+    ChspsDomNode* parent = aNode.Parent();
+    if ( parent )
+        {
+        ChspsDomList& nodeList = parent->ChildNodes();
+        TInt currentIndex( nodeList.ItemIndex( aNode ) );
+        TInt nextIndex( ++currentIndex );
+        TInt length( nodeList.Length() );
+        if ( nextIndex < length )  
+            {
+            left = static_cast<ChspsDomNode*>( nodeList.Item( nextIndex ) );
+            }
+        }
+    return left;     
+    }
+
+// -----------------------------------------------------------------------------
+// ChspsDomDepthIterator::PushL
+// -----------------------------------------------------------------------------
+//
+void ChspsDomDepthIterator::PushL( ChspsDomNode& aNode )
+    {
+    iDepthLevel.AppendL( &aNode );
+    }
+
+// -----------------------------------------------------------------------------
+// ChspsDomDepthIterator::Pop
+// -----------------------------------------------------------------------------
+//
+ChspsDomNode* ChspsDomDepthIterator::Pop()
+    {
+    ChspsDomNode* pop = NULL;
+    TInt count( iDepthLevel.Count() );
+    if ( count )
+        {
+        pop = iDepthLevel[ count-1 ];
+        iDepthLevel.Remove( count-1 );
+        }
+    return pop;    
+    }
+    
+//  End of File