messagingfw/msgsrvnstore/server/src/MSVIPC.CPP
changeset 62 db3f5fa34ec7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/msgsrvnstore/server/src/MSVIPC.CPP	Wed Nov 03 22:41:46 2010 +0530
@@ -0,0 +1,1158 @@
+// Copyright (c) 1998-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 <s32std.h>
+
+#include "MSVIPC.H"
+#include "MSVIDS.H"
+#include "MSVPANIC.H"
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "msvsearchsortconstants.h"
+#include "msvconsts.h"
+#endif
+
+GLDEF_C void DoUnpackEntry(TUint8*& aPtr, TMsvEntry& aEntry)
+//
+//
+//
+	{
+	// get the entry from the start of the buffer
+	const TMsvEntry* pEntry = (TMsvEntry*) aPtr;
+	aEntry = *pEntry;
+	aPtr = Align4(aPtr + sizeof(TMsvEntry));
+
+	const TText* textPtr = (TText*)aPtr;
+	TInt length=aEntry.iDescription.Length();
+	aEntry.iDescription.Set(textPtr, length);
+	textPtr = Align4(textPtr + length);
+
+	length=aEntry.iDetails.Length();
+	aEntry.iDetails.Set(textPtr, length);
+	textPtr = Align4(textPtr + length);
+
+	aPtr = (TUint8*) textPtr;
+	}
+	
+
+GLDEF_C TInt DoPackEntry(const TUint8*& aPtrStart, const TUint8* aPtrEnd, const TMsvEntry& aEntry)
+//
+// Packs an entry into the memory area defined by the two pointers.
+// Fails with KErrOverflow if the packed entry is too large
+// aPtrStart is always returned pointing to the end of the packed entry (even if too large)
+//
+	{
+	// make sure the entry can fit into the memory area defined by the two pointers
+	TInt sizeEntry = Align4(sizeof(TMsvEntry));
+	TInt sizeString1 = Align4(aEntry.iDescription.Size());
+	TInt sizeString2 = Align4(aEntry.iDetails.Size());
+	TInt size =  sizeEntry + sizeString1 + sizeString2;
+	if ((aPtrStart + size)>aPtrEnd)
+		{
+		aPtrStart += size;
+		return KErrOverflow;
+		}
+		
+	// copy the entry and descriptors into the memory area
+	Mem::Copy((void*)aPtrStart, &aEntry, sizeof(TMsvEntry));
+	aPtrStart += sizeEntry;
+
+	Mem::Copy((void*)aPtrStart, aEntry.iDescription.Ptr(), aEntry.iDescription.Size());
+	aPtrStart += sizeString1;
+	
+	Mem::Copy((void*)aPtrStart, aEntry.iDetails.Ptr(), aEntry.iDetails.Size());
+	aPtrStart += sizeString2;
+	
+	return KErrNone;
+	}
+	
+	
+GLDEF_C void DoUnpackFilter(TUint8*& aPtr, CMsvEntryFilter& aFilter)
+//
+//
+//
+	{
+	// get the entry from the start of the buffer
+	const CMsvEntryFilter* pFilter = (CMsvEntryFilter*) aPtr;
+	Mem::Copy(&aFilter, pFilter, sizeof(CMsvEntryFilter));
+	aPtr = Align4(aPtr + sizeof(CMsvEntryFilter));
+	}
+
+
+GLDEF_C TInt DoPackFilter(const TUint8*& aPtrStart, const TUint8* aPtrEnd, const CMsvEntryFilter& aFilter)
+//
+//
+//
+	{
+	// make sure the entry can fit into the memory area defined by the two pointers
+	TInt size = Align4(sizeof(CMsvEntryFilter));
+	if ((aPtrStart + size)>aPtrEnd)
+		{
+		aPtrStart += size;
+		return KErrOverflow;
+		}
+		
+	// copy the filter into the memory area
+	Mem::Copy((void*)aPtrStart, &aFilter, sizeof(CMsvEntryFilter));
+	aPtrStart += size;
+	
+	return KErrNone;
+	}
+
+//**********************************
+// TMsvPackedEntry
+//**********************************
+
+
+EXPORT_C TMsvPackedEntry::TMsvPackedEntry(HBufC8*& aBuffer)
+: iBuffer(aBuffer)
+	{}
+
+EXPORT_C TInt TMsvPackedEntry::PackEntry(const TMsvEntry& aEntry)
+//
+//
+//
+	{
+	// find the start and end of the buffer
+	const TUint8* pS = iBuffer->Ptr();
+	const TUint8* pE = PtrAdd(pS, iBuffer->Des().MaxSize());
+
+	TInt error = DoPackEntry(pS, pE, aEntry);
+	if (error==KErrNone)
+		{
+		// update the length of the buffer
+		iBuffer->Des().SetLength(pS-iBuffer->Ptr());
+		}
+
+	return error;
+	}
+
+EXPORT_C void TMsvPackedEntry::UnpackEntry(TMsvEntry& aEntry)
+//
+//
+//
+	{
+#if defined(_DEBUG)
+	// check that the buffer contain a valid package
+	const TMsvEntry* dEntry = (TMsvEntry*) iBuffer->Ptr();
+	const TUint8* dPos = PtrAdd(iBuffer->Ptr(), Align4(sizeof(TMsvEntry)) + Align4(dEntry->iDescription.Size()) + Align4(dEntry->iDetails.Size()));
+	__ASSERT_DEBUG(dPos <= PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvEntryOverrunBuffer));
+#endif
+	
+	TUint8* pS = CONST_CAST(TUint8*, iBuffer->Ptr());
+	DoUnpackEntry(pS, aEntry);
+	}
+
+TInt TMsvPackedEntry::PackEntryAndService(const TMsvEntry& aEntry, const TMsvId& aServiceId)
+    {
+    // find the start and end of the buffer
+    const TUint8* pS = iBuffer->Ptr();
+    const TUint8* pE = PtrAdd(pS, iBuffer->Des().MaxSize());
+
+    TInt error = DoPackEntry(pS, pE, aEntry);
+    if (error==KErrNone)
+        {
+        TInt sizeDes = Align4(sizeof(TMsvId));
+        if ((pS + sizeDes)>pE)
+            {
+            return KErrOverflow;
+            }            
+        // copy the entry and descriptors into the memory area
+        Mem::Copy((void*)pS, &aServiceId, sizeof(TMsvId));
+        pS += sizeDes;
+
+        // update the length of the buffer
+        iBuffer->Des().SetLength(pS-iBuffer->Ptr());
+        }
+
+    return error;    
+    }
+
+void TMsvPackedEntry::UnpackEntryAndService(TMsvEntry& aEntry, TMsvId& aServiceId)
+    {
+#if defined(_DEBUG)
+    // check that the buffer contain a valid package
+    const TMsvEntry* dEntry = (TMsvEntry*) iBuffer->Ptr();
+    const TUint8* dPos = PtrAdd(iBuffer->Ptr(), Align4(sizeof(TMsvEntry)) + Align4(dEntry->iDescription.Size()) + Align4(dEntry->iDetails.Size()) + Align4(sizeof(TMsvId)) );
+    __ASSERT_DEBUG(dPos <= PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvEntryOverrunBuffer));
+#endif
+    
+    TUint8* pS = CONST_CAST(TUint8*, iBuffer->Ptr());
+    DoUnpackEntry(pS, aEntry);
+
+    // get the service id from the current position in the buffer
+    const TMsvId* pServiceId = (TMsvId*)pS;
+    aServiceId = *pServiceId;
+    pS = Align4(pS + sizeof(TMsvId));
+    }
+
+//**********************************
+// TMsvPackedEntryArray
+//**********************************
+
+
+EXPORT_C TMsvPackedEntryArray::TMsvPackedEntryArray(HBufC8*& aBuffer, TInt aCount)
+: iIndex(0), iCount(aCount), iBuffer(aBuffer) 
+	{
+	iPos = iBuffer->Ptr();
+	}
+
+
+EXPORT_C void TMsvPackedEntryArray::Reset()
+//
+//
+//
+	{
+	iBuffer->Des().SetLength(0);
+	iPos  = iBuffer->Ptr();
+	iIndex=0;
+	iCount=0;
+	}
+
+EXPORT_C TInt TMsvPackedEntryArray::PackEntry(const TMsvEntry& aEntry)
+//
+//
+//
+	{
+	const TUint8* pS = iPos;
+	const TUint8* pE = PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxSize());
+
+	TInt error = DoPackEntry(pS, pE, aEntry);
+	if (error==KErrNone)
+		{
+		// update the length of the buffer and the position for the next entry
+		iBuffer->Des().SetLength(pS-iBuffer->Ptr());
+		iPos = pS;
+		iIndex++;
+		iCount++;
+		}
+	
+	return error;
+	}
+
+EXPORT_C TInt TMsvPackedEntryArray::UnpackEntry(TInt aIndex, TMsvEntry& aEntry)
+//
+//
+//
+	{
+	TInt error=KErrNone;
+
+	if (iIndex!=aIndex)
+		error = FindEntryInArray(aIndex);
+
+	if (error==KErrNone)
+		{
+		TUint8* pS=CONST_CAST(TUint8*, iPos);
+		DoUnpackEntry(pS, aEntry);
+		iPos=pS;
+		iIndex++;
+		}	
+
+	return error;
+	}
+
+
+TInt TMsvPackedEntryArray::FindEntryInArray(TInt aIndex)
+//
+//
+//
+	{
+	if (aIndex>=iCount)
+		return KErrNotFound;
+
+	if (iIndex>aIndex)
+		{
+		// have to reset to the start of the buffer
+		iPos = iBuffer->Ptr();
+		iIndex=0;
+		}
+
+	while (iIndex!=aIndex)
+		{
+		const TMsvEntry* pEntry = (TMsvEntry*) iPos;
+		iPos += Align4(sizeof(TMsvEntry)) + Align4(pEntry->iDescription.Size()) + Align4(pEntry->iDetails.Size());
+		iIndex++;
+		}
+
+	__ASSERT_DEBUG(iPos < PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvPointerOverrunBuffer));
+
+	return KErrNone;
+	}
+
+
+
+//**********************************
+// TMsvMoveCopyDetails
+//**********************************
+
+EXPORT_C TMsvLocalOperationProgress::TMsvLocalOperationProgress()
+: iType(ELocalNone), iTotalNumberOfEntries(0), iNumberCompleted(0), iNumberFailed(0), iNumberRemaining(0), iError(KErrNone), iId(KMsvNullIndexEntryId)
+/** Initialises the new object to suitable zero or null values. */
+	{
+	}
+
+//**********************************
+// TMsvServerOperationProgress
+//**********************************
+
+EXPORT_C TMsvServerOperationProgress::TMsvServerOperationProgress()
+: iOperationType(EMsvNoOperation)
+/** Default constructor.
+
+Sets iOperationType to EMsvNoOperation. */
+	{
+	}
+
+TMsvServerOperationProgress::TMsvServerOperationProgress(TMsvServerOperationType aType)
+: iOperationType(aType)
+	{
+	}
+
+//**********************************
+// TMsvIndexProgress
+//**********************************
+
+EXPORT_C TMsvIndexProgress::TMsvIndexProgress()
+: iTotal(0), iCompleted(0), iRemaining(0), iId(KMsvNullIndexEntryId)
+/** Default constructor.
+
+Data members are intialised to 0 or KMsvNullIndexEntryId as appropriate. */
+	{
+	}
+
+//**********************************
+// TMsvIndexLoadProgress
+//**********************************
+
+EXPORT_C TMsvIndexLoadProgress::TMsvIndexLoadProgress()
+: TMsvServerOperationProgress(EMsvChangeDriveOperation), iError(KErrNone), iState(EIndexNotLoaded)
+/** Default constructor.
+
+iOperationType is set to EMsvChangeDriveOperation; iError is set to KErrNone; 
+iState is set to EIndexNotLoaded. */
+	{
+	}
+	
+	
+	
+//**********************************
+// TMsvCopyProgress
+//**********************************
+
+/** Default constructor.
+iOperationType is set to EMsvCopyOperation; iError is set to KErrNone; 
+iState is set to ENotYetStarted. */  
+
+EXPORT_C TMsvCopyProgress::TMsvCopyProgress()
+: TMsvServerOperationProgress(EMsvCopyOperation), iError(KErrNone), iState(ENotYetStarted)
+	{
+	}
+
+
+//**********************************
+// TMsvDeleteProgress
+//**********************************
+
+/** Default constructor.
+iOperationType is set to EMsvDeleteOperation; iError is set to KErrNone; 
+iState is set to ENotYetStarted. */
+
+EXPORT_C TMsvDeleteProgress::TMsvDeleteProgress()
+: TMsvServerOperationProgress(EMsvDeleteOperation), iError(KErrNone), iState(ENotYetStarted)
+
+	{
+	}
+
+
+//**********************************
+// TMsvChildrenDetails
+//**********************************
+
+EXPORT_C TMsvChildrenDetails::TMsvChildrenDetails()
+: iParentId(KMsvNullIndexEntryId), iTotalNumberChildren(0), iNumberChildrenInArray(0), iLastEntryInArray(0)
+	{
+	}
+
+
+//**********************************
+// TMsvPackedOperation
+//**********************************
+
+EXPORT_C TMsvPackedOperation::TMsvPackedOperation(HBufC8*& aBuffer)
+: iBuffer(aBuffer)
+	{
+	}
+
+
+EXPORT_C TInt TMsvPackedOperation::Pack(const CMsvEntrySelection& aSelection, TInt aParameter1, TInt aParameter2)
+	{
+	// check the buffer is large enough
+	TInt requiredSize = (aSelection.Count()+3)*4;
+	if (requiredSize>iBuffer->Des().MaxSize())
+		return KErrOverflow;
+	// set the buffer with correct length
+	iBuffer->Des().SetLength(requiredSize);
+
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+	*ptr++ = aSelection.Count();
+	for (TInt count=0; count<aSelection.Count(); count++)
+		*ptr++ = aSelection.At(count);
+	*ptr++ = aParameter1;
+	*ptr++ = aParameter2;
+	return KErrNone;
+	}
+
+
+EXPORT_C void TMsvPackedOperation::UnpackL(CMsvEntrySelection& aSelection, TInt& aParameter1, TInt& aParameter2)
+	{
+	__ASSERT_DEBUG(aSelection.Count()==0, PanicServer(EMsvOperationUnpackSelectionNotEmpty));	
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+
+	TInt count = *ptr++;
+	
+	TInt bufSize = iBuffer->Des().Length();
+	
+	// This length is calculated on the basis of length set in TMsvPackedOperation::Pack above.
+	TInt len = (count+3)*4; 
+	if(bufSize == len)	
+		{
+		while (count--)
+			{
+			aSelection.AppendL(*ptr++);
+			}
+		aParameter1 = *ptr++;
+		aParameter2 = *ptr++;
+		}
+	else
+		{
+		User::Leave(KErrArgument);
+		}
+	}
+
+
+EXPORT_C TMsvPackedChangeNotification::TMsvPackedChangeNotification(TMsvNotifBuffer& aBuffer)
+: iBuffer(aBuffer)
+	{
+	}
+
+
+EXPORT_C void TMsvPackedChangeNotification::Pack(TMsvServerChangeNotificationType aChangeType, const CMsvEntrySelection& aSelection, TInt aParameter1, TInt aParameter2, TInt aStartIndex, TInt aFinishIndex)
+//
+// Packs the aStartIndex->aFinishIndex (inc) into the buffer
+//
+	{
+	__ASSERT_DEBUG(aFinishIndex-aStartIndex+1<=KMsvPackedChangeLimit, PanicServer(EMsvChangeSelectionTooLarge));
+
+	// set the buffer with correct length
+	TInt requiredSize = (aFinishIndex-aStartIndex+1+KMsvChangeNotificationNumberOfTInts)*4;
+	iBuffer.SetLength(requiredSize);
+
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer.Ptr());
+	*ptr++ = aChangeType;
+	*ptr++ = aParameter1;
+	*ptr++ = aParameter2;
+	*ptr++ = aFinishIndex - aStartIndex + 1;
+	for (TInt count=aStartIndex; count<=aFinishIndex; count++)
+		*ptr++ = aSelection.At(count);
+	}
+
+
+EXPORT_C void TMsvPackedChangeNotification::Pack(TMsvServerChangeNotificationType aChangeType, TMsvId aId, TInt aParameter1, TInt aParameter2)
+//
+// Packs a single id
+//
+	{
+	// set the buffer with correct length
+	TInt requiredSize = (1+KMsvChangeNotificationNumberOfTInts)*4;
+	iBuffer.SetLength(requiredSize);
+
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer.Ptr());
+	*ptr++ = aChangeType;
+	*ptr++ = aParameter1;
+	*ptr++ = aParameter2;
+	*ptr++ = 1;
+	*ptr++ = aId;
+	}
+
+
+EXPORT_C void TMsvPackedChangeNotification::UnpackL(TMsvServerChangeNotificationType& aChangeType, CMsvEntrySelection& aSelection, TInt& aParameter1, TInt& aParameter2)
+//
+//
+//
+	{
+	__ASSERT_DEBUG(aSelection.Count()==0, PanicServer(EMsvChangedUnpackSelectionNotEmpty));	
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer.Ptr());
+	switch (*ptr++)
+		{
+		case 1:
+			aChangeType = EMsvEntriesCreated;
+			break;
+		case 2:
+			aChangeType = EMsvEntriesChanged;
+			break;
+		case 3:
+			aChangeType = EMsvEntriesDeleted;
+			break;
+		case 4:
+			aChangeType = EMsvEntriesMoved;
+			break;
+		case 5:
+			aChangeType = EMsvMtmGroupInstalled;
+			break;
+		case 6:
+			aChangeType = EMsvMtmGroupDeInstalled;
+			break;
+		case 8:
+			aChangeType = EMsvCloseSession;
+			break;
+		case 9:
+			aChangeType = EMsvIndexLoaded;
+			break;
+		case 10:
+			aChangeType = EMsvIndexFailedToLoad;
+			break;
+		case 12:
+			aChangeType = EMsvMediaChanged;
+			break;
+		case 13:
+			aChangeType = EMsvMediaUnavailable;
+			break;
+		case 14:
+			aChangeType = EMsvMediaAvailable;
+			break;
+		case 15:
+			aChangeType = EMsvMediaIncorrect;
+			break;
+#if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
+		case 16:
+			aChangeType = EMsvMessageStoreNotSupported;
+			break;
+		case 17:
+			aChangeType = EMsvMessageStoreCorrupt;
+			break;
+		case 18:
+			aChangeType = EMsvRefreshMessageView;
+			break;
+		case 19:
+			aChangeType = EMsvDiskNotAvailable;
+			break;
+		case 20:
+			aChangeType = EMsvUnableToProcessDiskNotification;
+			break;
+#endif	
+		default:
+			__ASSERT_DEBUG(EFalse, PanicServer(EMsvUnknownChangeType));
+			aChangeType = EMsvEntriesNoChange;
+		}
+	aParameter1 = *ptr++;
+	aParameter2 = *ptr++;
+	TInt count = *ptr++;
+	while (count--)
+		aSelection.AppendL(*ptr++);
+	}
+
+TMsvPackedEntryFilter::TMsvPackedEntryFilter(HBufC8*& aBuffer)
+: iBuffer(aBuffer)
+	{}
+
+TInt TMsvPackedEntryFilter::PackFilter(const CMsvEntryFilter& aFilter)
+	{
+	// find the start and end of the buffer
+	const TUint8* pS = iBuffer->Ptr();
+	const TUint8* pE = PtrAdd(pS, iBuffer->Des().MaxSize());
+
+	TInt error = DoPackFilter(pS, pE, aFilter);
+	if (error==KErrNone)
+		{
+		// update the length of the buffer
+		iBuffer->Des().SetLength(pS-iBuffer->Ptr());
+		}
+
+	return error;
+	}
+
+void TMsvPackedEntryFilter::UnpackFilter(CMsvEntryFilter& aFilter)
+	{
+#if defined(_DEBUG)
+	// check that the buffer contain a valid package
+	const TUint8* dPos = PtrAdd(iBuffer->Ptr(), Align4(sizeof(CMsvEntryFilter)));
+	__ASSERT_DEBUG(dPos <= PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvEntryOverrunBuffer));
+#endif	
+	TUint8* pS = CONST_CAST(TUint8*, iBuffer->Ptr());
+	DoUnpackFilter(pS, aFilter);
+	}
+
+/**
+Constructor for TMsvPackQuery.
+@internalComponent
+@released
+@param aBuffer: buffer for packing
+*/
+
+EXPORT_C TMsvPackQuery::TMsvPackQuery(HBufC8*& aBuffer)
+: iBuffer(aBuffer)
+	{}
+
+
+TInt TMsvPackQuery::DoPackQuery(const TUint8*& aPtrStart, const TUint8* aPtrEnd, const CMsvSearchSortQuery* aQuery)
+	{
+	//size of class - sizeof(iQueryTable pointer)
+	TInt sizeOfClass = Align4(sizeof(CMsvSearchSortQuery) - sizeof(TInt));
+	TInt sizeQueryTable = Align4(sizeof(TMsvQueryTable) * KMaxLevelOfSearchAndSort);
+	TInt size = sizeOfClass + sizeQueryTable;
+	
+	if ((aPtrStart + size)>aPtrEnd)
+		{
+		aPtrStart += size;
+		return KErrOverflow;
+		}
+		
+	// copy the entry and descriptors into the memory area
+	Mem::Copy((void*)aPtrStart, aQuery, sizeOfClass);
+	aPtrStart += sizeOfClass;
+
+	Mem::Copy((void*)aPtrStart, aQuery->iQueryTable, sizeQueryTable);
+	aPtrStart += sizeQueryTable;
+
+	return KErrNone;
+	}
+
+/**
+Packs TMsvSearchSortQuery object into a buffer for sending across IPC. 
+@internalComponent
+@released
+@param aQuery: TMsvSearchSortQuery object needs to pack.
+@return: reurn KErrNone if successful else KErrOverflow.
+*/
+EXPORT_C TInt TMsvPackQuery::PackQuery(const CMsvSearchSortQuery* aQuery)
+	{
+	// find the start and end of the buffer
+	const TUint8* pS = iBuffer->Ptr();
+	const TUint8* pE = PtrAdd(pS, iBuffer->Des().MaxSize());
+
+	TInt error = DoPackQuery(pS, pE, aQuery);
+	if (error==KErrNone)
+		{
+		// update the length of the buffer
+		iBuffer->Des().SetLength(pS-iBuffer->Ptr());
+		}
+	return error;
+	}
+	
+
+void TMsvPackQuery::DoUnpackQuery(TUint8*& aPtr, CMsvSearchSortQuery* aQuery)
+	{
+	//size of class - sizeof(iQueryTable pointer)
+	TInt sizeOfClass = Align4(sizeof(CMsvSearchSortQuery) - sizeof(TInt));
+	TInt sizeQueryTable = Align4(sizeof(TMsvQueryTable) * KMaxLevelOfSearchAndSort);
+	
+	Mem::Copy((void*)aQuery, aPtr, sizeOfClass);
+	aPtr += sizeOfClass;
+	
+	Mem::Copy((void*)aQuery->iQueryTable, aPtr, sizeQueryTable);
+	aPtr += sizeQueryTable;
+	}	
+
+/**
+Unpacks the data to a aQuery.
+@internalComponent
+@released
+@param aQuery: Unpacked TMsvSearchSortQuery object.
+*/
+EXPORT_C void TMsvPackQuery::UnpackQuery(CMsvSearchSortQuery* aQuery)
+	{
+#if defined(_DEBUG)
+	// check that the buffer contain a valid package
+	const TUint8* dPos = PtrAdd(iBuffer->Ptr(), Align4(sizeof(CMsvSearchSortQuery)));
+	__ASSERT_DEBUG(dPos <= PtrAdd(iBuffer->Ptr(), iBuffer->Des().MaxLength()), PanicServer(EMsvEntryOverrunBuffer));
+#endif
+	
+	TUint8* pS = CONST_CAST(TUint8*, iBuffer->Ptr());
+	DoUnpackQuery(pS, aQuery);
+	}
+
+/**
+Constructor for TMsvPackedIdOperation.
+@internalComponent
+@released
+@param aBuffer: buffer for packing
+*/
+EXPORT_C TMsvPackedIdOperation::TMsvPackedIdOperation(HBufC8*& aBuffer)
+: iBuffer(aBuffer)
+	{
+	}
+
+/**
+Packs RArray of TMsvId and count value into a buffer for sending across IPC. 
+@internalComponent
+@released
+@param aId: RArray of TMsvIds needs to pack.
+@return: reurn KErrNone if successful else KErrOverflow.
+*/
+EXPORT_C TInt TMsvPackedIdOperation::Pack(const RArray<TMsvId>& aId)
+	{
+	//place for TMsvId's and count
+	TInt requiredSize = (aId.Count() + 1) * 4;
+	
+	// check the buffer is large enough
+	if (requiredSize > iBuffer->Des().MaxSize())
+		{
+		return KErrOverflow;
+		}
+		
+	// set the buffer with correct length
+	iBuffer->Des().SetLength(requiredSize);
+	
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+	//number of TMsvId's
+	*ptr++ = aId.Count();
+	
+	//copy TMsvId's to buffer 	
+	for (TInt count=0; count<aId.Count(); count++)
+		{
+		*ptr++ = aId[count];
+		}
+		
+	return KErrNone;
+	}
+
+/**
+Unpacks the data in buffer to a RArray.
+@internalComponent
+@released
+@param aId: Unpacked RArray of TMsvIds.
+*/
+EXPORT_C void TMsvPackedIdOperation::UnpackL(RArray<TMsvId>& aId)
+	{
+	__ASSERT_DEBUG(aId.Count()==0, PanicServer(EMsvOperationUnpackSelectionNotEmpty));	
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+
+	//unpack the count
+	TInt count = *ptr++;
+	//unpack TMsvId's to RArray
+	while (count--)
+		{
+		aId.AppendL(*ptr++);
+		}
+	}
+
+
+/**
+Constructor for TMsvPackedIdAndMessagePart.
+@internalComponent
+@released
+*/
+EXPORT_C TMsvPackedIdAndMessagePart::TMsvPackedIdAndMessagePart()
+	{
+	}
+
+/**
+Size() will returns size of the data occupied by TMsvIdWithSortField.
+@internalComponent
+@released
+@param aData: RArray of TMsvIdWithSortField.
+*/	
+EXPORT_C TInt TMsvPackedIdAndMessagePart::Size(const RArray<TMsvIdWithSortField>& aData)
+	{
+	// number of TMsvId's in RArray
+	TInt count = aData.Count();
+	TInt size = 0;
+	
+	// to hold counter value
+	size += sizeof(TInt);
+	
+	// calculate length of RArray<TMsvId + SortFiled>
+	for(TInt index = 0; index < count; index++)
+		{
+		size += sizeof(TMsvId);
+		size += aData[index].iContentMessagePart.Length();
+		}
+	return size;
+	}
+
+/**
+Packs or Externalize the RArray of TMsvIdWithSortField into a aWriteStream for sending across IPC. 
+@internalComponent
+@released
+@param aWriteStream: aData will be written to aWriteStream.
+@param aData: RArray of TMsvIdWithSortField
+*/	
+EXPORT_C void TMsvPackedIdAndMessagePart::ExternalizeL(RWriteStream& aWriteStream, RArray<TMsvIdWithSortField>& aData) const
+	{
+	TInt count = aData.Count();
+	aWriteStream.WriteInt32L(count);
+  	
+  	for(TInt index=0; index < count; ++index)
+ 		{
+ 		aWriteStream.WriteInt32L(aData[index].iMessageId);
+ 		aWriteStream << aData[index].iContentMessagePart;
+ 		}
+	}
+
+/**
+Unpacks or Internalize aReadStream buffer to RArray of TMsvIdWithSortField.
+@internalComponent
+@released
+@param aReadStream: aReadStream data will be unpacked to TMsvIdWithSortField of aData.
+@param aData: RArray of TMsvIdWithSortField
+*/	
+EXPORT_C void TMsvPackedIdAndMessagePart::InternalizeL(RReadStream& aReadStream, RArray<TMsvIdWithSortField>& aData)
+	{
+	TInt count =  aReadStream.ReadInt32L();
+	
+	TMsvIdWithSortField tmsvidAndmessagepart;
+	
+	for(TInt index=0; index < count; ++index)
+ 		{
+ 		tmsvidAndmessagepart.iMessageId = aReadStream.ReadInt32L();
+ 		aReadStream >> tmsvidAndmessagepart.iContentMessagePart;
+ 		aData.AppendL(tmsvidAndmessagepart);
+ 		}
+	}
+
+
+#if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
+EXPORT_C TMsvPackedDriveIdOperation::TMsvPackedDriveIdOperation(HBufC8*& aBuffer)
+: iBuffer(aBuffer)
+	{
+	}
+	
+	
+EXPORT_C void TMsvPackedDriveIdOperation::UnpackL(RArray<TDriveNumber>& aDriveNumber)
+	{
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+
+	// Unpack the count.
+	TInt count = *ptr++;
+	
+	// Append TDriveNumber
+	while (count--)
+		{
+		aDriveNumber.AppendL((TDriveNumber)*ptr++);
+		}	
+	}
+	
+	
+EXPORT_C TInt TMsvPackedDriveIdOperation::Pack(const RArray<TDriveNumber>& aDriveNumber)
+	{
+	// place for TMsvId's and count
+	TInt requiredSize = (aDriveNumber.Count() + 1) * 4;
+	
+	// check the buffer is large enough
+	if (requiredSize > iBuffer->Des().MaxSize())
+		{
+		return KErrOverflow;
+		}
+		
+	// set the buffer with correct length
+	iBuffer->Des().SetLength(requiredSize);
+	
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+	//number of TMsvId's
+	*ptr++ = aDriveNumber.Count();
+	
+	//copy TMsvId's to buffer 	
+	for (TInt count=0; count<aDriveNumber.Count(); count++)
+		{
+		*ptr++ = aDriveNumber[count];
+		}
+		
+	return KErrNone;
+	}
+
+#endif		// #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
+
+
+
+
+
+#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
+
+/**
+ * TMsvPackedHeaderStructure()
+ * 
+ * TMsvPackedHeaderStructure Constructor.
+ *
+ * @param HBufC8*&
+ * @return None.
+ * @leave None.
+ */	
+EXPORT_C TMsvPackedHeaderStructure::TMsvPackedHeaderStructure(HBufC8*& aBuffer)
+: iBuffer(aBuffer)
+	{
+	}
+	
+
+/**
+ * UnpackL()
+ * 
+ * Unpacks the buffer to fill header structure.
+ *
+ * @param RPointerArray<CFieldPair>&: Header Structure.
+ * @return None.
+ * @leave KErrNoMemory
+ */	
+EXPORT_C void TMsvPackedHeaderStructure::UnpackL(RPointerArray<CFieldPair>& aFieldDetails)
+	{
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+
+	// Unpack the count.
+	TInt count = *ptr++;
+
+	TInt size = 0;
+	TPtrC16 ptrBuf;	
+
+	while (count--)
+		{
+		CFieldPair* fieldPair = new(ELeave) CFieldPair();
+		CleanupStack::PushL(fieldPair);
+		size = *ptr++;
+		
+		const TText* textPtr = (TText*)ptr;
+		ptrBuf.Set(textPtr, (size/2));			// ptrBuf is 16 bits.
+		ptr += Align4(size)/sizeof(TInt);
+		
+		fieldPair->iFieldName = ptrBuf.AllocL();
+		fieldPair->iFieldType = (EFieldType) *ptr++;
+		aFieldDetails.AppendL(fieldPair);
+		CleanupStack::Pop();			// fieldPair
+		}	
+	}
+	
+
+
+/**
+ * Pack()
+ * 
+ * Packs the header structure to a buffer.
+ *
+ * @param RPointerArray<CFieldPair>&: Header Structure.
+ * @return TInt: KErrOverflow, if buffer does not have sufficient memory.
+ */		
+EXPORT_C TInt TMsvPackedHeaderStructure::Pack(const RPointerArray<CFieldPair>& aFieldDetails)
+	{
+	TInt count = aFieldDetails.Count();
+	TInt requiredSize = 0;
+	
+	// Calculate the size of the data to be written.
+	for(TInt index=0; index<count; index++)
+		{
+		CFieldPair* fieldPair = aFieldDetails[index]; 	
+		requiredSize += Align4(fieldPair->iFieldName->Des().Size());
+		requiredSize += 8;		// 4 bytes for EFieldType and 4 bytes for size of iFieldName
+		}
+	
+	// 4 bytes are needed to store the array count.
+	requiredSize += 4;
+	if(requiredSize > iBuffer->Des().MaxSize())
+		{
+		return KErrOverflow;
+		}
+
+	// Set the buffer with correct length
+	iBuffer->Des().SetLength(requiredSize);
+		
+	// Start writing to the buffer.
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+	*ptr++ = count;
+	
+	for(TInt index=0; index<count; index++)
+		{
+		CFieldPair* fieldPair = aFieldDetails[index];
+		TInt size = fieldPair->iFieldName->Des().Size();
+		
+		*ptr++ = size;
+		Mem::Copy((void*)ptr, fieldPair->iFieldName->Des().Ptr(), size);
+		ptr += (Align4(size))/sizeof(TInt);
+		*ptr++ = (TInt)(fieldPair->iFieldType);
+		}
+
+	// place for TMsvId's and count
+	return KErrNone;
+	}
+
+
+
+
+/**
+ * TMsvPackedHeaderData()
+ * 
+ * TMsvPackedHeaderData Constructor.
+ *
+ * @param HBufC8*&
+ * @return None.
+ * @leave None.
+ */	
+EXPORT_C TMsvPackedHeaderData::TMsvPackedHeaderData(HBufC8*& aBuffer)
+: iBuffer(aBuffer)
+	{
+	}
+	
+
+/**
+ * UnpackL()
+ * 
+ * Unpacks the buffer to fill header data structure.
+ *
+ * @param RPointerArray<CHeaderFields>&: Header Structure.
+ * @return None.
+ * @leave KErrNoMemory
+ */		
+EXPORT_C void TMsvPackedHeaderData::UnpackL(RPointerArray<CHeaderFields>& aFieldDetails)
+	{
+	aFieldDetails.ResetAndDestroy();
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+
+	// Unpack the count.
+	TInt count = *ptr++;
+
+	TPtrC16 ptrBuf;
+	while (count--)
+		{
+		CHeaderFields* headerRow = new(ELeave) CHeaderFields();
+		CleanupStack::PushL(headerRow);
+		
+		headerRow->iUid = TUid::Uid(*ptr++);
+		TInt colCount = *ptr++;
+		while(colCount--)
+			{
+			CFieldPair* fieldObj = new(ELeave) CFieldPair();
+			CleanupStack::PushL(fieldObj);
+			
+			if(EIntegerField == (EFieldType)*ptr++)
+				{
+				TUint32 rVal = *ptr++;
+				fieldObj->iFieldNumValue = rVal;
+				TUint64 lVal = (*ptr++);
+				lVal = lVal << 32;
+				fieldObj->iFieldNumValue |= lVal;
+				}
+			else
+				{
+				TInt size = *ptr++;
+				const TText* textPtr = (TText*)ptr;
+				ptrBuf.Set(textPtr, (size/2));
+				ptr += Align4(size)/sizeof(TInt);
+				
+				fieldObj->iFieldTextValue = ptrBuf.AllocL();
+				}
+
+			headerRow->iFieldPairList.AppendL(fieldObj);
+			CleanupStack::Pop(fieldObj);
+			}
+		
+		aFieldDetails.AppendL(headerRow);
+		CleanupStack::Pop(headerRow);
+		}	
+	}
+	
+
+
+
+/**
+ * Pack()
+ * 
+ * Packs the header data to a buffer.
+ *
+ * @param RPointerArray<CHeaderFields>&: Header Data.
+ * @return TInt: KErrOverflow, if buffer does not have sufficient memory.
+ */		
+EXPORT_C TInt TMsvPackedHeaderData::Pack(const RPointerArray<CHeaderFields>& aFieldDetails)
+	{
+	TInt count = aFieldDetails.Count();
+	TInt requiredSize = 0;
+	
+	// Calculate the size of the data to be written.
+	for(TInt headerRow=0; headerRow<count; headerRow++)
+		{
+		RPointerArray<CFieldPair>& fieldPairList = aFieldDetails[headerRow]->iFieldPairList;
+		for(TInt fieldIndex=0; fieldIndex<fieldPairList.Count(); fieldIndex++)	
+			{
+			requiredSize += 4;			// Store the data type.
+			// If it is a text field
+			if(fieldPairList[fieldIndex]->iFieldTextValue)
+				{
+				requiredSize += 4; 		// 4 bytes to store size of iFieldTextValue
+				requiredSize += Align4(fieldPairList[fieldIndex]->iFieldTextValue->Des().Size());				
+				}
+			else	// For Int or date field.
+				{
+				requiredSize += sizeof(TInt64);
+				}				
+			}
+		requiredSize += 8;		// 4 bytes for TUid, 4 bytes for size of iFieldPairList
+		}
+	requiredSize += 4; 			// 4 bytes are needed to store the array count. (count)
+	
+	if(requiredSize > iBuffer->Des().MaxSize())
+		{
+		return KErrOverflow;
+		}
+
+	// Set the buffer with correct length
+	iBuffer->Des().SetLength(requiredSize);
+	
+	// Start writing to the buffer.
+	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
+	*ptr++ = count;
+	
+	for(TInt headerRow=0; headerRow<count; headerRow++)
+		{
+		// For each header row...
+		
+		// Store UID of the row.
+		*ptr++ = aFieldDetails[headerRow]->iUid.iUid;
+		
+		// Store field list.
+		RPointerArray<CFieldPair>& fieldPairList = aFieldDetails[headerRow]->iFieldPairList;
+		*ptr++ = fieldPairList.Count();
+		
+		for(TInt fieldIndex=0; fieldIndex<fieldPairList.Count(); fieldIndex++)
+			{
+			CFieldPair* fieldPair = fieldPairList[fieldIndex];
+			if(fieldPair->iFieldTextValue)
+				{
+				// Data type
+				*ptr++ = ETextField;				
+				// Data Size
+				TInt textSize = fieldPair->iFieldTextValue->Des().Size();
+				*ptr++ = textSize;
+				// Data
+				Mem::Copy((void*)ptr, fieldPair->iFieldTextValue->Des().Ptr(), textSize);
+				ptr += Align4(textSize)/sizeof(TInt);
+				}
+			else
+				{
+				// Data type
+				*ptr++ = EIntegerField;
+				// Data (64 bits)
+				TUint64 maskVal = KMaxTUint32;
+				*ptr++ = (fieldPair->iFieldNumValue) & maskVal;
+				maskVal = ~maskVal;
+				*ptr++ = (fieldPair->iFieldNumValue & maskVal) >> 32;
+				}
+			}
+		}
+		
+	return KErrNone;
+	}
+	
+
+
+#endif		// #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
+
+
+
+