--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/msgsrvnstore/server/src/MSVIPC.CPP Fri Jun 04 10:32:16 2010 +0100
@@ -0,0 +1,1115 @@
+// 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);
+ }
+
+//**********************************
+// 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)
+
+
+
+