diff -r 000000000000 -r 72b543305e3a email/imap4mtm/imapmailstore/src/cbodyqueueentry8.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/imap4mtm/imapmailstore/src/cbodyqueueentry8.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,230 @@ +// Copyright (c) 2006-2009 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: +// + + +#include "cbodyqueueentry8.h" +#include +#include "cimaputils.h" +#include "cimaplogger.h" + +const TInt KBufferGranularity = 256; + +/** +Constructor. +*/ +CBodyChunk8Info::CBodyChunk8Info(TInt aChunkNumber,HBufC8* aData) +:iChunkNumber(aChunkNumber),iData(aData) + { + } +/** +Destructor. +*/ +CBodyChunk8Info::~CBodyChunk8Info() + { + delete iData; + } +/** +Constructor. +*/ +CBodyQueueEntry8::CBodyQueueEntry8(TInt aTotalChunks,CImapMailStore& aParent,CMsvServerEntry& aServerEntry,CImapSettings& aImapSettings,CFetchBodyInfo& aFetchBodyInfo,TInt aLogId,MMailStoreObserver& aObserver, TBool aBinaryCap) + : CQueueEntryBase(aFetchBodyInfo.PartId(),EBody8,aParent,aServerEntry,aObserver), + iTotalChunks(aTotalChunks), + iEncoding(aFetchBodyInfo.ContentTransferEncoding()), + iCharsetId(aFetchBodyInfo.CharsetId()), + iBodyPartRemainingSize(aFetchBodyInfo.BodyPartRemainingSize()), + iImapSettings(aImapSettings), + iLogId(aLogId) +#if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT) + , iBinaryCap(aBinaryCap) +#endif + { + //to ignore compilation warnings + aBinaryCap = aBinaryCap; + } + +/** +Destructor. +*/ +CBodyQueueEntry8::~CBodyQueueEntry8() + { + delete iBodyBuf; + delete iBodyText; + delete iStoreUtilities; + delete iCharConv; + delete iCharacterConverter; + iDataArray.Close(); + } + +/** +Factory constructors. +*/ +CBodyQueueEntry8* CBodyQueueEntry8::NewL(TInt aTotalChunks,CImapMailStore& aParent,CMsvServerEntry& aServerEntry,CImapSettings& aImapSettings,CFetchBodyInfo& aFetchBodyInfo,TInt aLogId,MMailStoreObserver& aObserver, TBool aBinaryCap) + { + CBodyQueueEntry8* self=new(ELeave)CBodyQueueEntry8(aTotalChunks,aParent,aServerEntry,aImapSettings,aFetchBodyInfo,aLogId,aObserver, aBinaryCap); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +void CBodyQueueEntry8::ConstructL() + { + BaseConstructL(); + iBodyBuf=CBufSeg::NewL(KBufferGranularity); + iBodyText = CMsvBodyText::NewL(); + iStoreUtilities=CStoreUtilities::NewL(iEncoding,iCharsetId, CImapUtils::GetRef().Fs()); + + iCharacterConverter=CCnvCharacterSetConverter::NewL(); + iCharConv=CImConvertCharconv::NewL(*iCharacterConverter, CImapUtils::GetRef().Fs()); + + //set the character set for the data + iBodyText->SetDefaultCharacterSet(iCharConv->SystemDefaultCharset()); + if (iCharsetId == KUidMsvCharsetNone) + { + iBodyText->SetCharacterSet(0); + } + else + { + iBodyText->SetCharacterSet(iCharsetId); + } + } + +/** +Adds a chunk of body data to the data array and sorts the array +@param aData the body data, ownership is taken. +@param aChunkNumber the order number in which the chunk makes up the whole data. +@return +*/ +void CBodyQueueEntry8::AddChunkL(HBufC8* aData,TInt aChunkNumber, TInt aExtraFetchRequestCount) + { +#if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT) + if(iBinaryCap) + { + iExtraFetchRequestCount=aExtraFetchRequestCount; + } +#else + //to ignore compilation warnings + aExtraFetchRequestCount = aExtraFetchRequestCount; +#endif + __LOG_FORMAT((iLogId, "CBodyQueueEntry8::AddChunkL chunk number = %d",aChunkNumber)); + CleanupStack::PushL(aData); + __ASSERT_DEBUG(aChunkNumbercompareChunks(CompareChunks); + iDataArray.InsertInOrderL(chunkInfo,compareChunks); + CleanupStack::Pop(2,aData); + + if(!IsActive()) + { + CompleteSelf(); + } + } + +/** +Used to sort chunks of data by chunk number. +@param aChunkBodyInfo1 the first chunk in the comparision +@param aChunkBodyInfo2 the second chunk in the comparision +@return TInt the difference between the first chunks number and the second chunks number. +*/ +TInt CBodyQueueEntry8::CompareChunks(const CBodyChunk8Info& aChunkBodyInfo1, const CBodyChunk8Info& aChunkBodyInfo2) + { + return aChunkBodyInfo1.iChunkNumber-aChunkBodyInfo2.iChunkNumber; + } + + +TInt CBodyQueueEntry8::RunError(TInt aError) + { + iDataArray.Close(); + return CQueueEntryBase::RunError(aError); + } + + +/** +Uses CMsvEntry to synchronousy store the requests data object. +@param +@return +*/ +void CBodyQueueEntry8::RunL() + { + //while there are contiguous chunk in the data array append the data to the CRichText object + while(iDataArray.Count()>0 && iDataArray[0]->iChunkNumber==iNextExpectedChunk) + { + ++iNextExpectedChunk; + //is this the last chunk? + TBool lastChunk=(iNextExpectedChunk==iTotalChunks); + HBufC8* decodedData = NULL; +#if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT) + if(iBinaryCap) + { + __LOG_FORMAT((iLogId, "CBodyQueueEntry8::RunL Decoding not required since binary capability is set...")); + const TPtrC8& bodyData = *(iDataArray[0]->iData); + decodedData = HBufC8::NewL(bodyData.Length()); + // Message body is downloaded using Fetch Binary and the data is decoded by the IMAP mail server + // Nothing to do, just copy data + decodedData->Des().Append(bodyData); + } + else +#endif + { + //decode the data + __LOG_FORMAT((iLogId, "CBodyQueueEntry8::RunL Decoding...")); + decodedData=iStoreUtilities->DecodeL(*(iDataArray[0]->iData),lastChunk); + } + __ASSERT_DEBUG(decodedData!=NULL, TImapServerPanic::ImapPanic(TImapServerPanic::EMailStoreDecodeDataNull)); + CleanupStack::PushL(decodedData); + + //if this is the last chunk and if was a partial download then add footer + if(iBodyPartRemainingSize && iNextExpectedChunk==iTotalChunks) + { + __LOG_FORMAT((iLogId, "CBodyQueueEntry8::RunL AttachFooterInfoL...")); + iStoreUtilities->AttachFooterInfoL(iBodyPartRemainingSize,iImapSettings,decodedData); + } + + iBodyBuf->InsertL(iBodyBuf->Size(), *decodedData); + CleanupStack::PopAndDestroy(decodedData); + //delete the data + CBodyChunk8Info* chunkInfo=iDataArray[0]; + iDataArray.Remove(0); + delete chunkInfo; + } + +#if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT) + // if message body is downloaded using FETCH BINARY, there might be some extra fetch command + // issued, remove these extra fetch requests from iTotalChunks. + if(iBinaryCap && iExtraFetchRequestCount > 0) + { + iTotalChunks-=iExtraFetchRequestCount; + //reset iExtraFetchRequestCount to zero + iExtraFetchRequestCount=0; + } +#endif + + //if we have appended all the chunks then store the data. + if(iNextExpectedChunk==iTotalChunks) + { + __LOG_FORMAT((iLogId, "CBodyQueueEntry8::RunL Commiting body data...")); + iServerEntry.SetEntry(iId); + CMsvStore* store = iServerEntry.EditStoreL(); + CleanupStack::PushL(store); + iBodyText->StoreL(*store, *iBodyBuf); + store->CommitL(); + CleanupStack::PopAndDestroy(store); + //call back to the observer as the operation is complete + StoreComplete(KErrNone); + //request can be removed from the queue + iParent.RemoveFromQueueAndDelete(this); + } + }