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