email/imap4mtm/imapmailstore/src/cbodyqueueentry16.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 "cbodyqueueentry16.h"
       
    17 #include "cimaputils.h"
       
    18 #include "cimaplogger.h"
       
    19 #include <txtrich.h>
       
    20 
       
    21 /**
       
    22 Constructor.
       
    23 */
       
    24 CBodyChunk16Info::CBodyChunk16Info(TInt aChunkNumber,HBufC8* aData)
       
    25 :iChunkNumber(aChunkNumber),iData(aData)
       
    26 	{
       
    27 	}
       
    28 /**
       
    29 Destructor.
       
    30 */	
       
    31 CBodyChunk16Info::~CBodyChunk16Info()
       
    32 	{
       
    33 	delete iData;
       
    34 	}
       
    35 /**
       
    36 Constructor.
       
    37 */
       
    38 CBodyQueueEntry16::CBodyQueueEntry16(TInt aTotalChunks,CImapMailStore& aParent,CMsvServerEntry& aServerEntry,CImapSettings& aImapSettings,CFetchBodyInfo& aFetchBodyInfo,TInt aLogId,MMailStoreObserver& aObserver, TBool aBinaryCap)
       
    39 	: CQueueEntryBase(aFetchBodyInfo.PartId(),EBody16,aParent,aServerEntry,aObserver),
       
    40 	iTotalChunks(aTotalChunks),
       
    41 	iEncoding(aFetchBodyInfo.ContentTransferEncoding()),
       
    42 	iCharsetId(aFetchBodyInfo.CharsetId()),
       
    43 	iBodyPartRemainingSize(aFetchBodyInfo.BodyPartRemainingSize()),
       
    44 	iImapSettings(aImapSettings),
       
    45 	iLogId(aLogId)
       
    46 #if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT)		
       
    47 	, iBinaryCap(aBinaryCap)
       
    48 #endif
       
    49 	{
       
    50 	//to ignore compilation warnings
       
    51 	aBinaryCap = aBinaryCap;
       
    52 	}
       
    53 
       
    54 /**
       
    55 Destructor.
       
    56 */		
       
    57 CBodyQueueEntry16::~CBodyQueueEntry16()
       
    58 	{
       
    59 	delete iBodyText;
       
    60 	delete iCharFormatLayer;
       
    61 	delete iParaFormatLayer;
       
    62 	delete iStoreUtilities;
       
    63 	iDataArray.Close();
       
    64 	}
       
    65 	
       
    66 /**
       
    67 Factory constructors.
       
    68 */
       
    69 CBodyQueueEntry16* CBodyQueueEntry16::NewL(TInt aTotalChunks,CImapMailStore& aParent,CMsvServerEntry& aServerEntry,CImapSettings& aImapSettings,CFetchBodyInfo& aFetchBodyInfo,TInt aLogId,MMailStoreObserver& aObserver, TBool aBinaryCap)
       
    70 	{
       
    71 	CBodyQueueEntry16* self=new(ELeave)CBodyQueueEntry16(aTotalChunks,aParent,aServerEntry,aImapSettings,aFetchBodyInfo,aLogId,aObserver,aBinaryCap);
       
    72 	CleanupStack::PushL(self);
       
    73 	self->ConstructL();
       
    74 	CleanupStack::Pop();
       
    75 	return self;
       
    76 	}
       
    77 
       
    78 void CBodyQueueEntry16::ConstructL()
       
    79 	{
       
    80 	BaseConstructL();
       
    81 	iParaFormatLayer=CParaFormatLayer::NewL();
       
    82 	iCharFormatLayer=CCharFormatLayer::NewL(); 
       
    83 	iBodyText=CRichText::NewL(iParaFormatLayer, iCharFormatLayer);
       
    84 	if(iCharsetId == KUidMsvCharsetNone)
       
    85 		{
       
    86 		// Get the default charset
       
    87 		CCnvCharacterSetConverter* characterConverter = CCnvCharacterSetConverter::NewL();
       
    88 		CleanupStack::PushL(characterConverter);
       
    89 		CImConvertCharconv* charConv = CImConvertCharconv::NewL(*characterConverter, CImapUtils::GetRef().Fs());
       
    90 	
       
    91 		iCharsetId = charConv->SystemDefaultCharset();
       
    92 		delete charConv;
       
    93 		CleanupStack::PopAndDestroy();//characterConverter
       
    94 		}
       
    95 	iStoreUtilities=CStoreUtilities::NewL(iEncoding,iCharsetId, CImapUtils::GetRef().Fs());
       
    96 	}
       
    97 
       
    98 /**
       
    99 Adds a chunk of body data to the data array and sorts the array
       
   100 @param aData 			the body data, ownership  is taken.
       
   101 @param aChunkNumber 	the order number in which the chunk makes up the whole data.
       
   102 @return 
       
   103 */		
       
   104 void CBodyQueueEntry16::AddChunkL(HBufC8* aData,TInt aChunkNumber, TInt aExtraFetchRequestCount)
       
   105 	{
       
   106 #if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT)		
       
   107 	if(iBinaryCap)
       
   108 		{
       
   109 		iExtraFetchRequestCount=aExtraFetchRequestCount;
       
   110 		}
       
   111 #else
       
   112 	//to ignore compilation warnings
       
   113 	aExtraFetchRequestCount = aExtraFetchRequestCount;	
       
   114 #endif
       
   115 	__LOG_FORMAT((iLogId, "CBodyQueueEntry16::AddChunkL chunk number = %d",aChunkNumber));
       
   116 	CleanupStack::PushL(aData);
       
   117 	//make sure the chunk is within range.
       
   118 	__ASSERT_DEBUG(aChunkNumber<iTotalChunks,TImapServerPanic::ImapPanic(TImapServerPanic::EMailStoreDataChunkOutOfRange));
       
   119 	//append the chunk
       
   120  	CBodyChunk16Info* chunkInfo = new(ELeave) CBodyChunk16Info(aChunkNumber,aData);
       
   121  	CleanupStack::PushL(chunkInfo);
       
   122  	TLinearOrder<CBodyChunk16Info>compareChunks(CompareChunks); 	
       
   123  	iDataArray.InsertInOrderL(chunkInfo,compareChunks);
       
   124     CleanupStack::Pop(2,aData);
       
   125     
       
   126     if(!IsActive())
       
   127 		{
       
   128   	  	CompleteSelf();	
       
   129 		}
       
   130 	}
       
   131 	
       
   132 /**
       
   133 Used to sort chunks of data by chunk number.
       
   134 @param aChunkBodyInfo1 	the first chunk in the comparision
       
   135 @param aChunkBodyInfo2 	the second chunk in the comparision
       
   136 @return TInt			the difference between the first chunks number and the second chunks number.
       
   137 */	
       
   138 TInt CBodyQueueEntry16::CompareChunks(const CBodyChunk16Info& aChunkBodyInfo1, const CBodyChunk16Info& aChunkBodyInfo2)
       
   139 	{
       
   140 	return aChunkBodyInfo1.iChunkNumber-aChunkBodyInfo2.iChunkNumber;	
       
   141 	}
       
   142 
       
   143 TInt CBodyQueueEntry16::RunError(TInt aError)
       
   144 	{
       
   145 	iDataArray.Close();
       
   146 	return CQueueEntryBase::RunError(aError);
       
   147 	}
       
   148 	
       
   149 /**
       
   150 Uses CMsvEntry to synchronousy store the requests data object.
       
   151 @param 
       
   152 @return
       
   153 */
       
   154 void CBodyQueueEntry16::RunL()
       
   155 	{
       
   156 	
       
   157 	//while there are contiguous chunk in the data array append the data to the CRichText object
       
   158 	while(iDataArray.Count()>0 && iDataArray[0]->iChunkNumber==iNextExpectedChunk)
       
   159 		{
       
   160 		++iNextExpectedChunk;
       
   161 		//is this the last chunk?
       
   162 		TBool lastChunk=(iNextExpectedChunk==iTotalChunks);
       
   163 		HBufC8* decodedData = NULL;
       
   164 #if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT)		
       
   165 		if(iBinaryCap)
       
   166 			{
       
   167 			__LOG_FORMAT((iLogId, "CBodyQueueEntry16::RunL Decoding not required since binary capability is set..."));	
       
   168 			const TPtrC8& bodyData = *(iDataArray[0]->iData);
       
   169 			decodedData = HBufC8::NewL(bodyData.Length());
       
   170 			// Message body is downloaded using Fetch Binary and the data is decoded by the IMAP mail server
       
   171 			// Nothing to do, just copy data
       
   172 			decodedData->Des().Append(bodyData);			
       
   173 			}
       
   174 		else
       
   175 #endif
       
   176 			{	
       
   177 			//decode the data
       
   178 			__LOG_FORMAT((iLogId, "CBodyQueueEntry16::RunL Decoding..."));
       
   179 			decodedData=iStoreUtilities->DecodeL(*(iDataArray[0]->iData),lastChunk);
       
   180 			}	
       
   181 		__ASSERT_DEBUG(decodedData!=NULL, TImapServerPanic::ImapPanic(TImapServerPanic::EMailStoreDecodeDataNull));
       
   182 		CleanupStack::PushL(decodedData); 
       
   183 		//if this is the last chunk and if was a partial download then add footer
       
   184 		if(iBodyPartRemainingSize && iNextExpectedChunk==iTotalChunks)
       
   185 			{
       
   186 			__LOG_FORMAT((iLogId, "CBodyQueueEntry16::RunL AttachFooterInfoL..."));
       
   187 			iStoreUtilities->AttachFooterInfoL(iBodyPartRemainingSize,iImapSettings,decodedData);	
       
   188 			}
       
   189 			
       
   190 		__LOG_FORMAT((iLogId, "CBodyQueueEntry16::RunL WriteToBodyL..."));
       
   191 		//convert the data
       
   192 		iStoreUtilities->WriteToBodyL(decodedData->Des(),iBodyText);
       
   193 		
       
   194 		CleanupStack::PopAndDestroy(decodedData); 
       
   195 		//delete the data
       
   196 		CBodyChunk16Info* chunkInfo=iDataArray[0];
       
   197 		iDataArray.Remove(0);
       
   198 		delete chunkInfo;
       
   199 		}
       
   200 		
       
   201 #if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT)				
       
   202 	// if message body is downloaded using FETCH BINARY, there might be some extra fetch command
       
   203 	// issued, remove these extra fetch requests from iTotalChunks.
       
   204 	if(iBinaryCap && iExtraFetchRequestCount > 0)
       
   205 		{
       
   206 		iTotalChunks-=iExtraFetchRequestCount;
       
   207 		//reset iExtraFetchRequestCount to zero
       
   208 		iExtraFetchRequestCount=0;
       
   209 		}
       
   210 #endif
       
   211 	
       
   212 	//if we have appended all the chunks then store the data.
       
   213 	if(iNextExpectedChunk==iTotalChunks)
       
   214 		{
       
   215 		__LOG_FORMAT((iLogId, "CBodyQueueEntry16::RunL Commiting body data..."));
       
   216 		iServerEntry.SetEntry(iId);
       
   217 		CMsvStore* store = iServerEntry.EditStoreL();
       
   218 		CleanupStack::PushL(store);		
       
   219 		store->StoreBodyTextL(*iBodyText);
       
   220 		store->CommitL();
       
   221 		CleanupStack::PopAndDestroy(store); 
       
   222 		//call back to the observer as the operation is complete
       
   223 		StoreComplete(KErrNone);	
       
   224 		//request can be removed from the queue
       
   225 		iParent.RemoveFromQueueAndDelete(this);	
       
   226 		}
       
   227 	}