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