email/imap4mtm/imapsession/src/cimapatomwalker.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "cimapatomwalker.h"
       
    17 #include "cimapatom.h"
       
    18 
       
    19 #include "cimapsessionconsts.h"
       
    20 #include "cimapcommand.h"
       
    21 #include "imappaniccodes.h"
       
    22 
       
    23 
       
    24 CImapAtomWalker* CImapAtomWalker::NewL(TInt aLogId)
       
    25 // static method
       
    26 	{
       
    27 	return new(ELeave)CImapAtomWalker(aLogId);
       
    28 	}
       
    29 	
       
    30 CImapAtomWalker::CImapAtomWalker(TInt aLogId)
       
    31 	: iLogId(aLogId)
       
    32 	{}
       
    33 	
       
    34 CImapAtomWalker::~CImapAtomWalker()
       
    35 	{
       
    36 	iAtomStack.Reset();
       
    37 	}
       
    38 
       
    39 /**
       
    40 Sets the root atom
       
    41 */
       
    42 void CImapAtomWalker::SetRootL(CImapAtom* aRootAtom)
       
    43 	{
       
    44 	iAtomStack.Reset();	
       
    45 	
       
    46 	iAtomStack.AppendL(aRootAtom);
       
    47 	iCurrentAtom = aRootAtom;
       
    48 	}
       
    49 
       
    50 /**
       
    51 Walks down to the child of the current atom, and updates the current atom.
       
    52 If the current atom has no child, then this method will leave with KErrCorrupt.
       
    53 */
       
    54 void CImapAtomWalker::WalkDownL()
       
    55 	{	
       
    56 	// Try going down
       
    57 	CImapAtom* candidateAtom = iCurrentAtom->Child();
       
    58 	if (candidateAtom)
       
    59 		{
       
    60 		iAtomStack.AppendL(candidateAtom);
       
    61 		iCurrentAtom = candidateAtom;
       
    62 		}
       
    63 	else
       
    64 		{
       
    65 		// WalkDownL() should only be called when the caller is expecting a child to walk down to.
       
    66 		// So if there is no such child, the incoming data must be corrupt.
       
    67 		CImapCommand::CorruptDataL(iLogId);
       
    68 		}	
       
    69 	}
       
    70 
       
    71 /**
       
    72 Walks across to the next sibling of the current atom, and updates the current atom.
       
    73 @param aLeaveIfNull If ETrue, then if the current atom has no next sibling, then this method will leave with KErrCorrupt.
       
    74 @return the updated current atom or NULL if not found.  Ownership is not transferred.
       
    75 */
       
    76 CImapAtom* CImapAtomWalker::WalkAcrossL(TBool aLeaveIfNull)
       
    77 	{
       
    78 	CImapAtom* candidateAtom = iCurrentAtom->Next();
       
    79 	if (candidateAtom)
       
    80 		{
       
    81 		// Check for internal programming error
       
    82 		__ASSERT_DEBUG(iAtomStack.Count() > 0, TImapServerPanic::ImapPanic(TImapServerPanic::EAtomWalkerStackIsEmpty));
       
    83 		
       
    84 		iAtomStack[iAtomStack.Count() - 1] = candidateAtom;
       
    85 		iCurrentAtom = candidateAtom;
       
    86 		}
       
    87 	else if (aLeaveIfNull)
       
    88 		{
       
    89 		// Caller has signified that they are expecting the next atom to be non-NULL.
       
    90 		// So of there is no next atom, the incoming data must be corrupt.
       
    91 		CImapCommand::CorruptDataL(iLogId);
       
    92 		}
       
    93 		
       
    94 	return candidateAtom;
       
    95 	}
       
    96 
       
    97 /**
       
    98 Walks up to the parent of the current atom, and updates the current atom.
       
    99 If the current atom has no parent, then this method will leave with KErrUnderflow.
       
   100 */
       
   101 void CImapAtomWalker::WalkUpL()
       
   102 	{
       
   103 	TInt topOfStack = iAtomStack.Count() - 1;
       
   104 	
       
   105 	// Check for internal programming error
       
   106 	__ASSERT_DEBUG(topOfStack > 0, TImapServerPanic::ImapPanic(TImapServerPanic::EAtomWalkerNothingToWalkUpTo));
       
   107 	
       
   108 	// Go up
       
   109 	iAtomStack.Remove(topOfStack);
       
   110 	--topOfStack;
       
   111 	
       
   112 	iCurrentAtom = iAtomStack[topOfStack];
       
   113 	
       
   114 	// Check for internal programming error.
       
   115 	__ASSERT_DEBUG(iCurrentAtom != NULL, TImapServerPanic::ImapPanic(TImapServerPanic::EAtomWalkerNullStackEntry)); // would never expect this to be NULL as it has come from the stack!
       
   116 	}
       
   117 
       
   118 /** 
       
   119 Returns a pointer to the child of the current atom if one exists, or NULL.
       
   120 The current atom is NOT updated.
       
   121 @return the child of the current atom or NULL.  Ownership is not transferred.
       
   122 */
       
   123 CImapAtom* CImapAtomWalker::PeekDown() const
       
   124 	{
       
   125 	return iCurrentAtom->Child();
       
   126 	}
       
   127 /** 
       
   128 Returns a pointer to the next sibling of the current atom if one exists, or NULL.
       
   129 The current atom is NOT updated.
       
   130 @return the next sibling of the current atom or NULL.  Ownership is not transferred.
       
   131 */
       
   132 CImapAtom* CImapAtomWalker::PeekAcross() const
       
   133 	{
       
   134 	return iCurrentAtom->Next();
       
   135 	}
       
   136 
       
   137 /**
       
   138 Returns whether the supplied string matches the string in the current atom.
       
   139 String matching uses Folded comparison - i.e. case insensitive.
       
   140 @param aValue the string to match with the current atom's string.
       
   141 @return whether the strings match.
       
   142 */
       
   143 TBool CImapAtomWalker::CurrentMatch(const TDesC8& aValue) const
       
   144 	{
       
   145 	return iCurrentAtom->Match(aValue);
       
   146 	}
       
   147 
       
   148 /**
       
   149 The string assoiated with current atom.
       
   150 If the string is to be interpreted as an nstring, then if the actual string 
       
   151 was "NIL" and was not quoted in the input data, an empty string will be returned.
       
   152 @param aNString whether to return an empty string in place of a non-quoted "NIL"
       
   153 @return the string assoiated with current atom.
       
   154 */
       
   155 const TDesC8& CImapAtomWalker::CurrentDes(TBool aNString) const
       
   156 	{
       
   157 	return iCurrentAtom->Atom(aNString);
       
   158 	}
       
   159 
       
   160 /**
       
   161 @return a pointer to the current atom.  Ownership is not transferred.
       
   162 */
       
   163 CImapAtom* CImapAtomWalker::Current() const
       
   164 	{
       
   165 	return iCurrentAtom;
       
   166 	}
       
   167 
       
   168 /**
       
   169 Walks across to the next atom, updating the current atom.
       
   170 This method expects the next atom to be either "NIL" or "(", and will leave 
       
   171 with the KErrCorrupt code if any other atom is found.
       
   172 @return an enumeration that signifies whether "NIL" or "(" was found.
       
   173 */
       
   174 CImapAtomWalker::TAtomType CImapAtomWalker::WalkAcrossToNilOrOpenL()
       
   175 	{
       
   176 	CImapAtom* atom = WalkAcrossL(ETrue);
       
   177 	
       
   178 	// Check for internal programming error: WalkAcrossL(ETrue) will leave rather than return NULL
       
   179 	__ASSERT_DEBUG(atom != NULL, TImapServerPanic::ImapPanic(TImapServerPanic::EAtomWalkerWalkedAcrossToNull));
       
   180 
       
   181 	TAtomType atomType = EAtomNil;
       
   182 	
       
   183 	if (atom->Match(KImapTxtNil()))
       
   184 		{
       
   185 		atomType = EAtomNil;
       
   186 		}
       
   187 	else if (atom->Match(KImapTxtOpenBracket()))
       
   188 		{
       
   189 		atomType = EAtomOpen;
       
   190 		}
       
   191 	else
       
   192 		{
       
   193 		// Not "NIL" or "(" as expected.
       
   194 		// Data must be corrupt.
       
   195 		CImapCommand::CorruptDataL(iLogId);
       
   196 		}
       
   197 
       
   198 	return atomType;
       
   199 	}
       
   200 
       
   201 TInt CImapAtomWalker::StackCount() const
       
   202 	{
       
   203 	return iAtomStack.Count();
       
   204 	}