diff -r e6e896426eac -r 2691f6aa1921 omads/omadsextensions/adapters/sms/src/SmsDataStore.cpp --- a/omads/omadsextensions/adapters/sms/src/SmsDataStore.cpp Tue Feb 02 00:02:49 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1362 +0,0 @@ -/* -* Copyright (c) 2005-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: Part of SyncML Data Synchronization Plug In Adapter -* -*/ - - -#include -#include -#include -#include -#include -#include -#include "SmsDataStore.h" -#include "SmsDataProviderDefs.h" -#include "Logger.h" -#include "SMSAdapterMsvApi.h" -#include "VMessageParser.h" -#include "OMADSFolderObject.h" - -// This is used, when databuffer is not initialized -const TInt KDataBufferNotReady = -1; -// Size for internal CBufFlat, used to buffer SMS messages -const TInt KDataBufferSize = 1024; - -_LIT8(KSmsMimeType, "text/x-vMessage"); -_LIT8(KSmsMimeVersion, "1.2"); -_LIT8(KFolderMimeType, "application/vnd.omads-folder+xml"); -_LIT8(KFolderMimeVersion, "1.2"); - - -// ----------------------------------------------------------------------------- -// CSmsDataStore::CSmsDataStore -// C++ default constructor can NOT contain any code, that might leave. -// ----------------------------------------------------------------------------- -CSmsDataStore::CSmsDataStore(): - iHasHistory(EFalse), - iDataBaseOpened(EFalse), - iKey(TKeyArrayFix(_FOFF(TSnapshotItem, ItemId()), ECmpTInt)) - { - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::ConstructL -// Symbian 2nd phase constructor, can leave. -// ----------------------------------------------------------------------------- -void CSmsDataStore::ConstructL() - { - LOGGER_ENTERFN("CSmsDataStore::ConstructL"); - - iMsvApi = CSmsAdapterMsvApi::NewL(); - - // Item UID sets, used to transfer change info - iNewItems = new (ELeave) CNSmlDataItemUidSet; - iDeletedItems = new (ELeave) CNSmlDataItemUidSet; - iUpdatedItems = new (ELeave) CNSmlDataItemUidSet; - iMovedItems = new (ELeave) CNSmlDataItemUidSet; - iSoftDeletedItems = new (ELeave) CNSmlDataItemUidSet; - - iMessageParser = CVMessageParser::NewL(); - iFolderObjectParser = COMADSFolderObject::NewL(); - - LOGGER_LEAVEFN("CSmsDataStore::ConstructL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::NewLC -// Two-phased constructor. -// ----------------------------------------------------------------------------- -CSmsDataStore* CSmsDataStore::NewLC() - { - CSmsDataStore* self = new (ELeave) CSmsDataStore; - - CleanupStack::PushL(self); - self->ConstructL(); - - return self; - } - - -// ----------------------------------------------------------------------------- -// CSmsDataStore::~CSmsDataStore -// Destructor -// ----------------------------------------------------------------------------- -CSmsDataStore::~CSmsDataStore() - { - LOGGER_ENTERFN("CSmsDataStore::~CSmsDataStore()"); - - SAFEDELETE(iFolderObjectParser); - SAFEDELETE(iMessageParser); - - SAFEDELETE(iMsvApi); - SAFEDELETE(iChangeFinder); - - // UID sets - SAFEDELETE(iNewItems); - SAFEDELETE(iDeletedItems); - SAFEDELETE(iSoftDeletedItems); - SAFEDELETE(iUpdatedItems); - SAFEDELETE(iMovedItems); - - SAFEDELETE(iDataBuffer); - - LOGGER_LEAVEFN("CSmsDataStore::~CSmsDataStore()"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoOpenL -// Opens database. This operation is performed SYNCHRONOUSLY -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoOpenL(const TDesC& /*aStoreName*/, MSmlSyncRelationship& aContext, - TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoOpenL"); - - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - if (iDataBaseOpened) - { - User::RequestComplete(iCallerStatus, KErrInUse); - LOGGER_WRITE("CSmsDataStore::DoOpenL failed with KErrInUse."); - return; - } - - *iContext = aContext; - - // Create ChangeFinder object - iChangeFinder = CChangeFinder::NewL(aContext, iKey, iHasHistory, KSmsDataProviderImplUid); - - RegisterSnapshotL(); - - iDataBaseOpened = ETrue; - iCurrentState = ESmsOpenAndWaiting; - User::RequestComplete(iCallerStatus, KErrNone); - - LOGGER_LEAVEFN("CSmsDataStore::DoOpenL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoCancelRequest -// Not supported, does nothing. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoCancelRequest() - { - LOGGER_ENTERFN("CSmsDataStore::DoCancelRequestL"); - LOGGER_LEAVEFN("CSmsDataStore::DoCancelRequestL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoStoreName -// Returns the name of the DataStore -// ----------------------------------------------------------------------------- -const TDesC& CSmsDataStore::DoStoreName() const - { - LOGGER_ENTERFN("CSmsDataStore::DoStoreName"); - - if (iDataBaseOpened) - { - LOGGER_LEAVEFN("CSmsDataStore::DoStoreName"); - return KNSmlDefaultLocalDbName; - } - - LOGGER_LEAVEFN("CSmsDataStore::DoStoreName"); - return KNullDesC; - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoBeginTransactionL -// Transactions are not supported. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoBeginTransactionL() - { - LOGGER_ENTERFN("CSmsDataStore::DoBeginTransactionL"); - LOGGER_WRITE("CSmsDataStore::DoBeginTransactionL leaved with KErrNotSupported.") - User::Leave(KErrNotSupported); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoCommitTransactionL -// Transactions are not supported. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoCommitTransactionL(TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoCommitTransactionL"); - LOGGER_WRITE("CSmsDataStore::DoCommitTransactionL failed with KErrNotSupported."); - - iCallerStatus = &aStatus; - User::RequestComplete(iCallerStatus, KErrNotSupported); - - LOGGER_LEAVEFN("CSmsDataStore::DoCommitTransactionL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoRevertTransaction -// Transactions are not supported. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoRevertTransaction(TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoRevertTransaction"); - iCallerStatus = &aStatus; - User::RequestComplete(iCallerStatus, KErrNone); - LOGGER_LEAVEFN("CSmsDataStore::DoRevertTransaction"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoBeginBatchL -// Batching is not supported. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoBeginBatchL() - { - LOGGER_ENTERFN("CSmsDataStore::DoBeginBatchL"); - LOGGER_WRITE("CSmsDataStore::DoBeginBatchL leaved with KErrNotSupported."); - User::Leave(KErrNotSupported); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoCommitBatchL -// Batching is not supported -// ----------------------------------------------------------------------------- -// -void CSmsDataStore::DoCommitBatchL(RArray& /*aResultArray*/, TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoCommitBatchL"); - LOGGER_WRITE("CSmsDataStore::DoCommitBatchL failed with KErrNotSupported"); - - iCallerStatus = &aStatus; - User::RequestComplete(iCallerStatus, KErrNotSupported); - - LOGGER_LEAVEFN("CSmsDataStore::DoCommitBatchL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoCancelBatch -// Batching is not supported -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoCancelBatch() - { - LOGGER_ENTERFN("CSmsDataStore::DoCancelBatch"); - LOGGER_LEAVEFN("CSmsDataStore::DoCancelBatch"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoSetRemoteStoreFormatL -// Not supported -// ----------------------------------------------------------------------------- -// -void CSmsDataStore::DoSetRemoteStoreFormatL(const CSmlDataStoreFormat& /*aServerDataStoreFormat*/) - { - LOGGER_ENTERFN("CSmsDataStore::DoSetRemoteStoreFormatL"); - LOGGER_LEAVEFN("CSmsDataStore::DoSetRemoteStoreFormatL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoSetRemoteMaxObjectSize -// Not supported -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoSetRemoteMaxObjectSize(TInt /*aServerMaxObjectSize*/) - { - LOGGER_ENTERFN("CSmsDataStore::DoSetRemoteMaxObjectSize"); - LOGGER_LEAVEFN("CSmsDataStore::DoSetRemoteMaxObjectSize"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoMaxObjectSize -// -// ----------------------------------------------------------------------------- -TInt CSmsDataStore::DoMaxObjectSize() const - { - LOGGER_ENTERFN("CSmsDataStore::DoMaxObjectSize"); - LOGGER_LEAVEFN("CSmsDataStore::DoMaxObjectSize"); - return 0; - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoOpenItemL -// Opens item in the DataStore, reads it (either completely or partially) -// to the temporary buffer where it can be later read to the remote database. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoOpenItemL(TSmlDbItemUid aUid, TBool& aFieldChange, - TInt& aSize, TSmlDbItemUid& aParent, TDes8& aMimeType, - TDes8& aMimeVer, TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoOpenItemL"); - - LOGGER_WRITE_1("Opening item %d.", aUid); - - // Store these for later use - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Check that we're in a proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoOpenItemL, Incorrect state: %d", iCurrentState); - } - - // Allocate new buffer - SAFEDELETE(iDataBuffer); - iDataBuffer = CBufFlat::NewL(KDataBufferSize); - - TBool userFolderFound(EFalse); - TTime timeStamp; - TPtrC folderName; - userFolderFound = iMsvApi->FindUserFolderL(aUid, folderName, timeStamp); - if (userFolderFound) - { - iMimeType = EMessageFolder; - iParentId = KMsvMyFoldersEntryIdValue; - - iFolderObjectParser->SetName(folderName); - iFolderObjectParser->SetCreatedDate(timeStamp.DateTime()); - iFolderObjectParser->SetModifiedDate(timeStamp.DateTime()); - iFolderObjectParser->ExportFolderXmlL(*iDataBuffer); - } - else - { - iMimeType = ESmsMessage; - iMessageParser->ResetAll(); - - TBool unread; - TMsvId parent; - TRAPD(error, iMsvApi->RetrieveSML(aUid, parent, *iMessageParser, unread)); - if(error != KErrNone) - { - User::RequestComplete(iCallerStatus, KErrNotFound); - LOGGER_WRITE_1("RetrieveSML(aUid, &parser, flags) leaved with %d.", error); - return; - } - - iParentId = parent; - iMessageParser->ConstructMessageL(*iDataBuffer); - } - - // Adjust buffer - iDataBuffer->Compress(); - iReaderPosition = 0; - iCurrentState = ESmsItemOpen; - - // Return these - aFieldChange = EFalse; - aParent = iParentId; - aSize = iDataBuffer->Size(); - - if (iMimeType == EMessageFolder) - { - TInt targetLength = KFolderMimeType().Length(); - if (aMimeType.MaxLength() < targetLength) - targetLength = aMimeType.MaxLength(); - aMimeType.Copy(KFolderMimeType().Ptr(), targetLength); - - // Set mime version (do not exceed the allocated buffer) - targetLength = KFolderMimeVersion().Length(); - if (aMimeVer.MaxLength() < targetLength) - targetLength = aMimeVer.MaxLength(); - aMimeVer.Copy(KFolderMimeVersion().Ptr(), targetLength); - } - else // ESmsMessage - { - TInt targetLength = KSmsMimeType().Length(); - if (aMimeType.MaxLength() < targetLength) - targetLength = aMimeType.MaxLength(); - aMimeType.Copy(KSmsMimeType().Ptr(), targetLength); - - // Set mime version (do not exceed the allocated buffer) - targetLength = KSmsMimeVersion().Length(); - if (aMimeVer.MaxLength() < targetLength) - targetLength = aMimeVer.MaxLength(); - aMimeVer.Copy(KSmsMimeVersion().Ptr(), targetLength); - } - - // Signal we're complete - User::RequestComplete(iCallerStatus, KErrNone); - - LOGGER_LEAVEFN("CSmsDataStore::DoOpenItemL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoCreateItemL -// Create new item to the message store. -// Return the id number of the newly created item -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoCreateItemL(TSmlDbItemUid& aUid, TInt aSize, - TSmlDbItemUid aParent, const TDesC8& aMimeType, const TDesC8& /*aMimeVer*/, - TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoCreateItemL"); - - // Store some variables for further use - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Ensure that we're in proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("Incorrect state: %d", iCurrentState); - } - - // Check MIME type - LOG(aMimeType); - if (aMimeType.Compare( KFolderMimeType() ) == 0) - { - iMimeType = EMessageFolder; - } - else if (aMimeType.Compare( KSmsMimeType() ) == 0) - { - iMimeType = ESmsMessage; - } - else - { - User::RequestComplete( iCallerStatus, KErrNotSupported ); - LOGGER_WRITE("Bad MIME type"); - return; - } - - LOGGER_WRITE_1( "Parent folder: %d", aParent); - if ((iMimeType == EMessageFolder && aParent != KMsvMyFoldersEntryIdValue) || - (iMimeType == ESmsMessage && !iMsvApi->ValidFolderL(aParent))) - { - User::RequestComplete( iCallerStatus, KErrNotSupported ); - LOGGER_WRITE( "Bad parent folder"); - return; - } - - // Ensure that we've got enough disk space for the item - if(iMsvApi->DiskSpaceBelowCriticalLevelL(aSize)) - { - User::RequestComplete(iCallerStatus, KErrDiskFull); - LOGGER_WRITE("Disk full"); - return; - } - - // Store uid values - iCreatedUid = &aUid; - iParentId = aParent; - - // Create message buffer, item will be written into this buffer - SAFEDELETE(iDataBuffer); - iDataBuffer = CBufFlat::NewL(KDataBufferSize); - iWriterPosition = 0; - iCurrentState = ESmsItemCreating; - - // Signal we're complete - User::RequestComplete( iCallerStatus, KErrNone ); - - LOGGER_LEAVEFN("CSmsDataStore::DoCreateItemL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoReplaceItemL -// Begin the replace operation, ensure that the item really exists -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoReplaceItemL(TSmlDbItemUid aUid, TInt aSize, TSmlDbItemUid aParent, - TBool /*aFieldChange*/, TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoReplaceItemL"); - LOGGER_WRITE_1("Replacing item %d.", aUid); - LOGGER_WRITE_1("Parent folder: %d.", aParent); - - // Store some variables for further use - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Ensure proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("Incorrect state: %d", iCurrentState); - } - - // Ensure that we've got enough disk space for the item - if (iMsvApi->DiskSpaceBelowCriticalLevelL(aSize)) - { - User::RequestComplete(iCallerStatus, KErrDiskFull); - LOGGER_WRITE("Disk full"); - return; - } - - // Find entry - CMsvEntry* entry(NULL); - TRAPD(error, entry = iMsvApi->MsvSessionL()->GetEntryL(aUid)); - if (error != KErrNone) - { - User::RequestComplete(iCallerStatus, KErrNotFound); - LOGGER_WRITE("Item not found"); - return; - } - - // This is the representation of the actual message - TMsvEntry tEntry = entry->Entry(); - - // Not needed anymore - SAFEDELETE(entry); - - // Check entry type - if (tEntry.iType == KUidMsvFolderEntry) - { - iMimeType = EMessageFolder; - LOGGER_WRITE("Type: folder"); - } - else - { - iMimeType = ESmsMessage; - LOGGER_WRITE("Type: SMS message"); - } - - if ((iMimeType == EMessageFolder && aParent != KMsvMyFoldersEntryIdValue) || - (iMimeType == ESmsMessage && !iMsvApi->ValidFolderL(aParent) || - (aParent != tEntry.Parent()))) - { - User::RequestComplete(iCallerStatus, KErrNotSupported); - LOGGER_WRITE_1("Bad parent folder, message entry parent is %d", tEntry.Parent()); - return; - } - - // Store these for further use - iParentId = aParent; - iCurrentId = aUid; - - // Create temporary buffer for message data, item will be written here - SAFEDELETE(iDataBuffer); - iDataBuffer = CBufFlat::NewL(KDataBufferSize); - iWriterPosition = 0; - iCurrentState = ESmsItemUpdating; - - // Signal we're complete - User::RequestComplete(iCallerStatus, KErrNone); - - LOGGER_LEAVEFN("CSmsDataStore::DoReplaceItemL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoReadItemL -// Read specified amount of data from the temporary buffer -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoReadItemL(TDes8& aBuffer) - { - LOGGER_ENTERFN("CSmsDataStore::DoReadItemL"); - - // Check that we're in proper state - if (iCurrentState != ESmsItemOpen || !iDataBuffer) - { - LOGGER_WRITE("CSmsDataStore::DoReadItemL leaved with KErrNotReady."); - User::Leave(KErrNotReady); - } - - if (iReaderPosition == KDataBufferNotReady) - { - LOGGER_WRITE("CSmsDataStore::DoReadItemL leaved with KErrEof."); - User::Leave(KErrEof); - } - - // This is how much we've got left in the buffer - TInt left = iDataBuffer->Size() - iReaderPosition; - - // Make sure that there's something to read - if(left > 0) - { - // This is how much there's space in the destination buffer - TInt destSize = aBuffer.MaxSize(); - - // This is how much we can read - TInt toRead = destSize < left ? destSize : left; - - // Read the data from the buffer, then update the position - iDataBuffer->Read(iReaderPosition, aBuffer, toRead); - iReaderPosition += toRead; - } - else - { - iReaderPosition = KDataBufferNotReady; - LOGGER_WRITE("CSmsDataStore::DoReadItemL leaved with KErrEof."); - User::Leave(KErrEof); - } - - LOGGER_LEAVEFN("CSmsDataStore::DoReadItemL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoWriteItemL -// Write specified amount of data to the temporary buffer -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoWriteItemL(const TDesC8& aData) - { - LOGGER_ENTERFN("CSmsDataStore::DoWriteItemL"); - - // Ensure that we're in proper state - if ( iCurrentState != ESmsItemCreating && iCurrentState != ESmsItemUpdating ) - { - LOGGER_WRITE("CSmsDataStore::DoWriteItemL leaved with KErrNotReady."); - User::Leave( KErrNotReady ); - } - - // Calculate total size - TInt totalSize = aData.Size() + iDataBuffer->Size(); - - // Check that we have enough disk space to store this much data - if ( iMsvApi->DiskSpaceBelowCriticalLevelL( totalSize ) ) - { - LOGGER_WRITE("CSmsDataStore::DoWriteItemL leaved with KErrDiskFull."); - User::Leave(KErrDiskFull); - } - - // Add data to buffer - iDataBuffer->InsertL( iWriterPosition, aData ); - iWriterPosition += aData.Size(); - - LOGGER_LEAVEFN("CSmsDataStore::DoWriteItemL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoCommitItemL -// Commits item from temporary buffer to the message store -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoCommitItemL(TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoCommitItemL"); - TInt error(KErrNone); - - // Store some variables - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Check that we're in proper state - if ((iCurrentState != ESmsItemCreating && iCurrentState != ESmsItemUpdating) || !iDataBuffer) - { - User::RequestComplete(iCallerStatus, KErrNotReady); - LOGGER_WRITE_1("Bad state: %d", iCurrentState); - return; - } - - iDataBuffer->Compress(); - TInt size = iDataBuffer->Size(); - - // Variable to hold the information whether SMS message is unread or not for Change Finder. - // For message folders this information is not relevant and value is EFalse by default. - TBool unread(EFalse); - - if ( iMimeType == ESmsMessage ) - { - // Reset parser - iMessageParser->ResetAll(); - - // This function returns the index, where the parsing ends (>=0) - // (the error codes are in the range below 0) - error = iMessageParser->ParseMessageL(iDataBuffer->Ptr(0)); - - if ( error >= 0 ) - { - unread = iMessageParser->iStatus.Compare(KVMsgStatusUnread) == 0 ? ETrue : EFalse; - - // Check the datastore state. We're either creating or updating an item. - if (iCurrentState == ESmsItemCreating) - { - TMsvId id; - TMsvId temporaryParent = iParentId; - // in message sending case, save message first to drafts folder - if ( iParentId == KMsvGlobalOutBoxIndexEntryId ) - { - temporaryParent = KMsvDraftEntryId; - } - - TRAP(error, iMsvApi->AddSML(*iMessageParser, temporaryParent, id)); - if ( error == KErrNone ) - { - *iCreatedUid = id; - iCurrentId = id; - } - else - { - LOGGER_WRITE_1("iMsvApi->AddSML leaved with %d.", error); - } - } - else // EItemUpdating - { - if ( iParentId == KMsvGlobalInBoxIndexEntryId ) - { - // For arrived message in Inbox only status is updated - TRAP(error, iMsvApi->UpdateSMStatusL( iCurrentId, *iMessageParser)); - } - else - { - TRAP(error, iMsvApi->ReplaceSML(iCurrentId, *iMessageParser)); - } - if(error != KErrNone) - { - LOGGER_WRITE_1("iMsvApi->ReplaceSML leaved with %d.", error); - } - } - } - else - { - LOGGER_WRITE_1("iMessageParser->ParseMessageL failed with %d.", error); - } - } // if (iMimeType == ESmsMessage) - - else // EMessageFolder - { - error = iFolderObjectParser->ImportFolderXml(iDataBuffer->Ptr(0)); - - if ( error == KErrNone ) - { - const TDesC& name = iFolderObjectParser->GetName(); - - if ( name.Length() > 0 ) - { - if ( iCurrentState == ESmsItemCreating ) - { - TMsvId id; - error = iMsvApi->AddUserFolderL( id, name ); - if ( error == KErrNone ) - { - *iCreatedUid = id; - iCurrentId = id; - } - else - { - LOGGER_WRITE_1("iMsvApi->AddFolderL failed with %d", error); - } - } - else // Updating - { - error = iMsvApi->UpdateUserFolderL( iCurrentId, name ); - if ( error != KErrNone ) - { - LOGGER_WRITE_1("iMsvApi->UpdateFolderL failed with %d", error); - } - } - } - else - { - LOGGER_WRITE("No folder name available"); - error = KErrArgument; - } - } - } - - // Send the message if the parent folder is outbox - if( iParentId == KMsvGlobalOutBoxIndexEntryId && - iMimeType == ESmsMessage && - iCurrentState == ESmsItemCreating && - error == KErrNone ) - { - LOGGER_WRITE("CSmsDataStore::DoCommitItemL, sending message."); - - TRAP( error, iMsvApi->MoveSML( iCurrentId, iParentId ) ); - if( error != KErrNone ) - { - LOGGER_WRITE_1("Moving to folder failed with %d", error); - iMsvApi->DeleteSML( iCurrentId ); - } - else - { - TRAP( error, iMsvApi->SendSML(iCurrentId) ); - if ( error != KErrNone ) - { - LOGGER_WRITE_1("iMsvApi->SendSML failed with %d.", error); - iMsvApi->DeleteSML( iCurrentId ); - } - } - } - - if ( error == KErrNone ) // Update Change Finder - { - CMsvSession* msvSession = iMsvApi->MsvSessionL(); - TMsvId service; - TMsvEntry msgEntry; - - // Inform ChangeFinder of added item - TSnapshotItem snapshotItem( iCurrentId, iParentId, unread ); - error = msvSession->GetEntry( iCurrentId, service, msgEntry ); - - if ( error == KErrNone ) - { - snapshotItem.SetLastChangedDate( msgEntry.iDate ); - if ( iMimeType == EMessageFolder ) - { - snapshotItem.SetFolderNameL( msgEntry.iDetails ); - } - - if ( iCurrentState == ESmsItemCreating ) - { - iChangeFinder->ItemAddedL( snapshotItem ); - } - else - { - iChangeFinder->ItemUpdatedL( snapshotItem ); - } - } - else - { - LOGGER_WRITE_1("CMsvSession::GetEntry failed with %d", error); - } - } - - // Reset and destroy write buffer, it's no longer needed - iWriterPosition = KDataBufferNotReady; - SAFEDELETE(iDataBuffer); - - // We'll be waiting for next event, signal we're done - iCurrentState = ESmsOpenAndWaiting; - User::RequestComplete(iCallerStatus, error); - - LOGGER_LEAVEFN("CSmsDataStore::DoCommitItemL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoCloseItem -// Closes open item in the data store -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoCloseItem() - { - LOGGER_ENTERFN("CSmsDataStore::DoCloseItem"); - - // Make sure that we're opened an item - if ( iCurrentState == ESmsItemOpen ) - { - // Reset read buffer - iReaderPosition = KDataBufferNotReady; - SAFEDELETE(iDataBuffer); - - // Start to wait for the next operation - iCurrentState = ESmsOpenAndWaiting; - } - else - { - LOGGER_WRITE_1("CSmsDataStore::DoCloseItem, invalid state %d.", iCurrentState); - } - - LOGGER_LEAVEFN("CSmsDataStore::DoCloseItem"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoMoveItemL -// Moves item from one folder to another in the message store -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoMoveItemL(TSmlDbItemUid aUid, TSmlDbItemUid aNewParent, TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoMoveItemL"); - - LOGGER_WRITE_1("Moving item %d.", aUid); - - // Store some variables for further use - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Check that we're in proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoMoveItemL, Incorrect state: %d", iCurrentState); - } - - TInt error_move(KErrNone); - TRAP(error_move, iMsvApi->MoveSML(aUid, aNewParent)); - if(error_move != KErrNone) - { - User::RequestComplete(iCallerStatus, error_move); - LOGGER_WRITE_1("iMsvApi->MoveSML leaved with %d.", error_move); - return; - } - - // Inform ChangeFinder of the moved item - TSnapshotItem snapshotItem(aUid, aNewParent); - iChangeFinder->ItemMovedL(snapshotItem); - - // Signal we're done - User::RequestComplete(iCallerStatus, KErrNone); - - LOGGER_LEAVEFN("CSmsDataStore::DoMoveItemL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoDeleteItemL -// Removes item from the message store -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoDeleteItemL(TSmlDbItemUid aUid, TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoDeleteItemL"); - - // Store some variables for further use - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Check that we're in proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoDeleteItemL, Incorrect state: %d", iCurrentState); - } - - TInt error(KErrNone); - - // Check if this is a user folder - TBool userFolder = iMsvApi->FindUserFolderL(aUid); - - if (userFolder) - { - LOGGER_WRITE_1("Delete user folder %d", aUid); - - // First delete SMS messages under the folder - CMsvEntrySelection* deletedItems = iMsvApi->CleanFolderGetMsvIdsL(aUid); - CleanupStack::PushL(deletedItems); - - for (TInt i = 0; i < deletedItems->Count(); i++) - { - TMsvId id = deletedItems->At(i); - TSnapshotItem item(id); - iChangeFinder->ItemDeletedL(item); - } - CleanupStack::PopAndDestroy(deletedItems); - - // Then delete the actual folder - // Note: folder is not deleted if it contains other message items (like MMS) - TRAP(error, iMsvApi->DeleteUserFolderL(aUid)); - } - else - { - LOGGER_WRITE_1("Delete SMS message %d", aUid); - TRAP(error, iMsvApi->DeleteSML(aUid)) - } - - if ( error != KErrNone ) - { - User::RequestComplete(iCallerStatus, error); - LOGGER_WRITE_1("iMsvApi function call leaved with %d", error); - return; - } - - // Inform ChangeFinder of the removed item - TSnapshotItem item(aUid); - iChangeFinder->ItemDeletedL(item); - - // Signal we're done - User::RequestComplete(iCallerStatus, KErrNone); - - LOGGER_LEAVEFN("CSmsDataStore::DoDeleteItemL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoSoftDeleteItemL -// Soft delete is not supported. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoSoftDeleteItemL(TSmlDbItemUid /*aUid*/, TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoSoftDeleteItemL"); - - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - User::RequestComplete(iCallerStatus, KErrNotSupported); - - LOGGER_LEAVEFN("CSmsDataStore::DoSoftDeleteItemL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoDeleteAllItemsL -// Deletes all items in the standard folders of message store -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoDeleteAllItemsL(TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoDeleteAllItemsL"); - - // Store some variables for further use - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Check that we're in proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoDeleteAllItemsL, Incorrect state: %d", iCurrentState); - } - - // Delete all messages in the standard folders (except outbox) - iMsvApi->CleanFolderL(KMsvGlobalInBoxIndexEntryId); - iMsvApi->CleanFolderL(KMsvDraftEntryId); - iMsvApi->CleanFolderL(KMsvSentEntryId); - - iMsvApi->CleanUserFoldersL(); - - iChangeFinder->ResetL(); - - User::RequestComplete(iCallerStatus, KErrNone); - - LOGGER_LEAVEFN("CSmsDataStore::DoDeleteAllItemsL"); - } - - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoHasSyncHistory -// This method returns ETrue if Data Store has history information. -// Slow-sync will be used if Data Store does not have history information. -// ----------------------------------------------------------------------------- -TBool CSmsDataStore::DoHasSyncHistory() const - { - LOGGER_WRITE_1("CSmsDataStore::DoHasSyncHistory return %d", (TInt)iHasHistory ); - - // iHasHistory is initialized in DoOpenL method - return iHasHistory; - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoAddedItems -// This method returns UIDs of added items. Those items are added after previous -// synchronization with current synchronization relationship. -// ----------------------------------------------------------------------------- -const MSmlDataItemUidSet& CSmsDataStore::DoAddedItems() const - { - LOGGER_ENTERFN("CSmsDataStore::DoAddedItems"); - - // Ensure that we're in a proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoAddedItems, invalid state %d.", iCurrentState); - } - - TInt error(KErrNone); - - // Clear new-items array - iNewItems->Reset(); - - // Search for new items - TRAP( error, iChangeFinder->FindNewItemsL(*iNewItems) ); - if ( error != KErrNone ) - { - LOGGER_WRITE_1("CSmsDataStore::DoAddedItems, iChangeFinder->FindNewItemsL leaved with %d.", error); - } - - LOGGER_WRITE_1("New item count: %d.", iNewItems->ItemCount()); - LOGGER_LEAVEFN("CSmsDataStore::DoAddedItems"); - - return *iNewItems; - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoDeletedItems -// -// ----------------------------------------------------------------------------- -const MSmlDataItemUidSet& CSmsDataStore::DoDeletedItems() const - { - LOGGER_ENTERFN("CSmsDataStore::DoDeletedItemsL"); - - // Ensure that we're in a proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoDeletedItems, invalid state %d.", iCurrentState); - } - - TInt error(KErrNone); - - // Clear deleted-items array - iDeletedItems->Reset(); - - // Search for deleted items - TRAP( error, iChangeFinder->FindDeletedItemsL(*iDeletedItems) ); - if ( error != KErrNone ) - { - LOGGER_WRITE_1("CSmsDataStore::DoDeletedItems, iChangeFinder->FindDeletedItemsL leaved with %d.", error); - } - - - LOGGER_WRITE_1("Deleted item count: %d.", iDeletedItems->ItemCount()); - LOGGER_LEAVEFN("CSmsDataStore::DoDeletedItemsL"); - return *iDeletedItems; - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoSoftDeletedItems -// Not directly supported, equals to "hard" delete -// ----------------------------------------------------------------------------- -const MSmlDataItemUidSet& CSmsDataStore::DoSoftDeletedItems() const - { - TRACE_FUNC; - - // Return empty array as a result - iSoftDeletedItems->Reset(); - return *iSoftDeletedItems; - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoModifiedItems -// Finds all modified items in the data store -// ----------------------------------------------------------------------------- -const MSmlDataItemUidSet& CSmsDataStore::DoModifiedItems() const - { - LOGGER_ENTERFN("CSmsDataStore::DoModifiedItems"); - - // Ensure that we're in a proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoModifiedItems, invalid state %d.", iCurrentState); - } - - TInt error(KErrNone); - - // Clear updated-items array - iUpdatedItems->Reset(); - - // Search for updated items - TRAP( error, iChangeFinder->FindChangedItemsL(*iUpdatedItems) ) - if ( error != KErrNone ) - { - LOGGER_WRITE_1("CSmsDataStore::DoModifiedItems, iChangeFinder->FindChangedItemsL leaved with %d.", error); - } - else - { - TRAP( error, iChangeFinder->FindMovedItemsL(*iUpdatedItems) ); - if( error != KErrNone ) - { - LOGGER_WRITE_1("CSmsDataStore::DoModifiedItems, iChangeFinder->FindMovedItemsL leaved with %d.", error); - } - } - - LOGGER_WRITE_1("Modified item count: %d.", iUpdatedItems->ItemCount()); - LOGGER_LEAVEFN("CSmsDataStore::DoModifiedItems"); - return *iUpdatedItems; - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoMovedItems -// Moved items not supported (handled as replaced items) -// ----------------------------------------------------------------------------- -const MSmlDataItemUidSet& CSmsDataStore::DoMovedItems() const - { - TRACE_FUNC; - - // Clear moved-items array - iMovedItems->Reset(); - - return *iMovedItems; - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoResetChangeInfoL -// Resets change history in the data store. All content is considered -// new in the data store point of view. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoResetChangeInfoL(TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoResetChangeInfoL"); - - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Check that we're in proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoResetChangeInfoL, invalid state %d.", iCurrentState); - } - - // Reset change info in ChangeFinder - iChangeFinder->ResetL(); - iHasHistory = EFalse; - - // Signal we're done - User::RequestComplete(iCallerStatus, KErrNone); - - LOGGER_LEAVEFN("CSmsDataStore::DoResetChangeInfoL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoCommitChangeInfoL -// Commits change info. These items are no longer reported, when change -// information is being queried. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoCommitChangeInfoL(TRequestStatus& aStatus, const MSmlDataItemUidSet& aItems) - { - LOGGER_ENTERFN("CSmsDataStore::DoCommitChangeInfoL(MSmlDataItemUidSet)"); - LOGGER_WRITE_1("Item count: %d", aItems.ItemCount()); - - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Ensure that we're in a proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoCommitChangeInfoL, invalid state %d.", iCurrentState); - } - - // Notify ChangeFinder - iChangeFinder->CommitChangesL(aItems); - iHasHistory = ETrue; - - // Signal we're done - User::RequestComplete(iCallerStatus, KErrNone); - - LOGGER_LEAVEFN("CSmsDataStore::DoCommitChangeInfoL"); - } - - -// ----------------------------------------------------------------------------- -// CSmsDataStore::DoCommitChangeInfoL -// Commits change info. There is no more nothing to report when change -// information is being queried. -// ----------------------------------------------------------------------------- -void CSmsDataStore::DoCommitChangeInfoL(TRequestStatus& aStatus) - { - LOGGER_ENTERFN("CSmsDataStore::DoCommitChangeInfoL"); - - iCallerStatus = &aStatus; - *iCallerStatus = KRequestPending; - - // Ensure that we're in a proper state - if (iCurrentState != ESmsOpenAndWaiting) - { - LOGGER_WRITE_1("CSmsDataStore::DoCommitChangeInfoL, invalid state %d.", iCurrentState); - } - - // Notify ChangeFinder - iChangeFinder->CommitChangesL(); - iHasHistory = ETrue; - - // Signal we're done - User::RequestComplete(iCallerStatus, KErrNone); - - LOGGER_LEAVEFN("CSmsDataStore::DoCommitChangeInfoL"); - } - - -// ----------------------------------------------------------------------------- -// CSmsDataStore::RegisterSnapshotL -// Sets Changefinder to compare against current message store content -// ----------------------------------------------------------------------------- -void CSmsDataStore::RegisterSnapshotL() const - { - LOGGER_ENTERFN("CSmsDataStore::RegisterSnapshotL"); - - CSnapshotArray* snapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity ); - CleanupStack::PushL(snapshot); - - // Use only standard folders (outbox isn't synchronized) - LOGGER_WRITE( "KMsvGlobalInBoxIndexEntryId" ); - RegisterFolderL(snapshot, KMsvGlobalInBoxIndexEntryId); - LOGGER_WRITE( "KMsvDraftEntryId" ); - RegisterFolderL(snapshot, KMsvDraftEntryId); - LOGGER_WRITE( "KMsvSentEntryId" ); - RegisterFolderL(snapshot, KMsvSentEntryId); - LOGGER_WRITE( "KMsvGlobalOutBoxIndexEntryId" ); - RegisterFolderL(snapshot, KMsvGlobalOutBoxIndexEntryId); - RegisterUserFoldersL(snapshot); - - // Set new snapshot to compare against - iChangeFinder->SetNewSnapshot(snapshot); - - // Changefinder takes ownership of the snapshot - CleanupStack::Pop(); - - LOGGER_LEAVEFN("CSmsDataStore::RegisterSnapshotL"); - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::RegisterFolderL -// Adds a single folder into the snapshot array -// ----------------------------------------------------------------------------- -TInt CSmsDataStore::RegisterFolderL(CSnapshotArray* aSnapshot, const TMsvId& aId) const - { - LOGGER_ENTERFN("CSmsDataStore::RegisterFolderL"); - - CMsvSession* msvSession = iMsvApi->MsvSessionL(); - - // Get the folder - CMsvEntry* msvEntry = msvSession->GetEntryL(aId); - CleanupStack::PushL(msvEntry); - - // Find all of it's childs - CMsvEntrySelection* messages = msvEntry->ChildrenWithTypeL(KUidMsvMessageEntry); - CleanupStack::PopAndDestroy(); // msvEntry - CleanupStack::PushL(messages); - - TMsvId id; - TMsvEntry msg; - LOGGER_WRITE_1( "messages count %d", messages->Count() ); - for(TInt index=0; indexCount(); index++) - { - TInt result = msvSession->GetEntry(messages->At(index), id, msg); - User::LeaveIfError(result); - - // We're only interested about the SMS content - if(msg.iMtm == KUidMsgTypeSMS) - { - // Create snapshot item - TKeyArrayFix key(iKey); - TSnapshotItem item((TUint) msg.Id(), msg.Parent(), msg.Unread()); - - item.SetLastChangedDate(msg.iDate); - LOGGER_WRITE_1( "item id %d", msg.Id() ); - // Add to snapshot - aSnapshot->InsertIsqL(item, key); - } - else - { - LOGGER_WRITE("Wrong type"); - } - } - - CleanupStack::PopAndDestroy(); // messages - - LOGGER_LEAVEFN("CSmsDataStore::RegisterFolderL"); - - return KErrNone; - } - -// ----------------------------------------------------------------------------- -// CSmsDataStore::RegisterUserFoldersL -// Adds user folder messages into the snapshot array -// ----------------------------------------------------------------------------- -TInt CSmsDataStore::RegisterUserFoldersL(CSnapshotArray* aSnapshot) const - { - LOGGER_ENTERFN("CSmsDataStore::RegisterUserFoldersL"); - - CMsvSession* msvSession = iMsvApi->MsvSessionL(); - - // Get the folder - CMsvEntry* msvEntry = msvSession->GetEntryL(KMsvMyFoldersEntryIdValue); - CleanupStack::PushL(msvEntry); - - // Find all of it's childs - CMsvEntrySelection* folders = msvEntry->ChildrenWithTypeL( KUidMsvFolderEntry ); - CleanupStack::PopAndDestroy( msvEntry ); - CleanupStack::PushL( folders ); - LOGGER_WRITE_1("Folders: %d", folders->Count()); - for ( TInt index = 0; index < folders->Count(); index++ ) - { - TMsvId folderId = folders->At(index); - - if ( folderId != KMsvMyFoldersTemplatesFolderId ) - { - TMsvId service; - TMsvEntry folderEntry; - TInt result = msvSession->GetEntry(folderId, service, folderEntry); - User::LeaveIfError( result ); - - TKeyArrayFix key(iKey); - TBool unread(EFalse); - TSnapshotItem item( (TUint) folderId, folderEntry.Parent(), unread ); - item.SetLastChangedDate( folderEntry.iDate ); - item.SetFolderNameL( folderEntry.iDetails ); - - aSnapshot->InsertIsqL( item, key ); - - RegisterFolderL( aSnapshot, folderId ); - } - } - - CleanupStack::PopAndDestroy( folders ); - - // Register also SMS messages directly under My Folders - RegisterFolderL( aSnapshot, KMsvMyFoldersEntryIdValue ); - - LOGGER_LEAVEFN("CSmsDataStore::RegisterUserFoldersL"); - - return KErrNone; - } -