email/imap4mtm/imapsession/src/cimapstatus.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 
       
    17 #include "cimapstatus.h"
       
    18 #include "moutputstream.h"
       
    19 #include "cimapsessionconsts.h"
       
    20 #include "cimapatomwalker.h"
       
    21 #include "cimapatom.h"
       
    22 #include "cimaputils.h"
       
    23 #include "cimapcharconv.h"
       
    24 
       
    25 // IMAP STATUS command
       
    26 _LIT8(KCommandLogin, "%d STATUS %S %S\r\n");
       
    27 
       
    28 /**
       
    29 The factory constructor. Part of two phased construction.
       
    30 */
       
    31 CImapStatus* CImapStatus::NewL(CImapFolderInfo* aSelectedFolderData, TInt aLogId, const TDesC& aMailboxName, const TDesC8& aStatusDataItemNames, CImapFolderInfo& aFolderInfo)
       
    32 // static method first phase construction
       
    33 	{		
       
    34 	CImapStatus* self = new (ELeave) CImapStatus(aSelectedFolderData, aLogId, aFolderInfo);
       
    35 	CleanupStack::PushL(self);
       
    36 	self->ConstructL(aMailboxName, aStatusDataItemNames);
       
    37 	CleanupStack::Pop();
       
    38 	return self;
       
    39 	}
       
    40 	
       
    41 CImapStatus::CImapStatus(CImapFolderInfo* aSelectedFolderData, TInt aLogId, CImapFolderInfo& aFolderInfo) 
       
    42 	: CImapCommandEx(aSelectedFolderData, aLogId)
       
    43 	, iFolderInfo(aFolderInfo)
       
    44 	{	
       
    45 	}
       
    46 
       
    47 
       
    48 /**
       
    49 Second phase constructor.
       
    50 */		
       
    51 void CImapStatus::ConstructL(const TDesC& aMailboxName, const TDesC8& aStatusDataItemNames)
       
    52 	{
       
    53 	// Converting the mailbox name from 16 bit to imap-UTF7 charset..
       
    54 	iMailboxName = CImapUtils::GetRef().Charconv().ConvertFromUnicodeToImapUtf7L(aMailboxName);
       
    55 	
       
    56 	iStatusDataItemNames = aStatusDataItemNames.AllocL();
       
    57 	iAtomParser = CImapAtomParser::NewL(EFalse, iLogId);
       
    58 	}
       
    59 /**
       
    60 Destructor.
       
    61 */
       
    62 CImapStatus::~CImapStatus()
       
    63 	{
       
    64 	delete iAtomParser;
       
    65 	delete iMailboxName;
       
    66 	delete iStatusDataItemNames;
       
    67 	}
       
    68 
       
    69 /** 
       
    70 Formats and sends the IMAP STATUS command.
       
    71 @param aTagId Command sequence id which will be sent along with the IMAP command.
       
    72 @param aStream A wrapper for the outbound stream of a connected socket, using which 
       
    73 the command will be send to the server
       
    74 */
       
    75 void CImapStatus::SendMessageL(TInt aTagId, MOutputStream& aStream)
       
    76 	{
       
    77 	iTagId = aTagId;
       
    78 
       
    79 	TInt buffLength = KCommandLogin().Length();	
       
    80 	buffLength += iMailboxName->Length();
       
    81 	buffLength += iStatusDataItemNames->Length();
       
    82 	
       
    83 	__ASSERT_DEBUG(iOutputBuffer==NULL, TImapServerPanic::ImapPanic(TImapServerPanic::ECommandOutputBufferNotNull));
       
    84 	iOutputBuffer = HBufC8::NewL(buffLength + TagLength(aTagId));	
       
    85 	iOutputBuffer->Des().Format(KCommandLogin, aTagId, iMailboxName, iStatusDataItemNames);	
       
    86 	
       
    87 	//send the command to the server
       
    88 	aStream.SendDataReq(*iOutputBuffer);
       
    89 	}
       
    90 
       
    91 /**
       
    92 Checks whether this is a STATUS response.
       
    93 If it is, then it starts buiding an atom tree.  
       
    94 If the tree is completed then the data is parsed straight away.  Otherwise, more data is requested.
       
    95 If the atom tree is completed by this line, then tree is parsed to decode the response.
       
    96 @return ENotRecognised if this is not a STATUS response
       
    97 		EResponseIncomplete if this is a STATUS resposne, but more data is required.
       
    98 		ECompleteUntagged if this is a STATUS response that has been fully parsed.
       
    99 */
       
   100 CImapCommand::TParseBlockResult CImapStatus::ParseUntaggedResponseL()
       
   101 	{
       
   102 	TParseBlockResult result = ENotRecognised;
       
   103 	
       
   104 	TPtrC8 response = GetNextPart();
       
   105 	if(response.CompareF(KImapTxtStatus) == 0)
       
   106 		{
       
   107 		TPtrC8 remainingData = Remainder();
       
   108    		TBool wantMoreData = iAtomParser->ProcessLineL(remainingData);
       
   109    		if (wantMoreData)
       
   110    			{
       
   111    			result = EResponseIncomplete;
       
   112    			}
       
   113    		else
       
   114    			{
       
   115    			ParseStatusResponseL();
       
   116    			result = ECompleteUntagged;
       
   117    			}
       
   118 		}
       
   119 	
       
   120 	return result;
       
   121 	}
       
   122 
       
   123 /**
       
   124 Adds the block of literal data to the atom tree.
       
   125 And waits for the following line.
       
   126 */
       
   127 void CImapStatus::ParseLiteralBlockL()
       
   128 	{
       
   129 	iAtomParser->ProcessLiteralBlockL(iUnparsedData);
       
   130 	}
       
   131 
       
   132 /**
       
   133 Adds the line of data to the atom tree.
       
   134 If the atom tree is completed by this line, then tree is parsed to decode the response.
       
   135 @return Whether more data (i.e. another literal block) is expected.
       
   136 */
       
   137 TBool CImapStatus::ParseLineFollowingLiteralL()
       
   138 	{
       
   139 	TBool wantMoreData = iAtomParser->ProcessLineL(iUnparsedData);
       
   140 	
       
   141 	if(!wantMoreData)
       
   142 		{
       
   143 		ParseStatusResponseL();
       
   144 		}
       
   145 		
       
   146 	return wantMoreData;
       
   147 	}
       
   148 
       
   149 void CImapStatus::ParseStatusResponseL()
       
   150  	{
       
   151  	// Traverse the atom tree
       
   152  	CImapAtomWalker* atomWalker = CImapAtomWalker::NewL(iLogId);
       
   153  	CleanupStack::PushL(atomWalker);
       
   154  	
       
   155  	atomWalker->SetRootL(iAtomParser->RootAtom());
       
   156  	
       
   157  	// Move to the first item of the atom tree...
       
   158  	atomWalker->WalkDownL();
       
   159  	
       
   160  	// Skip over the mailbox name
       
   161  	atomWalker->WalkAcrossL(ETrue);
       
   162  	
       
   163   	// We should now be at the opening bracket for the status-att-list
       
   164   	atomWalker->WalkDownL();
       
   165   	
       
   166   	// status-att-list = status-att SP number *(SP status-att SP number)
       
   167  	do
       
   168  		{
       
   169  		// Get the status-att
       
   170  		TPtrC8 statusAtt = atomWalker->CurrentDes(EFalse);
       
   171  		
       
   172  		// Get the number value corrosponding to a status data item.
       
   173  		atomWalker->WalkAcrossL(ETrue);
       
   174  		TPtrC8 value = atomWalker->CurrentDes(EFalse);
       
   175  		
       
   176  		ParseStatusAttributeL(statusAtt, value);
       
   177  		} 
       
   178   		while (atomWalker->WalkAcrossL(EFalse));
       
   179  		 	
       
   180  	CleanupStack::PopAndDestroy(atomWalker);
       
   181  	}
       
   182 
       
   183 /**
       
   184 Parses the status response.
       
   185 @param aAttribute.The status data item.(MESSAGES/UIDNEXT/RECENT/UIDVALIDITY/UNSEEN)
       
   186 @param aValue. The value corrosponding a particular status data item.
       
   187 */
       
   188 void CImapStatus::ParseStatusAttributeL(const TDesC8& aAttribute, const TDesC8& aValue )
       
   189 // Parse response of the form (MESSAGES 899 UIDNEXT 8874)...
       
   190 	{
       
   191 	TPtrC8 nextPart(aAttribute);
       
   192 	TLex8 desToInt(aValue);
       
   193 	TInt tempVal = 0;
       
   194 	
       
   195 	if(desToInt.Val(tempVal) != KErrNone)
       
   196 		{
       
   197 		CorruptDataL();
       
   198 		}
       
   199 	
       
   200 	// From RFC3501 section 9
       
   201 	//	
       
   202 	// status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" / "UNSEEN"
       
   203 		
       
   204 	if(nextPart.CompareF(KImapTxtMessages) == 0)
       
   205 		{					
       
   206 		iFolderInfo.SetMessages(tempVal);
       
   207 		}
       
   208 	else if(nextPart.CompareF(KImapTxtRecent) == 0)
       
   209 		{
       
   210 		iFolderInfo.SetRecent(tempVal);					
       
   211 		}
       
   212 	else if(nextPart.CompareF(KImapTxtUidNext) == 0)
       
   213 		{
       
   214 		iFolderInfo.SetUidNext(tempVal);					
       
   215 		}
       
   216 	else if(nextPart.CompareF(KImapTxtUidValidity) == 0)
       
   217 		{					
       
   218 		iFolderInfo.SetUidValidity(tempVal);
       
   219 		}
       
   220 	else if(nextPart.CompareF(KImapTxtUnseen) == 0)
       
   221 		{					
       
   222 		iFolderInfo.SetUnseen(tempVal);
       
   223 		}			
       
   224 	}
       
   225