diff -r 000000000000 -r 72b543305e3a mmsengine/mmsmessage/src/mmsheaders.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmsengine/mmsmessage/src/mmsheaders.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,2190 @@ +/* +* Copyright (c) 2002-2007 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: mmsheaders implementation +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include "mmsconst.h" +#include "mmsheaders.h" +#include "mmssettings.h" +#include "mmsversion.h" +#include "mmselementdescriptor.h" +#include "mmsmmboxmessageheaders.h" +#include "mmsmmboxviewheaders.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +const TInt KMmsArrayAllocationNumber = 6; + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// ==================== LOCAL FUNCTIONS ==================== + + +// ================= MEMBER FUNCTIONS ======================= + +// C++ default constructor can NOT contain any code that +// might leave. +// +CMmsHeaders::CMmsHeaders(): + iLinearOrder( CMmsSendingChain::Compare ), + iDeleteResultOrder( CMmsDeleteResultArray::Compare ) +// in a class derived from CBase all member variables are set initially to 0 + { + } + +// Symbian OS default constructor can leave. +void CMmsHeaders::ConstructL( TInt16 aMmsDefaultVersion ) + { + iToArray = new ( ELeave )CDesCArrayFlat( KMmsArrayAllocationNumber ); + iCcArray = new ( ELeave )CDesCArrayFlat( KMmsArrayAllocationNumber ); + iBccArray = new ( ELeave )CDesCArrayFlat( KMmsArrayAllocationNumber ); + iMmsDefaultVersion = aMmsDefaultVersion; + if ( iMmsDefaultVersion < KMmsMinimumSupportedVersion || + iMmsDefaultVersion > KMmsMaximumSupportedVersion ) + { + // The supported default version must be within limits. + // The actual messages can carry any version + iMmsDefaultVersion = KMmsDefaultVersion; + } + Reset( NULL ); + } + +// Two-phased constructor. +EXPORT_C CMmsHeaders* CMmsHeaders::NewL( TInt16 aMmsVersion ) + { + CMmsHeaders* self = new ( ELeave ) CMmsHeaders; + + CleanupStack::PushL( self ); + // default value for legacy applications that are not aware of mms version + self->ConstructL( aMmsVersion ); + CleanupStack::Pop( self ); + + return self; + } + +// Two-phased constructor. +EXPORT_C CMmsHeaders* CMmsHeaders::NewL() + { + CMmsHeaders* self = new ( ELeave ) CMmsHeaders; + + CleanupStack::PushL( self ); + // default value for legacy applications that are not aware of mms version + self->ConstructL( KMmsDefaultVersion ); + CleanupStack::Pop( self ); + + return self; + } + +// Destructor +CMmsHeaders::~CMmsHeaders() + { + iPreviouslySentArray.ResetAndDestroy(); + iDeleteResultArray.ResetAndDestroy(); + delete iOperatorResponseText; + delete iReplyChargingId; + delete iToArray; + delete iCcArray; + delete iBccArray; + delete iSender; + delete iContentLocation; + delete iSubject; + delete iTID; + delete iMessageId; + delete iRootContentID; + delete iElementDescriptor; + delete iMmBoxMessageHeaders; + delete iMmBoxViewHeaders; + delete iExtendedNotificationText; + delete iApplicationId; + delete iReplyToApplicationId; + delete iApplicationInfo; + delete iRecommendedRetrievalModeText; + delete iReplaceCancelId; + } + +// --------------------------------------------------------- +// CMmsHeaders::RestoreL +// +// --------------------------------------------------------- +// + +EXPORT_C void CMmsHeaders::RestoreL( + CMsvStore& aStore ) + { + + RMsvReadStream stream; + Reset( NULL ); // all old pointers are deleted here + if ( aStore.IsPresentL( KUidMmsHeaderStream ) ) + { + stream.OpenLC( aStore, KUidMmsHeaderStream ); // pushes 'stream' to the stack + InternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + // restore MMBox header streams if present + if ( aStore.IsPresentL( KUidMMsElementDescriptorStream ) ) + { + stream.OpenLC( aStore, KUidMMsElementDescriptorStream ); // pushes 'stream' to the stack + iElementDescriptor = new( ELeave )CMmsElementDescriptor; + iElementDescriptor->InternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + if ( aStore.IsPresentL( KUidMMsMMBoxMessageHeaderStream ) ) + { + stream.OpenLC( aStore, KUidMMsMMBoxMessageHeaderStream ); // pushes 'stream' to the stack + iMmBoxMessageHeaders = CMmsMMBoxMessageHeaders::NewL(); + iMmBoxMessageHeaders->InternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + if ( aStore.IsPresentL( KUidMMsMMBoxViewHeadersStream ) ) + { + stream.OpenLC( aStore, KUidMMsMMBoxViewHeadersStream ); // pushes 'stream' to the stack + iMmBoxViewHeaders = new( ELeave )CMmsMMBoxViewHeaders; + iMmBoxViewHeaders->InternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + + // Extended notification also restored here + TInt length = 0; // string length + + // Completeness indicator is not saved or restored. + // If we have stored the text, it normally indicates that the message is not complete + if ( aStore.IsPresentL( KUidMMsExtendedNotificationStream ) ) + { + stream.OpenLC( aStore, KUidMMsExtendedNotificationStream ); // pushes 'stream' to the stack + length = stream.ReadInt32L(); + if ( length > 0 ) + { + iExtendedNotificationText = HBufC::NewL( stream, length ); + } + CleanupStack::PopAndDestroy( &stream ); // close stream + } + + if ( aStore.IsPresentL( KUidMmsApplicationInfoStream ) ) + { + stream.OpenLC( aStore, KUidMmsApplicationInfoStream ); // pushes 'stream' to the stack + length = stream.ReadInt32L(); + if ( length > 0 ) + { + iApplicationId = HBufC::NewL( stream, length ); + } + length = stream.ReadInt32L(); + if ( length > 0 ) + { + iReplyToApplicationId = HBufC::NewL( stream, length ); + } + length = stream.ReadInt32L(); + if ( length > 0 ) + { + iApplicationInfo = HBufC8::NewL( stream, length ); + } + + CleanupStack::PopAndDestroy( &stream ); // close stream + } + + if ( aStore.IsPresentL( KUidMmsReserved ) ) + { + stream.OpenLC( aStore, KUidMmsReserved ); // pushes 'stream' to the stack + iRecommendedRetrievalMode = stream.ReadInt32L(); + length = stream.ReadInt32L(); + if ( length > 0 ) + { + iRecommendedRetrievalModeText = HBufC16::NewL( stream, length ); + } + length = stream.ReadInt32L(); + if ( length > 0 ) + { + iReplaceCancelId = HBufC8::NewL( stream, length ); + } + iCancelStatus = stream.ReadInt32L(); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + + } + +// --------------------------------------------------------- +// CMmsEntry::StoreL +// +// --------------------------------------------------------- +// + +EXPORT_C void CMmsHeaders::StoreL( + CMsvStore& aStore ) + { + + // Check if message root is correctly set + // We have an edit store in our hands, so we can access the attachment manager + + if ( iStart != 0 ) + { + MMsvAttachmentManager& attaMan = aStore.AttachmentManagerL(); + CMsvAttachment* attaInfo = NULL; + TRAPD( error, attaInfo = attaMan.GetAttachmentInfoL( iStart ) ); + if ( error == KErrNotFound ) + { + // The attachment is not present, clear the root indicator + iStart = 0; + delete iRootContentID; + iRootContentID = 0; + } + else if ( error == KErrNone ) + { + // got the attachment, check content id + CleanupStack::PushL( attaInfo ); + CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL(); + CleanupStack::PushL( mimeHeaders ); + mimeHeaders->RestoreL( *attaInfo ); + if ( RootContentId().Compare( mimeHeaders->ContentId() ) != 0 ) + { + if ( mimeHeaders->ContentId().Length() > 0 ) + { + // mime headers win + SetRootContentIdL( mimeHeaders->ContentId() ); + } + else if ( RootContentId().Length() > 0 ) + { + // if mime headers not set, but root set, root wins + mimeHeaders->SetContentIdL( RootContentId() ); + mimeHeaders->StoreL( *attaInfo ); + } + else + { + // keep LINT happy + } + } + CleanupStack::PopAndDestroy( mimeHeaders ); + CleanupStack::PopAndDestroy( attaInfo ); + } + // If error == KErrNoMemory there is nothing we can do + // We try to continue anyway, maybe we still can save our message + else + { + // Keep LINT happy. + } + } + + // caller must commit the store + RMsvWriteStream stream; + stream.AssignLC( aStore, KUidMmsHeaderStream ); // pushes 'stream' to the stack + ExternalizeL( stream ); + stream.CommitL(); + stream.Close(); + CleanupStack::PopAndDestroy( &stream ); // close stream + + // store element descriptor and mmbox headers, if they are present + if ( iElementDescriptor ) + { + stream.AssignLC( aStore, KUidMMsElementDescriptorStream ); // pushes 'stream' to the stack + iElementDescriptor->ExternalizeL( stream ); + stream.CommitL(); + stream.Close(); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + if ( iMmBoxMessageHeaders ) + { + stream.AssignLC( aStore, KUidMMsMMBoxMessageHeaderStream ); // pushes 'stream' to the stack + iMmBoxMessageHeaders->ExternalizeL( stream ); + stream.CommitL(); + stream.Close(); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + if ( iMmBoxViewHeaders ) + { + stream.AssignLC( aStore, KUidMMsMMBoxViewHeadersStream ); // pushes 'stream' to the stack + iMmBoxViewHeaders->ExternalizeL( stream ); + stream.CommitL(); + stream.Close(); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + + TInt length = 0; // + // store extended notification if present + if ( iExtendedNotificationText ) + { + stream.AssignLC( aStore, KUidMMsExtendedNotificationStream ); // pushes 'stream' to the stack + length = ExtendedNotification().Length(); + stream.WriteInt32L( length ); + if ( length > 0 ) + { + stream << ExtendedNotification(); + } + stream.CommitL(); + stream.Close(); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + + if ( iApplicationId || + iReplyToApplicationId || + iApplicationInfo ) + { + stream.AssignLC( aStore, KUidMmsApplicationInfoStream ); // pushes 'stream' to the stack + length = ApplicId().Length(); + stream.WriteInt32L( length ); + if ( length > 0 ) + { + stream << iApplicationId->Des(); + } + + length = ReplyApplicId().Length(); + stream.WriteInt32L( length ); + if ( length > 0 ) + { + stream << iReplyToApplicationId->Des(); + } + + length = AuxApplicInfo().Length(); + stream.WriteInt32L( length ); + if ( length > 0 ) + { + stream << iApplicationInfo->Des(); + } + + stream.CommitL(); + stream.Close(); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + + // reserved transaction info stream + if ( iRecommendedRetrievalMode != 0 || + iRecommendedRetrievalModeText || + iReplaceCancelId || + iCancelStatus != 0 ) + { + stream.AssignLC( aStore, KUidMmsReserved ); // pushes 'stream' to the stack + + stream.WriteInt32L( iRecommendedRetrievalMode ); + + length = RecommendedRetrievalModeText().Length(); + stream.WriteInt32L( length ); + if ( length > 0 ) + { + stream << iRecommendedRetrievalModeText->Des(); + } + + length = ReplaceCancelId().Length(); + stream.WriteInt32L( length ); + if ( length > 0 ) + { + stream << iReplaceCancelId->Des(); + } + + stream.WriteInt32L( iCancelStatus ); + + stream.CommitL(); + stream.Close(); + CleanupStack::PopAndDestroy( &stream ); // close stream + } + + } + +// --------------------------------------------------------- +// CMmsHeaders::TypedAddresseeList +// +// --------------------------------------------------------- +// +EXPORT_C const CDesCArray& CMmsHeaders::TypedAddresseeList( + TMmsRecipients aType ) + { + + TInt type = aType; + + if (type == EMmsTo) + { + return *iToArray; + } + else if ( type == EMmsCc ) + { + return *iCcArray; + } + else + { + return *iBccArray; + } + } + +// --------------------------------------------------------- +// CMmsHeaders::AddTypedAddresseeL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::AddTypedAddresseeL( + const TDesC& aRealAddress, + TMmsRecipients aType ) + { + + TInt type = aType; + + if ( type == EMmsTo ) + { + iToArray->AppendL( aRealAddress ); + } + if ( type == EMmsCc ) + { + iCcArray->AppendL( aRealAddress ); + } + if ( type == EMmsBcc ) + { + iBccArray->AppendL( aRealAddress ); + } + } + +// --------------------------------------------------------- +// CMmsHeaders::RemoveAddresseeL +// +// --------------------------------------------------------- +// +EXPORT_C TBool CMmsHeaders::RemoveAddressee( const TDesC& aRealAddress ) + { + + if ( RemoveAddressee( *iToArray, aRealAddress) ) + { + return ETrue; + } + if ( RemoveAddressee( *iCcArray, aRealAddress) ) + { + return ETrue; + } + if ( RemoveAddressee( *iBccArray, aRealAddress) ) + { + return ETrue; + } + + return EFalse; + + } + +// --------------------------------------------------------- +// CMmsHeaders::SetSubjectL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetSubjectL( const TDesC& aSubject ) + { + HBufC* newAttrib = aSubject.AllocL(); + delete iSubject; + iSubject = newAttrib; + } + +// --------------------------------------------------------- +// CMmsHeaders::Subject +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC CMmsHeaders::Subject() const + { + return iSubject ? TPtrC( *iSubject ) : TPtrC(); + } + +// --------------------------------------------------------- +// CMmsHeaders::SetSenderL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetSenderL( const TDesC& aAlias ) + { + HBufC* newAttrib = aAlias.AllocL(); + delete iSender; + iSender = newAttrib; + } + +// --------------------------------------------------------- +// CMmsHeaders::Sender +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC CMmsHeaders::Sender() const + { + return iSender ? TPtrC( *iSender ) : TPtrC(); + } + +// --------------------------------------------------------- +// CMmsHeaders::SetExpiryInterval +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetExpiryInterval( + TInt aInterval ) + { + iExpiry = aInterval; + iExpiryAbs = EFalse; + } + +// --------------------------------------------------------- +// CMmsHeaders::ExpiryInterval +// +// --------------------------------------------------------- +// +EXPORT_C TInt CMmsHeaders::ExpiryInterval() + { + return iExpiryAbs ? 0 : I64LOW( iExpiry ); + } + + +// --------------------------------------------------------- +// CMmsHeaders::SetExpiryDate +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetExpiryDate( TInt64 aDate ) + { + iExpiry = aDate; + iExpiryAbs = ETrue; + } + +// --------------------------------------------------------- +// CMmsHeaders::ExpiryDate +// +// --------------------------------------------------------- +// +EXPORT_C TInt64 CMmsHeaders::ExpiryDate() + { + return iExpiryAbs ? iExpiry : TInt64( 0 ); + } + +// --------------------------------------------------------- +// CMmsHeaders::SetDeliveryTimeInterval +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetDeliveryTimeInterval( TInt aInterval ) + { + iDelivery = aInterval; + iDeliveryAbs = EFalse; + } + +// --------------------------------------------------------- +// CMmsHeaders::DeliveryTimeInterval +// +// --------------------------------------------------------- +// +EXPORT_C TInt CMmsHeaders::DeliveryTimeInterval() + { + return iDeliveryAbs ? 0 : I64LOW( iDelivery ); + } + +// --------------------------------------------------------- +// CMmsHeaders::SetDeliveryDate +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetDeliveryDate( TInt64 aDate ) + { + iDelivery = aDate; + iDeliveryAbs = ETrue; + } + +// --------------------------------------------------------- +// CMmsHeaders::DeliveryDate +// +// --------------------------------------------------------- +// +EXPORT_C TInt64 CMmsHeaders::DeliveryDate() + { + return iDeliveryAbs ? iDelivery : TInt64( 0 ); + } + +// --------------------------------------------------------- +// CMmsHeaders::SetTidL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetTidL( const TDesC8& aCid ) + { + // If New TID has length zero, TID is cleared + if ( aCid.Length() == 0 ) + { + delete iTID; + iTID = NULL; + } + else + { + HBufC8 * newAttrib = aCid.AllocL(); + if ( newAttrib->Length() > KMaxHeaderStringLength ) + { + newAttrib->Des().SetLength( KMaxHeaderStringLength ); + } + delete iTID; + iTID = newAttrib; + } + } + +// --------------------------------------------------------- +// CMmsHeaders::ContentLocation +// +// --------------------------------------------------------- +// + +EXPORT_C TPtrC8 CMmsHeaders::ContentLocation() const + { + return iContentLocation ? TPtrC8( *iContentLocation ) : TPtrC8(); + } + +// --------------------------------------------------------- +// CMmsHeaders::SetContentLocationL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetContentLocationL( const TDesC8& aURL ) + { + HBufC8 * newAttrib = aURL.AllocL(); + if ( newAttrib->Length() > KMaxHeaderStringLength ) + { + newAttrib->Des().SetLength( KMaxHeaderStringLength ); + } + delete iContentLocation; + iContentLocation = newAttrib; + } + +// --------------------------------------------------------- +// CMmsHeaders::Tid +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC8 CMmsHeaders::Tid() const + { + return iTID ? TPtrC8( *iTID ) : TPtrC8(); + } + +// --------------------------------------------------------- +// CMmsHeaders::InternalizeL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::InternalizeL( RMsvReadStream& aStream ) + { + + aStream >> iVersion; + aStream >> iMsgType; + + iSubject = HBufC::NewL( aStream, KMaxHeaderStringLength ); + iTID = HBufC8::NewL( aStream, KMaxHeaderStringLength ); + aStream >> iDate; + + iSender = HBufC::NewL( aStream, KMaxHeaderStringLength ); + aStream >> iMsgClass; + + aStream >> iExpiry; + iExpiryAbs = aStream.ReadInt8L(); + aStream >> iDelivery; + iDeliveryAbs = aStream.ReadInt8L(); + + aStream >> iPriority; + aStream >> iSenderVisi; + + aStream >> iDelivReport; + aStream >> iReadReply; + + iStart = aStream.ReadInt32L(); + iContentLocation = HBufC8::NewL( aStream, KMaxHeaderStringLength ); + + aStream >> iMessageSize; + aStream >> iReportAllowed; + aStream >> iResponseStatus; + + iMessageId = HBufC8::NewL( aStream, KMaxHeaderStringLength ); + aStream >> iStatus; + + aStream >> iMaxImageWidth; + aStream >> iMaxImageHeight; + + // Internalize fields which may have multiple values. + InternalizeArrayL( *iToArray, aStream ); + InternalizeArrayL( *iCcArray, aStream ); + InternalizeArrayL( *iBccArray, aStream ); + + TInt32 length = 0; + length = aStream.ReadInt32L(); + + if ( length > 0 ) + { + iRootContentID = HBufC8::NewL( aStream, length ); + } + + length = aStream.ReadInt32L(); + if ( length > 0 ) + { + iOperatorResponseText = HBufC::NewL( aStream, length ); + } + + TInt i; + aStream >> iReadStatus; + aStream >> iReplyCharging; + aStream >> iReplyChargingDeadline; + iReplyChargingAbs = aStream.ReadInt8L(); + aStream >> iReplyChargingSize; + aStream >> length; + if ( length > 0 ) + { + iReplyChargingId = HBufC8::NewL( aStream, length ); + } + + aStream >> length; + + for ( i = 0; i < length ; i++ ) + { + CMmsSendingChain* item = new( ELeave )CMmsSendingChain; + CleanupStack::PushL( item ); + item->InternalizeL( aStream ); + User::LeaveIfError( iPreviouslySentArray.InsertInOrder( item, iLinearOrder )); + CleanupStack::Pop( item ); // item is in member array now + } + + iDistributionIndicator = aStream.ReadInt32L(); + + iRelatedEntry = aStream.ReadInt32L(); + iMultipartType = aStream.ReadInt32L(); + + TInt64 tempTime; + aStream >> tempTime; + iReceivingTime = TTime( tempTime ); + + iContentClass = aStream.ReadInt32L(); + iDrmContent = aStream.ReadInt32L(); + iAdaptationAllowed = aStream.ReadInt32L(); + } + +// --------------------------------------------------------- +// CMmsHeaders::ExternalizeL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::ExternalizeL( RMsvWriteStream& aStream ) const + { + + // This MUST be the 1st item written into the stream + aStream << iVersion; + // This must be 2nd. + aStream << iMsgType; + + aStream << LimitStringSize( Subject(), KMaxHeaderStringLength ); + aStream << LimitStringSize( Tid(), KMaxHeaderStringLength ); + aStream << iDate; + + aStream << LimitStringSize( Sender(), KMaxHeaderStringLength ); + aStream << iMsgClass; + + aStream << iExpiry; + aStream.WriteInt8L( iExpiryAbs ); + aStream << iDelivery; + aStream.WriteInt8L( iDeliveryAbs ); + + aStream << iPriority; + aStream << iSenderVisi; + + aStream << iDelivReport; + aStream << iReadReply; + + aStream.WriteInt32L( iStart ); + aStream << LimitStringSize( ContentLocation(), KMaxHeaderStringLength ); + + aStream << iMessageSize; + aStream << iReportAllowed; + aStream << iResponseStatus; + + aStream << LimitStringSize( MessageId(), KMaxHeaderStringLength ); + aStream << iStatus; + + aStream << iMaxImageWidth; + aStream << iMaxImageHeight; + + // Externalize fields which may have multiple values. + ExternalizeArrayL( *iToArray, aStream ); + ExternalizeArrayL( *iCcArray, aStream ); + ExternalizeArrayL( *iBccArray, aStream ); + + TInt32 length; + length = RootContentId().Length(); + aStream << length; + if ( length > 0 ) + { + aStream << RootContentId(); + } + length = ResponseText().Length(); + aStream << length; + if ( length > 0 ) + { + aStream << ResponseText(); + } + + TInt i; + aStream << iReadStatus; + aStream << iReplyCharging; + aStream << iReplyChargingDeadline; + aStream.WriteInt8L( iReplyChargingAbs ); + aStream << iReplyChargingSize; + length = ReplyChargingId().Length(); + aStream << length; + if ( length > 0 ) + { + aStream << ReplyChargingId(); + } + + length = iPreviouslySentArray.Count(); + aStream << length; + for ( i = 0; i < iPreviouslySentArray.Count(); i++ ) + { + iPreviouslySentArray[ i ]->ExternalizeL( aStream ); + } + + aStream.WriteInt32L( iDistributionIndicator ); + aStream.WriteInt32L( iRelatedEntry ); + aStream.WriteInt32L( iMultipartType ); + + aStream << iReceivingTime.Int64(); + + aStream.WriteInt32L( iContentClass ); + aStream.WriteInt32L( iDrmContent ); + aStream.WriteInt32L( iAdaptationAllowed ); + + } + +// --------------------------------------------------------- +// CMmsHeaders::ElementDescriptorL +// +// --------------------------------------------------------- +// +EXPORT_C CMmsElementDescriptor& CMmsHeaders::ElementDescriptorL() + { + if ( !iElementDescriptor ) + { + iElementDescriptor = new( ELeave )CMmsElementDescriptor; + } + return *iElementDescriptor; + } + +// --------------------------------------------------------- +// CMmsHeaders::MMBoxMessageHeadersL +// +// --------------------------------------------------------- +// +EXPORT_C CMmsMMBoxMessageHeaders& CMmsHeaders::MMBoxMessageHeadersL() + { + if ( !iMmBoxMessageHeaders ) + { + iMmBoxMessageHeaders = CMmsMMBoxMessageHeaders::NewL(); + } + return *iMmBoxMessageHeaders; + } + +// --------------------------------------------------------- +// CMmsHeaders::MMBoxViewHeadersL +// +// --------------------------------------------------------- +// +EXPORT_C CMmsMMBoxViewHeaders& CMmsHeaders::MMBoxViewHeadersL() + { + if ( !iMmBoxViewHeaders ) + { + iMmBoxViewHeaders = new( ELeave )CMmsMMBoxViewHeaders; + } + return *iMmBoxViewHeaders; + } + +// --------------------------------------------------------- +// CMmsHeaders::SetExtendedNotificationL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetExtendedNotificationL( const TDesC& aText ) + { + HBufC* newAttrib = NULL; + if ( aText.Length() > 0 ) + { + newAttrib = aText.AllocL(); + } + delete iExtendedNotificationText; + iExtendedNotificationText = newAttrib; + } + +// --------------------------------------------------------- +// CMmsHeaders::ExtendedNotification +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC CMmsHeaders::ExtendedNotification() const + { + return iExtendedNotificationText ? TPtrC( *iExtendedNotificationText ) : TPtrC(); + } + +// --------------------------------------------------------- +// CMmsHeaders::RemoveAddressee +// +// --------------------------------------------------------- +// +TBool CMmsHeaders::RemoveAddressee( + CDesCArray& aList, + const TDesC& aAddress ) + { + + TInt count = aList.Count(); + TInt i; + + // We must compare only pure addresses. + // The list may contain addresses that include aliases. + for ( i = count - 1; i >= 0; i-- ) + { + if ( TMmsGenUtils::PureAddress( aAddress ).CompareF( + TMmsGenUtils::PureAddress( aList.MdcaPoint( i ) ) ) == 0 ) + { + aList.Delete( i ); + aList.Compress(); + return ETrue; + } + } + + return EFalse; + } + +// --------------------------------------------------------- +// CMmsHeaders::Reset +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::Reset( CMmsSettings* aSettings ) + { + + iMsgType = 0; + + delete iTID; + iTID = NULL; + + // Always restore the default version - even if not reading other settings + iVersion = iMmsDefaultVersion; + iDate = 0; + + delete iSender; + iSender = NULL; + + iToArray->Reset(); + iCcArray->Reset(); + iBccArray->Reset(); + + delete iSubject; + iSubject = NULL; + + iMsgClass = 0; + + iExpiry = 0; + iExpiryAbs = 0; + iDelivery = 0; + iDeliveryAbs = 0; + iPriority = 0; + iSenderVisi = 0; + iDelivReport = 0; + iReadReply = 0; + iStart = KMsvNullIndexEntryId; + + delete iContentLocation; + iContentLocation = NULL; + + iMessageSize = 0; + iReportAllowed = 0; + iResponseStatus = 0; + + delete iMessageId; + iMessageId = NULL; + + iStatus = 0; + + iMaxImageHeight = 0; + iMaxImageWidth = 0; + + delete iOperatorResponseText; + iOperatorResponseText = NULL; + + delete iRootContentID; + iRootContentID = NULL; + + iReadStatus = 0; + iReplyCharging = 0; + iReplyChargingDeadline = 0; + iReplyChargingAbs = EFalse; + delete iReplyChargingId; + iReplyChargingId = NULL; + iReplyChargingSize = 0; + iPreviouslySentArray.ResetAndDestroy(); + iDeleteResultArray.ResetAndDestroy(); + + iDistributionIndicator = 0; + iRelatedEntry = 0; + iMultipartType = 0; + iReceivingTime = 0; + // encapsulation 1.3 headers + iContentClass = 0; + iDrmContent = 0; + iAdaptationAllowed = 0; + + delete iElementDescriptor; + iElementDescriptor = NULL; + delete iMmBoxMessageHeaders; + iMmBoxMessageHeaders = NULL; + delete iMmBoxViewHeaders; + iMmBoxViewHeaders = NULL; + + delete iExtendedNotificationText; + iExtendedNotificationText = NULL; + + iExtensionStatus = 0; // set unknown status + + delete iApplicationId; + iApplicationId = NULL; + delete iReplyToApplicationId; + iReplyToApplicationId = NULL; + delete iApplicationInfo; + iApplicationInfo = NULL; + + iRecommendedRetrievalMode = 0; + delete iRecommendedRetrievalModeText; + iRecommendedRetrievalModeText = NULL; + delete iReplaceCancelId; + iReplaceCancelId = NULL; + iCancelStatus = 0; + + SetSettings( aSettings ); + + } + +// --------------------------------------------------------- +// CMmsHeaders::Size +// +// --------------------------------------------------------- +// +EXPORT_C TInt CMmsHeaders::Size() const + { + + TInt size = sizeof( iMsgType ); + + size+= Tid().Size(); + + size+= sizeof( iVersion ); + + size+= sizeof( iDate ); + + TInt i; + + TInt nbr = iToArray->MdcaCount(); + for ( i=0; i < nbr; ++i ) + { + size += iToArray->MdcaPoint(i).Size(); + } + + nbr = iCcArray->MdcaCount(); + for ( i=0; i < nbr; ++i ) + { + size+=iCcArray->MdcaPoint(i).Size(); + } + + nbr = iBccArray->MdcaCount(); + for ( i=0; i < nbr; ++i ) + { + size+=iBccArray->MdcaPoint(i).Size(); + } + + size+= Sender().Size(); + + size+= Subject().Size(); + + size+= sizeof( iMsgClass ); + + size+= sizeof( iExpiry ); + + size+= sizeof( iExpiryAbs ); + + size+= sizeof( iDelivery ); + + size+= sizeof( iDeliveryAbs ); + + size+= sizeof( iPriority ); + + size+= sizeof( iSenderVisi ); + + size+= sizeof( iDelivReport ); + + size+= sizeof( iReadReply ); + + size+= sizeof( iStart ); + + size+= ContentLocation().Size(); + + size+= sizeof( iMessageSize ); + + size+= sizeof( iReportAllowed ); + + size+= sizeof( iResponseStatus ); + + size+= MessageId().Size(); + + size+= sizeof( iStatus ); + + size+= sizeof( iMaxImageWidth ); + + size+= sizeof( iMaxImageHeight ); + + // operator response text + size += sizeof( TInt32 ); + size += ResponseText().Length(); + + // length of root content + size+= sizeof( TInt32 ); + size += RootContentId().Length(); + + if ( iVersion > KMmsVersion1 ) + { + size+= sizeof( iReadStatus ); + + size+= sizeof( iReplyCharging ); + + size+= sizeof( iReplyChargingDeadline ); + + size+= sizeof( iReplyChargingAbs ); + + size+= sizeof( iReplyChargingSize ); + + // length of reply charging id + size+= sizeof( TInt32 ); + size+= ReplyChargingId().Length(); + + // number of items in array + size+= sizeof( TInt32 ); + for ( i = 0; i < iPreviouslySentArray.Count(); i++ ) + { + size += iPreviouslySentArray[ i ]->Size(); + } + } + + size += sizeof( iDistributionIndicator ); + size += sizeof( iRelatedEntry ); + size += sizeof( iMultipartType ); + size += sizeof( iReceivingTime ); + + // iContentClass, iDrmContent & iAdaptationAllowed + size += sizeof( TInt32 ); + size += sizeof( TInt32 ); + size += sizeof( TInt32 ); + + // add element descriptor and mmbox header sizes + if ( iElementDescriptor ) + { + size += iElementDescriptor->Size(); + } + + if ( iMmBoxMessageHeaders ) + { + size += iMmBoxMessageHeaders->Size(); + } + + if ( iMmBoxViewHeaders ) + { + size += iMmBoxViewHeaders->Size(); + } + + // add extended notification size + if ( ExtendedNotification().Length() > 0 ) + { + // size of lenghth + size+= sizeof( TInt32 ); + size += ExtendedNotification().Size(); + } + + if ( iApplicationId || + iReplyToApplicationId || + iApplicationInfo ) + { + // size of lenghth + size+= sizeof( TInt32 ); + size += ApplicId().Size(); + size+= sizeof( TInt32 ); + size += ReplyApplicId().Size(); + size+= sizeof( TInt32 ); + size += AuxApplicInfo().Size(); + } + + if ( iRecommendedRetrievalMode > 0 || + iRecommendedRetrievalModeText || + iReplaceCancelId || + iCancelStatus ) + { + size+= sizeof( TInt32 ); + size+= sizeof( TInt32 ); + size += RecommendedRetrievalModeText().Size(); + size+= sizeof( TInt32 ); + size += ReplaceCancelId().Size(); + size+= sizeof( TInt32 ); + } + + return size; + + } + +// --------------------------------------------------------- +// CMmsHeaders::SetMessageIdL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetMessageIdL( const TDesC8& aId ) + { + HBufC8 * newAttrib = aId.AllocL(); + if ( newAttrib->Length() > KMaxHeaderStringLength ) + { + newAttrib->Des().SetLength( KMaxHeaderStringLength ); + } + delete iMessageId; + iMessageId = newAttrib; + } + +// --------------------------------------------------------- +// CMmsHeaders::MessageId +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC8 CMmsHeaders::MessageId() const + { + return iMessageId ? TPtrC8( *iMessageId ) : TPtrC8(); + } + +// --------------------------------------------------------- +// CMmsHeaders::CopyL +// +// --------------------------------------------------------- +// + +EXPORT_C CMmsHeaders* CMmsHeaders::CopyL( + TMsvPartList aParts, + TBool aReply ) + { + // legacy function, opens new file system handle + // DEPRECATED + RFs fs; + CleanupClosePushL( fs ); + User::LeaveIfError( fs.Connect() ); + + CMmsHeaders* mms = CopyL( aParts, aReply, fs ); + + CleanupStack::PopAndDestroy( &fs ); //fs + + return mms; // caller takes posession + + } + +// --------------------------------------------------------- +// CMmsHeaders::CopyL +// +// --------------------------------------------------------- +// + +EXPORT_C CMmsHeaders* CMmsHeaders::CopyL( + TMsvPartList aParts, + TBool aReply, + RFs& aFs ) + { + + CMmsHeaders* mms = CMmsHeaders::NewL(); + CleanupStack::PushL( mms ); + HBufC* buffer = NULL; + + // Copy those values as specified by aParts. + + if ( aReply ) + { + + // Copy original sender as recipient + if ( this->Sender().Length() > 0 ) + { + buffer = AliasedAddressL( this->Sender(), aFs ); + CleanupStack::PushL( buffer ); + mms->AddTypedAddresseeL( buffer->Des(), EMmsTo ); + CleanupStack::PopAndDestroy( buffer ); + buffer = NULL; + } + + if ( aParts & KMsvMessagePartRecipient ) + { + // Copy all recipients for reply-to-all message. + const CDesCArray& array1 = this->ToRecipients(); + mms->CopyAddresseeListL( array1, EMmsTo, this->Sender(), aFs ); + + const CDesCArray& array2 = this->BccRecipients(); + mms->CopyAddresseeListL( array2, EMmsBcc, this->Sender(), aFs ); + + const CDesCArray& array3 = this->CcRecipients(); + mms->CopyAddresseeListL( array3, EMmsCc, this->Sender(), aFs ); + } + } + else + { + // forward + if ( aParts & KMsvMessagePartRecipient ) + { + // Copy original Recipient to recipient + const CDesCArray& array1 = this->ToRecipients(); + mms->CopyAddresseeListL( array1, EMmsTo, TPtrC(), aFs ); + + const CDesCArray& array2 = this->BccRecipients(); + mms->CopyAddresseeListL( array2, EMmsBcc, TPtrC(), aFs ); + + const CDesCArray& array3 = this->CcRecipients(); + mms->CopyAddresseeListL( array3, EMmsCc, TPtrC(), aFs ); + } + if ( aParts & KMsvMessagePartOriginator ) + { + // Copy original originator to originator + mms->SetSenderL( Sender() ); + } + + // message class and priority must always be copied + // when forwarding a message + mms->SetMessageClass( MessageClass() ); + mms->SetMessagePriority( MessagePriority() ); + + // When forwarding a message, root part pointer must be + // copied, too. However, root is referred to by TMsvId, + // and when the message is copied, new id is generated. + // The root pointer copying must be done by someone else. + + } + if ( aParts & KMsvMessagePartDescription ) + { + mms->SetSubjectL( Subject() ); + } + + CleanupStack::Pop( mms ); + return mms; + } + +// --------------------------------------------------------- +// CMmsHeaders::SetSettings +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetSettings( + CMmsSettings* aSettings ) + { + if( !aSettings ) + { + return; + } + // Make sure the version number follows the default setting + iMmsDefaultVersion = aSettings->MmsVersion(); + iVersion = iMmsDefaultVersion; + SetExpiryInterval( aSettings->ExpiryInterval() ); + SetSenderVisibility( aSettings->SenderVisibility() ); + SetDeliveryReport( aSettings->DeliveryReportWanted() ); + SetReadReply( aSettings->ReadReplyReportWanted() ); + // Don't override priority if it has been set already. + // It gets set when message is forwarded. + if ( iPriority == 0 ) + { + SetMessagePriority( aSettings->MessagePriority() ); + } + // Don't override message class if it has been set already. + // It gets set when message is forwarded. + if ( iMsgClass == 0 ) + { + SetMessageClass( aSettings->MessageClass() ); + } + SetMaximumImage( aSettings->ImageWidth(), aSettings->ImageHeight()); + } + + +// --------------------------------------------------------- +// CMmsHeaders::SetMaximumImage +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetMaximumImage( + TInt aWidth, TInt aHeight ) + { + iMaxImageHeight = aHeight; + iMaxImageWidth = aWidth; + } + +// --------------------------------------------------------- +// CMmsHeaders::GetMaximumImage +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::GetMaximumImage( + TInt& aWidth, TInt& aHeight ) const + { + aHeight = iMaxImageHeight; + aWidth = iMaxImageWidth; + } + +// --------------------------------------------------------- +// CMmsHeaders::SetRootContentIdL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetRootContentIdL( const TDesC8& aId ) + { + delete iRootContentID; + iRootContentID = NULL; + if ( aId.Length() > 0 ) + { + iRootContentID = aId.AllocL(); + } + } + +// --------------------------------------------------------- +// CMmsHeaders::RootContentId +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC8 CMmsHeaders::RootContentId() const + { + return iRootContentID ? TPtrC8( *iRootContentID ) : TPtrC8(); + } + + +// --------------------------------------------------------- +// CMmsHeaders::SetReplyChargingIdL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetReplyChargingIdL( const TDesC8& aId ) + { + delete iReplyChargingId; + iReplyChargingId = NULL; + iReplyChargingId = aId.AllocL(); + } + + +// --------------------------------------------------------- +// CMmsHeaders::ReplyChargingId +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC8 CMmsHeaders::ReplyChargingId() const + { + return iReplyChargingId ? TPtrC8( *iReplyChargingId ) : TPtrC8(); + } + +// --------------------------------------------------------- +// CMmsHeaders::SetReplyChargingInterval +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetReplyChargingInterval( + TInt aInterval ) + { + iReplyChargingDeadline = aInterval; + iReplyChargingAbs = EFalse; + } + +// --------------------------------------------------------- +// CMmsHeaders::ReplyChargingInterval +// +// --------------------------------------------------------- +// +EXPORT_C TInt CMmsHeaders::ReplyChargingInterval() + { + return iReplyChargingAbs ? 0 : I64LOW( iReplyChargingDeadline ); + } + + +// --------------------------------------------------------- +// CMmsHeaders::SetReplyChargingDate +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetReplyChargingDate( TInt64 aDate ) + { + iReplyChargingDeadline = aDate; + iReplyChargingAbs = ETrue; + } + +// --------------------------------------------------------- +// CMmsHeaders::ReplyChargingDate +// +// --------------------------------------------------------- +// +EXPORT_C TInt64 CMmsHeaders::ReplyChargingDate() + { + return iReplyChargingAbs ? iReplyChargingDeadline : TInt64( 0 ); + } + +// --------------------------------------------------------- +// CMmsHeaders::InsertPreviouslySentByL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::InsertPreviouslySentByL( TInt aOrder, const TDesC& aSender ) + { + TInt error = KErrNone; + CMmsSendingChain* item = new (ELeave)CMmsSendingChain; + CleanupStack::PushL( item ); + item->SetOrder( aOrder ); + item->SetSenderL( aSender ); + + TInt index = KErrNotFound; + index = iPreviouslySentArray.FindInOrder( item, iLinearOrder ); + CleanupStack::Pop( item ); + if ( index == KErrNotFound ) + { + error = iPreviouslySentArray.InsertInOrder( item, iLinearOrder ); + if ( error != KErrNone ) + { + delete item; + } + } + else + { + delete item; + // modify existing entry + // order is already set, as we use that as our match + // we just put in new sender. + // Index is valid because we just set it to the index where match was found + iPreviouslySentArray[index]->SetSenderL( aSender ); + } + item = NULL; // this was either deleted or inserted into our array. + + User::LeaveIfError( error ); // The only error that should be possible is KErrNoMemory + + } + +// --------------------------------------------------------- +// CMmsHeaders::InsertPreviouslySentDateL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::InsertPreviouslySentDateL( TInt aOrder, TInt64 aDate ) + { + + TInt error = KErrNone; + CMmsSendingChain* item = new (ELeave)CMmsSendingChain; + CleanupStack::PushL( item ); + item->SetOrder( aOrder ); + item->SetDate( aDate ); + + TInt index = KErrNotFound; + index = iPreviouslySentArray.FindInOrder( item, iLinearOrder ); + CleanupStack::Pop( item ); + if ( index == KErrNotFound ) + { + error = iPreviouslySentArray.InsertInOrder( item, iLinearOrder ); + if ( error != KErrNone ) + { + delete item; + } + } + else + { + delete item; + // modify existing entry + // order is already set, as we use that as our match + // we just put in new sender. + // Index is valid because we just set it to the index where match was found + iPreviouslySentArray[index]->SetDate( aDate ); + } + item = NULL; // this was either deleted or inserted into our array. + + User::LeaveIfError( error ); // The only error that should be possible is KErrNoMemory + + } + +// --------------------------------------------------------- +// CMmsHeaders::AppendPreviouslySentItemL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::AppendPreviouslySentItemL( TInt64 aDate, const TDesC& aSender ) + { + TInt error = KErrNone; + CMmsSendingChain* item = new (ELeave)CMmsSendingChain; + CleanupStack::PushL( item ); + item->SetDate( aDate ); + item->SetSenderL( aSender ); + TInt count = iPreviouslySentArray.Count(); + // we are creating a new item that must go to the end of the array + if ( count == 0 ) + { + // First item in array + item->SetOrder( 1 ); + } + else + { + item->SetOrder( iPreviouslySentArray[ count - 1 ]->Order() + 1 ); + } + CleanupStack::Pop( item ); + error = iPreviouslySentArray.InsertInOrder( item, iLinearOrder ); + if ( error != KErrNone ) + { + delete item; + } + User::LeaveIfError( error ); // The only error that should be possible is KErrNoMemory + } + +// --------------------------------------------------------- +// CMmsHeaders::SetResponseTextL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetResponseTextL( const TDesC& aText ) + { + // If the length of the new text is 0, the text is cleared + delete iOperatorResponseText; + iOperatorResponseText = NULL; + if ( aText.Length() > 0 ) + { + HBufC* newAttrib = aText.AllocL(); + iOperatorResponseText = newAttrib; + } + } + +// --------------------------------------------------------- +// CMmsHeaders::ResponseText +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC CMmsHeaders::ResponseText() const + { + return iOperatorResponseText ? TPtrC( *iOperatorResponseText ) : TPtrC(); + } + +// --------------------------------------------------------- +// CMmsHeaders::InsertDeleteStatusL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::InsertDeleteStatusL( TUint aOrder, const TInt32 aStatus ) + { + TInt error = KErrNone; + CMmsDeleteResultArray* item = new (ELeave)CMmsDeleteResultArray; + CleanupStack::PushL( item ); + item->SetOrder( aOrder ); + item->SetResponseStatus( aStatus ); + + TInt index = KErrNotFound; + index = iDeleteResultArray.FindInOrder( item, iDeleteResultOrder ); + CleanupStack::Pop( item ); + + if ( index == KErrNotFound ) + { + error = iDeleteResultArray.InsertInOrder( item, iDeleteResultOrder ); + if ( error != KErrNone ) + { + delete item; + } + } + else + { + delete item; + // modify existing entry - find all possible matches and modify all. + TInt i; + for ( i = 0; i < iDeleteResultArray.Count(); i++ ) + { + if ( iDeleteResultArray[i]->Order() == aOrder ) + { + iDeleteResultArray[i]->SetResponseStatus( aStatus ); + } + } + } + item = NULL; // this was either deleted or inserted into our array. + + User::LeaveIfError( error ); // The only error that should be possible is KErrNoMemory + + } + +// --------------------------------------------------------- +// CMmsHeaders::InsertDeleteContentLocationL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::InsertDeleteContentLocationL( + TUint aOrder, const TDesC8& aContentLocation ) + { + TInt error = KErrNone; + CMmsDeleteResultArray* item = new (ELeave)CMmsDeleteResultArray; + CleanupStack::PushL( item ); + item->SetOrder( aOrder ); + item->SetContentLocationL( aContentLocation ); + + TInt index = KErrNotFound; + index = iDeleteResultArray.FindInOrder( item, iDeleteResultOrder ); + CleanupStack::Pop( item ); + + if ( index == KErrNotFound ) + { + error = iDeleteResultArray.InsertInOrder( item, iDeleteResultOrder ); + if ( error != KErrNone ) + { + delete item; + } + } + else + { + // If we find an entry without content location we modify existing entry + // otherwise we insert a new entry + TInt i; + TBool updated = EFalse; + for ( i = 0; i < iDeleteResultArray.Count() && !updated ; i++ ) + { + if ( iDeleteResultArray[i]->Order() == aOrder && + iDeleteResultArray[i]->ContentLocation().Length() == 0 ) + { + iDeleteResultArray[i]->SetContentLocationL( aContentLocation ); + updated = ETrue; + } + } + if ( !updated ) + { + item->SetResponseStatus( iDeleteResultArray[index]->ResponseStatus() ); + item->SetResponseTextL( iDeleteResultArray[index]->ResponseText() ); + // order and contentlocation are already there + error = iDeleteResultArray.InsertInOrderAllowRepeats( item, iDeleteResultOrder ); + if ( error != KErrNone ) + { + delete item; + } + } + else + { + delete item; + } + } + item = NULL; // this was either deleted or inserted into our array. + + User::LeaveIfError( error ); // The only error that should be possible is KErrNoMemory + + } + +// --------------------------------------------------------- +// CMmsHeaders::InsertDeleteResponseTextL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::InsertDeleteResponseTextL( TUint aOrder, const TDesC& aResponseText ) + { + TInt error = KErrNone; + CMmsDeleteResultArray* item = new (ELeave)CMmsDeleteResultArray; + CleanupStack::PushL( item ); + item->SetOrder( aOrder ); + item->SetResponseTextL( aResponseText ); + + TInt index = KErrNotFound; + index = iDeleteResultArray.FindInOrder( item, iDeleteResultOrder ); + CleanupStack::Pop( item ); + + if ( index == KErrNotFound ) + { + error = iDeleteResultArray.InsertInOrder( item, iDeleteResultOrder ); + if ( error != KErrNone ) + { + delete item; + } + } + else + { + delete item; + // modify existing entry + // order is already set, as we use that as our match + TInt i; + for ( i = 0; i < iDeleteResultArray.Count(); i++ ) + { + if ( iDeleteResultArray[i]->Order() == aOrder ) + { + iDeleteResultArray[i]->SetResponseTextL( aResponseText ); + } + } + } + item = NULL; // this was either deleted or inserted into our array. + + User::LeaveIfError( error ); // The only error that should be possible is KErrNoMemory + + } + +// --------------------------------------------------------- +// CMmsHeaders::SetApplicIdL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetApplicIdL( const TDesC16& aApplicId ) + { + // If the length of the new text is 0, the text is cleared + delete iApplicationId; + iApplicationId = NULL; + if ( aApplicId.Length() > 0 ) + { + HBufC* newAttrib = aApplicId.AllocL(); + iApplicationId = newAttrib; + } + } + +// --------------------------------------------------------- +// CMmsHeaders::ApplicId +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC16 CMmsHeaders::ApplicId() const + { + return iApplicationId ? TPtrC16( *iApplicationId ) : TPtrC16(); + } + +// --------------------------------------------------------- +// CMmsHeaders::SetReplyApplicIdL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetReplyApplicIdL( const TDesC16& aApplicId ) + { + // If the length of the new text is 0, the text is cleared + delete iReplyToApplicationId; + iReplyToApplicationId = NULL; + if ( aApplicId.Length() > 0 ) + { + HBufC* newAttrib = aApplicId.AllocL(); + iReplyToApplicationId = newAttrib; + } + } + +// --------------------------------------------------------- +// CMmsHeaders::ReplyApplicId +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC16 CMmsHeaders::ReplyApplicId() const + { + return iReplyToApplicationId ? TPtrC16( *iReplyToApplicationId ) : TPtrC16(); + } + +// --------------------------------------------------------- +// CMmsHeaders::SetAuxApplicInfoL +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetAuxApplicInfoL( const TDesC8& aAuxApplicInfo ) + { + // If the length of the new text is 0, the text is cleared + delete iApplicationInfo; + iApplicationInfo = NULL; + if ( aAuxApplicInfo.Length() > 0 ) + { + HBufC8* newAttrib = aAuxApplicInfo.AllocL(); + iApplicationInfo = newAttrib; + } + } + +// --------------------------------------------------------- +// CMmsHeaders::AuxApplicInfo +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC8 CMmsHeaders::AuxApplicInfo() const + { + return iApplicationInfo ? TPtrC8( *iApplicationInfo ) : TPtrC8(); + } + +// --------------------------------------------------------- +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetRecommendedRetrievalModeTextL( + const TDesC16& aRecommendedRetrievalModeText ) + { + // If the length of the new text is 0, the text is cleared + delete iRecommendedRetrievalModeText; + iRecommendedRetrievalModeText = NULL; + if ( aRecommendedRetrievalModeText.Length() > 0 ) + { + HBufC* newAttrib = aRecommendedRetrievalModeText.AllocL(); + iRecommendedRetrievalModeText = newAttrib; + } + } + +// --------------------------------------------------------- +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC16 CMmsHeaders::RecommendedRetrievalModeText() const + { + return iRecommendedRetrievalModeText ? + TPtrC16( *iRecommendedRetrievalModeText ) : TPtrC16(); + } + +// --------------------------------------------------------- +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::SetReplaceCancelIdL( const TDesC8& aReplaceCancelId ) + { + HBufC8 * newAttrib = aReplaceCancelId.AllocL(); + if ( newAttrib->Length() > KMaxHeaderStringLength ) + { + newAttrib->Des().SetLength( KMaxHeaderStringLength ); + } + delete iReplaceCancelId; + iReplaceCancelId = newAttrib; + } + +// --------------------------------------------------------- +// +// --------------------------------------------------------- +// +EXPORT_C TPtrC8 CMmsHeaders::ReplaceCancelId() const + { + return iReplaceCancelId ? TPtrC8( *iReplaceCancelId ) : TPtrC8(); + } + +// --------------------------------------------------------- +// CMmsHeaders::ExternalizeArrayL +// +// --------------------------------------------------------- +// +void CMmsHeaders::ExternalizeArrayL( + CDesC16Array& anArray, + RWriteStream& aStream ) const + { + + TInt count=anArray.Count(); + aStream << TCardinality( count ); // compressed value + for ( TInt ii = 0; ii < count; ++ii ) + { + aStream << anArray[ii].Left( Min( anArray[ii].Length(), KMaxHeaderStringLength ) ) ; + } + } + +// --------------------------------------------------------- +// CMmsHeaders::InternalizeArrayL +// +// --------------------------------------------------------- +// +void CMmsHeaders::InternalizeArrayL( + CDesC16Array& anArray, + RReadStream& aStream ) + { + TCardinality card; + aStream >> card; + TInt count=card; + anArray.Reset(); + for ( TInt ii = 0; ii < count; ++ii ) + { + HBufC16* buf=HBufC16::NewLC( aStream, KMaxHeaderStringLength ); + anArray.CArrayFixBase::InsertL( ii, &buf ); + CleanupStack::Pop( buf ); + } + } + +// --------------------------------------------------------- +// CMmsHeaders::CopyAddresseeListL() +// +// --------------------------------------------------------- +// +void CMmsHeaders::CopyAddresseeListL( + const CDesCArray& aArray, + TMmsRecipients aType, + const TPtrC& aExclude, + RFs& aFs ) + { + TInt size; + size = aArray.Count(); + CDesCArray* array = NULL; + array = AliasedAddressL( aArray, aFs ); + CleanupStack::PushL( array ); + + for (TInt i=0; i < size; i++) + { + if ( aExclude.Length() == 0 || + ( aExclude.Length() > 0 && + TMmsGenUtils::PureAddress( aExclude ).CompareF( + TMmsGenUtils::PureAddress( array->MdcaPoint(i) ) ) != 0 ) ) + { + this->AddTypedAddresseeL( array->MdcaPoint(i), aType ); + } + } + CleanupStack::PopAndDestroy( array ); + } + +// --------------------------------------------------------- +// CMmsHeaders::AliasedAddressL() +// +// --------------------------------------------------------- +// +HBufC* CMmsHeaders::AliasedAddressL( + const TDesC& aOriginalAddress, + RFs& aFs ) + { + HBufC* result = NULL; + TPtrC realAddress; + TInt error = KErrNone; + + realAddress.Set( TMmsGenUtils::PureAddress( aOriginalAddress ) ); + HBufC* alias = HBufC::NewL( KMaxHeaderStringLength ); + CleanupStack::PushL( alias ); + TPtr aliasPtr = alias->Des(); + error = TMmsGenUtils::GetAlias( realAddress, aliasPtr, KMaxHeaderStringLength, aFs ); + if ( error == KErrNone && aliasPtr.Length() > 0 ) + { + result = TMmsGenUtils::GenerateAddressL( realAddress, aliasPtr ); + } + else + { + result = HBufC::NewL( aOriginalAddress.Length() ); + result->Des().Copy( aOriginalAddress ); + } + + CleanupStack::PopAndDestroy( alias ); + + // It is the caller's responsibility to put result on cleanup stack + return result; + + } +// --------------------------------------------------------- +// CMmsHeaders::AliasedAddressL() +// +// --------------------------------------------------------- +// +CDesCArray* CMmsHeaders::AliasedAddressL( + const CDesCArray& aOriginalAddress, + RFs& aFs ) + { + TInt size; + TInt error( KErrNone ); + TInt i( 0 ); + size = aOriginalAddress.MdcaCount(); + + CDesCArray* aliasArray = new ( ELeave )CDesCArrayFlat( KMmsArrayAllocationNumber ); + CleanupStack::PushL( aliasArray ); + + CDesCArray* realAddress = new ( ELeave )CDesCArrayFlat( KMmsArrayAllocationNumber ); + CleanupStack::PushL( realAddress ); + + //This is popped later because of the caller ... + CDesCArray* result = new ( ELeave )CDesCArrayFlat( KMmsArrayAllocationNumber ); + CleanupStack::PushL( result ); + + for ( i=0; i < size; i++ ) + { + // index is valid as i is always less than aOriginalAddress size + realAddress->InsertL( i, + ( TMmsGenUtils::PureAddress( aOriginalAddress[i] ) ) ); + } + + //GetAlias and GetAliasForAll returns error only in very rare case, in case on oom + //or in case of programming error. That's why if some of the alias matchings fails let's + //ignore the whole alias matching + TRAP( error, + TMmsGenUtils::GetAliasForAllL( *realAddress, *aliasArray, KMaxHeaderStringLength, aFs ) + ); + + size = aliasArray->MdcaCount(); + + HBufC* tempAddress( NULL ); + + if ( error != KErrNone ) + { + //Something badly wrong, let's not set any alias + for ( i = 0; i < size; i++ ) + { + // index is valid as i is always less than aOriginalAddress size + result->InsertL( i, aOriginalAddress[i] ); + } + } + else + { + for ( i = 0; i < size; i++ ) + { + if ( ( aliasArray->MdcaPoint(i)).Length() > 0 ) + { + tempAddress = TMmsGenUtils::GenerateAddressL( + realAddress->MdcaPoint(i), + aliasArray->MdcaPoint(i) ); + CleanupStack::PushL( tempAddress ); + result->InsertL( i, tempAddress->Des() ); + CleanupStack::PopAndDestroy( tempAddress ); + } + else + { + // index is valid as i is always less than aOriginalAddress size + result->InsertL( i, aOriginalAddress[i] ); + } + } + } + + CleanupStack::Pop( result ); + CleanupStack::PopAndDestroy( realAddress ); + CleanupStack::PopAndDestroy( aliasArray ); + + return result; + + } + +// --------------------------------------------------------- +// CMmsHeaders::CreateContentId() +// +// --------------------------------------------------------- +// +EXPORT_C void CMmsHeaders::CreateContentId( TDes8& aCid ) + { + TTime now; + now.UniversalTime(); + TInt random; + TInt64 seed = now.Int64(); + random = Math::Rand( seed ); + + aCid.Num( random ); + aCid.Insert(0, KMmsLeftAngle ); + aCid.Append( KMmsRightAngle ); + } + +// --------------------------------------------------------- +// CMmsHeaders::LimitStringSize +// +// --------------------------------------------------------- +// +TPtrC8 CMmsHeaders::LimitStringSize( const TPtrC8& aString, TInt aMaxSize) + { + if (aString.Length() < aMaxSize) + return aString; + else + return aString.Left(aMaxSize); + } + +// --------------------------------------------------------- +// CMmsHeaders::LimitStringSize +// +// --------------------------------------------------------- +// +TPtrC16 CMmsHeaders::LimitStringSize( const TPtrC16& aString, TInt aMaxSize) + { + if (aString.Length() < aMaxSize) + return aString; + else + return aString.Left(aMaxSize); + } + +// ================= OTHER EXPORTED FUNCTIONS ============== + + +// End of File +