messagingfw/msgtestfw/TestActions/Email/Smtp/src/ImCltCvRecv.cpp
changeset 0 8e480a14352b
equal deleted inserted replaced
-1:000000000000 0:8e480a14352b
       
     1 // Copyright (c) 2003-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 <imcm.rsg>
       
    17 #include <barsread.h>
       
    18 
       
    19 #include "imcvcodc.h"
       
    20 #include "imcvutil.h"
       
    21 #include "CMsvBodyText.h"
       
    22 #include "ImCltCvRecv.h"
       
    23 
       
    24 #ifdef __WINS__
       
    25 #include <e32wins.h> 
       
    26 #include <msvapi.h>
       
    27 #endif
       
    28 
       
    29 #ifndef __WINS__
       
    30 #include <msvapi.h>
       
    31 #endif
       
    32 #include <cmsvattachment.h> 
       
    33 #include <mmsvattachmentmanager.h>
       
    34 #include <mmsvattachmentmanagersync.h>
       
    35 
       
    36 #ifndef _MSG_NO_LOGGING
       
    37 #define __IMUT_LOGGING
       
    38 _LIT(KLogFilePath, "c:\\logs\\mailtext\\in.txt");
       
    39 _LIT8(KNewLogHeader, "\r\n------ New Receive Session ------\r\n");
       
    40 _LIT8(KFound, "found: ");
       
    41 _LIT8(KPartLine, "unknown or part line");
       
    42 _LIT8(KEndOFHeader, "End of header");
       
    43 _LIT8(KSkippingData, "Skipping data");
       
    44 
       
    45 _LIT8(KFoundMIMEBoundary, "MIME boundary");
       
    46 _LIT8(KRemoveBoundary, "Remove boundary");
       
    47 _LIT8(KRemovedBoundary, "Removed boundary");
       
    48 _LIT8(KSectionHeader, "Section header");
       
    49 _LIT8(KWritingToFile, "writing attachment");
       
    50 _LIT8(KWroteToFile, "wrote attachment");
       
    51 _LIT8(KFailedToWriteToFile, "Failed to write to attachment file");
       
    52 _LIT8(KFoundUUEStartBoundary, "UUE start boundary");
       
    53 _LIT8(KFoundUUEEndBoundary, "UUE end boundary");
       
    54 _LIT8(KReset, "Resetting CImRecvConvert");
       
    55 _LIT8(KReseted, "Resetting CImRecvConvert");
       
    56 _LIT8(KLastToken, "That was the last token");
       
    57 _LIT8(KResetForNewEntry, "Reset for a New Entry");
       
    58 _LIT8(KResetedForNewEntry, "Reseted for a New Entry");
       
    59 _LIT8(KCreatingEntry, "Creating Entry");
       
    60 _LIT8(KCreatedEntry, "Created Entry");
       
    61 _LIT8(KUpdatingEntry, "Updating Entry");
       
    62 _LIT8(KUpdatedEntry, "Updated Entry");
       
    63 _LIT8(KMoveToParentEntry, "Moved to parent entry");
       
    64 _LIT8(KMovedToParentEntry, "End of Moved to parent entry");
       
    65 
       
    66 _LIT8(KIgnoringStreams, "Discarding streams");
       
    67 _LIT8(KStartMessageComplete, "Start Message Complete");
       
    68 _LIT8(KMessageComplete, "Message Complete");
       
    69 _LIT8(KHeaderComplete, "Message Header complete");
       
    70 _LIT8(KReturnReceiptTo, "return-receipt-To is set");
       
    71 _LIT8(KStartStoringEntryStream, "Starting Storing Entry Stream");
       
    72 _LIT8(KStoringEntryStream, "Storing Entry Stream");
       
    73 _LIT8(KDoneStoringEntryStream, "Done Storing Entry Stream");
       
    74 
       
    75 #endif // _MSG_NO_LOGGING
       
    76 
       
    77 // uncomment the line below if logging is to be enabled
       
    78 
       
    79 #if defined(__IMUT_LOGGING)
       
    80 #define RECVLOG(text) (iImcvLog?iImcvLog->AppendComment(text):void(0));
       
    81 #define RECVLOG_OUT(text) (iImcvLog?iImcvLog->AppendOut(text):void(0));
       
    82 #define LOGGING(string1, string2) (Logging(string1, string2));
       
    83 #else
       
    84 #define RECVLOG(text) (void(0));
       
    85 #define RECVLOG_OUT(text) (void(0));
       
    86 #define LOGGING(string1, string2) (void(0));
       
    87 #endif
       
    88 
       
    89 
       
    90 const TInt KBodyTextChunkSizeBytes = 512;
       
    91 
       
    92 
       
    93 /*EXPORT_C*/ CImCltRecvConvert* CImCltRecvConvert::NewLC(RFs& anFs,CMsvEntry* aClientEntry,TUid aMsgType,TMsvId aEmailServiceId)
       
    94 	{
       
    95 	CImCltRecvConvert* self = new (ELeave) CImCltRecvConvert(anFs,aClientEntry,aMsgType,aEmailServiceId);
       
    96 	CleanupStack::PushL(self);
       
    97 	self->ConstructL(anFs);
       
    98 	return self;
       
    99 	}
       
   100 
       
   101 
       
   102 /*EXPORT_C*/ CImCltRecvConvert* CImCltRecvConvert::NewL(RFs& anFs,CMsvEntry* aClientEntry,TUid aMsgType,TMsvId aEmailServiceId)
       
   103 	{
       
   104 	CImCltRecvConvert* self = CImCltRecvConvert::NewLC(anFs,aClientEntry,aMsgType,aEmailServiceId);
       
   105 	CleanupStack::Pop();
       
   106 	return self;
       
   107 	}
       
   108 
       
   109 
       
   110 void CImCltRecvConvert::ConstructL(RFs& anFs)
       
   111 	{
       
   112 	iFsSession = &anFs;  
       
   113 
       
   114 	RResourceFile resFile;
       
   115 	OpenResourceFileL(resFile, anFs);	// NB leaves if file not found
       
   116 
       
   117 	// make sure the resource file will be closed if anything goes wrong
       
   118 	// CloseResourceFile is declared in IMUTDLL.H and defined in IMUTDLL.CPP
       
   119 	TCleanupItem close( CloseResourceFile, &resFile );
       
   120 	CleanupStack::PushL( close );
       
   121 	
       
   122 	// Read iStore8BitData flag.
       
   123 	HBufC8* buf = resFile.AllocReadLC(STORE_8BIT_BODY_TEXT);
       
   124 	TResourceReader reader;
       
   125 	reader.SetBuffer(buf);
       
   126 	iStore8BitData = reader.ReadInt8();
       
   127 	CleanupStack::PopAndDestroy(buf);
       
   128 
       
   129 	buf = resFile.AllocReadLC(REMOVED_ATTACHMENT_TAG);
       
   130 	reader.SetBuffer(buf);
       
   131 	iRemovedAttachmentTag = reader.ReadTPtrC().AllocL();
       
   132 	CleanupStack::PopAndDestroy(buf);
       
   133 	
       
   134 	buf = resFile.AllocReadLC(DEFAULT_ATTACHMENT_NAME);
       
   135 	reader.SetBuffer(buf);
       
   136 	iDefaultAttachmentName = reader.ReadTPtrC().AllocL();
       
   137 	CleanupStack::PopAndDestroy(buf);
       
   138 	buf = resFile.AllocReadLC(PARTIAL_DOWNLOAD_FOOTER_MESSAGE);
       
   139 	reader.SetBuffer(buf);
       
   140 	iPartialEmailFooter = (reader.ReadTPtrC()).AllocL();
       
   141 	CleanupStack::PopAndDestroy(buf);
       
   142 	buf = NULL;
       
   143 	CleanupStack::PopAndDestroy(&resFile);
       
   144 
       
   145 	// create CImHeader object to store Rfc822 header info...
       
   146 	iOutputHeader = CImHeader::NewLC();
       
   147 	CleanupStack::Pop();			   
       
   148 
       
   149 	if (iStore8BitData)
       
   150 		{
       
   151 		//Create body text storage helper.
       
   152 		iBodyText = CMsvBodyText::NewL();
       
   153 		}
       
   154 	else
       
   155 		{
       
   156 		// create CRichText object to store body...
       
   157 		iParaLayer = CParaFormatLayer::NewL();
       
   158 		iCharLayer = CCharFormatLayer::NewL();
       
   159 		iOutputBody = CRichText::NewL(iParaLayer, iCharLayer);
       
   160 		}
       
   161 	
       
   162 	// Create Rfc822 filter object...
       
   163 	iRfc822Token = CLocalRfc822Token::NewLC();
       
   164 	CleanupStack::Pop();				 
       
   165 	iRfc822Token->SetImRecvConvert(this);
       
   166 
       
   167 	// Create converter objects...
       
   168 	iCharacterConverter = CCnvCharacterSetConverter::NewL();
       
   169 	iCharConv = CImConvertCharconv::NewL(*iCharacterConverter, anFs);
       
   170 	iHeaderConverter = CImConvertHeader::NewL(*iCharConv); 
       
   171 
       
   172 	
       
   173 	// Create MIME filter object...
       
   174 	iMimeParser = CLocalMimeParser::NewL(*this);
       
   175 	
       
   176 	
       
   177 	// logfile stuff
       
   178 	iImcvLog=NULL;
       
   179 
       
   180 #ifdef __IMUT_LOGGING	
       
   181 	TRAP_IGNORE(iImcvLog=CImLog::NewL(KLogFilePath, EAppend));
       
   182 #endif
       
   183 
       
   184 	iRootEntryId = EntryId();
       
   185 
       
   186 	iNotFinishedRfc822Header = ETrue;
       
   187 	
       
   188 	iEmailEntry = new (ELeave) TMsvEmailEntry;
       
   189 	iReceivingHeadersOnly=EFalse;	
       
   190 
       
   191 	iParent = new (ELeave) CArrayFixFlat<TParentDetails>(3);
       
   192 
       
   193 	iFirstBoundaryReached=EFalse;
       
   194 
       
   195 	ResetL();
       
   196 	
       
   197 	RECVLOG( KNewLogHeader )
       
   198 	}
       
   199 
       
   200 CImCltRecvConvert::CImCltRecvConvert(RFs& anFs,CMsvEntry* aClientEntry,TUid aMsgType,TMsvId aEmailServiceId)
       
   201 	: CLocalImRecvConvert(anFs,iNullServerEntry,aMsgType,aEmailServiceId),
       
   202 	  iClientEntry(aClientEntry)
       
   203 	{
       
   204 	__DECLARE_NAME(_S("CImCltRecvConvert"));
       
   205 	}
       
   206 
       
   207 
       
   208 /*EXPORT_C*/ CImCltRecvConvert::~CImCltRecvConvert()
       
   209 	{
       
   210 	}
       
   211 
       
   212 
       
   213 /*EXPORT_C*/ void CImCltRecvConvert::ResetForHeadersL()
       
   214 	{
       
   215 	// This function is used in preference to ResetL() when the owner
       
   216 	// only wishes to create  email entries in the remote mailbox - 
       
   217 	// they do not wish to create any stores associated with the message
       
   218 	// entry
       
   219 	ResetL();
       
   220 	iReceivingHeadersOnly=ETrue;
       
   221 	}
       
   222 
       
   223 
       
   224 /*EXPORT_C*/ void CImCltRecvConvert::ResetL()
       
   225 	{
       
   226 	RECVLOG(KReset) 
       
   227 
       
   228 	iBodyId=KMsvNullIndexEntryId;
       
   229 	iSizeOfAttachmentsRemoved=0;
       
   230 	iClientEntry->SetEntryL(iRootEntryId);
       
   231 	
       
   232 	iReceivingHeadersOnly=EFalse;
       
   233 	iMessageEntryCalled=EFalse;
       
   234 	iLeaveError=KErrNone; 		
       
   235 	iCurrentMultipartFolderEntryId=0;
       
   236 
       
   237 	TParentDetails parent;
       
   238 	parent.iAttachment=parent.iMHTML=EFalse;
       
   239 	parent.iSize=0;
       
   240 	iParent->InsertL(0,parent);
       
   241 
       
   242 	if(iEmailEntry)
       
   243 		{
       
   244 		delete iEmailEntry;
       
   245 		iEmailEntry=NULL;
       
   246 		}
       
   247 	iEmailEntry = new (ELeave) TMsvEmailEntry;
       
   248 
       
   249 	// "iSavingAttachments" commands this code to store attachments in files.
       
   250 	// Currently this is always set to ETrue as we intend to save all attachments
       
   251 	// However, if the user wishes to discard (ie do not save) any 
       
   252 	// attachments in incoming email messages - then this member variable
       
   253 	// may be set to EFalse by the inline accessor function "SaveAllAttachments(TBool)"
       
   254 	iSavingAttachments=ETrue;
       
   255 	iAttachmentFileState=EFileIsClosed;
       
   256 
       
   257 	// iLeaveError contains the error value of any functions that leaves (ie CRichText::InsertL)
       
   258 	// or any returned error value that generates a leave from within CImRecvConvert (ie RFile::Create)
       
   259 
       
   260 	iGlobalIndent=0;
       
   261 	iLongestLine=50;
       
   262 	
       
   263 	iImPriority=EMsvMediumPriority;
       
   264 	delete iImcvUtils;
       
   265 	iImcvUtils=NULL;
       
   266 	iImcvUtils=CImcvUtils::NewL();
       
   267 
       
   268 	// reset internal date
       
   269 	iTimeDate.HomeTime();
       
   270 	
       
   271 	iMimeParser->Reset();
       
   272 	
       
   273 	iNewEntry=EFalse; //EFalse if the entry was moved to. ETrue if the entry was just created
       
   274 	iTopMessagePart=KMsvRootIndexEntryId;
       
   275 	ResetForNewEntryL(iDefaultEntryType);
       
   276 	iMIMEPart_822Header = EFalse;
       
   277 	iPartialEmail=EFalse;
       
   278 
       
   279 	RECVLOG(KReseted) 
       
   280 	}
       
   281 
       
   282 
       
   283 /*EXPORT_C*/ TInt CImCltRecvConvert::ParseNextFieldL(const TDesC8& aSourceLine) 
       
   284 	{
       
   285 	__ASSERT_DEBUG(iRootEntryId!=KMsvRootIndexEntryId, gPanic(KPanicServiceIdNotValid));
       
   286 	RECVLOG_OUT(aSourceLine);
       
   287 
       
   288 	if ((iLeaveError == KErrNone) && (iClientEntry->Entry().Id() == KMsvRootIndexEntryId))
       
   289 		{
       
   290 		iClientEntry->SetEntryL(iSavedEntryId);
       
   291 		}
       
   292 
       
   293 	if(iLeaveError==KErrNone)
       
   294 		{
       
   295 		TRAP(iLeaveError, ParseNextLineL(aSourceLine));		
       
   296 		}
       
   297 
       
   298 	if (iLeaveError==KErrNone)
       
   299 		iSavedEntryId = iClientEntry->Entry().Id();
       
   300 	TUid type = iClientEntry->Entry().iType;
       
   301 	if( type != KUidMsvMessageEntry    &&
       
   302 		type != KUidMsvEmailTextEntry  &&
       
   303 		type != KUidMsvEmailHtmlEntry  &&
       
   304 		type != KUidMsvAttachmentEntry)
       
   305 		{
       
   306 		iClientEntry->SetEntryL(KMsvRootIndexEntryId);
       
   307 		}
       
   308 
       
   309 
       
   310 	return iLeaveError;
       
   311 	}
       
   312 
       
   313 
       
   314 void CImCltRecvConvert::ParseNextLineL(const TDesC8& aSourceLine)
       
   315 	{
       
   316 	iParsedMimeBoundaryLast=0;
       
   317 	if(!iFinishedHeader)
       
   318 		{
       
   319 		// start by getting the next token from the header
       
   320 		iRfc822Token->ParseNextLineL(aSourceLine);
       
   321 
       
   322 		switch(iRfc822Token->iHeaderPart)
       
   323 			{
       
   324 			case CLocalRfc822Token::EUnknown:
       
   325 			case CLocalRfc822Token::ENotFinished:
       
   326 				RECVLOG(KPartLine)
       
   327 				break;
       
   328 			case CLocalRfc822Token::EFrom:
       
   329 				iOutputHeader->SetFromL(*iRfc822Token->OutputLine());
       
   330 				LOGGING(KFound,KImcvFromPrompt);
       
   331 				break;
       
   332 			case CLocalRfc822Token::EReplyTo:
       
   333 				iOutputHeader->SetReplyToL(*iRfc822Token->OutputLine());
       
   334 				LOGGING(KFound,KImcvReplyToPrompt);
       
   335 				break;
       
   336 			case CLocalRfc822Token::ETo:
       
   337 				ParseRecipientListL(iOutputHeader->ToRecipients());
       
   338 				LOGGING(KFound,KImcvToPrompt);
       
   339 				break;
       
   340 			case CLocalRfc822Token::ECc: 
       
   341 				ParseRecipientListL(iOutputHeader->CcRecipients());
       
   342 				LOGGING(KFound,KImcvCcPrompt);
       
   343 				break;
       
   344 			case CLocalRfc822Token::EBcc: 
       
   345 				ParseRecipientListL(iOutputHeader->BccRecipients());
       
   346 				LOGGING(KFound,KImcvBccPrompt);
       
   347 				break;
       
   348 			case CLocalRfc822Token::ESubject:
       
   349 				iOutputHeader->SetSubjectL(*iRfc822Token->OutputLine());
       
   350 				LOGGING(KFound,KImcvSubjectPrompt);
       
   351 				break;
       
   352 			case CLocalRfc822Token::EDate:
       
   353 				iRfc822Date.ParseDateField(*iRfc822Token->OutputLine() , iTimeDate); 
       
   354 				if (iEmailEntry->Id() != iTopMessagePart)
       
   355 					{
       
   356 					iEmailEntry->iDate = iTimeDate;
       
   357 					}
       
   358 				LOGGING(KFound,KImcvDatePrompt);
       
   359 				break;
       
   360 			case CLocalRfc822Token::EMessageId:
       
   361 				iOutputHeader->SetImMsgIdL(*iRfc822Token->OutputLine());
       
   362 				LOGGING(KFound,KImcvMessageIdPrompt);
       
   363 				break;
       
   364 			case CLocalRfc822Token::EPriority:
       
   365 				iImPriority=iImcvUtils->EvaluatePriorityText(*iRfc822Token->OutputLine());
       
   366 				LOGGING(KFound,KImcvPriorityPrompt);
       
   367 				break;
       
   368 			case CLocalRfc822Token::EReturnReceiptTo:
       
   369 				iOutputHeader->SetReceiptAddressL(*iRfc822Token->OutputLine());
       
   370 				LOGGING(KFound,KReturnReceiptTo);
       
   371 				break;
       
   372 			case CLocalRfc822Token::EEndOfHeader:
       
   373 				// the next line goes in the body part
       
   374 				iFinishedHeader = ETrue;
       
   375 				RECVLOG(KEndOFHeader)
       
   376 				break;
       
   377 			default:
       
   378 				RECVLOG(KEndOFHeader)
       
   379 				break;
       
   380 			}
       
   381 
       
   382 
       
   383 		if(iRfc822Token->iHeaderPart != CLocalRfc822Token::ENotFinished)
       
   384 			{
       
   385 			// Now that we've used the data, we also need to clear the output line from the tokeniser....
       
   386 			iRfc822Token->OutputLine()->Des() = KNullDesC8;
       
   387 
       
   388 			// whatever part we just read, we may also have read the empty line that separates
       
   389 			// the header from the body
       
   390 			if((iFinishedHeader = iRfc822Token->LastToken()) != EFalse)	//iFinishedHeader set to 1 on CRLF-
       
   391 				{
       
   392 				RECVLOG(KLastToken);
       
   393 				iNotFinishedRfc822Header = EFalse;
       
   394 
       
   395 				iHeaderConverter->SetMessageType(iMimeParser->MessageIsMime());
       
   396 				iHeaderConverter->DecodeAllHeaderFieldsL(*iOutputHeader);
       
   397 
       
   398 				if (iMimeParser->MessageIsMime())
       
   399 					{
       
   400 					EndOfHeaderMIMEProcessingL();
       
   401 					}
       
   402 				else
       
   403 					{
       
   404 					EndOfHeaderProcessingL();
       
   405 					}
       
   406 
       
   407 				if (iStore8BitData)
       
   408 					{
       
   409 					iBodyText->SetDefaultCharacterSet(iCharConv->SystemDefaultCharset());
       
   410 					if ( iMimeParser->MessageIsMime() && iMimeParser->ContentType()==EMimeText )
       
   411 						{
       
   412 						iBodyText->SetCharacterSet(iMimeParser->CurrentCharsetL());
       
   413 						}
       
   414 					else
       
   415 						{
       
   416 						iBodyText->SetCharacterSet(0);
       
   417 						}
       
   418 					}
       
   419 				else
       
   420 					{
       
   421 					// Get charset for decoding.
       
   422 					if ( iMimeParser->MessageIsMime() && iMimeParser->ContentType()==EMimeText )
       
   423 						{
       
   424 						iCharConv->PrepareToConvertToFromOurCharsetL(iMimeParser->CurrentCharsetL());
       
   425 						}
       
   426 					else
       
   427 						{
       
   428 						iCharConv->PrepareToConvertToFromOurCharsetL(iCharConv->SystemDefaultCharset());
       
   429 						}
       
   430 					}
       
   431 				}
       
   432 			}
       
   433 		}
       
   434 	else if (iReceivingHeadersOnly==EFalse)
       
   435 		{	
       
   436 		//Set to EFalse when a single line is to be skipped (ie boundary line)
       
   437 		iCommitLine=ETrue; 
       
   438 
       
   439 		// read one line of the message body if I am processing a whole email message
       
   440 		if(iMimeParser->MessageIsMime())
       
   441 			{
       
   442 			ParseMimeLineL(aSourceLine);
       
   443 			}
       
   444 		else
       
   445 			{
       
   446 			ParseBodyLineL(aSourceLine);	
       
   447 			}
       
   448 
       
   449 		if((iCommitLine)&&(!iSkipData))
       
   450 			{
       
   451 			DecodeAndStoreLineL(aSourceLine);
       
   452 			}	
       
   453 		}
       
   454 	}
       
   455 
       
   456 
       
   457 /*EXPORT_C*/ TMsvEmailEntry CImCltRecvConvert::MessageEntryDetailsL()
       
   458 	{
       
   459 
       
   460 	iMessageEntryCalled=ETrue;
       
   461 	CloseAttachmentFileL();
       
   462 
       
   463 	// A message requiring manual termination and not part way through a MIME part header
       
   464 	if( iTopMessagePart==EntryId() && iFinishedHeader) 
       
   465 		{
       
   466 		StoreEntryStreamsL(KStore822Header|KStoreMIMEHeader);
       
   467 		}
       
   468 	else
       
   469 		{
       
   470 		iClientEntry->SetEntryL(iTopMessagePart);         
       
   471 		if(iEmailEntry)
       
   472 			{
       
   473 			delete iEmailEntry;
       
   474 			iEmailEntry=NULL;
       
   475 			}
       
   476 	
       
   477 		iEmailEntry = new (ELeave) TMsvEmailEntry(iClientEntry->Entry());
       
   478 		}
       
   479 		
       
   480 	return *iEmailEntry;
       
   481 	}
       
   482 
       
   483 
       
   484 /*EXPORT_C*/ void CImCltRecvConvert::MessageCompleteL(TMsvEmailEntry aEmailEntry)
       
   485 	{
       
   486 	if (iClientEntry->Entry().Id() == KMsvRootIndexEntryId)
       
   487 		{
       
   488 		iClientEntry->SetEntryL(iSavedEntryId);
       
   489 		}
       
   490 
       
   491 	__ASSERT_DEBUG(iMessageEntryCalled, gPanic(KPanicMessageEntryNotCalled));
       
   492 	__ASSERT_DEBUG(aEmailEntry.Id()==iTopMessagePart, gPanic(KPanicMessageEntryIdHasChanged));
       
   493 
       
   494 	// Called ResetL() to reset object instead of ResetForHeadersL()
       
   495 	__ASSERT_DEBUG(iReceivingHeadersOnly, gPanic(KPanicIncorrectResetState)); 
       
   496 
       
   497 	if(iEmailEntry)
       
   498 		{
       
   499 		if (iEmailEntry->Id())
       
   500 			{
       
   501 			if(iLeaveError==KErrNone)
       
   502 				{
       
   503 				// a remote email header cannot have any attachments or be marked as complete...
       
   504 				aEmailEntry.SetAttachment(EFalse);
       
   505 				aEmailEntry.SetMHTMLEmail(EFalse);
       
   506 				aEmailEntry.SetComplete(EFalse);
       
   507 				iClientEntry->SetEntryL(aEmailEntry.Id());
       
   508 				RECVLOG(KHeaderComplete)
       
   509 				}
       
   510 			else
       
   511 				{
       
   512 				if (!iPopulateMessage)
       
   513 					{
       
   514 					TMsvId currentId = EntryId();
       
   515 					iClientEntry->SetEntryL(iClientEntry->Entry().Parent());			
       
   516 					iClientEntry->DeleteL(currentId);
       
   517 					}
       
   518 				User::Leave(iLeaveError);
       
   519 				}
       
   520 			}
       
   521 		}
       
   522 
       
   523 	iSavedEntryId = iClientEntry->Entry().Id();
       
   524 	iClientEntry->SetEntryL(KMsvRootIndexEntryId);
       
   525 	}
       
   526 
       
   527 
       
   528 /*EXPORT_C*/ TMsvId CImCltRecvConvert::MessageCompleteL()
       
   529 	{
       
   530 	RECVLOG(KStartMessageComplete)
       
   531 	if (iClientEntry->Entry().Id() == KMsvRootIndexEntryId)
       
   532 		{
       
   533 		iClientEntry->SetEntryL(iSavedEntryId);
       
   534 		}
       
   535 	if (iParsedMimeBoundaryLast==EFalse && iAttachmentFileState==EFileIsOpen && iPartialEmail!=EFalse)
       
   536 		{
       
   537 		iAttachmentFileState=EFileTopIncomplete;
       
   538 		}
       
   539 
       
   540 	CloseAttachmentFileL();
       
   541 
       
   542 	if(!iEmailEntry->Id())
       
   543 		{
       
   544 		return 0;
       
   545 		}
       
   546 
       
   547 	if(iLeaveError!=KErrNone)
       
   548 		{
       
   549 		User::Leave(iLeaveError);
       
   550 		}
       
   551 
       
   552 	if (EntryId()!=iTopMessagePart)
       
   553 		{
       
   554 		iEmailEntry->SetComplete(ETrue);
       
   555 		StoreEntryStreamsL(KStoreBodyText);
       
   556 		MoveToParentEntryL();
       
   557 
       
   558 		if( iTopMessagePart==EntryId() && iFinishedHeader) 
       
   559 			{
       
   560 			iEmailEntry->SetVisible(ETrue);
       
   561 			iEmailEntry->SetInPreparation(EFalse);
       
   562 			iEmailEntry->SetBodyTextComplete(ETrue);
       
   563 			iEmailEntry->SetComplete(ETrue);
       
   564 			iEmailEntry->SetSendingState(KMsvSendStateWaiting);
       
   565 			// Main message.
       
   566 			StoreMessageEntryDetailsL();
       
   567 			return iEmailEntry->Id();
       
   568 			}
       
   569 		else if(iEmailEntry->iType == KUidMsvMessageEntry)
       
   570 			{
       
   571 			StoreMessageEntryDetailsL();
       
   572 			MoveToParentEntryL();
       
   573 			StoreMessageEntryDetailsL();
       
   574 			}
       
   575 		}
       
   576 
       
   577 	iClientEntry->SetEntryL(iTopMessagePart);         
       
   578 	if(iEmailEntry)
       
   579 		{
       
   580 		delete iEmailEntry;
       
   581 		iEmailEntry=NULL;
       
   582 		}
       
   583 	iEmailEntry = new (ELeave) TMsvEmailEntry(iClientEntry->Entry());
       
   584 	iEmailEntry->SetVisible(ETrue);
       
   585 	iEmailEntry->SetInPreparation(EFalse);
       
   586 	iEmailEntry->SetComplete(ETrue);
       
   587 	iEmailEntry->SetBodyTextComplete(ETrue);
       
   588 
       
   589 	iEmailEntry->SetSendingState(KMsvSendStateWaiting);	
       
   590 
       
   591 
       
   592 	iEmailEntry->SetAttachment(iParent->At(0).iAttachment);
       
   593 	iEmailEntry->SetMHTMLEmail(iParent->At(0).iMHTML);
       
   594 
       
   595 	if(iEmailEntry->MHTMLEmail() == EFalse && iEmailEntry->Attachment() == EFalse && iRelatedAttachments !=EFalse)
       
   596 		{
       
   597 		iEmailEntry->SetAttachment(ETrue);
       
   598 		}
       
   599 	iRelatedAttachments=EFalse;
       
   600 	
       
   601 	iEmailEntry->iSize=iParent->At(0).iSize;
       
   602 	iEmailEntry->SetMessageFolderType(iParent->At(0).iFolder);
       
   603 
       
   604 	iClientEntry->ChangeL(*iEmailEntry);
       
   605 
       
   606 	iSavedEntryId = iClientEntry->Entry().Id();
       
   607 	iClientEntry->SetEntryL(KMsvRootIndexEntryId);
       
   608 	RECVLOG(KMessageComplete)
       
   609 	return iEmailEntry->Id();
       
   610 	}
       
   611 
       
   612 
       
   613  //----------------------------------------------------------------------------------------  
       
   614 void CImCltRecvConvert::ParseMimeLineL(const TDesC8& aSourceLine)
       
   615 //----------------------------------------------------------------------------------------  
       
   616 	{
       
   617 	iTopPartialDownloadCounter+=aSourceLine.Length(); // increment the number of bytes of the attachment downloaded so far
       
   618 	if(!iMimeParser->IsBoundary(aSourceLine))
       
   619 		{
       
   620 		if(!iPrepared) // first line of the body
       
   621 			{		
       
   622 			if (iMIMEPart_822Header)
       
   623 				{
       
   624 				// missing 822 part header. Revert to default.
       
   625 				EndOfHeaderMIMEProcessingL();
       
   626 				iMIMEPart_822Header=EFalse;
       
   627 				}
       
   628 
       
   629 			PrepareDecoder();
       
   630 			}
       
   631 
       
   632 		if (CheckUUEStartL(aSourceLine))
       
   633 			{
       
   634 			iAlgorithm=EUUDecode;
       
   635 			iCommitLine=EFalse;
       
   636 			}
       
   637 		}
       
   638 	else
       
   639 		{
       
   640 		iParsedMimeBoundaryLast=ETrue;
       
   641 		// found a MIME boundary so store the current parts data and update its entry.
       
   642 
       
   643 		RECVLOG(KFoundMIMEBoundary)
       
   644 		iCommitLine=EFalse; //Dont store this line as its a boundary.
       
   645 
       
   646 		if(!iFirstBoundaryReached && iEntryType==EFolderEntry)
       
   647 			{
       
   648 			iFirstBoundaryReached=ETrue;
       
   649 			if (!iCurrentMultipartFolderEntryId)
       
   650 				iCurrentMultipartFolderEntryId = EntryId();
       
   651 			MoveToParentEntryL();
       
   652 			ResetForNewEntryL(iDefaultEntryType);
       
   653 			return; // First boundary encountered.
       
   654 			}
       
   655 
       
   656 		CloseAttachmentFileL();
       
   657 		if(iNewEntry)
       
   658 			{
       
   659 			iEmailEntry->SetComplete(ETrue);
       
   660 			iEmailEntry->SetBodyTextComplete(ETrue);
       
   661 			StoreEntryStreamsL(KStoreMIMEHeader | KStoreBodyText);
       
   662 			if (iBodyId==KMsvNullIndexEntryId)
       
   663 				{
       
   664 				iBodyId=iEmailEntry->Id();
       
   665 				}
       
   666 			}
       
   667 
       
   668 		iSkipData = EFalse;
       
   669 
       
   670 		// check whether we just found the terminating boundary...
       
   671 		if(iMimeParser->IsTerminatingBoundary())
       
   672 			{
       
   673 			RECVLOG(KRemoveBoundary);
       
   674 			iMimeParser->RemoveBoundary();
       
   675 			RECVLOG(KRemovedBoundary);
       
   676 			iMIMEPart_822Header = EFalse;
       
   677 
       
   678 			if (EntryId()!=iTopMessagePart)
       
   679 				{
       
   680 				if(iEmailPart==KParentPart)
       
   681 					{
       
   682 					// rfc822 message which is not  not multipart.
       
   683 					iEmailPart=KNoPart;
       
   684 					MoveToParentEntryL();				
       
   685 
       
   686 					// Embedded message
       
   687 					iEmailEntry->SetComplete(ETrue);
       
   688 					iEmailEntry->SetBodyTextComplete(ETrue);
       
   689 					StoreMessageEntryDetailsL();
       
   690 					}
       
   691 				else if (iEmailEntry->iType==KUidMsvMessageEntry)
       
   692 					{
       
   693 					// Moving up from a multi embedded rfc822 message.
       
   694 					iEmailEntry->SetComplete(ETrue);
       
   695 					iEmailEntry->SetBodyTextComplete(ETrue);
       
   696 					StoreMessageEntryDetailsL();
       
   697 					}
       
   698 				}
       
   699 
       
   700 			MoveToParentEntryL();
       
   701 			iEntryDataSize = iEmailEntry->iSize;
       
   702 
       
   703 			if(iClientEntry->Entry().iType == KUidMsvFolderEntry)
       
   704 				{
       
   705 				iCurrentMultipartFolderEntryId = EntryId();
       
   706 				}
       
   707 			else if (EntryId()!=iTopMessagePart)
       
   708 				{
       
   709 				if(iEmailEntry->iType == KUidMsvMessageEntry)
       
   710 					{
       
   711 					iEmailEntry->SetComplete(ETrue);
       
   712 					iEmailEntry->SetBodyTextComplete(ETrue);
       
   713 					StoreMessageEntryDetailsL();
       
   714 					}
       
   715 				MoveToParentEntryL();
       
   716 				iEntryDataSize += iEmailEntry->iSize;
       
   717 				}
       
   718 
       
   719 			if(!iNewEntry)
       
   720 				ResetForNonMimeEntryL();
       
   721 
       
   722 			RECVLOG(KSkippingData)
       
   723 			iSkipData = ETrue;
       
   724 			iDefaultEntryType=ETextEntry;
       
   725 			}
       
   726 		else // if regular boundary
       
   727 			{ 
       
   728 			RECVLOG(KSectionHeader)
       
   729 			if(iEmailPart==KParentPart && EntryId()!=iTopMessagePart)
       
   730 				{
       
   731 				// rfc822 message which is not  not multipart.
       
   732 				iEmailPart=KNoPart;
       
   733 				MoveToParentEntryL();
       
   734 				// Embedded message
       
   735 				iEmailEntry->SetComplete(ETrue);
       
   736 				iEmailEntry->SetBodyTextComplete(ETrue);
       
   737 				StoreMessageEntryDetailsL();
       
   738 				}
       
   739 
       
   740 			if (!iCurrentMultipartFolderEntryId && iEmailPart==KNoPart)
       
   741 				MoveToParentEntryL();
       
   742 
       
   743 			ResetForNewEntryL(iDefaultEntryType);
       
   744 			}
       
   745 		}
       
   746 	}
       
   747 
       
   748 
       
   749 void CImCltRecvConvert::EndOfHeaderProcessingL()
       
   750 	{	
       
   751 	CreateEntryL();
       
   752 	StoreEntryStreamsL(KStore822Header);
       
   753 	iEntryDataSize = 0;
       
   754 	}
       
   755 
       
   756 
       
   757 void CImCltRecvConvert::ParseBodyLineL(const TDesC8& aSourceLine)
       
   758 	{
       
   759 	TInt len=aSourceLine.Length();
       
   760 	iTopPartialDownloadCounter+=len; // added for TOP. increment the number of bytes of the attachment downloaded so far
       
   761 	TMsvId id=0;
       
   762 	if (iBodyId==KMsvNullIndexEntryId)
       
   763 		{
       
   764 		iBodyId=iEmailEntry->Id();
       
   765 		}
       
   766 
       
   767 	// first check whether this line is a UUEncode start boundary
       
   768 	if(CheckUUEStartL(aSourceLine)) 
       
   769 		{
       
   770 		RECVLOG(KFoundUUEStartBoundary)
       
   771 		TFileName tempStore = iAttachmentName;
       
   772 		id = EntryId();
       
   773 		if (!iNewNonMIMEBodyPart || id!=iTopMessagePart) // main message entry
       
   774 			{
       
   775 			iEmailEntry->SetComplete(ETrue);
       
   776 			iEmailEntry->SetBodyTextComplete(ETrue);
       
   777 			StoreEntryStreamsL(KStoreBodyText);
       
   778 			}
       
   779 		MoveToParentEntryL();
       
   780 		if ( !CreateNonMIMEFolderEntryL(id))
       
   781 			{
       
   782 			ResetForNonMimeEntryL();
       
   783 			}
       
   784 			
       
   785 		iEntryType = EAttachmentEntry;
       
   786 		CreateEntryL();
       
   787 		SetAttachmentName(tempStore);
       
   788 		
       
   789 		iCurrentPartIsRichText = EFalse;
       
   790 		iAlgorithm=EUUDecode;
       
   791 		iCommitLine=EFalse;
       
   792 		if(!iSavingAttachments)
       
   793 			{
       
   794 			RECVLOG(KSkippingData)
       
   795 			iSkipData=ETrue;
       
   796 			}
       
   797 		iNewNonMIMEBodyPart=EFalse;
       
   798 		}
       
   799 	else if(aSourceLine.CompareF(KImcvUueEnd)==0) // Checks for the UUEncode end boundary
       
   800 		{
       
   801 		RECVLOG(KFoundUUEEndBoundary)
       
   802 		CloseAttachmentFileL();
       
   803 		StoreEntryDataL();
       
   804 		MoveToParentEntryL();
       
   805 		iSkipData = EFalse;
       
   806 		iCommitLine=EFalse;
       
   807 		iNewNonMIMEBodyPart=ETrue; 
       
   808 		}
       
   809 	else if (iNewNonMIMEBodyPart && !( len==2 && aSourceLine[0]==KImcvCR && aSourceLine[1]==KImcvLF ))
       
   810 		{
       
   811 		id = EntryId();
       
   812 		if (!iNewNonMIMEBodyPart || id!=iTopMessagePart)
       
   813 			{
       
   814 			iEmailEntry->SetComplete(ETrue);
       
   815 			iEmailEntry->SetBodyTextComplete(ETrue);
       
   816 			StoreEntryStreamsL(KStoreBodyText);
       
   817 			}
       
   818 		MoveToParentEntryL();
       
   819 		if ( !CreateNonMIMEFolderEntryL(id))
       
   820 			ResetForNonMimeEntryL();
       
   821 		iAlgorithm=ENoAlgorithm;
       
   822 		iEntryType = ETextEntry;
       
   823 		CreateEntryL();
       
   824 		iNewNonMIMEBodyPart=EFalse;
       
   825 		}	
       
   826 	}
       
   827 
       
   828 
       
   829 TBool CImCltRecvConvert::CreateNonMIMEFolderEntryL(TMsvId aCurrentId)
       
   830 	{
       
   831 	if ( aCurrentId==iTopMessagePart || iCurrentMultipartFolderEntryId )
       
   832 		return EFalse;
       
   833 
       
   834 	iClientEntry->SetEntryL(iTopMessagePart); 
       
   835 	iEmailPart = KMultiPart;
       
   836 	iEntryType = EFolderEntry;
       
   837 	CreateEntryL();
       
   838 
       
   839 	TMsvId destId = EntryId();
       
   840 	iClientEntry->SetEntryL(iTopMessagePart); 
       
   841 	iClientEntry->MoveL(aCurrentId, destId);
       
   842 	iClientEntry->SetEntryL(aCurrentId);
       
   843 	iClientEntry->SetEntryL(iClientEntry->Entry().Parent()); 
       
   844 
       
   845 	iEmailEntry->SetMessageFolderType(iMimeParser->MessageFolderType());
       
   846 
       
   847 	RECVLOG(KResetForNewEntry) 
       
   848 
       
   849 	iMimeParser->ResetForNewEntry();
       
   850 	
       
   851 	if (iStore8BitData)
       
   852 		{
       
   853 		//Create a buffer to hold the body text as it is down loaded.
       
   854 		delete iBodyBuf;
       
   855 		iBodyBuf = NULL;
       
   856 		iBodyBuf = CBufFlat::NewL(KBodyTextChunkSizeBytes);
       
   857 		}
       
   858 	else
       
   859 		{
       
   860 		iOutputBody->Reset();
       
   861 		}
       
   862 		
       
   863 	ResetForNonMimeEntryL(); 
       
   864 	RECVLOG(KResetedForNewEntry) 
       
   865 	return ETrue;
       
   866 	}
       
   867 
       
   868 
       
   869 TBool CImCltRecvConvert::CreateAttachmentL()
       
   870 	{
       
   871 	// Get and set Attachment File path
       
   872 	TFileName filepath;
       
   873 	// added to support TOP command. Reset the download counter each time we have a new
       
   874 	// attachment
       
   875 	iTopPartialDownloadCounter = 0; 
       
   876 
       
   877 	// Need to check that the complete filename: iAttachmentFullPath & iAttachmentName	
       
   878 	// does not exceed 256 characters. Greater than this and it cannot be saved as a file.
       
   879 
       
   880 	TBool addExtension=ETrue;
       
   881 	if(iAttachmentName.Length() == 0)	//i.e. problem with Attachment name
       
   882 	    {
       
   883 		// No filename present. Generate one.
       
   884 		if(iMimeParser->ContentDescription().Length()!=0)
       
   885 			{
       
   886 			// Use ContentDescription() as default name 
       
   887 			// - as this is more informative than the default
       
   888 
       
   889 			TLex sourceLineLex = iMimeParser->ContentDescription();
       
   890 			ExtractFilename(sourceLineLex, iAttachmentName);
       
   891 			}
       
   892 		else
       
   893 			iAttachmentName = *iDefaultAttachmentName;
       
   894 		}
       
   895 	else
       
   896 		{
       
   897 		// Filename present. Check it is valid.
       
   898 		ReplaceInvalidCharacters(iAttachmentName);
       
   899 		if (iAttachmentName.Locate(KImcvFullStop)!=KErrNotFound)
       
   900 			addExtension=EFalse;
       
   901 			}
       
   902 	if (addExtension)
       
   903 		{
       
   904 		AddFileExtension();
       
   905 		}
       
   906 	CMsvStore* store = iClientEntry->EditStoreL(); 
       
   907 	CleanupStack::PushL(store);
       
   908 	CMsvAttachment* attachment = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
       
   909 	CleanupStack::PushL(attachment);
       
   910 	attachment->SetAttachmentNameL(iAttachmentName);
       
   911 	
       
   912 	RFile file; 
       
   913 	store->AttachmentManagerExtensionsL().CreateAttachmentL(iAttachmentName,file,attachment);
       
   914 	CleanupStack::Pop(attachment);
       
   915 	
       
   916 	iAttachmentFile.SetFileHandle(file,TImAttachmentFile::EImFileWrite);
       
   917 	store->CommitL();
       
   918 	CleanupStack::PopAndDestroy(store); // store
       
   919 
       
   920 	if(KErrNone!=iLeaveError)
       
   921 		{
       
   922 		iAttachmentFileState=EFileFailedToOpen;
       
   923 		CloseAttachmentFileL();
       
   924 		return EFalse;
       
   925 		}
       
   926 
       
   927 	iAttachmentFileState=EFileIsOpen;
       
   928 	return ETrue;
       
   929 	}
       
   930 	
       
   931 //----------------------------------------------------------------------------------------  
       
   932 void CImCltRecvConvert::WriteToAttachmentL(const TDesC8& text)
       
   933 //----------------------------------------------------------------------------------------  
       
   934 	{
       
   935 	if ( (iAttachmentFileState==EFileIsClosed || iAttachmentFileState==EFileNotOpen) 
       
   936 		&& CreateAttachmentL() && iEntryType!=EHtmlEntry)
       
   937 			iEmailEntry->SetAttachment(ETrue);
       
   938 	
       
   939 	if(iAttachmentFileState!=EFileIsOpen || !text.Length())
       
   940 		{
       
   941 		RECVLOG(KSkippingData)
       
   942 		iSkipData = ETrue;
       
   943 		}
       
   944 
       
   945 	// write decoded data into a file if there is any data there to write.
       
   946 
       
   947 	RECVLOG(KWritingToFile)
       
   948 
       
   949 	// Convert text before writing to attachment.
       
   950 	
       
   951 	// Store as Binary files..
       
   952 	iLeaveError=iAttachmentFile.WriteFile(text);
       
   953 
       
   954 	if(KErrNone==iLeaveError)
       
   955 		iEntryDataSize += text.Length();
       
   956 	else	
       
   957 		{
       
   958 		// the file write failed (eg.there is no space left), set new file state and skip 
       
   959 		RECVLOG(KFailedToWriteToFile)
       
   960 		iAttachmentFileState=EFileIsIncomplete;
       
   961 		CloseAttachmentFileL();
       
   962 		}
       
   963 	RECVLOG(KWroteToFile)
       
   964 	}
       
   965 
       
   966 void CImCltRecvConvert::StoreEntryStreamsL()
       
   967 	{
       
   968 	StoreEntryStreamsL(KStoreBodyText|KStore822Header|KStoreMIMEHeader);
       
   969 	}
       
   970 
       
   971 
       
   972 void CImCltRecvConvert::StoreEntryStreamsL(TInt aSettings)
       
   973 	{
       
   974 	RECVLOG(KStartStoringEntryStream);
       
   975 	if (iReceivingHeadersOnly==EFalse)
       
   976 		{
       
   977 
       
   978 		CMsvStore* entryStore = NULL;
       
   979 		TBool commitStore = EFalse;
       
   980 		TRAPD(error, entryStore = iClientEntry->EditStoreL());
       
   981 		if(error==KErrNone) // if store does not exist then the entry is the wrong type
       
   982 			{
       
   983 			CleanupStack::PushL(entryStore);
       
   984 
       
   985 			if (aSettings & KStore822Header)
       
   986 				{
       
   987 				Store822HeaderL(*entryStore, commitStore);
       
   988 				}
       
   989 			
       
   990 			if (aSettings & KStoreMIMEHeader)
       
   991 				{
       
   992 				StoreMIMEHeaderL(*entryStore, commitStore);
       
   993 				}
       
   994 
       
   995 			if (aSettings & KStoreBodyText)
       
   996 				{
       
   997 				StoreBodyTextL(*entryStore, commitStore);
       
   998 				}
       
   999 			// only commit to the store if I wrote something into it
       
  1000 			if (commitStore)
       
  1001 				{
       
  1002 				RECVLOG(KStoringEntryStream);
       
  1003 				entryStore->CommitL();
       
  1004 				}
       
  1005 
       
  1006 			StoreEntryDataL();
       
  1007 			CleanupStack::PopAndDestroy(); //entryStore		
       
  1008 			}				
       
  1009 		
       
  1010 		}
       
  1011 	RECVLOG(KDoneStoringEntryStream);
       
  1012 	}
       
  1013 
       
  1014 
       
  1015 TBool CImCltRecvConvert::StoreEntryDataL()
       
  1016 	{
       
  1017 	// NB function should only be called if a whole email is being processed
       
  1018 	TBool commit=EFalse;
       
  1019 	RECVLOG(KUpdatingEntry)
       
  1020 
       
  1021 	if (iEmailEntry->iType==KUidMsvMessageEntry)
       
  1022 		{
       
  1023 		iParent->At(0).iSize += iEntryDataSize;
       
  1024 		}
       
  1025 	else
       
  1026 		{
       
  1027 		iEmailEntry->iSize += iEntryDataSize;
       
  1028 		if (iEntryType==EAttachmentEntry || iEntryType==EHtmlEntry)
       
  1029 			{
       
  1030 			iEmailEntry->iDetails.Set(iAttachmentName);
       
  1031 			}
       
  1032 		}
       
  1033 	iClientEntry->ChangeL(*iEmailEntry);
       
  1034 
       
  1035 	RECVLOG(KUpdatedEntry)
       
  1036 	return commit;	// if I wrote data into the store, tell owner	
       
  1037 	}
       
  1038 
       
  1039 
       
  1040 void CImCltRecvConvert::MoveToParentEntryL()
       
  1041 	{
       
  1042 	// This function changes the context to the current entry's parent entry.
       
  1043 	RECVLOG(KMoveToParentEntry)
       
  1044 
       
  1045 	// Change context to the parent entry	
       
  1046 	if (EntryId()==iTopMessagePart)
       
  1047 		{
       
  1048 		return; // Already there.
       
  1049 		}
       
  1050 
       
  1051 	iClientEntry->SetEntryL(iClientEntry->Entry().Parent()); 
       
  1052 
       
  1053 	iNewEntry = EFalse;
       
  1054 	
       
  1055 	// only read and write to store if this is a real email message; headers stored in
       
  1056 	// the remote mailbox do not require any store information.
       
  1057 	if (iReceivingHeadersOnly)
       
  1058 		{
       
  1059 		RECVLOG(KIgnoringStreams)
       
  1060 		return;
       
  1061 		}
       
  1062 
       
  1063 	TBool allowAttachmentFlag=ETrue;
       
  1064 	if(iClientEntry->Entry().iType == KUidMsvFolderEntry)
       
  1065 		{
       
  1066 		// Current entry is a folder entry signifying a MIME multipart.
       
  1067 		// Change context to the parent entry
       
  1068 		TMsvEmailEntry entry = (TMsvEmailEntry) iClientEntry->Entry();
       
  1069 		iCurrentMultipartFolderEntryId = EntryId();
       
  1070 		allowAttachmentFlag = !(entry.MessageFolderType()==EFolderTypeRelated || 
       
  1071 								entry.MessageFolderType()==EFolderTypeAlternative);
       
  1072 	
       
  1073 
       
  1074 		if (EntryId()!=iTopMessagePart)
       
  1075 			{	
       
  1076 			iClientEntry->SetEntryL(iClientEntry->Entry().Parent()); 
       
  1077 			}
       
  1078 		}
       
  1079 
       
  1080 	TBool childIsAttachment = (iEmailEntry->Attachment() || iEmailEntry->iType == KUidMsvMessageEntry) ? ETrue:EFalse;
       
  1081 	TBool childIsMHTML=EFalse;
       
  1082 	// Dont want the flag propogated 'up' past a message entry.
       
  1083 	if(iEmailEntry->iType != KUidMsvMessageEntry)
       
  1084 		{
       
  1085 		childIsMHTML = iEmailEntry->MHTMLEmail() ? ETrue:EFalse;
       
  1086 		}
       
  1087 	//Make the parent entry the current entry 
       
  1088 	if(iEmailEntry)
       
  1089 		{
       
  1090 		delete iEmailEntry;
       
  1091 		iEmailEntry=NULL;
       
  1092 		}
       
  1093 	iEmailEntry = new (ELeave) TMsvEmailEntry(iClientEntry->Entry());
       
  1094 
       
  1095 	if (!iParent->Count())
       
  1096 		{
       
  1097 		TParentDetails parentDetails;
       
  1098 		iParent->InsertL(0,parentDetails);
       
  1099 		}
       
  1100 
       
  1101 	if (! iParent->At(0).iAttachment)
       
  1102 		{
       
  1103 		iParent->At(0).iAttachment=(childIsAttachment && allowAttachmentFlag)? ETrue:EFalse;
       
  1104 
       
  1105 		// if we aren't allowing attachments because of the folder type
       
  1106 		// remember there where attachments and check at the end whether
       
  1107 		// it was an MHTML message or not.
       
  1108 		if(childIsAttachment && !allowAttachmentFlag)
       
  1109 			{
       
  1110 			iRelatedAttachments=ETrue;
       
  1111 			}
       
  1112 		}
       
  1113 	if (!iParent->At(0).iMHTML)
       
  1114 		{
       
  1115 		iParent->At(0).iMHTML = childIsMHTML ? ETrue:EFalse;
       
  1116 		}
       
  1117 	iParent->At(0).iSize += iEntryDataSize;
       
  1118 
       
  1119 	iOutputHeader->Reset();
       
  1120 	iEmptyHeaderSize=iOutputHeader->DataSize();
       
  1121 	iMimeParser->ResetForNewEntry();
       
  1122 
       
  1123 	iEntryDataSize=0;
       
  1124 
       
  1125 	RECVLOG(KMovedToParentEntry)
       
  1126 	}
       
  1127 
       
  1128 
       
  1129 void CImCltRecvConvert::CreateEntryL()
       
  1130 	{
       
  1131 	RECVLOG(KCreatingEntry);
       
  1132 	if(iEmailEntry)
       
  1133 		{
       
  1134 		delete iEmailEntry;
       
  1135 		iEmailEntry=NULL;
       
  1136 		}
       
  1137 
       
  1138 	if (iCurrentMultipartFolderEntryId)
       
  1139 		{
       
  1140 		iClientEntry->SetEntryL(iCurrentMultipartFolderEntryId);
       
  1141 		iCurrentMultipartFolderEntryId=0;
       
  1142 		}
       
  1143 		
       
  1144 	iEmailEntry = new (ELeave) TMsvEmailEntry;
       
  1145 
       
  1146 	TValidEntryType previousEntryType = iEntryType;
       
  1147 	if ((iTopMessagePart==KMsvRootIndexEntryId) || iMIMEPart_822Header)
       
  1148 		{
       
  1149 		// At the main header, want to create a message entry.
       
  1150 		// The stored iEntryType will indicate ( from header info) the next entry to be created.
       
  1151 		// Save temporarily.
       
  1152 		// Also applies to the special case where a message contains ony 1 embedded message.
       
  1153 
       
  1154 		previousEntryType=iEntryType;
       
  1155 		iEntryType=EMessageEntry;
       
  1156 		}
       
  1157 
       
  1158 	if ((iPopulateMessage) && (iTopMessagePart==KMsvRootIndexEntryId))
       
  1159 	// If this is the root of a message that is being populated then do not create it.
       
  1160 		{
       
  1161 		iClientEntry->SetEntryL(iRootEntryId);
       
  1162 		*iEmailEntry = iClientEntry->Entry();
       
  1163 		iTopMessagePart=iRootEntryId;
       
  1164 
       
  1165 		// Delete all the children of the message entry.  This is needed because if the
       
  1166 		// message has been purged, the entries will still exist.  When the message is populated,
       
  1167 		// new entries are created.  If the original entries are not removed, then duplicate 
       
  1168 		// entries will exist.
       
  1169 		CMsvEntrySelection*	children = iClientEntry->ChildrenL();
       
  1170 		CleanupStack::PushL(children);
       
  1171 		if (children->Count())
       
  1172 		{
       
  1173 		TMsvLocalOperationProgress prog;
       
  1174 		iClientEntry->DeleteL(*children,prog);
       
  1175 		}
       
  1176 		CleanupStack::PopAndDestroy(children);
       
  1177 		}
       
  1178 	else
       
  1179 		{
       
  1180 		iEmailEntry->iMtm=iNewMsgType;
       
  1181 		iEmailEntry->iServiceId = iEmailServiceId;
       
  1182 		iEmailEntry->SetComplete(EFalse);
       
  1183 		iEmailEntry->iSize = 0;
       
  1184 		iEmailEntry->SetVisible(ETrue);
       
  1185 		iEmailEntry->SetInPreparation(EFalse);
       
  1186 		iEmailEntry->SetReceipt(EFalse);
       
  1187 
       
  1188 		iEmailEntry->SetVCard(iMimeParser->VCard());
       
  1189 		iEmailEntry->SetVCalendar(iMimeParser->VCalendar());
       
  1190 		iEmailEntry->SetMessageFolderType(iMimeParser->MessageFolderType());
       
  1191 		iEmailEntry->SetPriority(iImPriority);
       
  1192 		iEmailEntry->SetNew(EFalse);
       
  1193 
       
  1194 		if(iOutputHeader->ReceiptAddress().Length()>0)
       
  1195 			{
       
  1196 			iEmailEntry->SetReceipt(ETrue);
       
  1197 			}
       
  1198 
       
  1199 		iEmailEntry->iDate=iTimeDate;
       
  1200 		switch(iEntryType)
       
  1201 			{
       
  1202 			case EMessageEntry:
       
  1203 				if(iTopMessagePart==KMsvRootIndexEntryId)
       
  1204 					{
       
  1205 					iEmailEntry->SetUnread(ETrue);
       
  1206 					iEmailEntry->SetNew(ETrue);
       
  1207 					iEmailEntry->SetVisible(EFalse);
       
  1208 					iEmailEntry->SetInPreparation(ETrue);
       
  1209 					iEmailEntry->SetSendingState(KMsvSendStateNotApplicable);
       
  1210 					}
       
  1211 				else
       
  1212 					{
       
  1213 					TParentDetails parentDetails;
       
  1214 					parentDetails.iMHTML=EFalse;
       
  1215 			        parentDetails.iAttachment=EFalse;
       
  1216 					parentDetails.iSize=0;
       
  1217 					iParent->InsertL(0,parentDetails);
       
  1218 					}
       
  1219 				iEmailEntry->iType=KUidMsvMessageEntry;
       
  1220 				iEmailEntry->iDetails.Set(iOutputHeader->From());
       
  1221 				iEmailEntry->iDescription.Set(iOutputHeader->Subject());
       
  1222 				break;
       
  1223 			case EFolderEntry:
       
  1224 				iEmailEntry->iType=KUidMsvFolderEntry;
       
  1225 				if (iMimeParser->MessageFolderType()==EFolderTypeUnknown)
       
  1226 					{
       
  1227 					// Get folder type of parent (the message)
       
  1228 					TMsvEmailEntry entry=iClientEntry->Entry();
       
  1229 					iEmailEntry->SetMessageFolderType(entry.MessageFolderType());
       
  1230 					}
       
  1231 				break;
       
  1232 			case EAttachmentEntry:
       
  1233 				iEmailEntry->iType=KUidMsvAttachmentEntry;
       
  1234 				iEmailEntry->iDetails.Set(iAttachmentName);
       
  1235 				iEmailEntry->iDescription.Set(iMimeParser->ContentDescription());
       
  1236 				break; 
       
  1237 			case ETextEntry:
       
  1238 				if ( iMimeParser->ContentDisposition()!=KImcvAttachment)
       
  1239 					iEmailEntry->iType=KUidMsvEmailTextEntry;
       
  1240 				else 
       
  1241 					{
       
  1242 					iEmailEntry->iType=KUidMsvAttachmentEntry;
       
  1243 					iEmailEntry->iDetails.Set(iAttachmentName);
       
  1244 					iEmailEntry->iDescription.Set(iMimeParser->ContentDescription());
       
  1245 					}
       
  1246 				break;
       
  1247 			case EHtmlEntry:
       
  1248 				iEmailEntry->iType=KUidMsvEmailHtmlEntry;
       
  1249 				// If disposition not set or is inline..
       
  1250 				if ( iMimeParser->ContentDisposition()==KImcvAttachment)
       
  1251 					iEmailEntry->iType=KUidMsvAttachmentEntry;
       
  1252 				else
       
  1253 					iEmailEntry->SetMHTMLEmail(ETrue);
       
  1254 				iEmailEntry->iDetails.Set(iAttachmentName);
       
  1255 				iEmailEntry->iDescription.Set(iMimeParser->ContentDescription());
       
  1256 				break;
       
  1257 			default:
       
  1258 				iEmailEntry->iType=KUidMsvAttachmentEntry;
       
  1259 				iEmailEntry->iDetails.Set(iAttachmentName);
       
  1260 				iEmailEntry->iDescription.Set(iMimeParser->ContentDescription());
       
  1261 			}
       
  1262 
       
  1263 		iClientEntry->CreateL(*iEmailEntry);
       
  1264 		iEmailEntry->iServiceId = iEmailServiceId;
       
  1265 		iClientEntry->SetEntryL(iEmailEntry->Id());
       
  1266 		if(iTopMessagePart==KMsvRootIndexEntryId)
       
  1267 			iTopMessagePart=iEmailEntry->Id();
       
  1268 
       
  1269 		}
       
  1270 
       
  1271 	iEntryType=previousEntryType;
       
  1272 	iNewEntry = ETrue;
       
  1273 	RECVLOG(KCreatedEntry);
       
  1274 	}
       
  1275 
       
  1276 
       
  1277 void CImCltRecvConvert::StoreMessageEntryDetailsL()
       
  1278 	{
       
  1279 	iEmailEntry->SetAttachment(iParent->At(0).iAttachment);
       
  1280 	iEmailEntry->SetMHTMLEmail(iParent->At(0).iMHTML);
       
  1281 
       
  1282 	if(iEmailEntry->MHTMLEmail() == EFalse && iEmailEntry->Attachment() == EFalse && iRelatedAttachments !=EFalse)
       
  1283 		{
       
  1284 		iEmailEntry->SetAttachment(ETrue);
       
  1285 		}
       
  1286 	iRelatedAttachments=EFalse;
       
  1287 	
       
  1288 	iEmailEntry->iSize=iParent->At(0).iSize;
       
  1289 	iEmailEntry->SetMessageFolderType(iParent->At(0).iFolder);
       
  1290 	StoreEntryDataL();
       
  1291 
       
  1292 	if (iParent->Count()>1)
       
  1293 		{
       
  1294 		iParent->At(1).iSize+=iEmailEntry->iSize;
       
  1295 		iParent->Delete(0);
       
  1296 		}
       
  1297 	else
       
  1298 		{
       
  1299 		iParent->At(0).iAttachment=iParent->At(0).iMHTML=EFalse;
       
  1300 		iParent->At(0).iSize=0;
       
  1301 		}
       
  1302 	}
       
  1303 
       
  1304