--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmsengine/mmscodec/inc/mmsencode.h Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,784 @@
+/*
+* Copyright (c) 2002 - 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:
+* Binary encoding of a multimedia message
+*
+*/
+
+
+
+#ifndef CMMSENCODE_H
+#define CMMSENCODE_H
+
+// INCLUDES
+#include <mentact.h>
+#include <badesca.h>
+#include <cmsvattachment.h>
+
+#include "mmsconst.h" // needed for TMmsRecipients
+#include "mmsservercommon.h" // needed for logging flag definition
+#include "mmscodecdatasupplier.h"
+
+// CONSTANTS
+
+// MACROS
+
+// DATA TYPES
+
+// FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+class RBufWriteStream;
+class CMmsHeaders;
+class CMsvMimeHeaders;
+class MMmsEntryWrapper;
+class MMmsEntry;
+class CMsgTextUtils;
+
+// CLASS DECLARATION
+
+/**
+* Binary encoding of a multimedia message.
+*
+* @lib mmscodec.lib
+* @since v2.1
+*/
+class CMmsEncode :public CMsgActive, public MMmsCodecDataSupplier
+ {
+public:
+
+ /**
+ * @param aFs file system handle.
+ */
+ IMPORT_C static CMmsEncode* NewL( RFs& aFs );
+
+ virtual ~CMmsEncode();
+
+public: // New functions
+
+ /**
+ * Start the state machine for encoding a message with headers and data.
+ *
+ * @param aEntryWrapper mixin for handling all message entry access
+ * @param aMmsHeaders reference to CMmsHeaders class.
+ * @param aEncodeBuffer buffer to hold the encoded data,
+ * @param aStatus status of calling active object
+ */
+ IMPORT_C void StartL(
+ MMmsEntryWrapper& aEntryWrapper,
+ CMmsHeaders& aMmsHeaders,
+ CBufFlat& aEncodeBuffer,
+ TRequestStatus& aStatus );
+
+ /**
+ * Encode headers only.
+ *
+ * This function is for the miscellaneous control messages.
+ * This is not an active function, one-shot only.
+ * @param aMmsHeaders reference to CMmsHeaders class.
+ * @param aEncodeBuffer buffer to hold the encoded data,
+ */
+ IMPORT_C void EncodeHeadersL(
+ CMmsHeaders& aMmsHeaders,
+ CBufFlat& aEncodeBuffer );
+
+ /**
+ * Start chunked encoding.
+ * This method can be called only when it is known that the component
+ * that handles the encoded data can use the callback to get more
+ * data chunks.
+ *
+ * @since v3.1
+ * @param aEntryWrapper mixin for handling all message entry access
+ * @param aMmsHeaders reference to CMmsHeaders class.
+ * @param aEncodeBuffer buffer to hold the encoded data,
+ * @param aStatus status of calling active object
+ */
+ IMPORT_C void StartChunkedL(
+ MMmsEntryWrapper& aEntryWrapper,
+ CMmsHeaders& aMmsHeaders,
+ CBufFlat& aEncodeBuffer,
+ TRequestStatus& aStatus );
+
+// from base class MMmsCodecDataSupplier
+
+ /**
+ * from MMmsCodecDataSupplier.
+ * Give poiner to next encoded data chunk.
+ *
+ * @since v3.1
+ * @param aDataPart pointer to the next encoded data part
+ * @param aLastDataChunk
+ * ETrue if this is the last data chunk
+ * EFalse if this is not the last data chunk
+ * @return error code, KErrNone if all is well.
+ * If returns some other error, transaction must be cancelled.
+ */
+ virtual TInt GetNextDataPart(
+ TPtrC8& aDataPart, TBool& aLastDataChunk );
+
+ /**
+ * from MMmsCodecDataSupplier.
+ * Empty buffer and prepare next data part (synchronous encoding).
+ * When needed, caller will tell HTTP stack that the next data part is
+ * ready by calling RHTTPTransaction::NotifyNewRequestBodyPartL()
+ *
+ * @since v3.1
+ * @return error code, KErrNone if all is well.
+ * If returns some other error, transaction must be cancelled.
+ */
+ virtual TInt ReleaseData();
+
+ /**
+ * from MMmsCodecDataSupplier.
+ * Return the overall data size.
+ *
+ * @since v3.1
+ * @return The overall data size if it is known, otherwise KErrNotFound
+ */
+ virtual TInt OverallDataSize();
+
+ /**
+ * from MMmsCodecDataSupplier.
+ * Reset the data supplier.
+ * Data supplier must start the data generation from the beginning again.
+ *
+ * @since v3.1
+ * @return KErrNone if reset is successful, other error code if data
+ * supplier cannot be reset
+ */
+ TInt ResetSupplier();
+
+protected:
+
+private:
+
+ CMmsEncode();
+
+ /**
+ * @param aFs file system handle.
+ */
+ void ConstructL( RFs& aFs );
+
+ /**
+ * from CMsgActive.
+ *
+ * Active object completion.
+ */
+ void DoRunL();
+
+ /**
+ * from CMsgActive.
+ *
+ * Sweep the floor after everything has crashed.
+ * @param aStatus completion code
+ */
+ void DoComplete( TInt& aStatus );
+
+ /**
+ * Select next state for state machine.
+ */
+ void SelectNextState();
+
+ /**
+ * Switch states.
+ */
+ void ChangeStateL();
+
+ /**
+ * Initialize members to allow one-shot functions.
+ * (for short tasks no active object invocation is needed)
+ */
+ void Reset();
+
+ /**
+ * Encode headers.
+ */
+ void EncodeHeadersL();
+
+ /**
+ * Encode headers in chunked mode.
+ */
+ void EncodeHeadersChunkedL();
+
+ /**
+ * Do one attachment at a time.
+ */
+ void EncodeAttachmentL();
+
+ /**
+ * Do the actual work, can be called from active loop or passive loop
+ */
+ void DoEncodeAttachmentL();
+
+ /**
+ * Get encoding length for one attachment
+ * @return size of the encoded attachment headers and attachment data
+ */
+ TInt DoGetAttachmentEncodingLengthL();
+
+ /**
+ * Encode attachment headers into the buffer and open the attachment file
+ * @param aAttachMan reference to attachment manager for accessing
+ * attachment information and opening the file
+ * @return size of the attachment
+ */
+ TInt EncodeHeadersAndGetFileL( MMsvAttachmentManager& aAttachMan );
+
+ /**
+ * Get the encoded size of the mime headers and the attachment data
+ * @param aAttachMan reference to attachment manager for accessing
+ * attachment information and opening the file
+ * @return size of the encoded attachment headers and attachment data
+ */
+ TInt GetHeadersAndFileSizeL( MMsvAttachmentManager& aAttachMan );
+
+ /**
+ * Calculate the length of headers for the attachment
+ * @param aAttachmentInfo attachmentInformation structure for current attacment
+ * @param aHeaderLength total length of encoded headers
+ * @param aFoundName ETrue the name is among content-type parameters
+ * EFalse the name is in the recommended filename parameter
+ * @param aContentTypeSize length of the content type header
+ * @param aContentType assigned number for content type, -1 if not found
+ * @param aContentTypeString content type in string format if aContentType == -1
+ * @return pointer to attachment name in 8bit format if aFoundName == EFalse
+ * If aFoundName == ETrue, returns NULL, because name in included in content
+ * type parameters and is not added separately.
+ * Caller must delete buffer when no longer needed.
+ */
+ HBufC8* CalculateAttachmentHeaderLengthL(
+ CMsvAttachment& aAttachmentInfo,
+ TUint& aHeaderLength,
+ TBool& aFoundName,
+ TUint& aContentTypeSize,
+ TInt8& aContentType,
+ TPtrC8& aContentTypeString );
+
+ /**
+ * Encode headers for one attachment
+ * @param aSize size of the attachment binary data
+ * @param aHeaderSize size of the headers in encoded format
+ * @param aFoundName ETrue if the name parameter is among the
+ * Content type parameters in MIME headers
+ * @param aContentTypeSize size of the content type header
+ * @param aContentType assigned number for the content type
+ * @param aContentTypeString content type in string format if
+ * no assigned number is available
+ * @param aNameString name of the attachment if aFoundName == EFalse
+ */
+ void EncodeAttachmentHeadersL(
+ TUint aSize,
+ TUint aHeaderSize,
+ TBool aFoundName,
+ TUint aContentTypeSize,
+ TInt8 aContentType,
+ TPtrC8& aContentTypeString,
+ TPtrC8& aNameString );
+
+ /**
+ * Write all attachment data to the buffer
+ * @param aAttachFile open handle for attachment file
+ * After reading the file pointer will point past data read
+ * @param aSize amount of data to be read
+ */
+ void EncodeAttachmentData( RFile& aAttachFile, TInt aSize );
+
+ /**
+ * Cleanup (close streams etc.).
+ */
+ void FinishL();
+
+ /**
+ * Encode MMS request headers depending on the PDU type
+ */
+ void EncodeRequestHeadersL();
+
+ // As different transactions have widely different headers,
+ // a separate routine is used for each to avoid lots of extra
+ // work when certain headers are not needed anyway.
+
+ // If new transactions (message types) are added, they need
+ // special handling anyway.
+
+ /**
+ * Send Request.
+ */
+ void EncodeSendRequestHeadersL();
+
+ /**
+ * Notify response.
+ */
+ void EncodeNotifyResponse();
+
+ /**
+ * Delivery acknowledgement.
+ */
+ void EncodeAcknowledgeIndication();
+
+ /**
+ * Mms notification.
+ */
+ void EncodeMmsNotificationL();
+
+ // PDUs reserved for testing purposes
+
+ /**
+ * Send confirmation
+ */
+ void EncodeSendConfirmationL();
+
+ /**
+ * Retrieve confirmation.
+ */
+ void EncodeRetrieveConfirmationL();
+
+ /**
+ * Delivery report.
+ */
+ void EncodeDeliveryReportL();
+
+ // MMS encapsulation version 1.1 PDUs
+
+ /**
+ * Forward Request.
+ */
+ void EncodeForwardRequestL();
+
+ /**
+ * Forward confirmation.
+ * for testing purposes
+ */
+ void EncodeForwardConfirmationL();
+
+ /**
+ * ReadReply.
+ * @param aPDUType KMmsMessageTypeReadRecInd or
+ * KMmsMessageTypeReadOrigInd (supported for testing purposes)
+ */
+ void EncodeReadReplyL();
+
+ // MMS encapsulation 1.2 PDUs
+
+ /**
+ * MMBox store request.
+ * @since 2.6
+ */
+ void EncodeMMBoxStoreRequestL();
+
+ /**
+ * MMBox store confirmation.
+ * for testing purposes.
+ * @since 2.6
+ */
+ void EncodeMMBoxStoreConfirmationL();
+
+ /**
+ * MMBox view request.
+ * @since 2.6
+ */
+ void EncodeMMBoxViewRequestL();
+
+ /**
+ * MMBox view confirmation.
+ * for testing purposes.
+ * @since 2.6
+ */
+ void EncodeMMBoxViewConfirmationL();
+
+ /**
+ * MMBox upload request
+ * @since 2.6
+ */
+ void EncodeMMBoxUploadRequestL();
+
+ /**
+ * MMBox upload confirmation
+ * for testing purposes.
+ * @since 2.6
+ */
+ void EncodeMMBoxUploadConfirmationL();
+
+ /**
+ * MMBox delete request or MMSC delete request
+ * @since 2.6
+ */
+ void EncodeDeleteRequestL();
+
+ /**
+ * MMBox delete confirmation or MMSC delete confirmation.
+ * for testing purposes.
+ * @since 2.6
+ */
+ void EncodeDeleteConfirmationL();
+
+ /**
+ * MMBox description
+ * for testing purposes.
+ * @since 2.6
+ */
+ void EncodeMMBoxDescriptionL();
+
+ // end of MMS encapsulation PDUs
+
+ /**
+ * Encode Text String (No Character set).
+ * @param aString byte string
+ */
+ void EncodeTextString( const TDesC8& aString );
+
+ /**
+ * Encode Quoted Text String (No Character set).
+ * This function adds a quote to the beginning of the text string.
+ * needed for content-id
+ * @param aString byte string
+ */
+ void EncodeQuotedTextString( const TDesC8& aString );
+
+ /**
+ * Encode Text String.
+ * Checks if string can be sent as plain ASCII,
+ * if not, encodes it into utf-8
+ * @param aString unicode string
+ */
+ void EncodeTextStringL( const TDesC& aString );
+
+ /**
+ * Encode date.
+ * @param aDate local datetime in seconds from 1.1.1970
+ */
+ void EncodeDate( const TInt64& aDate );
+
+ /**
+ * Encode long integer.
+ * @param 8 byte integer to be encoded
+ */
+ void EncodeLongInteger( const TInt64& aLongInteger );
+
+ /**
+ * Encode integer.
+ * Will be encoded as short integer or long integer depending on value.
+ * @param 4 byte integer to be encoded
+ */
+ void EncodeInteger( TUint aInteger );
+
+ /**
+ * Encode Sender.
+ * The result is either a legal sender address or an "insert-address"
+ * token.
+ * @param aSender pointer to sender name
+ */
+ void EncodeSenderL( const TPtrC& aSender );
+
+ /**
+ * Encode Address.
+ * @param aAddress pointer to address
+ */
+ void EncodeAddressL( const TPtrC& aAddress );
+
+ /**
+ * Encode value length (long or short).
+ * @param aLength value length that may be short or long
+ */
+ void EncodeValueLength( TUint aLength );
+
+ /**
+ * Encode Uintvar.
+ * @param aInteger the integer to be coded - usually a length
+ */
+ void EncodeUintvar( TUint aInteger );
+
+ /**
+ * Check how many bytes are needed to encode a Uintvar.
+ * @param aInteger the integer to be coded - usually a length
+ * @return number of bytes needed in the encoding.
+ */
+ TInt GetUintvarLength( TUint aInteger );
+
+ /**
+ * Encode recipient.
+ * @param aRecipientList array of recipient descriptors
+ * @param aType recipient type (To, Cc, Bcc)
+ */
+ void EncodeRecipientL( const CDesCArray& aRecipientList,
+ TMmsRecipients aType );
+
+ /**
+ * Encode optional encoded string text.
+ * @param aHeader assigned header byte
+ * @param aString text
+ */
+ void EncodeOptionalStringL( TUint8 aHeader, const TPtrC16& aString );
+
+ /**
+ * Encode optional encoded string text.
+ * @param aHeader assigned header byte
+ * @param aString text
+ */
+ void EncodeOptionalString( TUint8 aHeader, const TPtrC8& aString );
+
+ /**
+ * Encode absolute time or a time interval.
+ * @param aInterval interval.
+ * @param aDate absolute date. If date is 0, interval is encoded.
+ */
+ void EncodeIntervalOrDate( TInt aInterval, const TInt64& aDate );
+
+ /**
+ * Encode ReplyCharging size if defined.
+ * @param aReplyChargingSize maximum number in octets for the reply-MM
+ */
+ void EncodeReplyChargingSize( TInt aReplyChargingSize );
+
+ /**
+ * Encode specified header if value is different from zero.
+ * Encoding must be assigned byte value.
+ * @param aHeader assigned header byte
+ * @param aValue assigned value for the header
+ */
+ void EncodeOptionalByte( TUint8 aHeader, TInt aValue );
+
+ /**
+ * Encode specified header (mandatory).
+ * Encoding must be assigned byte value
+ * @param aHeader assigned header byte
+ * @param aValue assigned value for the header
+ */
+ void EncodeMandatoryByte( TUint8 aHeader, TInt aValue );
+
+ /**
+ * Encode optional header that may be date or interval
+ * @param aHeader assigned header byte
+ * @param aInterval interval.
+ * @param aDate absolute date. If date is 0, interval is encoded.
+ * if both date and interval are 0, header is not added
+ */
+ void EncodeOptionalIntervalOrDate( TUint8 aHeader,
+ TInt aInterval,
+ const TInt64& aDate );
+
+ /**
+ * Encode header byte and 8-bit Text String (No Character set).
+ * @param aHeader assigned header byte
+ * @param aString byte string
+ */
+ void EncodeHeaderAndTextString( TUint8 aHeader,
+ const TDesC8& aString );
+
+ /**
+ * Check if string contains only US-ASCII characters.
+ * @param aString the string to be checked
+ * @return ETrue = ASCII, EFalse = needs encoding
+ */
+ TBool IsStringSafe( const TDesC& aString );
+
+ /**
+ * Check if string contains only US-ASCII characters.
+ * @param aString the string to be checked
+ * @param aNumNonSafe number of characters >= 0x7F
+ * @return ETrue = ASCII, EFalse = needs encoding
+ */
+ TBool IsStringSafe( const TDesC8& aString, TInt& aNumNonSafe );
+
+ /**
+ * Encode Content type header with start parameter.
+ * The content-id of the attachment is searched. If the
+ * attachment has no content-id, an id is generated by a random
+ * number generator (not globally unique).
+ * @param aRootId Internal Id of the attachment that is the root
+ * part of the message.
+ */
+ void EncodeMultipartRelatedHeaderL( const TMsvAttachmentId aRootId );
+
+ /**
+ * Encode Content type as multipart/mixed (no start specified).
+ */
+ void EncodeMultipartMixedHeaderL();
+
+ /**
+ * Encode keyword array.
+ */
+ void EncodeKeywordArrayL();
+
+ /**
+ * Encode optional integer. If value is 0, it is not added
+ * @param aHeader assigned header byte
+ * @aValue value to be encoded as an integer
+ */
+ void EncodeOptionalInteger( TUint8 aHeader, TUint aValue );
+
+ /**
+ * Encode attribute headers from array.
+ * This is the list of information elements required for each message
+ * @param aAttributeArray list of attributes as assigned numbers
+ */
+ void EncodeAttributes( RArray<TUint>& aAttributeArray );
+
+ /**
+ * Encode X-Mms-MM-State headers from an array.
+ * In MMBox view PDUs this header may appear multiple times
+ * @param aStateArray list of states used for filtering messages
+ * (items have values draft/sent/new/retrieved/forwarded)
+ */
+ void EncodeMMBoxStates( RArray<TInt>& aStateArray );
+
+ /**
+ * Encode content location array.
+ * Encodes content location headers in cases where more than one are
+ * allowed
+ */
+ void EncodeContentLocationArray();
+
+ /**
+ * Encode the three headers appearing at the beginning of most PDUs.
+ * TID is not always required. If length of TID is 0, the header is
+ * not added.
+ * @param aMessageType value for X-Mms-Message-Type header
+ * @param aTID transaction ID
+ * @param aVersion MMS encapsulation version number
+ */
+ void EncodeStartingHeaders( TInt aMessageType,
+ const TPtrC8& aTID, TInt aVersion );
+
+ /**
+ * Encode Application Id and Reply to Application id as content type parameters
+ */
+ void EncodeApplicationIdParametersL();
+
+ /**
+ * Dump binary data into file.
+ */
+ void Dump();
+
+ /**
+ * Append a chunk of binary data into file - for chunked encoding support
+ */
+ void DumpAppend();
+
+ /**
+ * Encode that application id, reply application id and application info
+ */
+ void EncodeApplicationHeadersL();
+
+ /**
+ * Encode cancel request PDU - for testing only
+ */
+ void EncodeCancelRequest();
+
+ /**
+ * Encode cancel response PDU
+ */
+ void EncodeCancelResponse();
+
+ /**
+ * Encode utf8 string into MIME quoted printable format.
+ * @param aSource string in utf8 character set.
+ * @return data in encoded format. Caller must delete buffer
+ */
+ HBufC8* EncodeQuotedPrintableWordL( const TPtrC8& aSource );
+
+ /**
+ * Encode utf8 string into MIME base64 format.
+ * @param aSource string in utf8 character set
+ * @return data in encoded format. Caller must delete buffer
+ */
+ HBufC8* EncodeBase64WordL( const TPtrC8& aSource );
+
+ /**
+ * Open the message store(Edit mode) and process attachments
+ * for further encoding
+ * @param None
+ * @return void
+ */
+ void PreProcessAttachmentDataL();
+
+ /**
+ * Check and proceed if given attachment can be encoded using
+ * target encoding type based on its content type.
+ * @param aAttachmentInfo attachment of the msv entry
+ * aMimeHeaders corresponding attachment mime headers
+ * @return true/false based on attachment content type
+ */
+ TBool CheckAndUpdateAttachmentL( CMsvAttachment& aAttachmentInfo,
+ CMsvMimeHeaders& aMimeHeaders );
+
+
+ /**
+ * checks if input content type is supported for target encoding
+ * @param aSrcCharSetMIBEnum MIB enum reprsenting current data format
+ * aTargetCharSetMIBEnum target encoding MIB enum
+ * aAttachmentInfo attachment data to be converted
+ * @return true/false based on encoding success/failure
+ */
+ TBool ProcessAndConvertAttachmentDataL( TUint aSrcCharSetMIBEnum,
+ TUint aTargetCharSetMIBEnum,
+ CMsvAttachment& aAttachmentInfo);
+
+ /**
+ * checks if input content type is supported for target encoding
+ * @param aContentType to check if the attachment data encoding is supported
+ * @return true/false based on attachment content type
+ */
+ TBool IsConversionSupportedContentType( TInt aContentType );
+
+
+
+private: // Data
+ RFs iFs; // file system
+ TInt iError;
+ TInt iState;
+ MMmsEntryWrapper* iEntryWrapper;
+ CBufFlat* iEncodeBuffer;
+ CMmsHeaders* iMmsHeaders;
+ CMsvMimeHeaders* iMimeHeaders;
+ TInt iPosition; // pointer to encode buffer (if needed)
+ TInt iNumberOfAttachments;
+ TInt iCurrentAttachment; // AttachmentManager index
+ TFileName iFileName;
+#ifndef _NO_MMSS_LOGGING_
+// only needed if output logging is enabled
+// parse buffer as member to save stack space
+ TParse iParse;
+#endif
+ TMsvId iCurrentMessageId;
+
+ TInt iOverallDataSize;
+ TBool iLastChunk;
+ TBool iOnlyOneChunk;
+ TInt iEncodingStage; // stage for chunked encoding
+ // Handle for the current attachment.
+ // If the file is large it may be read to the buffer in chunks.
+ // The file is kept open between reads. We want sole access.
+ RFile iAttachFile;
+ // The attachment file is kept open if it is read in several parts.
+ // In destructor the file must be closed in case the transaction
+ // terminates with error
+ TBool iFileOpen;
+ // Size of the current attachment.
+ // This will allow us to keep track of the amount of data read from the file
+ TInt iCurrentFileSize;
+ // The stage variable that will keep track of the part of message that
+ // is going to be encoded next in case of chunked encoding
+ TInt iDataSupplierStage;
+ // The max size of the ecode buffer for chunked encoding.
+ TInt iBufferSize;
+ // object to provide chaconv functionalities
+ CMsgTextUtils* iTextUtils;
+ // target encoding type
+ TUint iTargetEncodingType;
+ };
+
+#endif // CMMSENCODE_H
+
+// End of File