messagingfw/msgsrvnstore/server/src/MSVIPC.CPP
changeset 62 db3f5fa34ec7
equal deleted inserted replaced
60:9f5ae1728557 62:db3f5fa34ec7
       
     1 // Copyright (c) 1998-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 <s32std.h>
       
    17 
       
    18 #include "MSVIPC.H"
       
    19 #include "MSVIDS.H"
       
    20 #include "MSVPANIC.H"
       
    21 
       
    22 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    23 #include "msvsearchsortconstants.h"
       
    24 #include "msvconsts.h"
       
    25 #endif
       
    26 
       
    27 GLDEF_C void DoUnpackEntry(TUint8*& aPtr, TMsvEntry& aEntry)
       
    28 //
       
    29 //
       
    30 //
       
    31 	{
       
    32 	// get the entry from the start of the buffer
       
    33 	const TMsvEntry* pEntry = (TMsvEntry*) aPtr;
       
    34 	aEntry = *pEntry;
       
    35 	aPtr = Align4(aPtr + sizeof(TMsvEntry));
       
    36 
       
    37 	const TText* textPtr = (TText*)aPtr;
       
    38 	TInt length=aEntry.iDescription.Length();
       
    39 	aEntry.iDescription.Set(textPtr, length);
       
    40 	textPtr = Align4(textPtr + length);
       
    41 
       
    42 	length=aEntry.iDetails.Length();
       
    43 	aEntry.iDetails.Set(textPtr, length);
       
    44 	textPtr = Align4(textPtr + length);
       
    45 
       
    46 	aPtr = (TUint8*) textPtr;
       
    47 	}
       
    48 	
       
    49 
       
    50 GLDEF_C TInt DoPackEntry(const TUint8*& aPtrStart, const TUint8* aPtrEnd, const TMsvEntry& aEntry)
       
    51 //
       
    52 // Packs an entry into the memory area defined by the two pointers.
       
    53 // Fails with KErrOverflow if the packed entry is too large
       
    54 // aPtrStart is always returned pointing to the end of the packed entry (even if too large)
       
    55 //
       
    56 	{
       
    57 	// make sure the entry can fit into the memory area defined by the two pointers
       
    58 	TInt sizeEntry = Align4(sizeof(TMsvEntry));
       
    59 	TInt sizeString1 = Align4(aEntry.iDescription.Size());
       
    60 	TInt sizeString2 = Align4(aEntry.iDetails.Size());
       
    61 	TInt size =  sizeEntry + sizeString1 + sizeString2;
       
    62 	if ((aPtrStart + size)>aPtrEnd)
       
    63 		{
       
    64 		aPtrStart += size;
       
    65 		return KErrOverflow;
       
    66 		}
       
    67 		
       
    68 	// copy the entry and descriptors into the memory area
       
    69 	Mem::Copy((void*)aPtrStart, &aEntry, sizeof(TMsvEntry));
       
    70 	aPtrStart += sizeEntry;
       
    71 
       
    72 	Mem::Copy((void*)aPtrStart, aEntry.iDescription.Ptr(), aEntry.iDescription.Size());
       
    73 	aPtrStart += sizeString1;
       
    74 	
       
    75 	Mem::Copy((void*)aPtrStart, aEntry.iDetails.Ptr(), aEntry.iDetails.Size());
       
    76 	aPtrStart += sizeString2;
       
    77 	
       
    78 	return KErrNone;
       
    79 	}
       
    80 	
       
    81 	
       
    82 GLDEF_C void DoUnpackFilter(TUint8*& aPtr, CMsvEntryFilter& aFilter)
       
    83 //
       
    84 //
       
    85 //
       
    86 	{
       
    87 	// get the entry from the start of the buffer
       
    88 	const CMsvEntryFilter* pFilter = (CMsvEntryFilter*) aPtr;
       
    89 	Mem::Copy(&aFilter, pFilter, sizeof(CMsvEntryFilter));
       
    90 	aPtr = Align4(aPtr + sizeof(CMsvEntryFilter));
       
    91 	}
       
    92 
       
    93 
       
    94 GLDEF_C TInt DoPackFilter(const TUint8*& aPtrStart, const TUint8* aPtrEnd, const CMsvEntryFilter& aFilter)
       
    95 //
       
    96 //
       
    97 //
       
    98 	{
       
    99 	// make sure the entry can fit into the memory area defined by the two pointers
       
   100 	TInt size = Align4(sizeof(CMsvEntryFilter));
       
   101 	if ((aPtrStart + size)>aPtrEnd)
       
   102 		{
       
   103 		aPtrStart += size;
       
   104 		return KErrOverflow;
       
   105 		}
       
   106 		
       
   107 	// copy the filter into the memory area
       
   108 	Mem::Copy((void*)aPtrStart, &aFilter, sizeof(CMsvEntryFilter));
       
   109 	aPtrStart += size;
       
   110 	
       
   111 	return KErrNone;
       
   112 	}
       
   113 
       
   114 //**********************************
       
   115 // TMsvPackedEntry
       
   116 //**********************************
       
   117 
       
   118 
       
   119 EXPORT_C TMsvPackedEntry::TMsvPackedEntry(HBufC8*& aBuffer)
       
   120 : iBuffer(aBuffer)
       
   121 	{}
       
   122 
       
   123 EXPORT_C TInt TMsvPackedEntry::PackEntry(const TMsvEntry& aEntry)
       
   124 //
       
   125 //
       
   126 //
       
   127 	{
       
   128 	// find the start and end of the buffer
       
   129 	const TUint8* pS = iBuffer->Ptr();
       
   130 	const TUint8* pE = PtrAdd(pS, iBuffer->Des().MaxSize());
       
   131 
       
   132 	TInt error = DoPackEntry(pS, pE, aEntry);
       
   133 	if (error==KErrNone)
       
   134 		{
       
   135 		// update the length of the buffer
       
   136 		iBuffer->Des().SetLength(pS-iBuffer->Ptr());
       
   137 		}
       
   138 
       
   139 	return error;
       
   140 	}
       
   141 
       
   142 EXPORT_C void TMsvPackedEntry::UnpackEntry(TMsvEntry& aEntry)
       
   143 //
       
   144 //
       
   145 //
       
   146 	{
       
   147 #if defined(_DEBUG)
       
   148 	// check that the buffer contain a valid package
       
   149 	const TMsvEntry* dEntry = (TMsvEntry*) iBuffer->Ptr();
       
   150 	const TUint8* dPos = PtrAdd(iBuffer->Ptr(), Align4(sizeof(TMsvEntry)) + Align4(dEntry->iDescription.Size()) + Align4(dEntry->iDetails.Size()));
       
   151 	__ASSERT_DEBUG(dPos <= PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvEntryOverrunBuffer));
       
   152 #endif
       
   153 	
       
   154 	TUint8* pS = CONST_CAST(TUint8*, iBuffer->Ptr());
       
   155 	DoUnpackEntry(pS, aEntry);
       
   156 	}
       
   157 
       
   158 TInt TMsvPackedEntry::PackEntryAndService(const TMsvEntry& aEntry, const TMsvId& aServiceId)
       
   159     {
       
   160     // find the start and end of the buffer
       
   161     const TUint8* pS = iBuffer->Ptr();
       
   162     const TUint8* pE = PtrAdd(pS, iBuffer->Des().MaxSize());
       
   163 
       
   164     TInt error = DoPackEntry(pS, pE, aEntry);
       
   165     if (error==KErrNone)
       
   166         {
       
   167         TInt sizeDes = Align4(sizeof(TMsvId));
       
   168         if ((pS + sizeDes)>pE)
       
   169             {
       
   170             return KErrOverflow;
       
   171             }            
       
   172         // copy the entry and descriptors into the memory area
       
   173         Mem::Copy((void*)pS, &aServiceId, sizeof(TMsvId));
       
   174         pS += sizeDes;
       
   175 
       
   176         // update the length of the buffer
       
   177         iBuffer->Des().SetLength(pS-iBuffer->Ptr());
       
   178         }
       
   179 
       
   180     return error;    
       
   181     }
       
   182 
       
   183 void TMsvPackedEntry::UnpackEntryAndService(TMsvEntry& aEntry, TMsvId& aServiceId)
       
   184     {
       
   185 #if defined(_DEBUG)
       
   186     // check that the buffer contain a valid package
       
   187     const TMsvEntry* dEntry = (TMsvEntry*) iBuffer->Ptr();
       
   188     const TUint8* dPos = PtrAdd(iBuffer->Ptr(), Align4(sizeof(TMsvEntry)) + Align4(dEntry->iDescription.Size()) + Align4(dEntry->iDetails.Size()) + Align4(sizeof(TMsvId)) );
       
   189     __ASSERT_DEBUG(dPos <= PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvEntryOverrunBuffer));
       
   190 #endif
       
   191     
       
   192     TUint8* pS = CONST_CAST(TUint8*, iBuffer->Ptr());
       
   193     DoUnpackEntry(pS, aEntry);
       
   194 
       
   195     // get the service id from the current position in the buffer
       
   196     const TMsvId* pServiceId = (TMsvId*)pS;
       
   197     aServiceId = *pServiceId;
       
   198     pS = Align4(pS + sizeof(TMsvId));
       
   199     }
       
   200 
       
   201 //**********************************
       
   202 // TMsvPackedEntryArray
       
   203 //**********************************
       
   204 
       
   205 
       
   206 EXPORT_C TMsvPackedEntryArray::TMsvPackedEntryArray(HBufC8*& aBuffer, TInt aCount)
       
   207 : iIndex(0), iCount(aCount), iBuffer(aBuffer) 
       
   208 	{
       
   209 	iPos = iBuffer->Ptr();
       
   210 	}
       
   211 
       
   212 
       
   213 EXPORT_C void TMsvPackedEntryArray::Reset()
       
   214 //
       
   215 //
       
   216 //
       
   217 	{
       
   218 	iBuffer->Des().SetLength(0);
       
   219 	iPos  = iBuffer->Ptr();
       
   220 	iIndex=0;
       
   221 	iCount=0;
       
   222 	}
       
   223 
       
   224 EXPORT_C TInt TMsvPackedEntryArray::PackEntry(const TMsvEntry& aEntry)
       
   225 //
       
   226 //
       
   227 //
       
   228 	{
       
   229 	const TUint8* pS = iPos;
       
   230 	const TUint8* pE = PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxSize());
       
   231 
       
   232 	TInt error = DoPackEntry(pS, pE, aEntry);
       
   233 	if (error==KErrNone)
       
   234 		{
       
   235 		// update the length of the buffer and the position for the next entry
       
   236 		iBuffer->Des().SetLength(pS-iBuffer->Ptr());
       
   237 		iPos = pS;
       
   238 		iIndex++;
       
   239 		iCount++;
       
   240 		}
       
   241 	
       
   242 	return error;
       
   243 	}
       
   244 
       
   245 EXPORT_C TInt TMsvPackedEntryArray::UnpackEntry(TInt aIndex, TMsvEntry& aEntry)
       
   246 //
       
   247 //
       
   248 //
       
   249 	{
       
   250 	TInt error=KErrNone;
       
   251 
       
   252 	if (iIndex!=aIndex)
       
   253 		error = FindEntryInArray(aIndex);
       
   254 
       
   255 	if (error==KErrNone)
       
   256 		{
       
   257 		TUint8* pS=CONST_CAST(TUint8*, iPos);
       
   258 		DoUnpackEntry(pS, aEntry);
       
   259 		iPos=pS;
       
   260 		iIndex++;
       
   261 		}	
       
   262 
       
   263 	return error;
       
   264 	}
       
   265 
       
   266 
       
   267 TInt TMsvPackedEntryArray::FindEntryInArray(TInt aIndex)
       
   268 //
       
   269 //
       
   270 //
       
   271 	{
       
   272 	if (aIndex>=iCount)
       
   273 		return KErrNotFound;
       
   274 
       
   275 	if (iIndex>aIndex)
       
   276 		{
       
   277 		// have to reset to the start of the buffer
       
   278 		iPos = iBuffer->Ptr();
       
   279 		iIndex=0;
       
   280 		}
       
   281 
       
   282 	while (iIndex!=aIndex)
       
   283 		{
       
   284 		const TMsvEntry* pEntry = (TMsvEntry*) iPos;
       
   285 		iPos += Align4(sizeof(TMsvEntry)) + Align4(pEntry->iDescription.Size()) + Align4(pEntry->iDetails.Size());
       
   286 		iIndex++;
       
   287 		}
       
   288 
       
   289 	__ASSERT_DEBUG(iPos < PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvPointerOverrunBuffer));
       
   290 
       
   291 	return KErrNone;
       
   292 	}
       
   293 
       
   294 
       
   295 
       
   296 //**********************************
       
   297 // TMsvMoveCopyDetails
       
   298 //**********************************
       
   299 
       
   300 EXPORT_C TMsvLocalOperationProgress::TMsvLocalOperationProgress()
       
   301 : iType(ELocalNone), iTotalNumberOfEntries(0), iNumberCompleted(0), iNumberFailed(0), iNumberRemaining(0), iError(KErrNone), iId(KMsvNullIndexEntryId)
       
   302 /** Initialises the new object to suitable zero or null values. */
       
   303 	{
       
   304 	}
       
   305 
       
   306 //**********************************
       
   307 // TMsvServerOperationProgress
       
   308 //**********************************
       
   309 
       
   310 EXPORT_C TMsvServerOperationProgress::TMsvServerOperationProgress()
       
   311 : iOperationType(EMsvNoOperation)
       
   312 /** Default constructor.
       
   313 
       
   314 Sets iOperationType to EMsvNoOperation. */
       
   315 	{
       
   316 	}
       
   317 
       
   318 TMsvServerOperationProgress::TMsvServerOperationProgress(TMsvServerOperationType aType)
       
   319 : iOperationType(aType)
       
   320 	{
       
   321 	}
       
   322 
       
   323 //**********************************
       
   324 // TMsvIndexProgress
       
   325 //**********************************
       
   326 
       
   327 EXPORT_C TMsvIndexProgress::TMsvIndexProgress()
       
   328 : iTotal(0), iCompleted(0), iRemaining(0), iId(KMsvNullIndexEntryId)
       
   329 /** Default constructor.
       
   330 
       
   331 Data members are intialised to 0 or KMsvNullIndexEntryId as appropriate. */
       
   332 	{
       
   333 	}
       
   334 
       
   335 //**********************************
       
   336 // TMsvIndexLoadProgress
       
   337 //**********************************
       
   338 
       
   339 EXPORT_C TMsvIndexLoadProgress::TMsvIndexLoadProgress()
       
   340 : TMsvServerOperationProgress(EMsvChangeDriveOperation), iError(KErrNone), iState(EIndexNotLoaded)
       
   341 /** Default constructor.
       
   342 
       
   343 iOperationType is set to EMsvChangeDriveOperation; iError is set to KErrNone; 
       
   344 iState is set to EIndexNotLoaded. */
       
   345 	{
       
   346 	}
       
   347 	
       
   348 	
       
   349 	
       
   350 //**********************************
       
   351 // TMsvCopyProgress
       
   352 //**********************************
       
   353 
       
   354 /** Default constructor.
       
   355 iOperationType is set to EMsvCopyOperation; iError is set to KErrNone; 
       
   356 iState is set to ENotYetStarted. */  
       
   357 
       
   358 EXPORT_C TMsvCopyProgress::TMsvCopyProgress()
       
   359 : TMsvServerOperationProgress(EMsvCopyOperation), iError(KErrNone), iState(ENotYetStarted)
       
   360 	{
       
   361 	}
       
   362 
       
   363 
       
   364 //**********************************
       
   365 // TMsvDeleteProgress
       
   366 //**********************************
       
   367 
       
   368 /** Default constructor.
       
   369 iOperationType is set to EMsvDeleteOperation; iError is set to KErrNone; 
       
   370 iState is set to ENotYetStarted. */
       
   371 
       
   372 EXPORT_C TMsvDeleteProgress::TMsvDeleteProgress()
       
   373 : TMsvServerOperationProgress(EMsvDeleteOperation), iError(KErrNone), iState(ENotYetStarted)
       
   374 
       
   375 	{
       
   376 	}
       
   377 
       
   378 
       
   379 //**********************************
       
   380 // TMsvChildrenDetails
       
   381 //**********************************
       
   382 
       
   383 EXPORT_C TMsvChildrenDetails::TMsvChildrenDetails()
       
   384 : iParentId(KMsvNullIndexEntryId), iTotalNumberChildren(0), iNumberChildrenInArray(0), iLastEntryInArray(0)
       
   385 	{
       
   386 	}
       
   387 
       
   388 
       
   389 //**********************************
       
   390 // TMsvPackedOperation
       
   391 //**********************************
       
   392 
       
   393 EXPORT_C TMsvPackedOperation::TMsvPackedOperation(HBufC8*& aBuffer)
       
   394 : iBuffer(aBuffer)
       
   395 	{
       
   396 	}
       
   397 
       
   398 
       
   399 EXPORT_C TInt TMsvPackedOperation::Pack(const CMsvEntrySelection& aSelection, TInt aParameter1, TInt aParameter2)
       
   400 	{
       
   401 	// check the buffer is large enough
       
   402 	TInt requiredSize = (aSelection.Count()+3)*4;
       
   403 	if (requiredSize>iBuffer->Des().MaxSize())
       
   404 		return KErrOverflow;
       
   405 	// set the buffer with correct length
       
   406 	iBuffer->Des().SetLength(requiredSize);
       
   407 
       
   408 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
   409 	*ptr++ = aSelection.Count();
       
   410 	for (TInt count=0; count<aSelection.Count(); count++)
       
   411 		*ptr++ = aSelection.At(count);
       
   412 	*ptr++ = aParameter1;
       
   413 	*ptr++ = aParameter2;
       
   414 	return KErrNone;
       
   415 	}
       
   416 
       
   417 
       
   418 EXPORT_C void TMsvPackedOperation::UnpackL(CMsvEntrySelection& aSelection, TInt& aParameter1, TInt& aParameter2)
       
   419 	{
       
   420 	__ASSERT_DEBUG(aSelection.Count()==0, PanicServer(EMsvOperationUnpackSelectionNotEmpty));	
       
   421 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
   422 
       
   423 	TInt count = *ptr++;
       
   424 	
       
   425 	TInt bufSize = iBuffer->Des().Length();
       
   426 	
       
   427 	// This length is calculated on the basis of length set in TMsvPackedOperation::Pack above.
       
   428 	TInt len = (count+3)*4; 
       
   429 	if(bufSize == len)	
       
   430 		{
       
   431 		while (count--)
       
   432 			{
       
   433 			aSelection.AppendL(*ptr++);
       
   434 			}
       
   435 		aParameter1 = *ptr++;
       
   436 		aParameter2 = *ptr++;
       
   437 		}
       
   438 	else
       
   439 		{
       
   440 		User::Leave(KErrArgument);
       
   441 		}
       
   442 	}
       
   443 
       
   444 
       
   445 EXPORT_C TMsvPackedChangeNotification::TMsvPackedChangeNotification(TMsvNotifBuffer& aBuffer)
       
   446 : iBuffer(aBuffer)
       
   447 	{
       
   448 	}
       
   449 
       
   450 
       
   451 EXPORT_C void TMsvPackedChangeNotification::Pack(TMsvServerChangeNotificationType aChangeType, const CMsvEntrySelection& aSelection, TInt aParameter1, TInt aParameter2, TInt aStartIndex, TInt aFinishIndex)
       
   452 //
       
   453 // Packs the aStartIndex->aFinishIndex (inc) into the buffer
       
   454 //
       
   455 	{
       
   456 	__ASSERT_DEBUG(aFinishIndex-aStartIndex+1<=KMsvPackedChangeLimit, PanicServer(EMsvChangeSelectionTooLarge));
       
   457 
       
   458 	// set the buffer with correct length
       
   459 	TInt requiredSize = (aFinishIndex-aStartIndex+1+KMsvChangeNotificationNumberOfTInts)*4;
       
   460 	iBuffer.SetLength(requiredSize);
       
   461 
       
   462 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer.Ptr());
       
   463 	*ptr++ = aChangeType;
       
   464 	*ptr++ = aParameter1;
       
   465 	*ptr++ = aParameter2;
       
   466 	*ptr++ = aFinishIndex - aStartIndex + 1;
       
   467 	for (TInt count=aStartIndex; count<=aFinishIndex; count++)
       
   468 		*ptr++ = aSelection.At(count);
       
   469 	}
       
   470 
       
   471 
       
   472 EXPORT_C void TMsvPackedChangeNotification::Pack(TMsvServerChangeNotificationType aChangeType, TMsvId aId, TInt aParameter1, TInt aParameter2)
       
   473 //
       
   474 // Packs a single id
       
   475 //
       
   476 	{
       
   477 	// set the buffer with correct length
       
   478 	TInt requiredSize = (1+KMsvChangeNotificationNumberOfTInts)*4;
       
   479 	iBuffer.SetLength(requiredSize);
       
   480 
       
   481 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer.Ptr());
       
   482 	*ptr++ = aChangeType;
       
   483 	*ptr++ = aParameter1;
       
   484 	*ptr++ = aParameter2;
       
   485 	*ptr++ = 1;
       
   486 	*ptr++ = aId;
       
   487 	}
       
   488 
       
   489 
       
   490 EXPORT_C void TMsvPackedChangeNotification::UnpackL(TMsvServerChangeNotificationType& aChangeType, CMsvEntrySelection& aSelection, TInt& aParameter1, TInt& aParameter2)
       
   491 //
       
   492 //
       
   493 //
       
   494 	{
       
   495 	__ASSERT_DEBUG(aSelection.Count()==0, PanicServer(EMsvChangedUnpackSelectionNotEmpty));	
       
   496 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer.Ptr());
       
   497 	switch (*ptr++)
       
   498 		{
       
   499 		case 1:
       
   500 			aChangeType = EMsvEntriesCreated;
       
   501 			break;
       
   502 		case 2:
       
   503 			aChangeType = EMsvEntriesChanged;
       
   504 			break;
       
   505 		case 3:
       
   506 			aChangeType = EMsvEntriesDeleted;
       
   507 			break;
       
   508 		case 4:
       
   509 			aChangeType = EMsvEntriesMoved;
       
   510 			break;
       
   511 		case 5:
       
   512 			aChangeType = EMsvMtmGroupInstalled;
       
   513 			break;
       
   514 		case 6:
       
   515 			aChangeType = EMsvMtmGroupDeInstalled;
       
   516 			break;
       
   517 		case 8:
       
   518 			aChangeType = EMsvCloseSession;
       
   519 			break;
       
   520 		case 9:
       
   521 			aChangeType = EMsvIndexLoaded;
       
   522 			break;
       
   523 		case 10:
       
   524 			aChangeType = EMsvIndexFailedToLoad;
       
   525 			break;
       
   526 		case 12:
       
   527 			aChangeType = EMsvMediaChanged;
       
   528 			break;
       
   529 		case 13:
       
   530 			aChangeType = EMsvMediaUnavailable;
       
   531 			break;
       
   532 		case 14:
       
   533 			aChangeType = EMsvMediaAvailable;
       
   534 			break;
       
   535 		case 15:
       
   536 			aChangeType = EMsvMediaIncorrect;
       
   537 			break;
       
   538 #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
   539 		case 16:
       
   540 			aChangeType = EMsvMessageStoreNotSupported;
       
   541 			break;
       
   542 		case 17:
       
   543 			aChangeType = EMsvMessageStoreCorrupt;
       
   544 			break;
       
   545 		case 18:
       
   546 			aChangeType = EMsvRefreshMessageView;
       
   547 			break;
       
   548 		case 19:
       
   549 			aChangeType = EMsvDiskNotAvailable;
       
   550 			break;
       
   551 		case 20:
       
   552 			aChangeType = EMsvUnableToProcessDiskNotification;
       
   553 			break;
       
   554 #endif	
       
   555 		default:
       
   556 			__ASSERT_DEBUG(EFalse, PanicServer(EMsvUnknownChangeType));
       
   557 			aChangeType = EMsvEntriesNoChange;
       
   558 		}
       
   559 	aParameter1 = *ptr++;
       
   560 	aParameter2 = *ptr++;
       
   561 	TInt count = *ptr++;
       
   562 	while (count--)
       
   563 		aSelection.AppendL(*ptr++);
       
   564 	}
       
   565 
       
   566 TMsvPackedEntryFilter::TMsvPackedEntryFilter(HBufC8*& aBuffer)
       
   567 : iBuffer(aBuffer)
       
   568 	{}
       
   569 
       
   570 TInt TMsvPackedEntryFilter::PackFilter(const CMsvEntryFilter& aFilter)
       
   571 	{
       
   572 	// find the start and end of the buffer
       
   573 	const TUint8* pS = iBuffer->Ptr();
       
   574 	const TUint8* pE = PtrAdd(pS, iBuffer->Des().MaxSize());
       
   575 
       
   576 	TInt error = DoPackFilter(pS, pE, aFilter);
       
   577 	if (error==KErrNone)
       
   578 		{
       
   579 		// update the length of the buffer
       
   580 		iBuffer->Des().SetLength(pS-iBuffer->Ptr());
       
   581 		}
       
   582 
       
   583 	return error;
       
   584 	}
       
   585 
       
   586 void TMsvPackedEntryFilter::UnpackFilter(CMsvEntryFilter& aFilter)
       
   587 	{
       
   588 #if defined(_DEBUG)
       
   589 	// check that the buffer contain a valid package
       
   590 	const TUint8* dPos = PtrAdd(iBuffer->Ptr(), Align4(sizeof(CMsvEntryFilter)));
       
   591 	__ASSERT_DEBUG(dPos <= PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvEntryOverrunBuffer));
       
   592 #endif	
       
   593 	TUint8* pS = CONST_CAST(TUint8*, iBuffer->Ptr());
       
   594 	DoUnpackFilter(pS, aFilter);
       
   595 	}
       
   596 
       
   597 /**
       
   598 Constructor for TMsvPackQuery.
       
   599 @internalComponent
       
   600 @released
       
   601 @param aBuffer: buffer for packing
       
   602 */
       
   603 
       
   604 EXPORT_C TMsvPackQuery::TMsvPackQuery(HBufC8*& aBuffer)
       
   605 : iBuffer(aBuffer)
       
   606 	{}
       
   607 
       
   608 
       
   609 TInt TMsvPackQuery::DoPackQuery(const TUint8*& aPtrStart, const TUint8* aPtrEnd, const CMsvSearchSortQuery* aQuery)
       
   610 	{
       
   611 	//size of class - sizeof(iQueryTable pointer)
       
   612 	TInt sizeOfClass = Align4(sizeof(CMsvSearchSortQuery) - sizeof(TInt));
       
   613 	TInt sizeQueryTable = Align4(sizeof(TMsvQueryTable) * KMaxLevelOfSearchAndSort);
       
   614 	TInt size = sizeOfClass + sizeQueryTable;
       
   615 	
       
   616 	if ((aPtrStart + size)>aPtrEnd)
       
   617 		{
       
   618 		aPtrStart += size;
       
   619 		return KErrOverflow;
       
   620 		}
       
   621 		
       
   622 	// copy the entry and descriptors into the memory area
       
   623 	Mem::Copy((void*)aPtrStart, aQuery, sizeOfClass);
       
   624 	aPtrStart += sizeOfClass;
       
   625 
       
   626 	Mem::Copy((void*)aPtrStart, aQuery->iQueryTable, sizeQueryTable);
       
   627 	aPtrStart += sizeQueryTable;
       
   628 
       
   629 	return KErrNone;
       
   630 	}
       
   631 
       
   632 /**
       
   633 Packs TMsvSearchSortQuery object into a buffer for sending across IPC. 
       
   634 @internalComponent
       
   635 @released
       
   636 @param aQuery: TMsvSearchSortQuery object needs to pack.
       
   637 @return: reurn KErrNone if successful else KErrOverflow.
       
   638 */
       
   639 EXPORT_C TInt TMsvPackQuery::PackQuery(const CMsvSearchSortQuery* aQuery)
       
   640 	{
       
   641 	// find the start and end of the buffer
       
   642 	const TUint8* pS = iBuffer->Ptr();
       
   643 	const TUint8* pE = PtrAdd(pS, iBuffer->Des().MaxSize());
       
   644 
       
   645 	TInt error = DoPackQuery(pS, pE, aQuery);
       
   646 	if (error==KErrNone)
       
   647 		{
       
   648 		// update the length of the buffer
       
   649 		iBuffer->Des().SetLength(pS-iBuffer->Ptr());
       
   650 		}
       
   651 	return error;
       
   652 	}
       
   653 	
       
   654 
       
   655 void TMsvPackQuery::DoUnpackQuery(TUint8*& aPtr, CMsvSearchSortQuery* aQuery)
       
   656 	{
       
   657 	//size of class - sizeof(iQueryTable pointer)
       
   658 	TInt sizeOfClass = Align4(sizeof(CMsvSearchSortQuery) - sizeof(TInt));
       
   659 	TInt sizeQueryTable = Align4(sizeof(TMsvQueryTable) * KMaxLevelOfSearchAndSort);
       
   660 	
       
   661 	Mem::Copy((void*)aQuery, aPtr, sizeOfClass);
       
   662 	aPtr += sizeOfClass;
       
   663 	
       
   664 	Mem::Copy((void*)aQuery->iQueryTable, aPtr, sizeQueryTable);
       
   665 	aPtr += sizeQueryTable;
       
   666 	}	
       
   667 
       
   668 /**
       
   669 Unpacks the data to a aQuery.
       
   670 @internalComponent
       
   671 @released
       
   672 @param aQuery: Unpacked TMsvSearchSortQuery object.
       
   673 */
       
   674 EXPORT_C void TMsvPackQuery::UnpackQuery(CMsvSearchSortQuery* aQuery)
       
   675 	{
       
   676 #if defined(_DEBUG)
       
   677 	// check that the buffer contain a valid package
       
   678 	const TUint8* dPos = PtrAdd(iBuffer->Ptr(), Align4(sizeof(CMsvSearchSortQuery)));
       
   679 	__ASSERT_DEBUG(dPos <= PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvEntryOverrunBuffer));
       
   680 #endif
       
   681 	
       
   682 	TUint8* pS = CONST_CAST(TUint8*, iBuffer->Ptr());
       
   683 	DoUnpackQuery(pS, aQuery);
       
   684 	}
       
   685 
       
   686 /**
       
   687 Constructor for TMsvPackedIdOperation.
       
   688 @internalComponent
       
   689 @released
       
   690 @param aBuffer: buffer for packing
       
   691 */
       
   692 EXPORT_C TMsvPackedIdOperation::TMsvPackedIdOperation(HBufC8*& aBuffer)
       
   693 : iBuffer(aBuffer)
       
   694 	{
       
   695 	}
       
   696 
       
   697 /**
       
   698 Packs RArray of TMsvId and count value into a buffer for sending across IPC. 
       
   699 @internalComponent
       
   700 @released
       
   701 @param aId: RArray of TMsvIds needs to pack.
       
   702 @return: reurn KErrNone if successful else KErrOverflow.
       
   703 */
       
   704 EXPORT_C TInt TMsvPackedIdOperation::Pack(const RArray<TMsvId>& aId)
       
   705 	{
       
   706 	//place for TMsvId's and count
       
   707 	TInt requiredSize = (aId.Count() + 1) * 4;
       
   708 	
       
   709 	// check the buffer is large enough
       
   710 	if (requiredSize > iBuffer->Des().MaxSize())
       
   711 		{
       
   712 		return KErrOverflow;
       
   713 		}
       
   714 		
       
   715 	// set the buffer with correct length
       
   716 	iBuffer->Des().SetLength(requiredSize);
       
   717 	
       
   718 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
   719 	//number of TMsvId's
       
   720 	*ptr++ = aId.Count();
       
   721 	
       
   722 	//copy TMsvId's to buffer 	
       
   723 	for (TInt count=0; count<aId.Count(); count++)
       
   724 		{
       
   725 		*ptr++ = aId[count];
       
   726 		}
       
   727 		
       
   728 	return KErrNone;
       
   729 	}
       
   730 
       
   731 /**
       
   732 Unpacks the data in buffer to a RArray.
       
   733 @internalComponent
       
   734 @released
       
   735 @param aId: Unpacked RArray of TMsvIds.
       
   736 */
       
   737 EXPORT_C void TMsvPackedIdOperation::UnpackL(RArray<TMsvId>& aId)
       
   738 	{
       
   739 	__ASSERT_DEBUG(aId.Count()==0, PanicServer(EMsvOperationUnpackSelectionNotEmpty));	
       
   740 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
   741 
       
   742 	//unpack the count
       
   743 	TInt count = *ptr++;
       
   744 	//unpack TMsvId's to RArray
       
   745 	while (count--)
       
   746 		{
       
   747 		aId.AppendL(*ptr++);
       
   748 		}
       
   749 	}
       
   750 
       
   751 
       
   752 /**
       
   753 Constructor for TMsvPackedIdAndMessagePart.
       
   754 @internalComponent
       
   755 @released
       
   756 */
       
   757 EXPORT_C TMsvPackedIdAndMessagePart::TMsvPackedIdAndMessagePart()
       
   758 	{
       
   759 	}
       
   760 
       
   761 /**
       
   762 Size() will returns size of the data occupied by TMsvIdWithSortField.
       
   763 @internalComponent
       
   764 @released
       
   765 @param aData: RArray of TMsvIdWithSortField.
       
   766 */	
       
   767 EXPORT_C TInt TMsvPackedIdAndMessagePart::Size(const RArray<TMsvIdWithSortField>& aData)
       
   768 	{
       
   769 	// number of TMsvId's in RArray
       
   770 	TInt count = aData.Count();
       
   771 	TInt size = 0;
       
   772 	
       
   773 	// to hold counter value
       
   774 	size += sizeof(TInt);
       
   775 	
       
   776 	// calculate length of RArray<TMsvId + SortFiled>
       
   777 	for(TInt index = 0; index < count; index++)
       
   778 		{
       
   779 		size += sizeof(TMsvId);
       
   780 		size += aData[index].iContentMessagePart.Length();
       
   781 		}
       
   782 	return size;
       
   783 	}
       
   784 
       
   785 /**
       
   786 Packs or Externalize the RArray of TMsvIdWithSortField into a aWriteStream for sending across IPC. 
       
   787 @internalComponent
       
   788 @released
       
   789 @param aWriteStream: aData will be written to aWriteStream.
       
   790 @param aData: RArray of TMsvIdWithSortField
       
   791 */	
       
   792 EXPORT_C void TMsvPackedIdAndMessagePart::ExternalizeL(RWriteStream& aWriteStream, RArray<TMsvIdWithSortField>& aData) const
       
   793 	{
       
   794 	TInt count = aData.Count();
       
   795 	aWriteStream.WriteInt32L(count);
       
   796   	
       
   797   	for(TInt index=0; index < count; ++index)
       
   798  		{
       
   799  		aWriteStream.WriteInt32L(aData[index].iMessageId);
       
   800  		aWriteStream << aData[index].iContentMessagePart;
       
   801  		}
       
   802 	}
       
   803 
       
   804 /**
       
   805 Unpacks or Internalize aReadStream buffer to RArray of TMsvIdWithSortField.
       
   806 @internalComponent
       
   807 @released
       
   808 @param aReadStream: aReadStream data will be unpacked to TMsvIdWithSortField of aData.
       
   809 @param aData: RArray of TMsvIdWithSortField
       
   810 */	
       
   811 EXPORT_C void TMsvPackedIdAndMessagePart::InternalizeL(RReadStream& aReadStream, RArray<TMsvIdWithSortField>& aData)
       
   812 	{
       
   813 	TInt count =  aReadStream.ReadInt32L();
       
   814 	
       
   815 	TMsvIdWithSortField tmsvidAndmessagepart;
       
   816 	
       
   817 	for(TInt index=0; index < count; ++index)
       
   818  		{
       
   819  		tmsvidAndmessagepart.iMessageId = aReadStream.ReadInt32L();
       
   820  		aReadStream >> tmsvidAndmessagepart.iContentMessagePart;
       
   821  		aData.AppendL(tmsvidAndmessagepart);
       
   822  		}
       
   823 	}
       
   824 
       
   825 
       
   826 #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
   827 EXPORT_C TMsvPackedDriveIdOperation::TMsvPackedDriveIdOperation(HBufC8*& aBuffer)
       
   828 : iBuffer(aBuffer)
       
   829 	{
       
   830 	}
       
   831 	
       
   832 	
       
   833 EXPORT_C void TMsvPackedDriveIdOperation::UnpackL(RArray<TDriveNumber>& aDriveNumber)
       
   834 	{
       
   835 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
   836 
       
   837 	// Unpack the count.
       
   838 	TInt count = *ptr++;
       
   839 	
       
   840 	// Append TDriveNumber
       
   841 	while (count--)
       
   842 		{
       
   843 		aDriveNumber.AppendL((TDriveNumber)*ptr++);
       
   844 		}	
       
   845 	}
       
   846 	
       
   847 	
       
   848 EXPORT_C TInt TMsvPackedDriveIdOperation::Pack(const RArray<TDriveNumber>& aDriveNumber)
       
   849 	{
       
   850 	// place for TMsvId's and count
       
   851 	TInt requiredSize = (aDriveNumber.Count() + 1) * 4;
       
   852 	
       
   853 	// check the buffer is large enough
       
   854 	if (requiredSize > iBuffer->Des().MaxSize())
       
   855 		{
       
   856 		return KErrOverflow;
       
   857 		}
       
   858 		
       
   859 	// set the buffer with correct length
       
   860 	iBuffer->Des().SetLength(requiredSize);
       
   861 	
       
   862 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
   863 	//number of TMsvId's
       
   864 	*ptr++ = aDriveNumber.Count();
       
   865 	
       
   866 	//copy TMsvId's to buffer 	
       
   867 	for (TInt count=0; count<aDriveNumber.Count(); count++)
       
   868 		{
       
   869 		*ptr++ = aDriveNumber[count];
       
   870 		}
       
   871 		
       
   872 	return KErrNone;
       
   873 	}
       
   874 
       
   875 #endif		// #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
   876 
       
   877 
       
   878 
       
   879 
       
   880 
       
   881 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   882 
       
   883 /**
       
   884  * TMsvPackedHeaderStructure()
       
   885  * 
       
   886  * TMsvPackedHeaderStructure Constructor.
       
   887  *
       
   888  * @param HBufC8*&
       
   889  * @return None.
       
   890  * @leave None.
       
   891  */	
       
   892 EXPORT_C TMsvPackedHeaderStructure::TMsvPackedHeaderStructure(HBufC8*& aBuffer)
       
   893 : iBuffer(aBuffer)
       
   894 	{
       
   895 	}
       
   896 	
       
   897 
       
   898 /**
       
   899  * UnpackL()
       
   900  * 
       
   901  * Unpacks the buffer to fill header structure.
       
   902  *
       
   903  * @param RPointerArray<CFieldPair>&: Header Structure.
       
   904  * @return None.
       
   905  * @leave KErrNoMemory
       
   906  */	
       
   907 EXPORT_C void TMsvPackedHeaderStructure::UnpackL(RPointerArray<CFieldPair>& aFieldDetails)
       
   908 	{
       
   909 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
   910 
       
   911 	// Unpack the count.
       
   912 	TInt count = *ptr++;
       
   913 
       
   914 	TInt size = 0;
       
   915 	TPtrC16 ptrBuf;	
       
   916 
       
   917 	while (count--)
       
   918 		{
       
   919 		CFieldPair* fieldPair = new(ELeave) CFieldPair();
       
   920 		CleanupStack::PushL(fieldPair);
       
   921 		size = *ptr++;
       
   922 		
       
   923 		const TText* textPtr = (TText*)ptr;
       
   924 		ptrBuf.Set(textPtr, (size/2));			// ptrBuf is 16 bits.
       
   925 		ptr += Align4(size)/sizeof(TInt);
       
   926 		
       
   927 		fieldPair->iFieldName = ptrBuf.AllocL();
       
   928 		fieldPair->iFieldType = (EFieldType) *ptr++;
       
   929 		aFieldDetails.AppendL(fieldPair);
       
   930 		CleanupStack::Pop();			// fieldPair
       
   931 		}	
       
   932 	}
       
   933 	
       
   934 
       
   935 
       
   936 /**
       
   937  * Pack()
       
   938  * 
       
   939  * Packs the header structure to a buffer.
       
   940  *
       
   941  * @param RPointerArray<CFieldPair>&: Header Structure.
       
   942  * @return TInt: KErrOverflow, if buffer does not have sufficient memory.
       
   943  */		
       
   944 EXPORT_C TInt TMsvPackedHeaderStructure::Pack(const RPointerArray<CFieldPair>& aFieldDetails)
       
   945 	{
       
   946 	TInt count = aFieldDetails.Count();
       
   947 	TInt requiredSize = 0;
       
   948 	
       
   949 	// Calculate the size of the data to be written.
       
   950 	for(TInt index=0; index<count; index++)
       
   951 		{
       
   952 		CFieldPair* fieldPair = aFieldDetails[index]; 	
       
   953 		requiredSize += Align4(fieldPair->iFieldName->Des().Size());
       
   954 		requiredSize += 8;		// 4 bytes for EFieldType and 4 bytes for size of iFieldName
       
   955 		}
       
   956 	
       
   957 	// 4 bytes are needed to store the array count.
       
   958 	requiredSize += 4;
       
   959 	if(requiredSize > iBuffer->Des().MaxSize())
       
   960 		{
       
   961 		return KErrOverflow;
       
   962 		}
       
   963 
       
   964 	// Set the buffer with correct length
       
   965 	iBuffer->Des().SetLength(requiredSize);
       
   966 		
       
   967 	// Start writing to the buffer.
       
   968 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
   969 	*ptr++ = count;
       
   970 	
       
   971 	for(TInt index=0; index<count; index++)
       
   972 		{
       
   973 		CFieldPair* fieldPair = aFieldDetails[index];
       
   974 		TInt size = fieldPair->iFieldName->Des().Size();
       
   975 		
       
   976 		*ptr++ = size;
       
   977 		Mem::Copy((void*)ptr, fieldPair->iFieldName->Des().Ptr(), size);
       
   978 		ptr += (Align4(size))/sizeof(TInt);
       
   979 		*ptr++ = (TInt)(fieldPair->iFieldType);
       
   980 		}
       
   981 
       
   982 	// place for TMsvId's and count
       
   983 	return KErrNone;
       
   984 	}
       
   985 
       
   986 
       
   987 
       
   988 
       
   989 /**
       
   990  * TMsvPackedHeaderData()
       
   991  * 
       
   992  * TMsvPackedHeaderData Constructor.
       
   993  *
       
   994  * @param HBufC8*&
       
   995  * @return None.
       
   996  * @leave None.
       
   997  */	
       
   998 EXPORT_C TMsvPackedHeaderData::TMsvPackedHeaderData(HBufC8*& aBuffer)
       
   999 : iBuffer(aBuffer)
       
  1000 	{
       
  1001 	}
       
  1002 	
       
  1003 
       
  1004 /**
       
  1005  * UnpackL()
       
  1006  * 
       
  1007  * Unpacks the buffer to fill header data structure.
       
  1008  *
       
  1009  * @param RPointerArray<CHeaderFields>&: Header Structure.
       
  1010  * @return None.
       
  1011  * @leave KErrNoMemory
       
  1012  */		
       
  1013 EXPORT_C void TMsvPackedHeaderData::UnpackL(RPointerArray<CHeaderFields>& aFieldDetails)
       
  1014 	{
       
  1015 	aFieldDetails.ResetAndDestroy();
       
  1016 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
  1017 
       
  1018 	// Unpack the count.
       
  1019 	TInt count = *ptr++;
       
  1020 
       
  1021 	TPtrC16 ptrBuf;
       
  1022 	while (count--)
       
  1023 		{
       
  1024 		CHeaderFields* headerRow = new(ELeave) CHeaderFields();
       
  1025 		CleanupStack::PushL(headerRow);
       
  1026 		
       
  1027 		headerRow->iUid = TUid::Uid(*ptr++);
       
  1028 		TInt colCount = *ptr++;
       
  1029 		while(colCount--)
       
  1030 			{
       
  1031 			CFieldPair* fieldObj = new(ELeave) CFieldPair();
       
  1032 			CleanupStack::PushL(fieldObj);
       
  1033 			
       
  1034 			if(EIntegerField == (EFieldType)*ptr++)
       
  1035 				{
       
  1036 				TUint32 rVal = *ptr++;
       
  1037 				fieldObj->iFieldNumValue = rVal;
       
  1038 				TUint64 lVal = (*ptr++);
       
  1039 				lVal = lVal << 32;
       
  1040 				fieldObj->iFieldNumValue |= lVal;
       
  1041 				}
       
  1042 			else
       
  1043 				{
       
  1044 				TInt size = *ptr++;
       
  1045 				const TText* textPtr = (TText*)ptr;
       
  1046 				ptrBuf.Set(textPtr, (size/2));
       
  1047 				ptr += Align4(size)/sizeof(TInt);
       
  1048 				
       
  1049 				fieldObj->iFieldTextValue = ptrBuf.AllocL();
       
  1050 				}
       
  1051 
       
  1052 			headerRow->iFieldPairList.AppendL(fieldObj);
       
  1053 			CleanupStack::Pop(fieldObj);
       
  1054 			}
       
  1055 		
       
  1056 		aFieldDetails.AppendL(headerRow);
       
  1057 		CleanupStack::Pop(headerRow);
       
  1058 		}	
       
  1059 	}
       
  1060 	
       
  1061 
       
  1062 
       
  1063 
       
  1064 /**
       
  1065  * Pack()
       
  1066  * 
       
  1067  * Packs the header data to a buffer.
       
  1068  *
       
  1069  * @param RPointerArray<CHeaderFields>&: Header Data.
       
  1070  * @return TInt: KErrOverflow, if buffer does not have sufficient memory.
       
  1071  */		
       
  1072 EXPORT_C TInt TMsvPackedHeaderData::Pack(const RPointerArray<CHeaderFields>& aFieldDetails)
       
  1073 	{
       
  1074 	TInt count = aFieldDetails.Count();
       
  1075 	TInt requiredSize = 0;
       
  1076 	
       
  1077 	// Calculate the size of the data to be written.
       
  1078 	for(TInt headerRow=0; headerRow<count; headerRow++)
       
  1079 		{
       
  1080 		RPointerArray<CFieldPair>& fieldPairList = aFieldDetails[headerRow]->iFieldPairList;
       
  1081 		for(TInt fieldIndex=0; fieldIndex<fieldPairList.Count(); fieldIndex++)	
       
  1082 			{
       
  1083 			requiredSize += 4;			// Store the data type.
       
  1084 			// If it is a text field
       
  1085 			if(fieldPairList[fieldIndex]->iFieldTextValue)
       
  1086 				{
       
  1087 				requiredSize += 4; 		// 4 bytes to store size of iFieldTextValue
       
  1088 				requiredSize += Align4(fieldPairList[fieldIndex]->iFieldTextValue->Des().Size());				
       
  1089 				}
       
  1090 			else	// For Int or date field.
       
  1091 				{
       
  1092 				requiredSize += sizeof(TInt64);
       
  1093 				}				
       
  1094 			}
       
  1095 		requiredSize += 8;		// 4 bytes for TUid, 4 bytes for size of iFieldPairList
       
  1096 		}
       
  1097 	requiredSize += 4; 			// 4 bytes are needed to store the array count. (count)
       
  1098 	
       
  1099 	if(requiredSize > iBuffer->Des().MaxSize())
       
  1100 		{
       
  1101 		return KErrOverflow;
       
  1102 		}
       
  1103 
       
  1104 	// Set the buffer with correct length
       
  1105 	iBuffer->Des().SetLength(requiredSize);
       
  1106 	
       
  1107 	// Start writing to the buffer.
       
  1108 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
  1109 	*ptr++ = count;
       
  1110 	
       
  1111 	for(TInt headerRow=0; headerRow<count; headerRow++)
       
  1112 		{
       
  1113 		// For each header row...
       
  1114 		
       
  1115 		// Store UID of the row.
       
  1116 		*ptr++ = aFieldDetails[headerRow]->iUid.iUid;
       
  1117 		
       
  1118 		// Store field list.
       
  1119 		RPointerArray<CFieldPair>& fieldPairList = aFieldDetails[headerRow]->iFieldPairList;
       
  1120 		*ptr++ = fieldPairList.Count();
       
  1121 		
       
  1122 		for(TInt fieldIndex=0; fieldIndex<fieldPairList.Count(); fieldIndex++)
       
  1123 			{
       
  1124 			CFieldPair* fieldPair = fieldPairList[fieldIndex];
       
  1125 			if(fieldPair->iFieldTextValue)
       
  1126 				{
       
  1127 				// Data type
       
  1128 				*ptr++ = ETextField;				
       
  1129 				// Data Size
       
  1130 				TInt textSize = fieldPair->iFieldTextValue->Des().Size();
       
  1131 				*ptr++ = textSize;
       
  1132 				// Data
       
  1133 				Mem::Copy((void*)ptr, fieldPair->iFieldTextValue->Des().Ptr(), textSize);
       
  1134 				ptr += Align4(textSize)/sizeof(TInt);
       
  1135 				}
       
  1136 			else
       
  1137 				{
       
  1138 				// Data type
       
  1139 				*ptr++ = EIntegerField;
       
  1140 				// Data (64 bits)
       
  1141 				TUint64 maskVal = KMaxTUint32;
       
  1142 				*ptr++ = (fieldPair->iFieldNumValue) & maskVal;
       
  1143 				maskVal = ~maskVal;
       
  1144 				*ptr++ = (fieldPair->iFieldNumValue & maskVal) >> 32;
       
  1145 				}
       
  1146 			}
       
  1147 		}
       
  1148 		
       
  1149 	return KErrNone;
       
  1150 	}
       
  1151 	
       
  1152 
       
  1153 
       
  1154 #endif		// #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
  1155 
       
  1156 
       
  1157 
       
  1158