diff -r 000000000000 -r 72b543305e3a email/pop3andsmtpmtm/servermtmutils/inc/IMCVSEND.H --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/pop3andsmtpmtm/servermtmutils/inc/IMCVSEND.H Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,731 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// IMCVSEND.H +// + +#if !defined(__IMCVSEND_H__) +#define __IMCVSEND_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include "timrfc822datefield.h" +#include "cimconvertheader.h" +#endif + +class CImSendEmail; +class CImEmailTraverser; +class CImSendPlainEmail; +class CImSendMimeEmail; +class CImSendMimeHeader; +class CImSendRfc822Header; +class CImSendRichText; +class CImSendFile; +class CMsvPlainBodyText; + +/** +@internalComponent +@released +*/ +enum TMimeHeaderType { EMainMimeHeader, EPartMimeHeader }; + + +const TImHeaderEncodingInfo::TEncodingType + KDefaultSendingHeaderEncoding = TImHeaderEncodingInfo::EBase64; +const TUint KDefaultSendingCharset = KCharacterSetIdentifierIso88591; +const TInt KArrayAllocationNumber =6; + +/** +The number of US ASCII UU Encoded characters per line between the CRLF line +terminator and the character count at the beginning of the encoded line when sending +UU encoded emails. +*/ +const TInt KMaxUUUnEncodedCharsPerLine = 45; // Historically, UU implmentations use 45. +const TInt KMaxUUEncodedCharsPerLine = static_cast(KMaxUUUnEncodedCharsPerLine / 0.75); // 60. + +/** +The maximum number of US ASCII characters per line that are before the CRLF line +terminator when sending emails. RFC 2822 recommends that each line SHOULD not exceed +80 characters including the CRLF terminator, and MUST not exceed 1000. +*/ +const TInt KMaxB64EncodedCharsPerLine = 60; // Could be increased to 75 characters for every encoded line if KDecodeLineLength = 675. 60 was chosen to maintain existing behaviour. + +/** +Size of 8 bit data chunk to extract when encoding using B64 or UU. +The size allows for the appending of CRLF every KMaxEncodedCharsPerLine +characters after encoding to limit the line length as per RFC 2822. +The size also allows for the expansion of every 3 bytes of unencoded data to +4 bytes when encoded. +*/ +const TInt KDecodeLineLength = 675; // 675/0.75= 900 = 100 bytes left for CRLF and UU length chars, 900/45 = exactly 20 UU lines per SMTP buffer sent, 900/60 = exactly 15 B64 lines per SMTP buffer sent. + + +// External interface to imcvsend. + +//---------------------------------------------------------------------------------------- +class CImSendMessage : public CBase +//---------------------------------------------------------------------------------------- +/** +@internalAll +@released +*/ + { +public: + IMPORT_C static CImSendMessage* NewL(CMsvServerEntry& aServerEntry); + IMPORT_C static CImSendMessage* NewLC(CMsvServerEntry& aServerEntry); + + IMPORT_C ~CImSendMessage( ); + + // Returns KImcvFinished when done. + IMPORT_C TInt NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ); + IMPORT_C void InitialiseL(TMsvId aMessageId, const TTime aTimeDate, + const TDesC& aDomainName, const TImEmailTransformingInfo& aInfo, + const TImSMTPSendCopyToSelf aCopyToSelf); + IMPORT_C void InitialiseL(TMsvId aMessageId, TImSendMethod aSendMethod, const TTime aTimeDate, + const TDesC& aDomainName, TUint aCharset, const TImSMTPSendCopyToSelf aCopyToSelf); + IMPORT_C TInt HeaderSize(); + IMPORT_C TInt BodySizeL(); + IMPORT_C void Reset(); + +private: + + CImSendMessage(CMsvServerEntry& aServerEntry); + void ConstructL(); + void SetSendMethodL(TImSendMethod aSendMethod); + +private: + CMsvServerEntry& iServerEntry; + + CImSendEmail* iSendEmail; + TMsvId iMessageId; + TTime iTimeDate; + + TBool iLogFileExists; // Logging. + RFile iLogFile; + }; + + + +// This class is a VIRTUAL base class from which email protocol classes are derived. +// gives derived classes ability to traverse the entry structure and extract +// information from entries. +// It determines which entry to set the current context to and which entry will follow, +// and knows when the end of the message has been reached. + +//---------------------------------------------------------------------------------------- +class CImSendEmail : public CBase +//---------------------------------------------------------------------------------------- +/** +@internalComponent +@released +*/ + { +public: + CImSendEmail(CMsvServerEntry& aServerEntry); + ~CImSendEmail( ); + + virtual TInt NextLineL(TDes8& rOutputLine, TInt& rPaddingCount) = 0; + virtual void Reset(); + + virtual void InitialiseL( const TTime aTimeDate, const TDesC& aDomainName, + const TImSMTPSendCopyToSelf aCopyToSelf, + const TImEmailTransformingInfo& aTransformingInfo); + virtual TInt HeaderSize(); + virtual TInt BodySizeL(); + +protected: + virtual void ConstructL(); // Call base class Construct in the derived function + TBool InitBodyObjectL(TMsvEntry& rEntry); + TBool InitAttachmentObjectL(TMsvEntry& rEntry); + TImFileCodec& Encoder(TImEncodingType aType); + +protected: + CMsvServerEntry& iServerEntry; + + // Encoding classes including a default. + TImCodecNull iNULLEncoder; + TImCodecUU iUUEncoder; + TImCodecB64WithLineBreaks iB64Encoder; + TImCodecQP iQPEncoder; + + // Objects common to all email types + + CImSendFile* iSendFile; + CImSendRfc822Header* iRfc822Header; + CImSendRichText* iSendRichText; + + CImConvertCharconv* iCharConv; + CCnvCharacterSetConverter* iCharacterConverter; + CImConvertHeader* iHeaderConverter; + + TInt iState; + CImEmailTraverser* iEmailTraverser; + CImHeader* iHeader; + + TInt iEmbeddedEmail; + + TTime iTimeDate; + TPtrC iDomainName; + + TUint iAlgorithm; // used for encoding a body/attachment. + TImEmailTransformingInfo iDefaultTransformingInfo; + }; + + +// Traverses the TMsvEntry structure of email message, used by CImSendEmail. +// Complex email messages have a hierarchical structure with more than one LEVEL. + +//---------------------------------------------------------------------------------------- +class CImEmailTraverser : CBase +//---------------------------------------------------------------------------------------- +/** +@internalComponent +@released +*/ + { +public: + static CImEmailTraverser* NewL( CMsvServerEntry& aServerEntry ); + ~CImEmailTraverser(); + void InitialiseL(TMsvId aId); + + TBool NextEntryL(TMsvEntry& rEntry); + TBool DownLevelL(); + TBool UpLevelL(); + inline void SetBaseEntry(); + + inline TBool IsBaseLevel() const; + inline CMsvEntrySelection& CurrentList() const; + inline const TMsvEntry& ThisEntry() const; + +private: + CImEmailTraverser( CMsvServerEntry& aServerEntry ); + void ConstructL(); + void Reset(); + + inline TBool LevelExists() const; + inline TBool DeleteCurrentList(); + inline void AddList(CMsvEntrySelection& children); + inline TInt CurrentEntry(); + +private: + TMsvId iBaseId; // ID of the Top level email entry. + CMsvServerEntry& iServerEntry; + + // Storing the child entries in a hierarchical entry structure. + // List and count arrays + CArrayFixFlat* iSelectionList; + CArrayFixFlat iCurrentEntryList; + }; + + +// This class is derived from CImSendEmail and encapsulates the non-MIME protocol. +// The class only knows about the entry which is currently in its context, which is +// determined by it base class. + +//---------------------------------------------------------------------------------------- +class CImSendPlainEmail : public CImSendEmail +//---------------------------------------------------------------------------------------- +/** +@internalComponent +@released +*/ + { +private: + enum TSendState { + ERfc822Header = 0, + EBody, + EAttachmentFile, + }; + +public: + static CImSendPlainEmail* NewL(CMsvServerEntry& aServerEntry ); + static CImSendPlainEmail* NewLC(CMsvServerEntry& aServerEntry ); + TInt NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ); + +private: + CImSendPlainEmail(CMsvServerEntry& aServerEntry); + TBool ChangeStateL(); + }; + + + +// It encapsulates the MIME protocol and controls what needs to be sent for a specific +// entry type, this being the type of entry that is currently in context. +// Only knows about the entry which is currently in its context, which is determined by +// it base class. Creates and looks after the boundary strings. + +//---------------------------------------------------------------------------------------- +class CImSendMimeEmail : public CImSendEmail +//---------------------------------------------------------------------------------------- +/** +@internalComponent +@released +*/ + { +public: + // From RFC 1521, (Boundaries) must be no longer than 70 characters. + enum{KBoundaryStringLength = 55}; + +private: + enum TSendState { + ERfc822Header = 0, + EMimeMainHeader, + EMimeText, + EBoundary, + EMimePartHeader, + EBody, + EAttachmentFile, + EEndBoundary, + ELineAfterEndBoundary, + }; + +public: + static CImSendMimeEmail* NewL(CMsvServerEntry& aServerEntry ); + static CImSendMimeEmail* NewLC(CMsvServerEntry& aServerEntry ); + ~CImSendMimeEmail( ); + + TInt NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ); + + void Reset(); + TInt HeaderSize(); + TBool InitBodyObjectL(TMsvEntry& rEntry); + +private: + CImSendMimeEmail(CMsvServerEntry& aServerEntry ); + void ConstructL(); + TBool ChangeStateL(); + + void CreateBoundaryL(); + void DeleteBoundary(); + + inline void Boundary(TDes8& rOutputLine); + inline TPtrC8 Boundary(); + inline TPtrC8 SetBoundaryL(TBool aMultipart); + inline TInt SendBoundaryLine( TDes8& rOutputLine, TInt& rPaddingCount); + inline TBool ValidBoundaryChar( TUint aCharacter ); + + void InitEmbeddedEmailL(); + + TBool CreateMimeHeaderL(); + void InitMimeHeaderL( TMsvEntry& aEntry, TPtrC8& rBoundary, TPtrC& rFilename); + void InitSendMimeHeaderL(TMsvEntry& aEntry, TMimeHeaderType aMimeHeaderType ); + + inline TBool Next(TMsvEntry& rEntry); + inline TBool Down(TMsvEntry& rEntry); + inline void GetNextEntryL(TMsvEntry& rEntry); + inline TBool CheckForEmbeddedEmailL(const TMsvEntry& aEntry) const; + inline TBool CheckForMultipartEmailL( TMsvEntry& rEntry, TImEmailFolderType& aFolder); + +private: + CDesC8ArrayFlat* iBoundaryArray; + CImSendMimeHeader* iSendMimeHeader; + CImMimeHeader* iMimeHeader; + + TBool iTextDisplayed; + TInt64 iRandSeed; + }; + + + +// This class creates the main message header lines which conform to the rfc822 specification. +// The code is currently implemented in Imcvsend.cpp. + +//---------------------------------------------------------------------------------------- +class CImSendRfc822Header : public CBase +//---------------------------------------------------------------------------------------- +/** +@internalComponent +@released +*/ + { +private: + // Defines the state order of the CImSendRfc822Header object... + // !! DO NOT CHANGE THE ORDER !! + + enum TSendState { + EFrom=0, // 0 + EReplyTo, + ETo, + ECc, + EBcc, + ESubject, + EDate, + EReturnReceiptTo, + EPriority, + EImportance, + EMessageID, + EXMailer, + EEndOfRfc822Header + }; + +public: + static CImSendRfc822Header* NewLC( RFs& anFs, CImConvertHeader& aConverter ); + static CImSendRfc822Header* NewL( RFs& anFs, CImConvertHeader& aConverter ); + ~CImSendRfc822Header(); + + TInt NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ); + TBool InitialiseL( const TTime aTimeDate , const TDesC& aDomainName, + CMsvServerEntry& aServerEntry, const TMsvPriority aPriority, + const TImSMTPSendCopyToSelf aCopyToSelf, + TImEmailTransformingInfo& rInfo); + + TInt DoRecipientsL( TDes8& rOutputLine, const TPtrC8& aPrompt, CDesCArray& aList ); + void PrepareBufferL( const TPtrC8& aPrompt, const TDesC& aData); + void PrepareBufferL( const TPtrC8& aPrompt, const TDesC8& aData); + TInt SendOutput( TDes8& rOutputLine ); + TInt PriorityL(TDes8& rOutputLine); + TInt ImportanceL(TDes8& rOutputLine); + + TUint HeaderCharset() const; + void SetMessageIdL(); + void Reset(); + TInt Size() const; + inline const TImEmailTransformingInfo& TransformingInfo() const; + +private: + CImSendRfc822Header( RFs& anFs, CImConvertHeader& aConverter ); + void ConstructL(); + + inline TInt FromL( TDes8& rOutputLine ); + inline TInt ReplyToL( TDes8& rOutputLine ); + inline TInt ToL( TDes8& rOutputLine ); + inline TInt CcL( TDes8& rOutputLine ); + inline TInt BccL( TDes8& rOutputLine ); + inline TInt SubjectL( TDes8& rOutputLine ); + inline TInt MessageIdL( TDes8& rOutputLine ); + inline TInt XMailerL( TDes8& rOutputLine ); + inline TInt ReturnReceiptsL(TDes8& rOutputLine); + inline TBool FieldIsEmailAddress() const; + + TBool ValidEmailAddress(const TPtrC8& aData, const TInt aPos, TInt& rStart, TInt& rEnd); + void EncodeHeaderFieldL(const TDesC& aBufIn, RBuf8& rBufOut, const TInt aArrayVal); + + void AddCopyToSelfL(TImSMTPSendCopyToSelf aCopyToSelf, CDesCArray& aList); + + void HandleSpecialCharacters(TPtr8& aAddressPtr); + TBool IsSpecialCharacter(const TUint aChar); + void PackRemainingData(TDes8& rOutputLine, TPtrC8& aBuf); + +private: + RFs& iFs; + CImHeader* iHeader; + TInt iState; + + HBufC8* iOutputBuffer; + const TUint8* ipOutputBuffer; + + TImRfc822DateField iRfc822Date; + TTime iTimeDate; + TMsvPriority iPriority; + + // resource strings + HBufC* iProductName; + HBufC* iDomainName; + + CImConvertHeader& iHeaderConverter; + CImcvUtils* iImcvUtils; + CDesC8Array* iPriorityFields; + CDesC8Array* iImportanceFields; + CDesC8Array* iReceiptFields; + + TUint iHeaderCharset; + TImEncodingType iHeaderEncoding; + + TImSMTPSendCopyToSelf iCopyToSelf; + TImEmailTransformingInfo iTransformingInfo; + TBool iAddSpaceToNewLine; + }; + + +// This class encapsulates the MIME header protocol. +// The header strings are created from a text resource of standard MIME tokens +// Info obtained from cImMimeHeader object. + +//---------------------------------------------------------------------------------------- +class CImSendMimeHeader : public CBase +//---------------------------------------------------------------------------------------- +/** +@internalComponent +@released +*/ + { +public: + enum TMimeHeaderState + { + EMimeVersion = 0, // Main only + EContentLanguage, // Main only + EDescription, // Part only + EContentType, + EBoundaryString, + EDisposition, + ETransferEncoding, + ECRLF, + EEndOfMimeHeader + }; + + enum TImSplitLine + { + EFirstLine = 0, + ESecondLine + }; +public: + static CImSendMimeHeader* NewL(CImConvertHeader& aConverter, TMimeHeaderType aType); + static CImSendMimeHeader* NewLC(CImConvertHeader& aConverter, TMimeHeaderType aType); + ~CImSendMimeHeader(); + + TInt NextLine( TDes8& rOutputLine, TInt& rPaddingCount ); + + void InitialiseL( CImMimeHeader& aMimeHeader, const TPtrC aFilename, + const TPtrC8& aBoundary, const TBool aEmbedded, + const TMsvEntry& aEntry, const TImEmailTransformingInfo& aInfo, + TBool aEmbeddedEmail = EFalse); + inline TInt BlankLine( TDes8& rOutputLine ) const; + inline TInt MimeVersion( TDes8& rOutputLine ) const; + inline TBool ContentType( TDes8& rOutputLine) const; + inline TBool TransferEncoding(TDes8& rOutputLine) const; + inline TInt ContentLanguage( TDes8& rOutputLine ) const; + inline TBool Description( TDes8& rOutputLine) const; + inline TBool Disposition( TDes8& rOutputLine, TInt& rAdvance); + inline const TPtrC8 EncodingType() const; + + TUint CharsetUid() const; + void SetCharsetUidL(const TUint aId); + TPtrC8 GetCharsetString() const; + + inline TInt Boundary(TDes8& rOutputLine) const; + void AppendFilenameL( TDes8& rOutputLine ) const; + TInt Size() const; + +private: + CImSendMimeHeader( CImConvertHeader& aConverter, TMimeHeaderType aType); + +private: + CImConvertHeader& iConverter; + TInt iHeaderState; + + CImMimeHeader* iMimeHeader; + // Info needed when filling in header details + TImEncodingType iAlgorithm; + HBufC8* iCharsetString; + TPtrC8 iBoundaryString; + TFileName iFilename; + TMsvEntry iEntry; + + TInt iLine; + TBool iIsMultipart; + TMimeHeaderType iMimeHeaderType; + + TUint iHeaderCharset; + TImEncodingType iHeaderEncodingType; + + TUint iCharsetUid; + TImEncodingType iEncodingType; + + TBool iDealingWithAnEmbeddedEmail; + }; + + +// This class sends the text from a richtext object. +// The text can be encoded using any of the available encoding techniques + +//---------------------------------------------------------------------------------------- +class CImSendRichText : public CBase +//---------------------------------------------------------------------------------------- +/** +@internalComponent +@released +*/ + { +public: + static CImSendRichText* NewL( CImConvertCharconv& aConv ); + static CImSendRichText* NewLC( CImConvertCharconv& aConv ); + + TBool InitialiseL( CMsvServerEntry& aServerEntry, TImCodec& anEncoder, + TImEncodingType aType, TUint aCharset); + TInt NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ); + void ExtractLineFromChunkL(TDes16& aOutputLine); + ~CImSendRichText(); + inline TInt Size() const; + +private: + CImSendRichText(CImConvertCharconv& aConv); + void ConstructL(); + + TInt NoEncodeNextLineL( TDes8& rOutputLine, TInt& rPaddingCount ); + TInt RemoveControlCharacters( const TDesC& aInputLine, TDes& rOutputLine, TInt& rPaddingCount ); + + TInt EncodeNextLineL( TDes8& rOutputLine, TInt& rPaddingCount ); + TInt EncodeQPNextLineL( TDes8& rOutputLine, TInt& rPaddingCount ); + + TInt ConvertNextLineL( const TDesC& aInput, TDes8& rOutput); + TBool SmartBreak( TInt written, const TDesC& pSource ); + TBool SmartBreak( TInt written, const TUint8* pSource, TInt aMaxLength ); + + inline TBool IsBreakable( TChar aChar ) const; + inline TBool IsEOL(TChar aChar) const; + inline TUint8 ReplacementChar(TChar aControlChar) const; + inline TBool IsPlain(TChar aChar) const; + inline int ConvertLineBreaks( TDes& aSource, TBool aLineBreak) const; + +private: + // The message store class for reteiving chunks of body text from mail store. + CMsvPlainBodyText* iPlainBodyText; + CImConvertCharconv& iConverter; + TBool iPreparedToConvert; + TImCodec* iEncoder; + + TInt iMaxLength; + TBool iUseRichText; + TInt iBodySize; + TInt iPos; + TImEncodingType iBodyEncoding; + HBufC8* iLeftOver; + // Buffer used for extracting line of body text from restored chunk. + RBuf iCurrentChunk; + // Indicates whether a chunk needs to be restored from Message Store. + TBool iIsNewChunk; + }; + + +// This class creates lines to send from files, +// the files can be encoded using any of the available encoding techniques. + +//---------------------------------------------------------------------------------------- +class CImSendFile : public CBase +//---------------------------------------------------------------------------------------- +/** +@internalComponent +@released +*/ + { +private: + enum TImSplitLine + { + EFirstLine = 0, + ESecondLine + }; + + // Length of source text buffer used when encoding and outputting. + // Taking into account that the length may increase. + + enum TImAttachmentSend + { + ENextFile = 0, + EPrefixLines, + EEncodeFile, + EPostfixLines, + EEndOfAttachments, + ECloseDelimiter, + ECRLFLine, + EEnd + }; +public: + static CImSendFile* NewLC(RFs& anFs, CImConvertCharconv& aCharConv); + static CImSendFile* NewL(RFs& anFs, CImConvertCharconv& aCharConv); + ~CImSendFile(); + + void InitialiseL( CMsvServerEntry& aServerEntry, TImFileCodec& anEncoder); + + TInt NextLineL( TDes8& rOutputLine, TInt& rPaddingCount ); + + inline TInt BlankLine( TDes8& rOutputLine, TInt& rPaddingCount ); + const TFileName& Filename() const; + + TFileName& Filename( CMsvServerEntry& aEntry, SAttachmentInfo& aInfo); + + static void EmbeddedEmailFilename(TMsvEntry& aEntry, TFileName& aFileName); + inline TInt Size() const; + +private: + CImSendFile(RFs& anFs, CImConvertCharconv& aCharConv); + void ConstructL(); + +private: + const RFs& iFs; + + TImFileCodec* iEncoder; // Either B64 or UU encoder or none + CImConvertCharconv& iConverter; + + SAttachmentInfo iAttachmentInfo; + TImAttachmentFile* iAttachmentFile; + TBuf8 iSourceLine; + CImMimeHeader* iMimeHeader; // Passed in. + + TInt iAttachmentState; // so dont change there order + TInt iFileIndex; // The following are init'ed in the Ctor list + TInt iBodyHeaderState; + + TInt iPrefixState; + TInt iPostfixState; + }; + + +//---------------------------------------------------------------------------------------- +class CImCalculateMsgSize : public CMsgActive +//---------------------------------------------------------------------------------------- +/** +@internalTechnology +@released +*/ + { +public: + IMPORT_C static CImCalculateMsgSize* NewL(RFs &anFs,CMsvServerEntry& aServerEntry); + IMPORT_C ~CImCalculateMsgSize(); + IMPORT_C void StartL(TRequestStatus& aStatus,TMsvId aMsvId, + TImSendMethod aAlgorithm, TTime& aTimeDate, + const TDesC& aDomainName, const TUint aCharset); + + inline TInt MessageSize() const; // total size of Email - once active object has completed + inline void Progress(TInt& aBytes, TInt& aTotal); // current info on size of Email + +private: + void DoRunL(); + void DoCancel(); +private: + CImCalculateMsgSize(RFs &anFs,CMsvServerEntry& aServerEntry); + void ConstructL(); + void Reset(); +private: + RFs& iFs; + CMsvServerEntry& iServerEntry; + TMsvId iMsvId; + + TInt iSize; + TInt iTotal; + + CImSendMessage* iSendMsg; + TBuf8 iMailString; + TBool iFinished; +#if defined (_DEBUG) + RFile iFile; + TBool iFileOpen; +#endif + }; + + +#include + +#endif