diff -r 6a20128ce557 -r ebfee66fde93 email/imap4mtm/imapmailstore/src/cmsvplainbodytextqueueentry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/imap4mtm/imapmailstore/src/cmsvplainbodytextqueueentry.cpp Fri Jun 04 10:25:39 2010 +0100 @@ -0,0 +1,285 @@ +// Copyright (c) 2007-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: +// CMSVPLAINBODYTEXTQUEENTRY.CPP +// +// + +#include "cmsvplainbodytextqueueentry.h" +#include "cimaputils.h" +#include "cimaplogger.h" + +#include + +const TInt KOutOfOrderChunks = 3; + + + +CPlainBodyChunkInfo* CPlainBodyChunkInfo::NewL(TInt aChunkNumber, HBufC8* aData) + { + CPlainBodyChunkInfo* self = new(ELeave) CPlainBodyChunkInfo(aChunkNumber,aData); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +/** +Constructor for CPlainBodyChunkInfo. +*/ +CPlainBodyChunkInfo::CPlainBodyChunkInfo(TInt aChunkNumber, HBufC8* aData) +:iChunkNumber(aChunkNumber), iData(aData) + { + } + +void CPlainBodyChunkInfo::ConstructL() + { + + } + +/** +Destructor for CPlainBodyChunkInfo. +*/ +CPlainBodyChunkInfo::~CPlainBodyChunkInfo() + { + delete iData; + } + +/** +Constructor. +*/ +CMsvPlainBodyTextQueueEntry::CMsvPlainBodyTextQueueEntry(TInt aTotalChunks, CImapMailStore& aParent, CMsvServerEntry& aServerEntry, CImapSettings& aImapSettings, CFetchBodyInfo& aFetchBodyInfo, TInt aLogId, MMailStoreObserver& aObserver, MChunkOutOfOrderObserver& aChunkObserver, TBool aBinaryCap) + :CQueueEntryBase(aFetchBodyInfo.PartId(), EPlainTextBody, aParent, aServerEntry, aObserver), + iTotalChunks(aTotalChunks), + iEncoding(aFetchBodyInfo.ContentTransferEncoding()), + iCharsetId(aFetchBodyInfo.CharsetId()), + iBodyPartRemainingSize(aFetchBodyInfo.BodyPartRemainingSize()), + iImapSettings(aImapSettings), + iLogId(aLogId), + iChunkObserver(aChunkObserver) +#if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT) + , iBinaryCap(aBinaryCap) +#endif + { + //to ignore compilation warnings + aBinaryCap = aBinaryCap; + } + + +/** +Destructor. +*/ +CMsvPlainBodyTextQueueEntry::~CMsvPlainBodyTextQueueEntry() + { + delete iStoreUtilities; + iDataArray.ResetAndDestroy(); + iDataArray.Close(); + delete iPlainBodyText; + delete iStore; + delete iDecodedData; + } + +/** +NewL Factory functions. +*/ +CMsvPlainBodyTextQueueEntry* CMsvPlainBodyTextQueueEntry::NewL(TInt aTotalChunks, CImapMailStore& aParent, CMsvServerEntry& aServerEntry, CImapSettings& aImapSettings, CFetchBodyInfo& aFetchBodyInfo, TInt aLogId, MMailStoreObserver& aObserver, MChunkOutOfOrderObserver& aChunkObserver, TBool aBinaryCap) + { + CMsvPlainBodyTextQueueEntry* self=new(ELeave)CMsvPlainBodyTextQueueEntry(aTotalChunks, aParent, aServerEntry, aImapSettings, aFetchBodyInfo, aLogId, aObserver, aChunkObserver, aBinaryCap); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +/** +The Two Phase constructor +*/ +void CMsvPlainBodyTextQueueEntry::ConstructL() + { + BaseConstructL(); + + // Get the default charset + CCnvCharacterSetConverter* characterConverter = CCnvCharacterSetConverter::NewL(); + CleanupStack::PushL(characterConverter); + CImConvertCharconv* charConv = CImConvertCharconv::NewL(*characterConverter, CImapUtils::GetRef().Fs()); + CleanupStack::PushL(charConv); + + TUint defaultCharset = charConv->SystemDefaultCharset(); + CleanupStack::PopAndDestroy(2, characterConverter); + if(iCharsetId == KUidMsvCharsetNone) + { + iCharsetId = defaultCharset; + } + + iStoreUtilities=CStoreUtilities::NewL(iEncoding,iCharsetId,CImapUtils::GetRef().Fs()); + iServerEntry.SetEntry(iId); + iStore = iServerEntry.EditStoreL(); + TInt is8Bit = iImapSettings.Store8BitData(); + iPlainBodyText = iStore->InitialisePlainBodyTextForWriteL(is8Bit,iCharsetId,defaultCharset); + } + + + +/** +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 TBool indicates whether the FETCH command need to be sent to server + ETrue : Send the FETCH command. + EFalse: Do not send the FETCH command. +*/ + +TBool CMsvPlainBodyTextQueueEntry::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 + TBool sendCommand = ETrue; + __LOG_FORMAT((iLogId, "CMsvPlainBodyTextQueueEntry::AddChunkL chunk number = %d",aChunkNumber)); + CleanupStack::PushL(aData); + //make sure the chunk is within range. + __ASSERT_DEBUG(aChunkNumbercompareChunks(CompareChunks); + iDataArray.InsertInOrderL(chunkInfo,compareChunks); + + if(iDataArray.Count() >= KOutOfOrderChunks) + { + sendCommand = EFalse; + } + + CleanupStack::Pop(chunkInfo); + + if(!IsActive()) + { + CompleteSelf(); + } + return sendCommand; + } + + +/** +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 CMsvPlainBodyTextQueueEntry::CompareChunks(const CPlainBodyChunkInfo& aChunkBodyInfo1, const CPlainBodyChunkInfo& aChunkBodyInfo2) + { + return aChunkBodyInfo1.iChunkNumber-aChunkBodyInfo2.iChunkNumber; + } + +TInt CMsvPlainBodyTextQueueEntry::RunError(TInt aError) + { + return CQueueEntryBase::RunError(aError); + } + + + +/** +Uses CMsvPlainBodyText to asynchronousy store the requests data object. +@param +@return +*/ +void CMsvPlainBodyTextQueueEntry::RunL() + { + User::LeaveIfError(iStatus.Int()); + if(iReadyToRemoveChunk) + { + delete iDecodedData; + iDecodedData=NULL; + iChunkObserver.EnableSendFetch(); + iReadyToRemoveChunk=EFalse; + } + +#if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT) + 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, "CMsvPlainBodyTextQueueEntry::RunL Commiting body data...")); + iPlainBodyText->CommitL(); + //call back to the observer as the operation is complete + StoreComplete(KErrNone); + //request can be removed from the queue + iParent.RemoveFromQueueAndDelete(this); + } + else if(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) + { + 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 + { + // create a new buffer, decodedData and push it to CleannupStack because AttachFooterInfoL will + // pop decodedData first and pushes it when it returns. + __LOG_FORMAT((iLogId, "CMsvPlainBodyTextQueueEntry::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, "CMsvPlainBodyTextQueueEntry::RunL AttachFooterInfoL...")); + iStoreUtilities->AttachFooterInfoL(iBodyPartRemainingSize, iImapSettings, decodedData); + } + + // pop decodedData since the ownership will be transferred to iDecodedData. + CleanupStack::Pop(decodedData); + __ASSERT_DEBUG(iDecodedData == NULL, TImapServerPanic::ImapPanic(TImapServerPanic::EMailStoreDecodeDataNotNull)); + + // transferring ownership to iDecodedData. + iDecodedData = decodedData; + + __LOG_FORMAT((iLogId, "CMsvPlainBodyTextQueueEntry::RunL StoreChunk...")); + iPlainBodyText->StoreChunkL(*iDecodedData, iStatus); + SetActive(); + + //delete the origninal encoded chunk + CPlainBodyChunkInfo* chunkInfo=iDataArray[0]; + iDataArray.Remove(0); + delete chunkInfo; + iReadyToRemoveChunk=ETrue; + } + }