diff -r 9f5ae1728557 -r db3f5fa34ec7 messagingfw/msgsrvnstore/server/src/MSVIPC.CPP --- /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 + +#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; countPtr()); + + 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& 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) + { + __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& 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 + 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& 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& 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& 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& 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&: Header Structure. + * @return None. + * @leave KErrNoMemory + */ +EXPORT_C void TMsvPackedHeaderStructure::UnpackL(RPointerArray& 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&: Header Structure. + * @return TInt: KErrOverflow, if buffer does not have sufficient memory. + */ +EXPORT_C TInt TMsvPackedHeaderStructure::Pack(const RPointerArray& aFieldDetails) + { + TInt count = aFieldDetails.Count(); + TInt requiredSize = 0; + + // Calculate the size of the data to be written. + for(TInt index=0; indexiFieldName->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; indexiFieldName->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&: Header Structure. + * @return None. + * @leave KErrNoMemory + */ +EXPORT_C void TMsvPackedHeaderData::UnpackL(RPointerArray& 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&: Header Data. + * @return TInt: KErrOverflow, if buffer does not have sufficient memory. + */ +EXPORT_C TInt TMsvPackedHeaderData::Pack(const RPointerArray& aFieldDetails) + { + TInt count = aFieldDetails.Count(); + TInt requiredSize = 0; + + // Calculate the size of the data to be written. + for(TInt headerRow=0; headerRow& fieldPairList = aFieldDetails[headerRow]->iFieldPairList; + for(TInt fieldIndex=0; fieldIndexiFieldTextValue) + { + 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; headerRowiUid.iUid; + + // Store field list. + RPointerArray& fieldPairList = aFieldDetails[headerRow]->iFieldPairList; + *ptr++ = fieldPairList.Count(); + + for(TInt fieldIndex=0; fieldIndexiFieldTextValue) + { + // 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) + + + +