diff -r 238255e8b033 -r 84d9eb65b26f messagingappbase/smsmtm/clientmtm/src/csmsemailfields.cpp --- a/messagingappbase/smsmtm/clientmtm/src/csmsemailfields.cpp Fri Apr 16 14:56:15 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,816 +0,0 @@ -// Copyright (c) 2004-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: -// - -#include - -#include - -const TInt KSmsEmailAddressesArrayGranularity = 4; - -const TUid KUidMsvSmsEmailFieldsStream = {0x10204C9D}; -const TInt KMsvSmsEmailFieldsVersion = 1; -const TUint8 KSmsEmailComma = ','; -const TUint8 KSmsEmailAtSign = '@'; -const TUint8 KSmsEmailSpace = ' '; -const TUint8 KSmsEmailOpenBracket = '('; -const TUint8 KSmsEmailCloseBracket = ')'; -const TUint8 KSmsEmailHash = '#'; -#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) -_LIT16(KDelimiter, ";"); -_LIT16(KComma, ","); -#endif -/** -Factory constructor. - -@return -An empty email fields object. -*/ -EXPORT_C CSmsEmailFields* CSmsEmailFields::NewL() - { - CSmsEmailFields* self = new (ELeave) CSmsEmailFields(); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } - -/** -Factory copy constructor. - -@param aEmailFields -The orginal email fields object from which a copy is made. - -@return -A copy of aEmailFields. -*/ -EXPORT_C CSmsEmailFields* CSmsEmailFields::NewL(const CSmsEmailFields& aEmailFields) - { - CSmsEmailFields* self = new (ELeave) CSmsEmailFields(); - CleanupStack::PushL(self); - self->ConstructL(aEmailFields); - CleanupStack::Pop(self); - return self; - } - -/** -Destructor. -*/ -EXPORT_C CSmsEmailFields::~CSmsEmailFields() - { - Reset(); - delete iAddresses; - } - -/** -Resets the contents of the email fields object. -*/ -EXPORT_C void CSmsEmailFields::Reset() - { - delete iSubject; - iSubject = NULL; - if( iAddresses!=NULL ) - { - iAddresses->Reset(); - } - } - -/** -The number of characters in the email fields. - -Calculates the number of characters that will be pre-pended to an SMS message -when SMS is set for interworking with email. The address and subject fields are -only valid if the their length is greater than zero. - -The address field is a comma separated list of addresses. - -It assumes that a subject will be added with the following format. - -@code - -
() - -@endcode - -No validation of the contents of the fields is performed. - -@return -The number of characters in the email fields. -*/ -EXPORT_C TInt CSmsEmailFields::Length() const - { - // Get the address length and subject length - TInt subject = Subject().Length(); - TInt address = 0; - - if( HasAddress() ) - { - // Go through address list - there is at least one address... - address = (*iAddresses)[0].Length(); - - TInt count = iAddresses->Count(); - for( TInt i=1; i < count; ++i ) - { - // Any subsequent addresses are in a comma separated list - include - // length of comma separator. - address += (1 + (*iAddresses)[i].Length()); - } - } - - if( subject > 0 ) - { - // There is a subject - add the address and subject lengths plus the - // two delimiters; the '(' and ')' delimiters. - return (address + subject + 2); - } - if( address > 0 ) - { - // There is no subject field, but there is an address field - add the - // address length and the single space delimiter for the end of the - // address field. - return (address + 1); - } - - // There is neither an address nor a subject field - return zero length. - return 0; - } - -/** -Indicates whether the address field contains at least one address - -@return -A value of true if the address field contains at least one address, false if the -address field is empty. -*/ -EXPORT_C TBool CSmsEmailFields::HasAddress() const - { - return (iAddresses->Count() > 0); - } - -/** -Composes the email fields. - -The email fields are formatted into a buffer. The buffer is returned and left -on the cleanup stack. - -If there is no address fields, then the function leaves with the error code -KErrCorrupt. - -The address field is a comma separate list of addresses. - -If a subject field exists then the address fields is delimited by a open bracket -'(' and the subject is delimited by a close bracket ')'. - -@return -A buffer contain the formatted email fields. A pointer to this buffer is left -on the cleanup stack. - -@leave KErrCorrupt -The email fields has a zero-length address field. - -@internalTechnology -*/ -EXPORT_C HBufC* CSmsEmailFields::ComposeLC() const - { - if( !HasAddress() ) - { - User::Leave(KErrCorrupt); - } - - HBufC* buf = HBufC::NewLC(Length()); - TPtr ptr(buf->Des()); - - // Append the addresses - must have at least one address... - ptr.Append((*iAddresses)[0]); - - // Append remaining addresses as comma separated list - TInt count = iAddresses->Count(); - for( TInt i=1; i < count; ++i ) - { - ptr.Append(KSmsEmailComma); - ptr.Append((*iAddresses)[i]); - } - - // The delimiter for the address depends on whether there is a subject. - if( Subject().Length() > 0 ) - { - // Append open bracket '(', followed by subject and then close bracket ')'. - ptr.Append(KSmsEmailOpenBracket); - ptr.Append(*iSubject); - ptr.Append(KSmsEmailCloseBracket); - } - else - { - // No subject - address delimited by a space. - ptr.Append(KSmsEmailSpace); - } - return buf; - } - -/** -Parses the given buffer for email fields. - -Supports the two address formats. - -@code - - user@domain1.domain2 - -or - - User Name - -@endcode - -Also, supports the two subject formats. - -@code - -
() - -or - -
### - -@endcode - -The parsed address and optional subject are set in the email fields object. Any -existing data in the object is deleted. - -@param aBuffer -The buffer to be parsed. - -@return -If the email fields were successfully parsed the start position of the actual -body text from the start of aBuffer is returned. If the email fields could not -be parsed from aBuffer the error code KErrCorrupt is returned. - -@internalComponent -*/ -TInt CSmsEmailFields::ParseL(const TDesC& aBuffer) - { - Reset(); - - // The to-address or the from-address can have following two formats - - // 1. user@domain1.domain2 - // 2. User Name - // In the second format the <> brackets are part of the address. - // The address is delimited by one of the following - - // 1. - // 2. ( - // 3. # - // The later two cases imply that there is a subject field. These two - // delimiters are also mutually exclusive. - // - // First find the @ symbol - this will be the address. - TPtrC buf(aBuffer); - TInt pos = buf.Locate(KSmsEmailAtSign); - if( pos <= 0 ) - { - return KErrCorrupt; - } - - // Found the address - search for the delimiters. - TInt atPos = pos; - buf.Set(buf.Mid(pos)); - pos = buf.Locate(KSmsEmailSpace); - TInt spacePos = pos != KErrNotFound ? pos : KMaxTInt; - - pos = buf.Locate(KSmsEmailOpenBracket); - TInt bracketPos = pos != KErrNotFound ? pos : KMaxTInt; - - pos = buf.Locate(KSmsEmailHash); - TInt hashPos = pos != KErrNotFound ? pos : KMaxTInt; - - TInt bodyPos = KErrNotFound; - if( spacePos < bracketPos && spacePos < hashPos ) - { - // There is no subject as the is the first delimiter. - pos = spacePos + atPos; - - // Set the start of the body text - need to move past the delimiter. - bodyPos = pos + 1; - } - else - { - // The delimiter is either the # or ( - this implies a subject field. - TInt end = KErrNotFound; - if( bracketPos < hashPos ) - { - // Address delimited by the bracket position; - pos = bracketPos + atPos; - - // Set the start of the body text - need to move past the delimiter. - bodyPos = pos + 1; - - // Subject has the (subject) format - find the end of the subject - // indicated by the closing bracket ')'. First move past delimiter. - buf.Set(buf.Mid(bracketPos+1)); - end = buf.Locate(KSmsEmailCloseBracket); - } - else if( hashPos < KMaxTInt && buf[hashPos+1] == KSmsEmailHash ) - { - // Address delimited by the hash position; - pos = hashPos + atPos; - - // Set the start of the body text - need to move past the two # - // delimiters. - bodyPos = pos + 2; - - // Subject has the ##subject# format - find the end of the subject - // indicated by a final hash '#'. First move past the delimiters. - buf.Set(buf.Mid(hashPos+2)); - end = buf.Locate(KSmsEmailHash); - } - if( end == KErrNotFound ) - { - // In this case the email fields are corrupt - one of the following - // has occurred - - // 1. The address had no delimiter - missing , # or (. - // 2. The subject had no delimiter - missing # or ). - // 3. The address has only a single delimiting #. - return KErrCorrupt; - } - SetSubjectL(buf.Left(end)); - - // Update the start of the body text to get passed the subject - need - // to move past the delimiter. - bodyPos += end + 1; - } - // Add the address and return the position of the start of the body text. - AddAddressL(aBuffer.Left(pos)); - - return bodyPos; - } - -/** -Adds the address to the list of addresses. - -The address to be added must have a non-zero length. A zero-length address will -not be added to the address list. - -@param aAddress -The address to be added. -*/ -EXPORT_C void CSmsEmailFields::AddAddressL(const TDesC& aAddress) - { - if( aAddress.Length() > 0 ) - { - iAddresses->AppendL(aAddress); - } - } - -/** -Removes the specified address. - -@param aIndex -The index for the address to be remvoed. -*/ -EXPORT_C void CSmsEmailFields::RemoveAddress(TInt aIndex) - { - iAddresses->Delete(aIndex); - } - -/** -The array of email addresses. - -@see MDesCArray - -@return -An array of email addresses. -*/ -EXPORT_C const MDesCArray& CSmsEmailFields::Addresses() const - { - return *iAddresses; - } - -/** -Sets the email subject field. - -Copies the contents of subject as the email subject field. If the copy is -unsuccessful the current contents is left unchanged. - -@param aSubject -The subject to be copied into the email field. -*/ -EXPORT_C void CSmsEmailFields::SetSubjectL(const TDesC& aSubject) - { - HBufC* subject = aSubject.AllocL(); - delete iSubject; - iSubject = subject; - } - -/** -The subject field. - -@return -The subject field. -*/ -EXPORT_C const TDesC& CSmsEmailFields::Subject() const - { - return (iSubject) ? static_cast(*iSubject) : KNullDesC(); - } - -/** -Restores the email fields. - -If the store does not contain email fields data, the current email data is reset. - -@param aStore -The store to be read. - -@internalComponent -*/ -void CSmsEmailFields::RestoreL(CMsvStore& aStore) - { - if( aStore.IsPresentL(KUidMsvSmsEmailFieldsStream) ) - { - // The email fields stream exists - internalise from the stream. - RMsvReadStream in; - in.OpenLC(aStore, KUidMsvSmsEmailFieldsStream); - InternalizeL(in); - CleanupStack::PopAndDestroy(&in); - } - else - { - // There is no stream - reset the email fields. - Reset(); - } - } - - -/** -Stores the email fields. - -The email fields data will only be stored if there is at least some address or -subject data. If there is neither address nor subject data and the store already -contains email fields data, then this existing data is removed. - -@param aStore -The store to be written. - -@internalComponent -*/ -void CSmsEmailFields::StoreL(CMsvStore& aStore) const - { - if( HasAddress() || Subject().Length() > 0 ) - { - // The email fields have some data - store them. - RMsvWriteStream out; - out.AssignLC(aStore, KUidMsvSmsEmailFieldsStream); - ExternalizeL(out); - out.CommitL(); - CleanupStack::PopAndDestroy(&out); - } - else if( aStore.IsPresentL(KUidMsvSmsEmailFieldsStream) ) - { - // Ok, the current email fields have no data, but the email fileds - // stream exists - remove it. - aStore.Remove(KUidMsvSmsEmailFieldsStream); - } - } - -/** -Internalizes the email fields from the given stream. - -@param aStream -The stream to be read. -*/ -void CSmsEmailFields::InternalizeL(RReadStream& aStream) - { - Reset(); - aStream.ReadInt16L(); // read the version - to local as causes warning in EABI... - - TCardinality cardinality; - aStream >> cardinality; - TInt count = cardinality; - - for( TInt i = 0; i < count; ++i ) - { - HBufC* buf = HBufC::NewLC(aStream, KMaxTInt); - AddAddressL(*buf); - CleanupStack::PopAndDestroy(buf); - } - iSubject = HBufC::NewL(aStream, KMaxTInt); - } - -/** -Externalizes the email fields into the given stream. - -@param aStream -The stream to be written. -*/ -void CSmsEmailFields::ExternalizeL(RWriteStream& aStream) const - { - aStream.WriteInt16L(KMsvSmsEmailFieldsVersion); - - TInt count = iAddresses->Count(); - aStream << TCardinality(count); - for( TInt i = 0; i < count; ++i ) - { - aStream << (*iAddresses)[i]; - } - aStream << Subject(); - } - -CSmsEmailFields::CSmsEmailFields() -: CBase() - { - } - -void CSmsEmailFields::ConstructL() - { - iAddresses = new (ELeave) CDesCArrayFlat(KSmsEmailAddressesArrayGranularity); - } - -void CSmsEmailFields::ConstructL(const CSmsEmailFields& aEmailFields) - { - ConstructL(); - - const MDesCArray& addresses = aEmailFields.Addresses(); - TInt count = addresses.MdcaCount(); - - for( TInt i=0; i < count; ++i ) - { - AddAddressL(addresses.MdcaPoint(i)); - } - iSubject = aEmailFields.Subject().AllocL(); - } - -#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) - -/** -Stores the email fields in SQL DB. - -The email fields data will only be stored if there is at least some address or -subject data. If there is neither address nor subject data and the store already -contains email fields data, then this existing data is removed. - -@param aStore -The store to be written. - -@internalComponent -*/ - -void CSmsEmailFields::StoreDBL(CMsvStore& aStore) - { - // This is the continuation of the header entry created - // in CSmsHeader::StoreDbL(). - - if( HasAddress() || Subject().Length() > 0 ) - { - CHeaderFields* emailOverSmsHeaderFields = new (ELeave)CHeaderFields(); - CleanupStack::PushL(emailOverSmsHeaderFields); - emailOverSmsHeaderFields->iUid = KUidMsvSmsEmailFieldsStream; - - //----------------------EOS Info 6th Field ------------------------------ - CFieldPair* smsdetailField = new (ELeave)CFieldPair(); - CleanupStack::PushL(smsdetailField); - - RBuf eosbuf; - CleanupClosePushL(eosbuf); - eosbuf.CreateL(GetBufSize()); - - // Header version - eosbuf.AppendNum(KMsvSmsEmailFieldsVersion); - eosbuf.Append(KDelimiter); - - // AddressCount - eosbuf.AppendNum(iAddresses->Count()); - eosbuf.Append(KDelimiter); - - // Addresses - for (TInt i=0; iCount(); i++) - { - eosbuf.Append(iAddresses->MdcaPoint(i)); - if(i<(iAddresses->MdcaCount())-1) - eosbuf.Append(KComma); - } - - eosbuf.Append(KDelimiter); - - // Subject - eosbuf.Append(Subject()); - eosbuf.Append(KDelimiter); - - HBufC* newFrom1 = HBufC::NewL(eosbuf.Length()); - newFrom1->Des().Copy(eosbuf); - smsdetailField->iFieldTextValue = newFrom1; - emailOverSmsHeaderFields->iFieldPairList.AppendL(smsdetailField); - - eosbuf.Close(); - CleanupStack::Pop(); // Rbuf - CleanupStack::Pop(smsdetailField); - - - TMsvWriteStore storeWriter(aStore); - storeWriter.AssignL(emailOverSmsHeaderFields); - storeWriter.CommitL(); - - CleanupStack::Pop(emailOverSmsHeaderFields); - - } - else if( aStore.IsPresentL(KUidMsvSmsEmailFieldsStream) ) - { - - CHeaderFields* emailOverSmsHeaderFields = new (ELeave)CHeaderFields(); - CleanupStack::PushL(emailOverSmsHeaderFields); - emailOverSmsHeaderFields->iUid = KUidMsvSmsEmailFieldsStream; - - - CFieldPair* smsdetailField = new (ELeave)CFieldPair(); - CleanupStack::PushL(smsdetailField); - smsdetailField->iFieldTextValue = KNullDesC().AllocL(); - emailOverSmsHeaderFields->iFieldPairList.AppendL(smsdetailField); - CleanupStack::Pop(smsdetailField); - - TMsvWriteStore storeWriter(aStore); - storeWriter.AssignL(emailOverSmsHeaderFields); - storeWriter.CommitL(); - - - // Ok, the current email fields have no data, but the email fileds - // stream exists - remove it. - aStore.Remove(KUidMsvSmsEmailFieldsStream); - - CleanupStack::Pop(emailOverSmsHeaderFields); - } - } - -/** -To gett he Buffer size. -*/ - -TInt CSmsEmailFields::GetBufSize() - { - TInt size = 0; - - size += sizeof(KMsvSmsEmailFieldsVersion) + 1; // 1 is for Delimiter - size += Subject().Length() + 1 ; - size += sizeof(iAddresses->Count()) + 1 ; - - for(TInt i=0; iCount(); i++) - { - size += iAddresses->MdcaPoint(i).Length() + 1; // Extra byte for Comma - } - - return size ; - - } - - - -/** -Retrives the email fields from SQL DB. - -If the store does not contain email fields data, the current email data is reset. - -@param aStore -The store to be read. - -@internalComponent -*/ - - -void CSmsEmailFields::ReStoreDBL(CMsvStore& aStore) - { - Reset(); - CHeaderFields* rcvEmailHeaderRow = NULL; - TMsvReadStore storeReader(aStore, KUidMsvSmsEmailFieldsStream); - TRAPD(err, storeReader.ReadL(rcvEmailHeaderRow)); - - if(KErrNotFound == err) - { - return; - } - - TInt i = 0; //SMS Email over SMS - HBufC* eosheaderinfo = rcvEmailHeaderRow->iFieldPairList[i++]->iFieldTextValue ; - TPtr16 eosheaderPtr = (eosheaderinfo->Des()); - - //Parsing the eos string - TInt firstSemiColonPos = eosheaderPtr.Locate(';'); - TInt lastSemiColonPos = eosheaderPtr.LocateReverse(';'); - - RPointerArray eosinfoData; - CleanupClosePushL(eosinfoData); - TInt ii = 0 ; - - do - { - TPtrC16 str1 = eosheaderPtr.Left(firstSemiColonPos); // First data - HBufC16* tt = str1.AllocLC(); - firstSemiColonPos++; - eosinfoData.AppendL(tt); - CleanupStack::Pop(); - - if(firstSemiColonPos != lastSemiColonPos) - { - eosheaderPtr = (eosheaderPtr.Mid(firstSemiColonPos,eosheaderPtr.Length()-(firstSemiColonPos) )); - firstSemiColonPos = eosheaderPtr.Locate(';'); - lastSemiColonPos = eosheaderPtr.LocateReverse(';'); - if(firstSemiColonPos == lastSemiColonPos) - { - TPtrC16 str1 = eosheaderPtr.Left(eosheaderPtr.Length() -1); // Last data is Subject . End with Semicolon. -1 is to remove semicolon. - HBufC16* tt = str1.AllocLC(); - eosinfoData.AppendL(tt); - CleanupStack::Pop(); - } - } - else - { - //Empty field. - HBufC16* tt = KNullDesC().AllocLC(); - eosinfoData.AppendL(tt); - CleanupStack::Pop(); - } - - ii++; - }while(firstSemiColonPos != lastSemiColonPos); - - TInt16 headerversion = ConvertToTInt(*eosinfoData[0]); - - TInt count = ConvertToTInt(*eosinfoData[1]); - - if(count > 0) - { - _LIT16(KSemicolon, ";"); - HBufC16* addressesList = eosinfoData[2]->Des().AllocLC(); - addressesList = addressesList->ReAllocL(addressesList->Length()+2); - TPtr16 addressesListPtr = (addressesList->Des()); - addressesListPtr.Append(KSemicolon); - GetRecipientListL(addressesListPtr); - CleanupStack::PopAndDestroy(); - } - else - { - AddAddressL(KNullDesC16); - } - - iSubject = eosinfoData[3]->Des().AllocL(); - - - eosinfoData.ResetAndDestroy(); - CleanupStack::PopAndDestroy(); //RPointerArray - } - - /* Convert a String to an Integer. - * @param aStr A string to make Integer. - * @return TInt A integer value - */ -TInt CSmsEmailFields::ConvertToTInt(TDesC16& aStr) - { - TLex str(aStr); - TInt32 string; - str.Val(string); - return string; - } - -/** -To parse the recipient address list. -*/ - -void CSmsEmailFields::GetRecipientListL(TDesC16& aStr) - { - TPtrC16 recvstr = aStr; - - if(KErrNotFound != recvstr.Locate(',') ) - { // It has multipule recipient list is :- example@nokia.com, example@nokia.com,example@nokia.com; - TInt startPos = recvstr.Locate(',') ; - while(1) - { - TPtrC16 partstrx = recvstr.Left(startPos); - AddAddressL(partstrx); - startPos++; - recvstr.Set(recvstr.Mid(startPos, recvstr.Length()- startPos)); - - startPos = recvstr.Locate(','); - if(startPos == KErrNotFound) - { - TPtrC16 partstrxy; - partstrxy.Set(recvstr.Mid(0,recvstr.Length()-1)); - AddAddressL(partstrxy); - break; - } - } - - } - else // It has one recipient list is like this-> example@nokia.com; - { - TInt lastpos = recvstr.Locate(';'); - TPtrC16 partstrx = recvstr.Left(lastpos); - AddAddressL(partstrx); - } - } -#endif