messagingappbase/smsmtm/clientmtm/src/csmsemailfields.cpp
changeset 23 238255e8b033
equal deleted inserted replaced
5:4697dfb2d7ad 23:238255e8b033
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <csmsemailfields.h>
       
    17 
       
    18 #include <msvstore.h>
       
    19 
       
    20 const TInt KSmsEmailAddressesArrayGranularity	= 4;
       
    21 
       
    22 const TUid KUidMsvSmsEmailFieldsStream	= {0x10204C9D};
       
    23 const TInt KMsvSmsEmailFieldsVersion	= 1;
       
    24 const TUint8 KSmsEmailComma			= ',';
       
    25 const TUint8 KSmsEmailAtSign		= '@';
       
    26 const TUint8 KSmsEmailSpace 		= ' ';
       
    27 const TUint8 KSmsEmailOpenBracket	= '(';
       
    28 const TUint8 KSmsEmailCloseBracket	= ')';
       
    29 const TUint8 KSmsEmailHash			= '#';
       
    30 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
    31 _LIT16(KDelimiter, ";");
       
    32 _LIT16(KComma, ",");
       
    33 #endif
       
    34 /**
       
    35 Factory constructor.
       
    36 
       
    37 @return
       
    38 An empty email fields object.
       
    39 */
       
    40 EXPORT_C CSmsEmailFields* CSmsEmailFields::NewL()
       
    41 	{
       
    42 	CSmsEmailFields* self = new (ELeave) CSmsEmailFields();
       
    43 	CleanupStack::PushL(self);
       
    44 	self->ConstructL();
       
    45 	CleanupStack::Pop(self);
       
    46 	return self;
       
    47 	}
       
    48 
       
    49 /**
       
    50 Factory copy constructor.
       
    51 
       
    52 @param	aEmailFields
       
    53 The orginal email fields object from which a copy is made.
       
    54 
       
    55 @return
       
    56 A copy of aEmailFields.
       
    57 */
       
    58 EXPORT_C CSmsEmailFields* CSmsEmailFields::NewL(const CSmsEmailFields& aEmailFields)
       
    59 	{
       
    60 	CSmsEmailFields* self = new (ELeave) CSmsEmailFields();
       
    61 	CleanupStack::PushL(self);
       
    62 	self->ConstructL(aEmailFields);
       
    63 	CleanupStack::Pop(self);
       
    64 	return self;
       
    65 	}
       
    66 	
       
    67 /**
       
    68 Destructor.
       
    69 */	
       
    70 EXPORT_C CSmsEmailFields::~CSmsEmailFields()
       
    71 	{
       
    72 	Reset();
       
    73 	delete iAddresses;
       
    74 	}
       
    75 	
       
    76 /**
       
    77 Resets the contents of the email fields object.
       
    78 */
       
    79 EXPORT_C void CSmsEmailFields::Reset()
       
    80 	{
       
    81 	delete iSubject;
       
    82 	iSubject = NULL;
       
    83 	if( iAddresses!=NULL )
       
    84 		{
       
    85 		iAddresses->Reset();
       
    86 		}
       
    87 	}
       
    88 	
       
    89 /**
       
    90 The number of characters in the email fields.
       
    91 
       
    92 Calculates the number of characters that will be pre-pended to an SMS message
       
    93 when SMS is set for interworking with email. The address and subject fields are
       
    94 only valid if the their length is greater than zero.
       
    95 
       
    96 The address field is a comma separated list of addresses.
       
    97 
       
    98 It assumes that a subject will be added with the following format.
       
    99 
       
   100 @code
       
   101 
       
   102 	<address>(<subject>)<message>
       
   103 
       
   104 @endcode
       
   105 
       
   106 No validation of the contents of the fields is performed.
       
   107 
       
   108 @return
       
   109 The number of characters in the email fields.
       
   110 */
       
   111 EXPORT_C TInt CSmsEmailFields::Length() const
       
   112 	{
       
   113 	// Get the address length and subject length
       
   114 	TInt subject = Subject().Length();
       
   115 	TInt address = 0;
       
   116 	
       
   117 	if( HasAddress() )
       
   118 		{
       
   119 		// Go through address list - there is at least one address...	
       
   120 		address = (*iAddresses)[0].Length();
       
   121 		
       
   122 		TInt count = iAddresses->Count();
       
   123 		for( TInt i=1; i < count; ++i )
       
   124 			{
       
   125 			// Any subsequent addresses are in a comma separated list - include
       
   126 			// length of comma separator.
       
   127 			address += (1 + (*iAddresses)[i].Length());
       
   128 			}
       
   129 		}
       
   130 	
       
   131 	if( subject > 0 )
       
   132 		{
       
   133 		// There is a subject - add the address and subject lengths plus the
       
   134 		// two delimiters; the '(' and ')' delimiters.
       
   135 		return (address + subject + 2);
       
   136 		}
       
   137 	if( address > 0 )
       
   138 		{
       
   139 		// There is no subject field, but there is an address field - add the
       
   140 		// address length and the single space delimiter for the end of the 
       
   141 		// address field.
       
   142 		return (address + 1);
       
   143 		}
       
   144 
       
   145 	// There is neither an address nor a subject field - return zero length.
       
   146 	return 0;
       
   147 	}
       
   148 	
       
   149 /**
       
   150 Indicates whether the address field contains at least one address
       
   151 
       
   152 @return
       
   153 A value of true if the address field contains at least one address, false if the
       
   154 address field is empty.
       
   155 */
       
   156 EXPORT_C TBool CSmsEmailFields::HasAddress() const
       
   157 	{
       
   158 	return (iAddresses->Count() > 0);
       
   159 	}
       
   160 	
       
   161 /**
       
   162 Composes the email fields.
       
   163 
       
   164 The email fields are formatted into a buffer. The buffer is returned and left
       
   165 on the cleanup stack.
       
   166 
       
   167 If there is no address fields, then the function leaves with the error code 
       
   168 KErrCorrupt.
       
   169 
       
   170 The address field is a comma separate list of addresses.
       
   171 
       
   172 If a subject field exists then the address fields is delimited by a open bracket
       
   173 '(' and the subject is delimited by a close bracket ')'.
       
   174 
       
   175 @return
       
   176 A buffer contain the formatted email fields. A pointer to this buffer is left
       
   177 on the cleanup stack.
       
   178 
       
   179 @leave	KErrCorrupt
       
   180 The email fields has a zero-length address field.
       
   181 
       
   182 @internalTechnology
       
   183 */
       
   184 EXPORT_C HBufC* CSmsEmailFields::ComposeLC() const
       
   185 	{
       
   186 	if( !HasAddress() )
       
   187 		{
       
   188 		User::Leave(KErrCorrupt);
       
   189 		}
       
   190 
       
   191 	HBufC* buf = HBufC::NewLC(Length());
       
   192 	TPtr ptr(buf->Des());
       
   193 	
       
   194 	// Append the addresses - must have at least one address...
       
   195 	ptr.Append((*iAddresses)[0]);
       
   196 	
       
   197 	// Append remaining addresses as comma separated list
       
   198 	TInt count = iAddresses->Count();
       
   199 	for( TInt i=1; i < count; ++i )
       
   200 		{
       
   201 		ptr.Append(KSmsEmailComma);
       
   202 		ptr.Append((*iAddresses)[i]);
       
   203 		}
       
   204 	
       
   205 	// The delimiter for the address depends on whether there is a subject.
       
   206 	if( Subject().Length() > 0 )
       
   207 		{
       
   208 		// Append open bracket '(', followed by subject and then close bracket ')'.
       
   209 		ptr.Append(KSmsEmailOpenBracket);
       
   210 		ptr.Append(*iSubject);
       
   211 		ptr.Append(KSmsEmailCloseBracket);
       
   212 		}
       
   213 	else
       
   214 		{
       
   215 		// No subject - address delimited by a space.
       
   216 		ptr.Append(KSmsEmailSpace);		
       
   217 		}
       
   218 	return buf;
       
   219 	}
       
   220 	
       
   221 /**
       
   222 Parses the given buffer for email fields.
       
   223 
       
   224 Supports the two address formats.
       
   225 
       
   226 @code
       
   227 
       
   228 	user@domain1.domain2
       
   229 
       
   230 or
       
   231 
       
   232 	User Name <user@domain1.domain2>
       
   233 
       
   234 @endcode
       
   235 
       
   236 Also, supports the two subject formats.
       
   237 
       
   238 @code
       
   239 
       
   240 	<address>(<subject>)<message>
       
   241 
       
   242 or
       
   243 	
       
   244 	<address>##<subject>#<message>
       
   245 
       
   246 @endcode
       
   247 
       
   248 The parsed address and optional subject are set in the email fields object. Any
       
   249 existing data in the object is deleted.
       
   250 
       
   251 @param	aBuffer
       
   252 The buffer to be parsed.
       
   253 
       
   254 @return
       
   255 If the email fields were successfully parsed the start position of the actual
       
   256 body text from the start of aBuffer is returned. If the email fields could not
       
   257 be parsed from aBuffer the error code KErrCorrupt is returned.
       
   258 
       
   259 @internalComponent
       
   260 */	
       
   261 TInt CSmsEmailFields::ParseL(const TDesC& aBuffer)
       
   262 	{
       
   263 	Reset();
       
   264 	
       
   265 	// The to-address or the from-address can have following two formats - 
       
   266 	// 1. user@domain1.domain2
       
   267 	// 2. User Name <user@domain1.domain2>
       
   268 	// In the second format the <> brackets are part of the address.
       
   269 	// The address is delimited by one of the following - 
       
   270 	// 1. <space>
       
   271 	// 2. (
       
   272 	// 3. #
       
   273 	// The later two cases imply that there is a subject field. These two 
       
   274 	// delimiters are also mutually exclusive.
       
   275 	//
       
   276 	// First find the @ symbol - this will be the address.
       
   277 	TPtrC buf(aBuffer);
       
   278 	TInt pos = buf.Locate(KSmsEmailAtSign);
       
   279 	if( pos <= 0 )
       
   280 		{
       
   281 		return KErrCorrupt;
       
   282 		}
       
   283 	
       
   284 	// Found the address - search for the delimiters.
       
   285 	TInt atPos = pos;
       
   286 	buf.Set(buf.Mid(pos));
       
   287 	pos = buf.Locate(KSmsEmailSpace);
       
   288 	TInt spacePos	= pos != KErrNotFound ? pos : KMaxTInt;
       
   289 
       
   290 	pos = buf.Locate(KSmsEmailOpenBracket);
       
   291 	TInt bracketPos	= pos != KErrNotFound ? pos : KMaxTInt;
       
   292 
       
   293 	pos = buf.Locate(KSmsEmailHash);
       
   294 	TInt hashPos	= pos != KErrNotFound ? pos : KMaxTInt;
       
   295 	
       
   296 	TInt bodyPos = KErrNotFound;
       
   297 	if( spacePos < bracketPos && spacePos < hashPos )
       
   298 		{
       
   299 		// There is no subject as the <space> is the first delimiter.
       
   300 		pos = spacePos + atPos;
       
   301 		
       
   302 		// Set the start of the body text - need to move past the delimiter.
       
   303 		bodyPos = pos + 1;
       
   304 		}
       
   305 	else 
       
   306 		{
       
   307 		// The delimiter is either the # or ( - this implies a subject field.
       
   308 		TInt end = KErrNotFound;
       
   309 		if( bracketPos < hashPos )
       
   310 			{
       
   311 			// Address delimited by the bracket position;
       
   312 			pos = bracketPos + atPos;
       
   313 			
       
   314 			// Set the start of the body text - need to move past the delimiter.
       
   315 			bodyPos = pos + 1;
       
   316 			
       
   317 			// Subject has the (subject) format - find the end of the subject
       
   318 			// indicated by the closing bracket ')'. First move past delimiter.
       
   319 			buf.Set(buf.Mid(bracketPos+1));
       
   320 			end = buf.Locate(KSmsEmailCloseBracket);
       
   321 			}
       
   322 		else if( hashPos < KMaxTInt && buf[hashPos+1] == KSmsEmailHash )
       
   323 			{
       
   324 			// Address delimited by the hash position;
       
   325 			pos = hashPos + atPos;
       
   326 			
       
   327 			// Set the start of the body text - need to move past the two # 
       
   328 			// delimiters.
       
   329 			bodyPos = pos + 2;
       
   330 
       
   331 			// Subject has the ##subject# format - find the end of the subject
       
   332 			// indicated by a final hash '#'. First move past the delimiters.
       
   333 			buf.Set(buf.Mid(hashPos+2));
       
   334 			end = buf.Locate(KSmsEmailHash);
       
   335 			}
       
   336 		if( end == KErrNotFound )
       
   337 			{
       
   338 			// In this case the email fields are corrupt - one of the following
       
   339 			// has occurred - 
       
   340 			// 1. The address had no delimiter - missing <space>, # or (.
       
   341 			// 2. The subject had no delimiter - missing # or ).
       
   342 			// 3. The address has only a single delimiting #.
       
   343 			return KErrCorrupt;
       
   344 			}
       
   345 		SetSubjectL(buf.Left(end));
       
   346 		
       
   347 		// Update the start of the body text to get passed the subject - need
       
   348 		// to move past the delimiter.
       
   349 		bodyPos += end + 1;
       
   350 		}
       
   351 	// Add the address and return the position of the start of the body text.
       
   352 	AddAddressL(aBuffer.Left(pos));
       
   353 	
       
   354 	return bodyPos;	
       
   355 	}
       
   356 	
       
   357 /**
       
   358 Adds the address to the list of addresses.
       
   359 
       
   360 The address to be added must have a non-zero length. A zero-length address will
       
   361 not be added to the address list.
       
   362 
       
   363 @param	aAddress
       
   364 The address to be added.
       
   365 */
       
   366 EXPORT_C void CSmsEmailFields::AddAddressL(const TDesC& aAddress)
       
   367 	{
       
   368 	if( aAddress.Length() > 0 )
       
   369 		{
       
   370 		iAddresses->AppendL(aAddress);
       
   371 		}
       
   372 	}
       
   373 	
       
   374 /**
       
   375 Removes the specified address.
       
   376 
       
   377 @param	aIndex
       
   378 The index for the address to be remvoed.
       
   379 */
       
   380 EXPORT_C void CSmsEmailFields::RemoveAddress(TInt aIndex)
       
   381 	{
       
   382 	iAddresses->Delete(aIndex);
       
   383 	}
       
   384 	
       
   385 /**
       
   386 The array of email addresses.
       
   387 
       
   388 @see	MDesCArray
       
   389 
       
   390 @return
       
   391 An array of email addresses.
       
   392 */
       
   393 EXPORT_C const MDesCArray& CSmsEmailFields::Addresses() const
       
   394 	{
       
   395 	return *iAddresses;
       
   396 	}
       
   397 	
       
   398 /**
       
   399 Sets the email subject field.
       
   400 
       
   401 Copies the contents of subject as the email subject field. If the copy is 
       
   402 unsuccessful the current contents is left unchanged.
       
   403 
       
   404 @param	aSubject
       
   405 The subject to be copied into the email field.
       
   406 */
       
   407 EXPORT_C void CSmsEmailFields::SetSubjectL(const TDesC& aSubject)
       
   408 	{
       
   409 	HBufC* subject = aSubject.AllocL();
       
   410 	delete iSubject;
       
   411 	iSubject = subject;	
       
   412 	}
       
   413 	
       
   414 /**
       
   415 The subject field.
       
   416 
       
   417 @return
       
   418 The subject field.
       
   419 */
       
   420 EXPORT_C const TDesC& CSmsEmailFields::Subject() const
       
   421 	{
       
   422 	return (iSubject) ? static_cast<const TDesC&>(*iSubject) : KNullDesC();
       
   423 	}
       
   424 
       
   425 /**
       
   426 Restores the email fields.
       
   427 
       
   428 If the store does not contain email fields data, the current email data is reset.
       
   429 
       
   430 @param	aStore
       
   431 The store to be read.
       
   432 
       
   433 @internalComponent
       
   434 */
       
   435 void CSmsEmailFields::RestoreL(CMsvStore& aStore)
       
   436 	{
       
   437 	if( aStore.IsPresentL(KUidMsvSmsEmailFieldsStream) )
       
   438 		{
       
   439 		// The email fields stream exists - internalise from the stream.
       
   440 		RMsvReadStream in;
       
   441 		in.OpenLC(aStore, KUidMsvSmsEmailFieldsStream);
       
   442 		InternalizeL(in);
       
   443 		CleanupStack::PopAndDestroy(&in);	
       
   444 		}
       
   445 	else
       
   446 		{
       
   447 		// There is no stream - reset the email fields.
       
   448 		Reset();
       
   449 		}
       
   450 	}
       
   451 
       
   452 
       
   453 /**
       
   454 Stores the email fields.
       
   455 
       
   456 The email fields data will only be stored if there is at least some address or
       
   457 subject data. If there is neither address nor subject data and the store already
       
   458 contains email fields data, then this existing data is removed.
       
   459 
       
   460 @param	aStore
       
   461 The store to be written.
       
   462 
       
   463 @internalComponent
       
   464 */
       
   465 void CSmsEmailFields::StoreL(CMsvStore& aStore) const
       
   466 	{
       
   467 	if( HasAddress() || Subject().Length() > 0 )
       
   468 		{
       
   469 		// The email fields have some data - store them.
       
   470 		RMsvWriteStream out;	
       
   471 		out.AssignLC(aStore, KUidMsvSmsEmailFieldsStream);
       
   472 		ExternalizeL(out);
       
   473 		out.CommitL();
       
   474 		CleanupStack::PopAndDestroy(&out);
       
   475 		}
       
   476 	else if( aStore.IsPresentL(KUidMsvSmsEmailFieldsStream) )
       
   477 		{
       
   478 		// Ok, the current email fields have no data, but the email fileds 
       
   479 		// stream exists - remove it.
       
   480 		aStore.Remove(KUidMsvSmsEmailFieldsStream);
       
   481 		}
       
   482 	}
       
   483 	
       
   484 /**
       
   485 Internalizes the email fields from the given stream.
       
   486 
       
   487 @param	aStream
       
   488 The stream to be read.
       
   489 */
       
   490 void CSmsEmailFields::InternalizeL(RReadStream& aStream)
       
   491 	{
       
   492 	Reset();
       
   493 	aStream.ReadInt16L();	// read the version - to local as causes warning in EABI...
       
   494 
       
   495 	TCardinality cardinality;
       
   496 	aStream >> cardinality;
       
   497 	TInt count = cardinality;
       
   498 
       
   499 	for( TInt i = 0; i < count; ++i )
       
   500 		{
       
   501 		HBufC* buf = HBufC::NewLC(aStream, KMaxTInt);
       
   502 		AddAddressL(*buf);
       
   503 		CleanupStack::PopAndDestroy(buf);
       
   504 		}
       
   505 	iSubject = HBufC::NewL(aStream, KMaxTInt);	
       
   506 	}
       
   507 	
       
   508 /**
       
   509 Externalizes the email fields into the given stream.
       
   510 
       
   511 @param	aStream
       
   512 The stream to be written.
       
   513 */
       
   514 void CSmsEmailFields::ExternalizeL(RWriteStream& aStream) const
       
   515 	{
       
   516 	aStream.WriteInt16L(KMsvSmsEmailFieldsVersion);
       
   517 	
       
   518 	TInt count = iAddresses->Count();	
       
   519 	aStream << TCardinality(count);
       
   520 	for( TInt i = 0; i < count; ++i )
       
   521 		{
       
   522 		aStream << (*iAddresses)[i];
       
   523 		}
       
   524 	aStream << Subject();
       
   525 	}
       
   526 
       
   527 CSmsEmailFields::CSmsEmailFields()
       
   528 : CBase()
       
   529 	{
       
   530 	}
       
   531 	
       
   532 void CSmsEmailFields::ConstructL()
       
   533 	{
       
   534 	iAddresses = new (ELeave) CDesCArrayFlat(KSmsEmailAddressesArrayGranularity); 	
       
   535 	}
       
   536 
       
   537 void CSmsEmailFields::ConstructL(const CSmsEmailFields& aEmailFields)
       
   538 	{
       
   539 	ConstructL();
       
   540 	
       
   541 	const MDesCArray& addresses = aEmailFields.Addresses();
       
   542 	TInt count = addresses.MdcaCount();
       
   543 	
       
   544 	for( TInt i=0; i < count; ++i )
       
   545 		{
       
   546 		AddAddressL(addresses.MdcaPoint(i));		
       
   547 		}
       
   548 	iSubject = aEmailFields.Subject().AllocL();
       
   549 	}
       
   550 
       
   551 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   552 
       
   553 /**
       
   554 Stores the email fields in SQL DB.
       
   555 
       
   556 The email fields data will only be stored if there is at least some address or
       
   557 subject data. If there is neither address nor subject data and the store already
       
   558 contains email fields data, then this existing data is removed.
       
   559 
       
   560 @param	aStore
       
   561 The store to be written.
       
   562 
       
   563 @internalComponent
       
   564 */
       
   565 
       
   566 void CSmsEmailFields::StoreDBL(CMsvStore& aStore) 
       
   567 	{
       
   568 	// This is the continuation of the header entry created 
       
   569 	// in CSmsHeader::StoreDbL().
       
   570 	
       
   571 	if( HasAddress() || Subject().Length() > 0 )
       
   572 		{
       
   573 		CHeaderFields* emailOverSmsHeaderFields = new (ELeave)CHeaderFields();
       
   574 		CleanupStack::PushL(emailOverSmsHeaderFields);
       
   575 		emailOverSmsHeaderFields->iUid = KUidMsvSmsEmailFieldsStream;
       
   576 
       
   577 		//----------------------EOS Info  6th Field ------------------------------	
       
   578 		CFieldPair* smsdetailField = new (ELeave)CFieldPair();
       
   579 		CleanupStack::PushL(smsdetailField);
       
   580 		
       
   581 		RBuf eosbuf;
       
   582 		CleanupClosePushL(eosbuf);
       
   583 		eosbuf.CreateL(GetBufSize()); 
       
   584 		
       
   585 		// Header version	
       
   586 		eosbuf.AppendNum(KMsvSmsEmailFieldsVersion);
       
   587 		eosbuf.Append(KDelimiter);
       
   588 			
       
   589 		// AddressCount	
       
   590 		eosbuf.AppendNum(iAddresses->Count());
       
   591 		eosbuf.Append(KDelimiter);
       
   592 
       
   593 		// Addresses
       
   594 		for (TInt i=0; i<iAddresses->Count(); i++)
       
   595 			{
       
   596 			eosbuf.Append(iAddresses->MdcaPoint(i));
       
   597 			if(i<(iAddresses->MdcaCount())-1)
       
   598 				eosbuf.Append(KComma);
       
   599 			}
       
   600 		
       
   601 		eosbuf.Append(KDelimiter);
       
   602 		
       
   603 		// Subject
       
   604 		eosbuf.Append(Subject());
       
   605 		eosbuf.Append(KDelimiter);
       
   606 		
       
   607 		HBufC* newFrom1 = HBufC::NewL(eosbuf.Length());
       
   608 		newFrom1->Des().Copy(eosbuf);
       
   609 		smsdetailField->iFieldTextValue = newFrom1;
       
   610 		emailOverSmsHeaderFields->iFieldPairList.AppendL(smsdetailField);
       
   611 		
       
   612 		eosbuf.Close();
       
   613 		CleanupStack::Pop();  // Rbuf
       
   614 		CleanupStack::Pop(smsdetailField);
       
   615 
       
   616 		
       
   617 		TMsvWriteStore storeWriter(aStore);
       
   618 		storeWriter.AssignL(emailOverSmsHeaderFields);
       
   619 		storeWriter.CommitL();
       
   620 		
       
   621 		CleanupStack::Pop(emailOverSmsHeaderFields);
       
   622 		
       
   623 		}
       
   624 	else if( aStore.IsPresentL(KUidMsvSmsEmailFieldsStream) )
       
   625 		{
       
   626 		
       
   627 		CHeaderFields* emailOverSmsHeaderFields = new (ELeave)CHeaderFields();
       
   628 		CleanupStack::PushL(emailOverSmsHeaderFields);
       
   629 		emailOverSmsHeaderFields->iUid = KUidMsvSmsEmailFieldsStream;
       
   630 
       
   631 			
       
   632 		CFieldPair* smsdetailField = new (ELeave)CFieldPair();
       
   633 		CleanupStack::PushL(smsdetailField);
       
   634 		smsdetailField->iFieldTextValue = KNullDesC().AllocL();
       
   635 		emailOverSmsHeaderFields->iFieldPairList.AppendL(smsdetailField);
       
   636 		CleanupStack::Pop(smsdetailField);
       
   637 
       
   638 		TMsvWriteStore storeWriter(aStore);
       
   639 		storeWriter.AssignL(emailOverSmsHeaderFields);
       
   640 		storeWriter.CommitL();
       
   641 
       
   642 		
       
   643 		// Ok, the current email fields have no data, but the email fileds 
       
   644 		// stream exists - remove it.
       
   645 		aStore.Remove(KUidMsvSmsEmailFieldsStream);
       
   646 		
       
   647 		CleanupStack::Pop(emailOverSmsHeaderFields);
       
   648 		}
       
   649 	}
       
   650 
       
   651 /**
       
   652 To gett he Buffer size.
       
   653 */	
       
   654 	
       
   655 TInt CSmsEmailFields::GetBufSize()
       
   656 	{
       
   657 	TInt size  = 0;
       
   658 	
       
   659 	size += sizeof(KMsvSmsEmailFieldsVersion) + 1;  // 1 is for Delimiter
       
   660 	size += Subject().Length() + 1 ;
       
   661 	size += sizeof(iAddresses->Count()) + 1 ;
       
   662 	
       
   663 	for(TInt i=0; i<iAddresses->Count(); i++)
       
   664 		{
       
   665 		size += iAddresses->MdcaPoint(i).Length() + 1;  	// Extra byte for Comma
       
   666 		}
       
   667 
       
   668 	return size ;
       
   669 	
       
   670 	}
       
   671 
       
   672 
       
   673 
       
   674 /**
       
   675 Retrives the email fields from SQL DB.
       
   676 
       
   677 If the store does not contain email fields data, the current email data is reset.
       
   678 
       
   679 @param	aStore
       
   680 The store to be read.
       
   681 
       
   682 @internalComponent
       
   683 */
       
   684 
       
   685 	
       
   686 void CSmsEmailFields::ReStoreDBL(CMsvStore& aStore)
       
   687 	{
       
   688 	Reset();
       
   689 	CHeaderFields* rcvEmailHeaderRow = NULL;
       
   690 	TMsvReadStore storeReader(aStore, KUidMsvSmsEmailFieldsStream);
       
   691 	TRAPD(err, storeReader.ReadL(rcvEmailHeaderRow));
       
   692 	
       
   693 	if(KErrNotFound == err)
       
   694 		{
       
   695 		return;
       
   696 		}
       
   697 	
       
   698 	TInt i = 0;  //SMS Email over SMS 	
       
   699 	HBufC* 	eosheaderinfo = rcvEmailHeaderRow->iFieldPairList[i++]->iFieldTextValue ;
       
   700 	TPtr16 eosheaderPtr = (eosheaderinfo->Des());	
       
   701 
       
   702 	//Parsing the eos string 
       
   703 	TInt firstSemiColonPos = eosheaderPtr.Locate(';');
       
   704 	TInt lastSemiColonPos = eosheaderPtr.LocateReverse(';');
       
   705 
       
   706 	RPointerArray<HBufC16> eosinfoData;
       
   707 	CleanupClosePushL(eosinfoData);
       
   708 	TInt ii = 0 ;
       
   709 
       
   710 	do
       
   711 		{
       
   712 		TPtrC16 str1 = eosheaderPtr.Left(firstSemiColonPos); // First data
       
   713 		HBufC16* tt = str1.AllocLC();
       
   714 		firstSemiColonPos++;
       
   715 		eosinfoData.AppendL(tt); 
       
   716 		CleanupStack::Pop();
       
   717 		
       
   718 		if(firstSemiColonPos != lastSemiColonPos)
       
   719 			{
       
   720 			eosheaderPtr = (eosheaderPtr.Mid(firstSemiColonPos,eosheaderPtr.Length()-(firstSemiColonPos) ));
       
   721 			firstSemiColonPos = eosheaderPtr.Locate(';');
       
   722 			lastSemiColonPos = eosheaderPtr.LocateReverse(';');
       
   723 			if(firstSemiColonPos == lastSemiColonPos)
       
   724 				{
       
   725 				TPtrC16 str1 = eosheaderPtr.Left(eosheaderPtr.Length() -1); // Last data is Subject . End with Semicolon. -1 is to remove semicolon.
       
   726 				HBufC16* tt = str1.AllocLC();
       
   727 				eosinfoData.AppendL(tt);
       
   728 				CleanupStack::Pop(); 
       
   729 				}
       
   730 			}
       
   731 		else
       
   732 			{
       
   733 			//Empty field.
       
   734 			HBufC16* tt = KNullDesC().AllocLC();
       
   735 			eosinfoData.AppendL(tt);
       
   736 			CleanupStack::Pop(); 
       
   737 			}
       
   738 		
       
   739 		ii++;	
       
   740 		}while(firstSemiColonPos != lastSemiColonPos);
       
   741 
       
   742 	TInt16 headerversion = ConvertToTInt(*eosinfoData[0]);
       
   743 	
       
   744 	TInt count = ConvertToTInt(*eosinfoData[1]);
       
   745 	
       
   746 	if(count > 0)
       
   747 		{
       
   748 		_LIT16(KSemicolon, ";");
       
   749 		HBufC16* addressesList = eosinfoData[2]->Des().AllocLC();
       
   750 		addressesList = addressesList->ReAllocL(addressesList->Length()+2);
       
   751 		TPtr16 addressesListPtr = (addressesList->Des());
       
   752 		addressesListPtr.Append(KSemicolon);
       
   753 		GetRecipientListL(addressesListPtr);
       
   754 		CleanupStack::PopAndDestroy();
       
   755 		}
       
   756 	else
       
   757 		{
       
   758 		AddAddressL(KNullDesC16);
       
   759 		}
       
   760 	
       
   761 	iSubject = eosinfoData[3]->Des().AllocL();
       
   762 	
       
   763 	
       
   764 	eosinfoData.ResetAndDestroy();
       
   765 	CleanupStack::PopAndDestroy();   //RPointerArray	
       
   766 	}
       
   767 
       
   768  /* Convert a String to an Integer.
       
   769  * @param aStr A string to make Integer.
       
   770  * @return TInt A integer value 
       
   771  */
       
   772 TInt CSmsEmailFields::ConvertToTInt(TDesC16& aStr)
       
   773 	{
       
   774 	TLex str(aStr);
       
   775 	TInt32 string;
       
   776 	str.Val(string);
       
   777 	return string;
       
   778 	}
       
   779 
       
   780 /**
       
   781 To parse the recipient address list.
       
   782 */
       
   783 
       
   784 void CSmsEmailFields::GetRecipientListL(TDesC16& aStr)
       
   785 	{
       
   786 	TPtrC16 recvstr = aStr;
       
   787 	
       
   788 	if(KErrNotFound != recvstr.Locate(',') )
       
   789 		{ // It has multipule recipient list is :-  example@nokia.com, example@nokia.com,example@nokia.com;
       
   790 		TInt startPos = recvstr.Locate(',') ;
       
   791 		while(1)
       
   792 			{
       
   793 			TPtrC16 partstrx = recvstr.Left(startPos);
       
   794 			AddAddressL(partstrx);
       
   795 			startPos++;
       
   796 			recvstr.Set(recvstr.Mid(startPos, recvstr.Length()- startPos));
       
   797 		
       
   798 			startPos = recvstr.Locate(',');
       
   799 			if(startPos == KErrNotFound)
       
   800 				{
       
   801 				TPtrC16 partstrxy;
       
   802 				partstrxy.Set(recvstr.Mid(0,recvstr.Length()-1));
       
   803 				AddAddressL(partstrxy);
       
   804 				break;
       
   805 				}
       
   806 			}
       
   807 		
       
   808 		}
       
   809 	else  // It has one recipient  list is like this->  example@nokia.com;
       
   810 		{
       
   811 		TInt lastpos = recvstr.Locate(';');	
       
   812 		TPtrC16 partstrx = recvstr.Left(lastpos);
       
   813 		AddAddressL(partstrx);
       
   814 		}
       
   815 	}
       
   816 #endif