--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/email/email/smtp/src/ImCltCvRecv.cpp Thu Jan 21 12:53:44 2010 +0000
@@ -0,0 +1,1444 @@
+// 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 the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+
+
+/**
+ @file
+*/
+
+#include <imcm.rsg>
+#include <barsread.h>
+
+#include <imcvcodc.h>
+#include <imcvutil.h>
+#include <cmsvbodytext.h>
+#include "ImCltCvRecv.h"
+
+#ifdef __WINS__
+#include <e32wins.h>
+#include <msvapi.h>
+#endif
+
+#ifndef __WINS__
+#include <msvapi.h>
+#endif
+#include <cmsvattachment.h>
+#include <mmsvattachmentmanager.h>
+#include <mmsvattachmentmanagersync.h>
+
+#ifndef _MSG_NO_LOGGING
+#define __IMUT_LOGGING
+_LIT(KLogFilePath, "c:\\logs\\mailtext\\in.txt");
+_LIT8(KNewLogHeader, "\r\n------ New Receive Session ------\r\n");
+_LIT8(KFound, "found: ");
+_LIT8(KPartLine, "unknown or part line");
+_LIT8(KEndOFHeader, "End of header");
+_LIT8(KSkippingData, "Skipping data");
+
+_LIT8(KFoundMIMEBoundary, "MIME boundary");
+_LIT8(KRemoveBoundary, "Remove boundary");
+_LIT8(KRemovedBoundary, "Removed boundary");
+_LIT8(KSectionHeader, "Section header");
+_LIT8(KWritingToFile, "writing attachment");
+_LIT8(KWroteToFile, "wrote attachment");
+_LIT8(KFailedToWriteToFile, "Failed to write to attachment file");
+_LIT8(KFoundUUEStartBoundary, "UUE start boundary");
+_LIT8(KFoundUUEEndBoundary, "UUE end boundary");
+_LIT8(KReset, "Resetting CImRecvConvert");
+_LIT8(KReseted, "Resetting CImRecvConvert");
+_LIT8(KLastToken, "That was the last token");
+_LIT8(KResetForNewEntry, "Reset for a New Entry");
+_LIT8(KResetedForNewEntry, "Reseted for a New Entry");
+_LIT8(KCreatingEntry, "Creating Entry");
+_LIT8(KCreatedEntry, "Created Entry");
+_LIT8(KUpdatingEntry, "Updating Entry");
+_LIT8(KUpdatedEntry, "Updated Entry");
+_LIT8(KMoveToParentEntry, "Moved to parent entry");
+_LIT8(KMovedToParentEntry, "End of Moved to parent entry");
+
+_LIT8(KIgnoringStreams, "Discarding streams");
+_LIT8(KStartMessageComplete, "Start Message Complete");
+_LIT8(KMessageComplete, "Message Complete");
+_LIT8(KHeaderComplete, "Message Header complete");
+_LIT8(KReturnReceiptTo, "return-receipt-To is set");
+_LIT8(KStartStoringEntryStream, "Starting Storing Entry Stream");
+_LIT8(KStoringEntryStream, "Storing Entry Stream");
+_LIT8(KDoneStoringEntryStream, "Done Storing Entry Stream");
+
+#endif // _MSG_NO_LOGGING
+
+// uncomment the line below if logging is to be enabled
+
+#if defined(__IMUT_LOGGING)
+#define RECVLOG(text) (iImcvLog?iImcvLog->AppendComment(text):void(0));
+#define RECVLOG_OUT(text) (iImcvLog?iImcvLog->AppendOut(text):void(0));
+#define LOGGING(string1, string2) (Logging(string1, string2));
+#else
+#define RECVLOG(text) (void(0));
+#define RECVLOG_OUT(text) (void(0));
+#define LOGGING(string1, string2) (void(0));
+#endif
+
+
+const TInt KBodyTextChunkSizeBytes = 512;
+
+
+/**
+NewLC()
+Static factory constructor. Uses two phase construction
+and pushes the newly created object into the Cleanup stack.
+
+@param anFs
+@param aClientEntry
+@param aMsgType
+@param aEmailServiceId
+@return
+*/
+ CImCltRecvConvert* CImCltRecvConvert::NewLC(RFs& anFs,CMsvEntry* aClientEntry,TUid aMsgType,TMsvId aEmailServiceId)
+ {
+ CImCltRecvConvert* self = new (ELeave) CImCltRecvConvert(anFs,aClientEntry,aMsgType,aEmailServiceId);
+ CleanupStack::PushL(self);
+ self->ConstructL(anFs);
+ return self;
+ }
+
+
+/**
+NewL()
+Static factory constructor. Uses two phase construction.
+
+@param anFs
+@param aClientEntry
+@param aMsgType
+@param aEmailServiceId
+@return
+*/
+ CImCltRecvConvert* CImCltRecvConvert::NewL(RFs& anFs,CMsvEntry* aClientEntry,TUid aMsgType,TMsvId aEmailServiceId)
+ {
+ CImCltRecvConvert* self = CImCltRecvConvert::NewLC(anFs,aClientEntry,aMsgType,aEmailServiceId);
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+/**
+ConstructL()
+
+@param anFs
+*/
+void CImCltRecvConvert::ConstructL(RFs& anFs)
+ {
+ iFsSession = &anFs;
+
+ RResourceFile resFile;
+ OpenResourceFileL(resFile, anFs); // NB leaves if file not found
+
+ // make sure the resource file will be closed if anything goes wrong
+ // CloseResourceFile is declared in IMUTDLL.H and defined in IMUTDLL.CPP
+ TCleanupItem close( CloseResourceFile, &resFile );
+ CleanupStack::PushL( close );
+
+ // Read iStore8BitData flag.
+ HBufC8* buf = resFile.AllocReadLC(STORE_8BIT_BODY_TEXT);
+ TResourceReader reader;
+ reader.SetBuffer(buf);
+ iStore8BitData = reader.ReadInt8();
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = resFile.AllocReadLC(REMOVED_ATTACHMENT_TAG);
+ reader.SetBuffer(buf);
+ iRemovedAttachmentTag = reader.ReadTPtrC().AllocL();
+ CleanupStack::PopAndDestroy(buf);
+
+ buf = resFile.AllocReadLC(DEFAULT_ATTACHMENT_NAME);
+ reader.SetBuffer(buf);
+ iDefaultAttachmentName = reader.ReadTPtrC().AllocL();
+ CleanupStack::PopAndDestroy(buf);
+ buf = resFile.AllocReadLC(PARTIAL_DOWNLOAD_FOOTER_MESSAGE);
+ reader.SetBuffer(buf);
+ iPartialEmailFooter = (reader.ReadTPtrC()).AllocL();
+ CleanupStack::PopAndDestroy(buf);
+ buf = NULL;
+ CleanupStack::PopAndDestroy(&resFile);
+
+ // create CImHeader object to store Rfc822 header info...
+ iOutputHeader = CImHeader::NewLC();
+ CleanupStack::Pop();
+
+ if (iStore8BitData)
+ {
+ //Create body text storage helper.
+ iBodyText = CMsvBodyText::NewL();
+ }
+ else
+ {
+ // create CRichText object to store body...
+ iParaLayer = CParaFormatLayer::NewL();
+ iCharLayer = CCharFormatLayer::NewL();
+ iOutputBody = CRichText::NewL(iParaLayer, iCharLayer);
+ }
+
+ // Create Rfc822 filter object...
+ iRfc822Token = CLocalRfc822Token::NewLC();
+ CleanupStack::Pop();
+ iRfc822Token->SetImRecvConvert(this);
+
+ // Create converter objects...
+ iCharacterConverter = CCnvCharacterSetConverter::NewL();
+ iCharConv = CImConvertCharconv::NewL(*iCharacterConverter, anFs);
+ iHeaderConverter = CImConvertHeader::NewL(*iCharConv);
+
+
+ // Create MIME filter object...
+ iMimeParser = CLocalMimeParser::NewL(*this);
+
+
+ // logfile stuff
+ iImcvLog=NULL;
+
+#ifdef __IMUT_LOGGING
+ TRAP_IGNORE(iImcvLog=CImLog::NewL(KLogFilePath, EAppend));
+#endif
+
+ iRootEntryId = EntryId();
+
+ iNotFinishedRfc822Header = ETrue;
+
+ iEmailEntry = new (ELeave) TMsvEmailEntry;
+ iReceivingHeadersOnly=EFalse;
+
+ iParent = new (ELeave) CArrayFixFlat<TParentDetails>(3);
+
+ iFirstBoundaryReached=EFalse;
+
+ ResetL();
+
+ RECVLOG( KNewLogHeader )
+ }
+
+
+/**
+CImCltRecvConvert()
+
+@param anFs
+@param aClientEntry
+@param aMsgType
+@param aEmailServiceId
+*/
+
+CImCltRecvConvert::CImCltRecvConvert(RFs& anFs,CMsvEntry* aClientEntry,TUid aMsgType,TMsvId aEmailServiceId)
+ : CLocalImRecvConvert(anFs,iNullServerEntry,aMsgType,aEmailServiceId),
+ iClientEntry(aClientEntry)
+ {
+ __DECLARE_NAME(_S("CImCltRecvConvert"));
+ }
+
+
+/**
+~CImCltRecvConvert()
+Destructor
+*/
+CImCltRecvConvert::~CImCltRecvConvert()
+ {
+ }
+
+
+/**
+ResetForHeadersL()
+*/
+ void CImCltRecvConvert::ResetForHeadersL()
+ {
+ // This function is used in preference to ResetL() when the owner
+ // only wishes to create email entries in the remote mailbox -
+ // they do not wish to create any stores associated with the message
+ // entry
+ ResetL();
+ iReceivingHeadersOnly = ETrue;
+ }
+
+
+/**
+ResetL()
+*/
+ void CImCltRecvConvert::ResetL()
+ {
+ RECVLOG(KReset)
+
+ iBodyId=KMsvNullIndexEntryId;
+ iSizeOfAttachmentsRemoved=0;
+ iClientEntry->SetEntryL(iRootEntryId);
+
+ iReceivingHeadersOnly=EFalse;
+ iMessageEntryCalled=EFalse;
+ iLeaveError=KErrNone;
+ iCurrentMultipartFolderEntryId=0;
+
+ TParentDetails parent;
+ parent.iAttachment=parent.iMHTML=EFalse;
+ parent.iSize=0;
+ iParent->InsertL(0,parent);
+
+ if(iEmailEntry)
+ {
+ delete iEmailEntry;
+ iEmailEntry=NULL;
+ }
+ iEmailEntry = new (ELeave) TMsvEmailEntry;
+
+ // "iSavingAttachments" commands this code to store attachments in files.
+ // Currently this is always set to ETrue as we intend to save all attachments
+ // However, if the user wishes to discard (ie do not save) any
+ // attachments in incoming email messages - then this member variable
+ // may be set to EFalse by the inline accessor function "SaveAllAttachments(TBool)"
+ iSavingAttachments=ETrue;
+ iAttachmentFileState=EFileIsClosed;
+
+ // iLeaveError contains the error value of any functions that leaves (ie CRichText::InsertL)
+ // or any returned error value that generates a leave from within CImRecvConvert (ie RFile::Create)
+
+ iGlobalIndent=0;
+ iLongestLine=50;
+
+ iImPriority=EMsvMediumPriority;
+ if(NULL!=iImcvUtils)
+ {
+ delete iImcvUtils;
+ iImcvUtils=NULL;
+ }
+ iImcvUtils=CImcvUtils::NewL();
+
+ // reset internal date
+ iTimeDate.HomeTime();
+
+ iMimeParser->Reset();
+
+ iNewEntry=EFalse; //EFalse if the entry was moved to. ETrue if the entry was just created
+ iTopMessagePart=KMsvRootIndexEntryId;
+ ResetForNewEntryL(iDefaultEntryType);
+ iMIMEPart_822Header = EFalse;
+ iPartialEmail=EFalse;
+
+ RECVLOG(KReseted)
+ }
+
+
+/**
+ParseNextFieldL()
+
+@param aSourceLine
+@return
+*/
+ TInt CImCltRecvConvert::ParseNextFieldL(const TDesC8& aSourceLine)
+ {
+ __ASSERT_DEBUG(iRootEntryId!=KMsvRootIndexEntryId, gPanic(KPanicServiceIdNotValid));
+ RECVLOG_OUT(aSourceLine);
+
+ if ((iLeaveError == KErrNone) && (iClientEntry->Entry().Id() == KMsvRootIndexEntryId))
+ {
+ iClientEntry->SetEntryL(iSavedEntryId);
+ }
+
+ if(iLeaveError==KErrNone)
+ {
+ TRAP(iLeaveError, ParseNextLineL(aSourceLine));
+ }
+
+ if (iLeaveError==KErrNone)
+ iSavedEntryId = iClientEntry->Entry().Id();
+ TUid type = iClientEntry->Entry().iType;
+ if( type != KUidMsvMessageEntry &&
+ type != KUidMsvEmailTextEntry &&
+ type != KUidMsvEmailHtmlEntry &&
+ type != KUidMsvAttachmentEntry)
+ {
+ iClientEntry->SetEntryL(KMsvRootIndexEntryId);
+ }
+
+
+ return iLeaveError;
+ }
+
+
+/**
+ParseNextLineL()
+
+@param aSourceLine
+*/
+void CImCltRecvConvert::ParseNextLineL(const TDesC8& aSourceLine)
+ {
+ iParsedMimeBoundaryLast=0;
+ if(!iFinishedHeader)
+ {
+ // start by getting the next token from the header
+ iRfc822Token->ParseNextLineL(aSourceLine);
+
+ switch(iRfc822Token->iHeaderPart)
+ {
+ case CLocalRfc822Token::EUnknown:
+ case CLocalRfc822Token::ENotFinished:
+ RECVLOG(KPartLine)
+ break;
+ case CLocalRfc822Token::EFrom:
+ iOutputHeader->SetFromL(*iRfc822Token->OutputLine());
+ LOGGING(KFound,KImcvFromPrompt);
+ break;
+ case CLocalRfc822Token::EReplyTo:
+ iOutputHeader->SetReplyToL(*iRfc822Token->OutputLine());
+ LOGGING(KFound,KImcvReplyToPrompt);
+ break;
+ case CLocalRfc822Token::ETo:
+ ParseRecipientListL(iOutputHeader->ToRecipients());
+ LOGGING(KFound,KImcvToPrompt);
+ break;
+ case CLocalRfc822Token::ECc:
+ ParseRecipientListL(iOutputHeader->CcRecipients());
+ LOGGING(KFound,KImcvCcPrompt);
+ break;
+ case CLocalRfc822Token::EBcc:
+ ParseRecipientListL(iOutputHeader->BccRecipients());
+ LOGGING(KFound,KImcvBccPrompt);
+ break;
+ case CLocalRfc822Token::ESubject:
+ iOutputHeader->SetSubjectL(*iRfc822Token->OutputLine());
+ LOGGING(KFound,KImcvSubjectPrompt);
+ break;
+ case CLocalRfc822Token::EDate:
+ iRfc822Date.ParseDateField(*iRfc822Token->OutputLine() , iTimeDate);
+ if (iEmailEntry->Id() != iTopMessagePart)
+ {
+ iEmailEntry->iDate = iTimeDate;
+ }
+ LOGGING(KFound,KImcvDatePrompt);
+ break;
+ case CLocalRfc822Token::EMessageId:
+ iOutputHeader->SetImMsgIdL(*iRfc822Token->OutputLine());
+ LOGGING(KFound,KImcvMessageIdPrompt);
+ break;
+ case CLocalRfc822Token::EPriority:
+ iImPriority=iImcvUtils->EvaluatePriorityText(*iRfc822Token->OutputLine());
+ LOGGING(KFound,KImcvPriorityPrompt);
+ break;
+ case CLocalRfc822Token::EReturnReceiptTo:
+ iOutputHeader->SetReceiptAddressL(*iRfc822Token->OutputLine());
+ LOGGING(KFound,KReturnReceiptTo);
+ break;
+ case CLocalRfc822Token::EEndOfHeader:
+ // the next line goes in the body part
+ iFinishedHeader = ETrue;
+ RECVLOG(KEndOFHeader)
+ break;
+ default:
+ RECVLOG(KEndOFHeader)
+ break;
+ }
+
+
+ if(iRfc822Token->iHeaderPart != CLocalRfc822Token::ENotFinished)
+ {
+ // Now that we've used the data, we also need to clear the output line from the tokeniser....
+ iRfc822Token->OutputLine()->Des() = KNullDesC8;
+
+ // whatever part we just read, we may also have read the empty line that separates
+ // the header from the body
+ if((iFinishedHeader = iRfc822Token->LastToken()) != EFalse) //iFinishedHeader set to 1 on CRLF-
+ {
+ RECVLOG(KLastToken);
+ iNotFinishedRfc822Header = EFalse;
+
+ iHeaderConverter->SetMessageType(iMimeParser->MessageIsMime());
+ iHeaderConverter->DecodeAllHeaderFieldsL(*iOutputHeader);
+
+ if (iMimeParser->MessageIsMime())
+ {
+ EndOfHeaderMIMEProcessingL();
+ }
+ else
+ {
+ EndOfHeaderProcessingL();
+ }
+
+ if (iStore8BitData)
+ {
+ iBodyText->SetDefaultCharacterSet(iCharConv->SystemDefaultCharset());
+ if ( iMimeParser->MessageIsMime() && iMimeParser->ContentType()==EMimeText )
+ {
+ iBodyText->SetCharacterSet(iMimeParser->CurrentCharsetL());
+ }
+ else
+ {
+ iBodyText->SetCharacterSet(0);
+ }
+ }
+ else
+ {
+ // Get charset for decoding.
+ if ( iMimeParser->MessageIsMime() && iMimeParser->ContentType()==EMimeText )
+ {
+ iCharConv->PrepareToConvertToFromOurCharsetL(iMimeParser->CurrentCharsetL());
+ }
+ else
+ {
+ iCharConv->PrepareToConvertToFromOurCharsetL(iCharConv->SystemDefaultCharset());
+ }
+ }
+ }
+ }
+ }
+ else if (iReceivingHeadersOnly==EFalse)
+ {
+ //Set to EFalse when a single line is to be skipped (ie boundary line)
+ iCommitLine=ETrue;
+
+ // read one line of the message body if I am processing a whole email message
+ if(iMimeParser->MessageIsMime())
+ {
+ ParseMimeLineL(aSourceLine);
+ }
+ else
+ {
+ ParseBodyLineL(aSourceLine);
+ }
+
+ if((iCommitLine)&&(!iSkipData))
+ {
+ DecodeAndStoreLineL(aSourceLine);
+ }
+ }
+ }
+
+
+/**
+MessageEntryDetailsL()
+
+@return
+*/
+ TMsvEmailEntry CImCltRecvConvert::MessageEntryDetailsL()
+ {
+
+ iMessageEntryCalled=ETrue;
+ CloseAttachmentFileL();
+
+ // A message requiring manual termination and not part way through a MIME part header
+ if( iTopMessagePart==EntryId() && iFinishedHeader)
+ {
+ StoreEntryStreamsL(KStore822Header|KStoreMIMEHeader);
+ }
+ else
+ {
+ iClientEntry->SetEntryL(iTopMessagePart);
+ if(iEmailEntry)
+ {
+ delete iEmailEntry;
+ iEmailEntry=NULL;
+ }
+
+ iEmailEntry = new (ELeave) TMsvEmailEntry(iClientEntry->Entry());
+ }
+
+ return *iEmailEntry;
+ }
+
+
+/**
+MessageCompleteL()
+
+@param aEmailEntry
+*/
+ void CImCltRecvConvert::MessageCompleteL(TMsvEmailEntry aEmailEntry)
+ {
+ if (iClientEntry->Entry().Id() == KMsvRootIndexEntryId)
+ {
+ iClientEntry->SetEntryL(iSavedEntryId);
+ }
+
+ __ASSERT_DEBUG(iMessageEntryCalled, gPanic(KPanicMessageEntryNotCalled));
+ __ASSERT_DEBUG(aEmailEntry.Id()==iTopMessagePart, gPanic(KPanicMessageEntryIdHasChanged));
+
+ // Called ResetL() to reset object instead of ResetForHeadersL()
+ __ASSERT_DEBUG(iReceivingHeadersOnly, gPanic(KPanicIncorrectResetState));
+
+ if(iEmailEntry)
+ {
+ if (iEmailEntry->Id())
+ {
+ if(iLeaveError==KErrNone)
+ {
+ // a remote email header cannot have any attachments or be marked as complete...
+ aEmailEntry.SetAttachment(EFalse);
+ aEmailEntry.SetMHTMLEmail(EFalse);
+ aEmailEntry.SetComplete(EFalse);
+ iClientEntry->SetEntryL(aEmailEntry.Id());
+ RECVLOG(KHeaderComplete)
+ }
+ else
+ {
+ if (!iPopulateMessage)
+ {
+ TMsvId currentId = EntryId();
+ iClientEntry->SetEntryL(iClientEntry->Entry().Parent());
+ iClientEntry->DeleteL(currentId);
+ }
+ User::Leave(iLeaveError);
+ }
+ }
+ }
+
+ iSavedEntryId = iClientEntry->Entry().Id();
+ iClientEntry->SetEntryL(KMsvRootIndexEntryId);
+ }
+
+
+/**
+MessageCompleteL()
+
+@return
+*/
+ TMsvId CImCltRecvConvert::MessageCompleteL()
+ {
+ RECVLOG(KStartMessageComplete)
+ if (iClientEntry->Entry().Id() == KMsvRootIndexEntryId)
+ {
+ iClientEntry->SetEntryL(iSavedEntryId);
+ }
+ if (iParsedMimeBoundaryLast==EFalse && iAttachmentFileState==EFileIsOpen && iPartialEmail!=EFalse)
+ {
+ iAttachmentFileState=EFileTopIncomplete;
+ }
+
+ CloseAttachmentFileL();
+
+ if(!iEmailEntry->Id())
+ {
+ return 0;
+ }
+
+ if(iLeaveError!=KErrNone)
+ {
+ User::Leave(iLeaveError);
+ }
+
+ if (EntryId()!=iTopMessagePart)
+ {
+ iEmailEntry->SetComplete(ETrue);
+ StoreEntryStreamsL(KStoreBodyText);
+ MoveToParentEntryL();
+
+ if( iTopMessagePart==EntryId() && iFinishedHeader)
+ {
+ iEmailEntry->SetVisible(ETrue);
+ iEmailEntry->SetInPreparation(EFalse);
+ iEmailEntry->SetBodyTextComplete(ETrue);
+ iEmailEntry->SetComplete(ETrue);
+ iEmailEntry->SetSendingState(KMsvSendStateWaiting);
+ // Main message.
+ StoreMessageEntryDetailsL();
+ return iEmailEntry->Id();
+ }
+ else if(iEmailEntry->iType == KUidMsvMessageEntry)
+ {
+ StoreMessageEntryDetailsL();
+ MoveToParentEntryL();
+ StoreMessageEntryDetailsL();
+ }
+ }
+
+ iClientEntry->SetEntryL(iTopMessagePart);
+ if(NULL!=iEmailEntry)
+ {
+ delete iEmailEntry;
+ iEmailEntry=NULL;
+ }
+ iEmailEntry = new (ELeave) TMsvEmailEntry(iClientEntry->Entry());
+ iEmailEntry->SetVisible(ETrue);
+ iEmailEntry->SetInPreparation(EFalse);
+ iEmailEntry->SetComplete(ETrue);
+ iEmailEntry->SetBodyTextComplete(ETrue);
+
+ iEmailEntry->SetSendingState(KMsvSendStateWaiting);
+
+
+ iEmailEntry->SetAttachment(iParent->At(0).iAttachment);
+ iEmailEntry->SetMHTMLEmail(iParent->At(0).iMHTML);
+
+ if(iEmailEntry->MHTMLEmail() == EFalse && iEmailEntry->Attachment() == EFalse && iRelatedAttachments !=EFalse)
+ {
+ iEmailEntry->SetAttachment(ETrue);
+ }
+ iRelatedAttachments=EFalse;
+
+ iEmailEntry->iSize=iParent->At(0).iSize;
+ iEmailEntry->SetMessageFolderType(iParent->At(0).iFolder);
+
+ iClientEntry->ChangeL(*iEmailEntry);
+
+ iSavedEntryId = iClientEntry->Entry().Id();
+ iClientEntry->SetEntryL(KMsvRootIndexEntryId);
+ RECVLOG(KMessageComplete)
+ return iEmailEntry->Id();
+ }
+
+
+ /**
+ParseMimeLineL()
+
+@param aSourceLine
+*/
+void CImCltRecvConvert::ParseMimeLineL(const TDesC8& aSourceLine)
+ {
+ iTopPartialDownloadCounter+=aSourceLine.Length(); // increment the number of bytes of the attachment downloaded so far
+ if(!iMimeParser->IsBoundary(aSourceLine))
+ {
+ if(!iPrepared) // first line of the body
+ {
+ if (iMIMEPart_822Header)
+ {
+ // missing 822 part header. Revert to default.
+ EndOfHeaderMIMEProcessingL();
+ iMIMEPart_822Header=EFalse;
+ }
+
+ PrepareDecoder();
+ }
+
+ if (CheckUUEStartL(aSourceLine))
+ {
+ iAlgorithm=EUUDecode;
+ iCommitLine=EFalse;
+ }
+ }
+ else
+ {
+ iParsedMimeBoundaryLast=ETrue;
+ // found a MIME boundary so store the current parts data and update its entry.
+
+ RECVLOG(KFoundMIMEBoundary)
+ iCommitLine=EFalse; //Dont store this line as its a boundary.
+
+ if(!iFirstBoundaryReached && iEntryType==EFolderEntry)
+ {
+ iFirstBoundaryReached=ETrue;
+ if (!iCurrentMultipartFolderEntryId)
+ iCurrentMultipartFolderEntryId = EntryId();
+ MoveToParentEntryL();
+ ResetForNewEntryL(iDefaultEntryType);
+ return; // First boundary encountered.
+ }
+
+ CloseAttachmentFileL();
+ if(iNewEntry)
+ {
+ iEmailEntry->SetComplete(ETrue);
+ iEmailEntry->SetBodyTextComplete(ETrue);
+ StoreEntryStreamsL(KStoreMIMEHeader | KStoreBodyText);
+ if (iBodyId==KMsvNullIndexEntryId)
+ {
+ iBodyId=iEmailEntry->Id();
+ }
+ }
+
+ iSkipData = EFalse;
+
+ // check whether we just found the terminating boundary...
+ if(iMimeParser->IsTerminatingBoundary())
+ {
+ RECVLOG(KRemoveBoundary);
+ iMimeParser->RemoveBoundary();
+ RECVLOG(KRemovedBoundary);
+ iMIMEPart_822Header = EFalse;
+
+ if (EntryId()!=iTopMessagePart)
+ {
+ if(iEmailPart==KParentPart)
+ {
+ // rfc822 message which is not not multipart.
+ iEmailPart=KNoPart;
+ MoveToParentEntryL();
+
+ // Embedded message
+ iEmailEntry->SetComplete(ETrue);
+ iEmailEntry->SetBodyTextComplete(ETrue);
+ StoreMessageEntryDetailsL();
+ }
+ else if (iEmailEntry->iType==KUidMsvMessageEntry)
+ {
+ // Moving up from a multi embedded rfc822 message.
+ iEmailEntry->SetComplete(ETrue);
+ iEmailEntry->SetBodyTextComplete(ETrue);
+ StoreMessageEntryDetailsL();
+ }
+ }
+
+ MoveToParentEntryL();
+ iEntryDataSize = iEmailEntry->iSize;
+
+ if(iClientEntry->Entry().iType == KUidMsvFolderEntry)
+ {
+ iCurrentMultipartFolderEntryId = EntryId();
+ }
+ else if (EntryId()!=iTopMessagePart)
+ {
+ if(iEmailEntry->iType == KUidMsvMessageEntry)
+ {
+ iEmailEntry->SetComplete(ETrue);
+ iEmailEntry->SetBodyTextComplete(ETrue);
+ StoreMessageEntryDetailsL();
+ }
+ MoveToParentEntryL();
+ iEntryDataSize += iEmailEntry->iSize;
+ }
+
+ if(!iNewEntry)
+ ResetForNonMimeEntryL();
+
+ RECVLOG(KSkippingData)
+ iSkipData = ETrue;
+ iDefaultEntryType=ETextEntry;
+ }
+ else // if regular boundary
+ {
+ RECVLOG(KSectionHeader)
+ if(iEmailPart==KParentPart && EntryId()!=iTopMessagePart)
+ {
+ // rfc822 message which is not not multipart.
+ iEmailPart=KNoPart;
+ MoveToParentEntryL();
+ // Embedded message
+ iEmailEntry->SetComplete(ETrue);
+ iEmailEntry->SetBodyTextComplete(ETrue);
+ StoreMessageEntryDetailsL();
+ }
+
+ if (!iCurrentMultipartFolderEntryId && iEmailPart==KNoPart)
+ MoveToParentEntryL();
+
+ ResetForNewEntryL(iDefaultEntryType);
+ }
+ }
+ }
+
+
+/**
+EndOfHeaderProcessingL()
+*/
+void CImCltRecvConvert::EndOfHeaderProcessingL()
+ {
+ CreateEntryL();
+ StoreEntryStreamsL(KStore822Header);
+ iEntryDataSize = 0;
+ }
+
+
+/**
+ParseBodyLineL()
+
+@param aSourceLine
+*/
+void CImCltRecvConvert::ParseBodyLineL(const TDesC8& aSourceLine)
+ {
+ TInt len=aSourceLine.Length();
+ iTopPartialDownloadCounter+=len; // added for TOP. increment the number of bytes of the attachment downloaded so far
+
+ if (iBodyId==KMsvNullIndexEntryId)
+ {
+ iBodyId=iEmailEntry->Id();
+ }
+
+ TMsvId id=0;
+ // first check whether this line is a UUEncode start boundary
+ if(CheckUUEStartL(aSourceLine))
+ {
+ RECVLOG(KFoundUUEStartBoundary)
+ TFileName tempStore = iAttachmentName;
+ id = EntryId();
+ if (!iNewNonMIMEBodyPart || id!=iTopMessagePart) // main message entry
+ {
+ iEmailEntry->SetComplete(ETrue);
+ iEmailEntry->SetBodyTextComplete(ETrue);
+ StoreEntryStreamsL(KStoreBodyText);
+ }
+ MoveToParentEntryL();
+ if ( !CreateNonMIMEFolderEntryL(id))
+ {
+ ResetForNonMimeEntryL();
+ }
+
+ iEntryType = EAttachmentEntry;
+ CreateEntryL();
+ SetAttachmentName(tempStore);
+
+ iCurrentPartIsRichText = EFalse;
+ iAlgorithm=EUUDecode;
+ iCommitLine=EFalse;
+ if(!iSavingAttachments)
+ {
+ RECVLOG(KSkippingData)
+ iSkipData=ETrue;
+ }
+ iNewNonMIMEBodyPart=EFalse;
+ }
+ else if(aSourceLine.CompareF(KImcvUueEnd)==0) // Checks for the UUEncode end boundary
+ {
+ RECVLOG(KFoundUUEEndBoundary)
+ CloseAttachmentFileL();
+ StoreEntryDataL();
+ MoveToParentEntryL();
+ iSkipData = EFalse;
+ iCommitLine=EFalse;
+ iNewNonMIMEBodyPart=ETrue;
+ }
+ else if (iNewNonMIMEBodyPart && !( len==2 && aSourceLine[0]==KImcvCR && aSourceLine[1]==KImcvLF ))
+ {
+ id = EntryId();
+ if (!iNewNonMIMEBodyPart || id!=iTopMessagePart)
+ {
+ iEmailEntry->SetComplete(ETrue);
+ iEmailEntry->SetBodyTextComplete(ETrue);
+ StoreEntryStreamsL(KStoreBodyText);
+ }
+ MoveToParentEntryL();
+ if ( !CreateNonMIMEFolderEntryL(id))
+ ResetForNonMimeEntryL();
+ iAlgorithm=ENoAlgorithm;
+ iEntryType = ETextEntry;
+ CreateEntryL();
+ iNewNonMIMEBodyPart=EFalse;
+ }
+ }
+
+
+/**
+CreateNonMIMEFolderEntryL()
+
+@param aCurrentId
+@return
+*/
+TBool CImCltRecvConvert::CreateNonMIMEFolderEntryL(TMsvId aCurrentId)
+ {
+ if ( aCurrentId==iTopMessagePart || iCurrentMultipartFolderEntryId )
+ return EFalse;
+
+ iClientEntry->SetEntryL(iTopMessagePart);
+ iEmailPart = KMultiPart;
+ iEntryType = EFolderEntry;
+ CreateEntryL();
+
+ TMsvId destId = EntryId();
+ iClientEntry->SetEntryL(iTopMessagePart);
+ iClientEntry->MoveL(aCurrentId, destId);
+ iClientEntry->SetEntryL(aCurrentId);
+ iClientEntry->SetEntryL(iClientEntry->Entry().Parent());
+
+ iEmailEntry->SetMessageFolderType(iMimeParser->MessageFolderType());
+
+ RECVLOG(KResetForNewEntry)
+
+ iMimeParser->ResetForNewEntry();
+
+ if (iStore8BitData)
+ {
+ //Create a buffer to hold the body text as it is down loaded.
+ delete iBodyBuf;
+ iBodyBuf = NULL;
+ iBodyBuf = CBufFlat::NewL(KBodyTextChunkSizeBytes);
+ }
+ else
+ {
+ iOutputBody->Reset();
+ }
+
+ ResetForNonMimeEntryL();
+ RECVLOG(KResetedForNewEntry)
+ return ETrue;
+ }
+
+
+/**
+CreateAttachmentL()
+
+@return
+*/
+TBool CImCltRecvConvert::CreateAttachmentL()
+ {
+ // added to support TOP command. Reset the download counter each time we have a new
+ // attachment
+ iTopPartialDownloadCounter = 0;
+
+ // Need to check that the complete filename: iAttachmentFullPath & iAttachmentName
+ // does not exceed 256 characters. Greater than this and it cannot be saved as a file.
+
+ TBool addExtension = ETrue;
+ if(iAttachmentName.Length() == 0) //i.e. problem with Attachment name
+ {
+ // No filename present. Generate one.
+ if(iMimeParser->ContentDescription().Length()!=0)
+ {
+ // Use ContentDescription() as default name
+ // - as this is more informative than the default
+
+ TLex sourceLineLex = iMimeParser->ContentDescription();
+ ExtractFilename(sourceLineLex, iAttachmentName);
+ }
+ else
+ {
+ iAttachmentName = *iDefaultAttachmentName;
+ }
+
+ }
+ else
+ {
+ // Filename present. Check it is valid.
+ ReplaceInvalidCharacters(iAttachmentName);
+ if (iAttachmentName.Locate(KImcvFullStop)!=KErrNotFound)
+ {
+ addExtension=EFalse;
+ }
+
+ }
+ if (addExtension)
+ {
+ AddFileExtension();
+ }
+ CMsvStore* store = iClientEntry->EditStoreL();
+ CleanupStack::PushL(store);
+ CMsvAttachment* attachment = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
+ CleanupStack::PushL(attachment);
+ attachment->SetAttachmentNameL(iAttachmentName);
+
+ RFile file;
+ store->AttachmentManagerExtensionsL().CreateAttachmentL(iAttachmentName,file,attachment);
+ CleanupStack::Pop(attachment);
+
+ iAttachmentFile.SetFileHandle(file,TImAttachmentFile::EImFileWrite);
+ store->CommitL();
+ CleanupStack::PopAndDestroy(store); // store
+
+ if(KErrNone!=iLeaveError)
+ {
+ iAttachmentFileState=EFileFailedToOpen;
+ CloseAttachmentFileL();
+ return EFalse;
+ }
+
+ iAttachmentFileState=EFileIsOpen;
+ return ETrue;
+ }
+
+
+/**
+WriteToAttachmentL()
+
+@param text
+*/
+void CImCltRecvConvert::WriteToAttachmentL(const TDesC8& text)
+ {
+ if ( (iAttachmentFileState==EFileIsClosed || iAttachmentFileState==EFileNotOpen)
+ && CreateAttachmentL() && iEntryType!=EHtmlEntry)
+ iEmailEntry->SetAttachment(ETrue);
+
+ if(iAttachmentFileState!=EFileIsOpen || !text.Length())
+ {
+ RECVLOG(KSkippingData)
+ iSkipData = ETrue;
+ }
+
+ // write decoded data into a file if there is any data there to write.
+
+ RECVLOG(KWritingToFile)
+
+ // Convert text before writing to attachment.
+
+ // Store as Binary files..
+ iLeaveError=iAttachmentFile.WriteFile(text);
+
+ if(KErrNone==iLeaveError)
+ {
+ iEntryDataSize += text.Length();
+ }
+
+ else
+ {
+ // the file write failed (eg.there is no space left), set new file state and skip
+ RECVLOG(KFailedToWriteToFile)
+ iAttachmentFileState=EFileIsIncomplete;
+ CloseAttachmentFileL();
+ }
+ RECVLOG(KWroteToFile)
+ }
+
+
+/**
+StoreEntryStreamsL()
+*/
+void CImCltRecvConvert::StoreEntryStreamsL()
+ {
+ StoreEntryStreamsL(KStoreBodyText | KStore822Header | KStoreMIMEHeader);
+ }
+
+
+
+/**
+StoreEntryStreamsL()
+
+@param aSettings
+*/
+void CImCltRecvConvert::StoreEntryStreamsL(TInt aSettings)
+ {
+ RECVLOG(KStartStoringEntryStream);
+ if (iReceivingHeadersOnly==EFalse)
+ {
+ CMsvStore* entryStore = NULL;
+ TBool commitStore = EFalse;
+
+ TRAPD(error, entryStore = iClientEntry->EditStoreL());
+ if(error==KErrNone) // if store does not exist then the entry is the wrong type
+ {
+ CleanupStack::PushL(entryStore);
+
+ if (aSettings & KStore822Header)
+ {
+ Store822HeaderL(*entryStore, commitStore);
+ }
+
+ if (aSettings & KStoreMIMEHeader)
+ {
+ StoreMIMEHeaderL(*entryStore, commitStore);
+ }
+
+ if (aSettings & KStoreBodyText)
+ {
+ StoreBodyTextL(*entryStore, commitStore);
+ }
+ // only commit to the store if I wrote something into it
+ if (commitStore)
+ {
+ RECVLOG(KStoringEntryStream);
+ entryStore->CommitL();
+ }
+
+ StoreEntryDataL();
+ CleanupStack::PopAndDestroy(); //entryStore
+ }
+
+ }
+ RECVLOG(KDoneStoringEntryStream);
+ }
+
+
+/**
+StoreEntryDataL()
+
+@return
+*/
+TBool CImCltRecvConvert::StoreEntryDataL()
+ {
+ // NB function should only be called if a whole email is being processed
+ TBool commit=EFalse;
+ RECVLOG(KUpdatingEntry)
+
+ if (iEmailEntry->iType==KUidMsvMessageEntry)
+ {
+ iParent->At(0).iSize += iEntryDataSize;
+ }
+ else
+ {
+ iEmailEntry->iSize += iEntryDataSize;
+ if (iEntryType==EAttachmentEntry || iEntryType==EHtmlEntry)
+ {
+ iEmailEntry->iDetails.Set(iAttachmentName);
+ }
+ }
+ iClientEntry->ChangeL(*iEmailEntry);
+
+ RECVLOG(KUpdatedEntry)
+ return commit; // if I wrote data into the store, tell owner
+ }
+
+
+/**
+MoveToParentEntryL()
+*/
+void CImCltRecvConvert::MoveToParentEntryL()
+ {
+ // This function changes the context to the current entry's parent entry.
+ RECVLOG(KMoveToParentEntry)
+
+ // Change context to the parent entry
+ if (EntryId()==iTopMessagePart)
+ {
+ return; // Already there.
+ }
+
+ iClientEntry->SetEntryL(iClientEntry->Entry().Parent());
+
+ iNewEntry = EFalse;
+
+ // only read and write to store if this is a real email message; headers stored in
+ // the remote mailbox do not require any store information.
+ if (iReceivingHeadersOnly)
+ {
+ RECVLOG(KIgnoringStreams)
+ return;
+ }
+
+ TBool allowAttachmentFlag=ETrue;
+ if(iClientEntry->Entry().iType == KUidMsvFolderEntry)
+ {
+ // Current entry is a folder entry signifying a MIME multipart.
+ // Change context to the parent entry
+ TMsvEmailEntry entry = (TMsvEmailEntry) iClientEntry->Entry();
+ iCurrentMultipartFolderEntryId = EntryId();
+ allowAttachmentFlag = !(entry.MessageFolderType()==EFolderTypeRelated ||
+ entry.MessageFolderType()==EFolderTypeAlternative);
+
+
+ if (EntryId()!=iTopMessagePart)
+ {
+ iClientEntry->SetEntryL(iClientEntry->Entry().Parent());
+ }
+ }
+
+ TBool childIsAttachment = (iEmailEntry->Attachment() || iEmailEntry->iType == KUidMsvMessageEntry) ? ETrue:EFalse;
+ TBool childIsMHTML=EFalse;
+ // Dont want the flag propogated 'up' past a message entry.
+ if(iEmailEntry->iType != KUidMsvMessageEntry)
+ {
+ childIsMHTML = iEmailEntry->MHTMLEmail() ? ETrue:EFalse;
+ }
+ //Make the parent entry the current entry
+ if(iEmailEntry)
+ {
+ delete iEmailEntry;
+ iEmailEntry=NULL;
+ }
+ iEmailEntry = new (ELeave) TMsvEmailEntry(iClientEntry->Entry());
+
+ if (!iParent->Count())
+ {
+ TParentDetails parentDetails;
+ iParent->InsertL(0,parentDetails);
+ }
+
+ if (! iParent->At(0).iAttachment)
+ {
+ iParent->At(0).iAttachment=(childIsAttachment && allowAttachmentFlag)? ETrue:EFalse;
+
+ // if we aren't allowing attachments because of the folder type
+ // remember there where attachments and check at the end whether
+ // it was an MHTML message or not.
+ if(childIsAttachment && !allowAttachmentFlag)
+ {
+ iRelatedAttachments=ETrue;
+ }
+ }
+ if (!iParent->At(0).iMHTML)
+ {
+ iParent->At(0).iMHTML = childIsMHTML ? ETrue:EFalse;
+ }
+ iParent->At(0).iSize += iEntryDataSize;
+
+ iOutputHeader->Reset();
+ iEmptyHeaderSize=iOutputHeader->DataSize();
+ iMimeParser->ResetForNewEntry();
+
+ iEntryDataSize=0;
+
+ RECVLOG(KMovedToParentEntry)
+ }
+
+
+/**
+CreateEntryL()
+Creates a new entry.
+*/
+void CImCltRecvConvert::CreateEntryL()
+ {
+ RECVLOG(KCreatingEntry);
+ if(NULL!=iEmailEntry)
+ {
+ delete iEmailEntry;
+ iEmailEntry=NULL;
+ }
+
+ if (iCurrentMultipartFolderEntryId)
+ {
+ iClientEntry->SetEntryL(iCurrentMultipartFolderEntryId);
+ iCurrentMultipartFolderEntryId=0;
+ }
+
+ iEmailEntry = new (ELeave) TMsvEmailEntry;
+
+ TValidEntryType previousEntryType = iEntryType;
+ if ((iTopMessagePart==KMsvRootIndexEntryId) || iMIMEPart_822Header)
+ {
+ // At the main header, want to create a message entry.
+ // The stored iEntryType will indicate ( from header info) the next entry to be created.
+ // Save temporarily.
+ // Also applies to the special case where a message contains ony 1 embedded message.
+
+ previousEntryType=iEntryType;
+ iEntryType=EMessageEntry;
+ }
+
+ if ((iPopulateMessage) && (iTopMessagePart==KMsvRootIndexEntryId))
+ // If this is the root of a message that is being populated then do not create it.
+ {
+ iClientEntry->SetEntryL(iRootEntryId);
+ *iEmailEntry = iClientEntry->Entry();
+ iTopMessagePart=iRootEntryId;
+
+ // Delete all the children of the message entry. This is needed because if the
+ // message has been purged, the entries will still exist. When the message is populated,
+ // new entries are created. If the original entries are not removed, then duplicate
+ // entries will exist.
+ CMsvEntrySelection* children = iClientEntry->ChildrenL();
+ CleanupStack::PushL(children);
+ if (children->Count())
+ {
+ TMsvLocalOperationProgress prog;
+ iClientEntry->DeleteL(*children,prog);
+ }
+ CleanupStack::PopAndDestroy(children);
+ }
+ else
+ {
+ iEmailEntry->iMtm=iNewMsgType;
+ iEmailEntry->iServiceId = iEmailServiceId;
+ iEmailEntry->SetComplete(EFalse);
+ iEmailEntry->iSize = 0;
+ iEmailEntry->SetVisible(ETrue);
+ iEmailEntry->SetInPreparation(EFalse);
+ iEmailEntry->SetReceipt(EFalse);
+
+ iEmailEntry->SetVCard(iMimeParser->VCard());
+ iEmailEntry->SetVCalendar(iMimeParser->VCalendar());
+ iEmailEntry->SetMessageFolderType(iMimeParser->MessageFolderType());
+ iEmailEntry->SetPriority(iImPriority);
+ iEmailEntry->SetNew(EFalse);
+
+ if(iOutputHeader->ReceiptAddress().Length()>0)
+ {
+ iEmailEntry->SetReceipt(ETrue);
+ }
+
+ iEmailEntry->iDate=iTimeDate;
+ switch(iEntryType)
+ {
+ case EMessageEntry:
+ if(iTopMessagePart==KMsvRootIndexEntryId)
+ {
+ iEmailEntry->SetUnread(ETrue);
+ iEmailEntry->SetNew(ETrue);
+ iEmailEntry->SetVisible(EFalse);
+ iEmailEntry->SetInPreparation(ETrue);
+ iEmailEntry->SetSendingState(KMsvSendStateNotApplicable);
+ }
+ else
+ {
+ TParentDetails parentDetails;
+ parentDetails.iMHTML=EFalse;
+ parentDetails.iAttachment=EFalse;
+ parentDetails.iSize=0;
+ iParent->InsertL(0,parentDetails);
+ }
+ iEmailEntry->iType=KUidMsvMessageEntry;
+ iEmailEntry->iDetails.Set(iOutputHeader->From());
+ iEmailEntry->iDescription.Set(iOutputHeader->Subject());
+ break;
+ case EFolderEntry:
+ iEmailEntry->iType=KUidMsvFolderEntry;
+ if (iMimeParser->MessageFolderType()==EFolderTypeUnknown)
+ {
+ // Get folder type of parent (the message)
+ TMsvEmailEntry entry=iClientEntry->Entry();
+ iEmailEntry->SetMessageFolderType(entry.MessageFolderType());
+ }
+ break;
+ case EAttachmentEntry:
+ iEmailEntry->iType=KUidMsvAttachmentEntry;
+ iEmailEntry->iDetails.Set(iAttachmentName);
+ iEmailEntry->iDescription.Set(iMimeParser->ContentDescription());
+ break;
+ case ETextEntry:
+ if ( iMimeParser->ContentDisposition()!=KImcvAttachment)
+ iEmailEntry->iType=KUidMsvEmailTextEntry;
+ else
+ {
+ iEmailEntry->iType=KUidMsvAttachmentEntry;
+ iEmailEntry->iDetails.Set(iAttachmentName);
+ iEmailEntry->iDescription.Set(iMimeParser->ContentDescription());
+ }
+ break;
+ case EHtmlEntry:
+ iEmailEntry->iType=KUidMsvEmailHtmlEntry;
+ // If disposition not set or is inline..
+ if ( iMimeParser->ContentDisposition()==KImcvAttachment)
+ iEmailEntry->iType=KUidMsvAttachmentEntry;
+ else
+ iEmailEntry->SetMHTMLEmail(ETrue);
+ iEmailEntry->iDetails.Set(iAttachmentName);
+ iEmailEntry->iDescription.Set(iMimeParser->ContentDescription());
+ break;
+ default:
+ iEmailEntry->iType=KUidMsvAttachmentEntry;
+ iEmailEntry->iDetails.Set(iAttachmentName);
+ iEmailEntry->iDescription.Set(iMimeParser->ContentDescription());
+ }
+
+ iClientEntry->CreateL(*iEmailEntry);
+ iEmailEntry->iServiceId = iEmailServiceId;
+ iClientEntry->SetEntryL(iEmailEntry->Id());
+ if(iTopMessagePart==KMsvRootIndexEntryId)
+ {
+ iTopMessagePart=iEmailEntry->Id();
+ }
+ }
+
+ iEntryType=previousEntryType;
+ iNewEntry = ETrue;
+ RECVLOG(KCreatedEntry);
+ }
+
+
+/**
+StoreMessageEntryDetailsL()
+Stores the details of a message entry.
+*/
+void CImCltRecvConvert::StoreMessageEntryDetailsL()
+ {
+ iEmailEntry->SetAttachment(iParent->At(0).iAttachment);
+ iEmailEntry->SetMHTMLEmail(iParent->At(0).iMHTML);
+
+ if(iEmailEntry->MHTMLEmail() == EFalse && iEmailEntry->Attachment() == EFalse && iRelatedAttachments !=EFalse)
+ {
+ iEmailEntry->SetAttachment(ETrue);
+ }
+ iRelatedAttachments=EFalse;
+
+ iEmailEntry->iSize=iParent->At(0).iSize;
+ iEmailEntry->SetMessageFolderType(iParent->At(0).iFolder);
+ StoreEntryDataL();
+
+ if (iParent->Count()>1)
+ {
+ iParent->At(1).iSize+=iEmailEntry->iSize;
+ iParent->Delete(0);
+ }
+ else
+ {
+ iParent->At(0).iAttachment=iParent->At(0).iMHTML=EFalse;
+ iParent->At(0).iSize=0;
+ }
+ }