diff -r 0aa8cc770c8a -r 4a793f564d72 connectivitymodules/SeCon/servers/syncserver/src/sconasynchandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectivitymodules/SeCon/servers/syncserver/src/sconasynchandler.cpp Wed Sep 01 12:20:56 2010 +0100 @@ -0,0 +1,1179 @@ +/* +* Copyright (c) 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: CSconAsyncHandler implementation +* +*/ + + +#include "sconasynchandler.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "sconsyncclientserver.h" +#include "sconsyncrelationship.h" +#include "scondataproviderinfo.h" +#include "debug.h" +#include "logdatastoreformat.h" + +// Data Store interface implementation Uid. +// Load all plugins with this uid. +const TUid KDSEcomIFUid = {0x101F4D3A}; + +const TInt KDefaultExpandSize = 1024; + +// one store per computer, max store count. +const TInt KMaxStoresCount = 10; + +const TInt KDefaultTimeOutInMicroSeconds = 30 * 1000000; // 30 seconds +const TInt KDeleteAllTimeOutInMicroSeconds = 300 * 1000000; // 5 minutes +const TInt KOpenStoreTimeOutInMicroSeconds = 180 * 1000000; // 180 seconds + +CSconAsyncHandler::~CSconAsyncHandler() + { + TRACE_FUNC_ENTRY; + Cancel(); + DoCloseStore(); + delete iItems; + delete iWriteData; + delete iDataStore; + delete iDataProvider; + delete iContext; + delete iStoreFormat; + iStringPool.Close(); + iFs.Close(); + REComSession::FinalClose(); + iChunk.Close(); + delete iTimeOut; + TRACE_FUNC_EXIT; + } + +CSconAsyncHandler::CSconAsyncHandler(): CActive( EPriorityStandard ) + { + TRACE_FUNC; + CActiveScheduler::Add( this ); + } + +CSconAsyncHandler* CSconAsyncHandler::NewL() + { + TRACE_FUNC; + CSconAsyncHandler* self = new(ELeave) CSconAsyncHandler(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +void CSconAsyncHandler::ConstructL() + { + TRACE_FUNC; + User::LeaveIfError( iFs.Connect() ); + TInt err = iFs.CreatePrivatePath( EDriveC ); + LOGGER_WRITE_1("CreatePrivatePath err: %d", err); + iStringPool.OpenL(); + iTimeOut = CCSconTimeOut::NewL( *this ); + } + +// ----------------------------------------------------------------------------- +// CSconAsyncHandler::HandleServiceL() +// Handles the client request +// ----------------------------------------------------------------------------- +// +void CSconAsyncHandler::HandleServiceL( const RMessage2& aMessage ) + { + TRACE_FUNC_ENTRY; + if ( aMessage.Function() == ECancelRequest ) + { + LOGGER_WRITE("ECancelRequest"); + if ( IsActive() ) + { + Cancel(); + LOGGER_WRITE("iMessage.Complete( KErrCancel )"); + CompleteRequest( KErrCancel ); + } + + LOGGER_WRITE("aMessage.Complete( KErrNone )"); + aMessage.Complete( KErrNone ); + TRACE_FUNC_EXIT; + return; + } + + iTimeOut->Start( KDefaultTimeOutInMicroSeconds ); + + iMessage = aMessage; + switch ( aMessage.Function() ) + { + case ESendChunkHandle: + LOGGER_WRITE( "CSconSyncSession::ServiceL() : ESendChunkHandle" ); + HandleChunkMessage(); + break; + + case EListImplementations: + LOGGER_WRITE( "CSconSyncSession::ServiceL() : EListImplementations" ); + ListAllImplementationsL(); + break; + + case EOpenStore: + LOGGER_WRITE( "CSconSyncSession::ServiceL() : EOpenStore" ); + iTimeOut->Start( KOpenStoreTimeOutInMicroSeconds ); + OpenStoreL(); + break; + + case EOpenItem: + OpenItemL(); + break; + case ECreateItem: + CreateItemL(); + break; + case EReplaceItem: + ReplaceItemL(); + break; + case EMoveItem: + MoveItemL(); + break; + case EDeleteItem: + DeleteItemL(); + break; + case ESoftDeleteItem: + SoftDeleteItemL(); + break; + case EDeleteAllItems: + iTimeOut->Start( KDeleteAllTimeOutInMicroSeconds ); + DeleteAllItemsL(); + break; + case EReadParent: + ReadParentL(); + break; + + case EHasHistory: + HasHistoryL(); + break; + case EAddedItems: + AddedItemsL(); + break; + case EDeletedItems: + DeletedItemsL(); + break; + case ESoftDeletedItems: + SoftDeletedItemsL(); + break; + case EModifiedItems: + ModifiedItemsL(); + break; + case EMovedItems: + MovedItemsL(); + break; + case EResetChangeInfo: + ResetChangeInfoL(); + break; + case ECommitChangeInfo: + CommitChangeInfoL(); + break; + case ECloseStore: + CloseStore(); + break; + case ESetSyncTimeStamp: + SetSyncTimeStampL(); + break; + case EGetSyncTimeStamp: + GetSyncTimeStampL(); + break; + case EExportStoreFormat: + ExportStoreFormatL(); + break; + case ESetRemoteStoreFormat: + SetRemoteStoreFormatL(); + break; + + default: + aMessage.Complete(KErrNotSupported); + break; + } + TRACE_FUNC_EXIT; + } + + +void CSconAsyncHandler::RunL() + { + TRACE_FUNC_ENTRY; + LOGGER_WRITE_1("iStatus.Int(): %d", iStatus.Int()); + switch ( iMessage.Function() ) + { + case EOpenStore: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : EOpenStore" ); + CompleteRequest( iStatus.Int() ); + break; + + case EOpenItem: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : EOpenItem" ); + OpenItemCompletedL( iStatus.Int() ); + break; + + case ECreateItem: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : ECreateItem" ); + if (!iCommitInProgress) + { + // Write data to item + CreateItemCompletedL( iStatus.Int() ); + } + else + { + // commit is done, all ready + LOGGER_WRITE( "CSconAsyncHandler::RunL() : ECreateItem, commit done" ); + TPckg pckg(iNewItem); + iMessage.WriteL( 0, pckg, 0); + CompleteRequest( iStatus.Int() ); + } + break; + + case EReplaceItem: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : EReplaceItem" ); + if (!iCommitInProgress) + { + // Write data to item + ReplaceItemCompletedL( iStatus.Int() ); + } + else + { + // commit is done, all ready + LOGGER_WRITE( "CSconAsyncHandler::RunL() : EReplaceItem, commit done" ); + CompleteRequest( iStatus.Int() ); + } + break; + + case EMoveItem: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : EMoveItem" ); + CompleteRequest( iStatus.Int() ); + break; + + case EDeleteItem: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : EDeleteItem" ); + CompleteRequest( iStatus.Int() ); + break; + + case ESoftDeleteItem: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : ESoftDeleteItem" ); + CompleteRequest( iStatus.Int() ); + break; + + case EDeleteAllItems: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : EDeleteAllItems" ); + CompleteRequest( iStatus.Int() ); + break; + + case EReadParent: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : EReadParent" ); + ReadParentCompletedL( iStatus.Int() ); + break; + + case EResetChangeInfo: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : EResetChangeInfo" ); + CompleteRequest( iStatus.Int() ); + break; + + case ECommitChangeInfo: + LOGGER_WRITE( "CSconAsyncHandler::RunL() : ECommitChangeInfo" ); + delete iItems; + iItems = NULL; + CompleteRequest( iStatus.Int() ); + break; + + default: + LOGGER_WRITE("Not asynchronous function") + CompleteRequest( KErrNotSupported ); + break; + } + TRACE_FUNC_EXIT; + } + +TInt CSconAsyncHandler::RunError(TInt aError) + { + LOGGER_WRITE_1("CSconAsyncHandler::RunError() aError: %d", aError); + delete iItems; + iItems = NULL; + delete iWriteData; + iWriteData = NULL; + + if ( IsActive() ) + { + LOGGER_WRITE("IsActive"); + //iDataStore->CancelRequest(); + Cancel(); + } + + if ( iDataStore && iMessage.Function() == EOpenItem ) + { + LOGGER_WRITE( "CSconAsyncHandler::RunError() : EOpenItem" ); + iDataStore->CloseItem(); + } + + CompleteRequest( aError ); + aError = KErrNone; + LOGGER_WRITE_1("CSconAsyncHandler::RunError() : Return %d", aError); + return aError; + //return KErrNone;//aError; + } + +void CSconAsyncHandler::DoCancel() + { + TRACE_FUNC_ENTRY; + iDataStore->CancelRequest(); + iTimeOut->Cancel(); + + if ( iStatus == KRequestPending ) + { + LOGGER_WRITE( "iStatus == KRequestPending" ); + } + + if ( iDataStore && iMessage.Function() == EOpenItem ) + { + LOGGER_WRITE( "CSconAsyncHandler::RunError() : EOpenItem" ); + iDataStore->CloseItem(); + } + + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::TimeOut() + { + TRACE_FUNC_ENTRY; + if ( IsActive() ) + { + Cancel(); + CompleteRequest( KErrCancel ); + } + TRACE_FUNC_EXIT; + } + + +void CSconAsyncHandler::HandleChunkMessage() + { + TRACE_FUNC_ENTRY; + TInt ret ( KErrNone ); + + ret = iChunk.Open( iMessage, 0, EFalse ); + + LOGGER_WRITE_1( "CSconAsyncHandler::HandleChunkMessageL() : ret %d", ret ); + CompleteRequest( ret ); + } + + + +void CSconAsyncHandler::ListAllImplementationsL() + { + TRACE_FUNC_ENTRY; + + RImplInfoPtrArray implInfoArray; + CleanupResetAndDestroyPushL( implInfoArray ); + REComSession::ListImplementationsL( KDSEcomIFUid, implInfoArray ); + + const TInt KDataproviderInfoSize = 250; // 250 bytes should be enought + TInt requiredSize = implInfoArray.Count() * KDataproviderInfoSize; + if ( iChunk.Size() < requiredSize ) + { + User::LeaveIfError( iChunk.Adjust( requiredSize ) ); + } + + RMemWriteStream stream ( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( stream ); + + RSconDataProviderInfoArray dpInfoArray; + CleanupResetAndDestroyPushL( dpInfoArray ); + + // Collect information from dataproviders + for ( TInt i=0; i < implInfoArray.Count(); i++ ) + { + LOGGER_WRITE_1("implInfoArray: %d",i); + CImplementationInformation& implInfo = *implInfoArray[i]; + + CSmlDataProvider* dp(NULL); + TRAPD( err, dp = CSmlDataProvider::NewL( implInfo.ImplementationUid().iUid ) ); + LOGGER_WRITE_2("CSmlDataProvider::NewL, uid(0x%08x) err: %d",implInfo.ImplementationUid().iUid, err ); + if ( !err ) + { + CleanupStack::PushL( dp ); + + CSconDataproviderInfo *dpInfo = CSconDataproviderInfo::NewL(); + CleanupStack::PushL( dpInfo ); + + dpInfo->SetImplementationUid( implInfo.ImplementationUid() ); + LOGGER_WRITE_1("ImplementationUid: 0x%08x", implInfo.ImplementationUid().iUid ); + dpInfo->SetDisplayNameL( implInfo.DisplayName() ); + LOGGER_WRITE_1("DisplayName: %S", &implInfo.DisplayName() ); + + dpInfo->SetDefaultStoreL( dp->DefaultStoreL() ); + LOGGER_WRITE_1("DefaultStoreL: %S", &dp->DefaultStoreL() ); + CDesCArray* stores = dp->ListStoresLC(); + dpInfo->SetStoresL( *stores ); + CleanupStack::PopAndDestroy( stores ); + + dpInfoArray.AppendL( dpInfo ); + CleanupStack::Pop( dpInfo ); + + CleanupStack::PopAndDestroy( dp ); + } + } + + // Wrtie to stream + stream.WriteUint16L( dpInfoArray.Count() ); + for ( TInt i = 0; i < dpInfoArray.Count(); i++ ) + { + CSconDataproviderInfo& dpInfo = *dpInfoArray[i]; + dpInfo.ExternalizeL( stream ); + } + + stream.CommitL(); + + CleanupStack::PopAndDestroy( &dpInfoArray ); + CleanupStack::PopAndDestroy( &stream ); + CleanupStack::PopAndDestroy( &implInfoArray ); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::OpenStoreL() + { + TRACE_FUNC_ENTRY; + if ( iDataStore ) + { + LOGGER_WRITE("Warning: Previous DataStore was not closed properly."); + DoCloseStore(); + } + + // copy data from the chunk + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + + TSmlDataProviderId providerId = readStream.ReadUint32L(); + LOGGER_WRITE_1("providerId: 0x%08x", providerId); + + TInt len = readStream.ReadUint32L(); + HBufC* storeName = HBufC::NewLC(len); + TPtr storeNamePtr = storeName->Des(); + readStream.ReadL(storeNamePtr, len); + LOGGER_WRITE_1("storeName: %S", &storeNamePtr); + + TInt contextUid = readStream.ReadUint32L(); + + LOGGER_WRITE_1("contextIdentifier: 0x%08x", contextUid); + + LOGGER_WRITE("Open provider"); + delete iDataProvider; + iDataProvider = NULL; + iDataProvider = CSmlDataProvider::NewL( providerId ); + + delete iContext; + iContext = NULL; + + delete iStoreFormat; + iStoreFormat = NULL; + + LOGGER_WRITE("Create context"); + iContext = CSconSyncRelationship::NewL( iFs, TUid::Uid(contextUid), providerId ); + + + LOGGER_WRITE("Create NewStoreInstanceLC"); + iDataStore = iDataProvider->NewStoreInstanceLC(); + CleanupStack::Pop( iDataStore ); + + SetActive(); + iStatus = KRequestPending; + LOGGER_WRITE("OpenL"); + TRAPD(err, iDataStore->OpenL(storeNamePtr,*iContext, iStatus)); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->OpenL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + + CleanupStack::PopAndDestroy( storeName ); + CleanupStack::PopAndDestroy( &readStream ); + + TRACE_FUNC_EXIT; + } + + +void CSconAsyncHandler::OpenItemL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + if ( IsActive() ) + { + LOGGER_WRITE("Was still in Active"); + Cancel(); + } + + TSmlDbItemUid itemUid = iMessage.Int0(); + LOGGER_WRITE_1("Open item: %d", itemUid); + + // set default values + iFieldChange = EFalse; + iSize = 0; + iParent = 0; + iMimeType.Copy(KNullDesC); + iMimeVer.Copy(KNullDesC); + + SetActive(); + LOGGER_WRITE("iDataStore->OpenItemL"); + iStatus = KRequestPending; + TRAPD( err, iDataStore->OpenItemL(itemUid,iFieldChange,iSize,iParent,iMimeType,iMimeVer,iStatus)); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->OpenItemL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::OpenItemCompletedL( TInt aError ) + { + TRACE_FUNC_ENTRY; + // item opened, now read it + if ( aError ) + { + CompleteRequest( aError ); + return; + } + LeaveIfNoInstanceL(); + + LOGGER_WRITE_1("item size: %d", iSize); + + TInt totalObjectSize( 0 ); + totalObjectSize+= sizeof(TInt32); // data length + totalObjectSize+= iSize; // data + totalObjectSize+= sizeof(TInt8); // iFieldChange + totalObjectSize+= sizeof(TInt32); // iParent + totalObjectSize+= sizeof(TInt32); // iMimeType + totalObjectSize+= iMimeType.Length(); // iMimeType + totalObjectSize+= sizeof(TInt32); // iMimeVer + totalObjectSize+= iMimeVer.Length(); // iMimeType + + LOGGER_WRITE_1("iChunk.Size(): %d", iChunk.Size()); + LOGGER_WRITE_1("iChunk.MaxSize(): %d", iChunk.MaxSize()); + LOGGER_WRITE_1("totalObjectSize: %d", totalObjectSize); + + if ( iChunk.Size() < totalObjectSize ) + { + LOGGER_WRITE("adjust chunk"); + TInt err = iChunk.Adjust( totalObjectSize ); + LOGGER_WRITE_1("Chunk.Adjust err: %d", err); + User::LeaveIfError( err ); + } + LOGGER_WRITE_1("new Chunk size: %d", iChunk.Size()); + LOGGER_WRITE_1("new ChunkMaxSize(): %d", iChunk.MaxSize()); + RMemWriteStream stream ( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( stream ); + + LOGGER_WRITE("ReadItemL"); + HBufC8* tempBuf = HBufC8::NewLC(iSize); + TPtr8 tempPtr = tempBuf->Des(); + + TUint8* ptr = (TUint8*) tempPtr.Ptr(); + + TPtr8 tempPtr2( ptr, 0, iSize ); + LOGGER_WRITE_1( "tempPtr2.Size(): %d", tempPtr2.Size()); + iDataStore->ReadItemL( tempPtr2 ); + LOGGER_WRITE("ReadItemL -ok"); + + LOGGER_WRITE_1("readed Length: %d", tempPtr2.Length() ); + LOGGER_WRITE_1("readed Size: %d", tempPtr2.Size() ); + + LOGGER_WRITE8_1("iMimeType: %S", &iMimeType ); + LOGGER_WRITE_1("iMimeType.Length(): %d", iMimeType.Length() ); + LOGGER_WRITE_1("iMimeType Size: %d", iMimeType.Size() ); + + LOGGER_WRITE8_1("iMimeVer: %S", &iMimeVer ); + LOGGER_WRITE_1("iMimeVer.Length(): %d", iMimeVer.Length() ); + LOGGER_WRITE_1("iMimeVer Size: %d", iMimeVer.Size() ); + + iDataStore->CloseItem(); + LOGGER_WRITE("Write to chunk"); + stream.WriteInt32L( tempPtr2.Length() ); + stream.WriteL( tempPtr2 ); + CleanupStack::PopAndDestroy( tempBuf ); + + stream.WriteInt8L( (TInt)iFieldChange ); + stream.WriteInt32L( iParent ); + stream.WriteInt32L( iMimeType.Length() ); + stream.WriteL( iMimeType ); + stream.WriteInt32L( iMimeVer.Length() ); + stream.WriteL( iMimeVer ); + + stream.CommitL(); + LOGGER_WRITE("Writed ok"); + CleanupStack::PopAndDestroy( &stream ); + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::CreateItemL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + iCommitInProgress = EFalse; + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + + TSmlDbItemUid parent = readStream.ReadUint32L(); + TInt len = readStream.ReadUint32L(); + readStream.ReadL(iMimeType, len); + len = readStream.ReadUint32L(); + readStream.ReadL(iMimeVer, len); + len = readStream.ReadUint32L(); + delete iWriteData; + iWriteData = NULL; + iWriteData = HBufC8::New(len); + TPtr8 dataPtr = iWriteData->Des(); + readStream.ReadL(dataPtr, len); + CleanupStack::PopAndDestroy( &readStream ); + SetActive(); + iStatus = KRequestPending; + TRAPD(err, iDataStore->CreateItemL( iNewItem, dataPtr.Size(), parent, iMimeType, iMimeVer, iStatus )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->CreateItemL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::CreateItemCompletedL( TInt aError ) + { + TRACE_FUNC_ENTRY; + User::LeaveIfError( aError ); + LeaveIfNoInstanceL(); + // CreateItem completed, now we must write the data to the created item and commit it. + + iDataStore->WriteItemL( iWriteData->Des() ); + delete iWriteData; + iWriteData = NULL; + SetActive(); + iStatus = KRequestPending; + TRAPD(err, iDataStore->CommitItemL( iStatus )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->CommitItemL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + iCommitInProgress = ETrue; + + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::ReplaceItemL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + + iCommitInProgress = EFalse; + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + + TSmlDbItemUid uid = readStream.ReadUint32L(); + TSmlDbItemUid parent = readStream.ReadUint32L(); + TBool fieldChange = readStream.ReadUint8L(); + TInt len = readStream.ReadUint32L(); + delete iWriteData; + iWriteData = NULL; + iWriteData = HBufC8::New(len); + TPtr8 dataPtr = iWriteData->Des(); + readStream.ReadL(dataPtr, len); + + CleanupStack::PopAndDestroy( &readStream ); + SetActive(); + iStatus = KRequestPending; + TRAPD(err,iDataStore->ReplaceItemL( uid,dataPtr.Size(),parent,fieldChange, iStatus )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->CommitItemL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::ReplaceItemCompletedL( TInt aError ) + { + TRACE_FUNC_ENTRY; + User::LeaveIfError( aError ); + LeaveIfNoInstanceL(); + // CreateItem completed, now we must write the data to the created item and commit it. + + iDataStore->WriteItemL( iWriteData->Des() ); + delete iWriteData; + iWriteData = NULL; + + SetActive(); + iStatus = KRequestPending; + TRAPD(err, iDataStore->CommitItemL( iStatus )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->CommitItemL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + iCommitInProgress = ETrue; + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::MoveItemL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + TSmlDbItemUid uid = iMessage.Int0(); + TSmlDbItemUid newParent = iMessage.Int1(); + LOGGER_WRITE_1( "uid: %d", uid ); + LOGGER_WRITE_1( "newParent: %d", newParent ); + + SetActive(); + iStatus = KRequestPending; + TRAPD(err, iDataStore->MoveItemL( uid, newParent, iStatus )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->MoveItemL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::DeleteItemL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + + TSmlDbItemUid uid = iMessage.Int0(); + LOGGER_WRITE_1( "uid: %d", uid ); + + SetActive(); + iStatus = KRequestPending; + TRAPD(err, iDataStore->DeleteItemL( uid, iStatus )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->DeleteItemL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::SoftDeleteItemL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + + TSmlDbItemUid uid = iMessage.Int0(); + LOGGER_WRITE_1( "uid: %d", uid ); + + SetActive(); + iStatus = KRequestPending; + TRAPD(err, iDataStore->SoftDeleteItemL( uid, iStatus )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->SoftDeleteItemL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::DeleteAllItemsL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + + SetActive(); + iStatus = KRequestPending; + TRAPD(err, iDataStore->DeleteAllItemsL( iStatus )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->DeleteAllItemsL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::ReadParentL() + { + TRACE_FUNC_ENTRY; + OpenItemL(); + + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::ReadParentCompletedL( TInt aError ) + { + TRACE_FUNC_ENTRY; + // item opened, now read it + if ( aError ) + { + CompleteRequest( aError ); + return; + } + LeaveIfNoInstanceL(); + + iDataStore->CloseItem(); + + TPckg pckg(iParent); + iMessage.WriteL( 1, pckg, 0); + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::HasHistoryL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + TBool hasHistory = iDataStore->HasSyncHistory(); + + TPckgC pckg(hasHistory); + iMessage.WriteL( 0, pckg, 0); + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::AddedItemsL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + const MSmlDataItemUidSet& items = iDataStore->AddedItems(); + + RMemWriteStream stream ( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( stream ); + items.ExternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::DeletedItemsL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + const MSmlDataItemUidSet& items = iDataStore->DeletedItems(); + + RMemWriteStream stream ( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( stream ); + items.ExternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::SoftDeletedItemsL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + const MSmlDataItemUidSet& items = iDataStore->SoftDeletedItems(); + + RMemWriteStream stream ( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( stream ); + items.ExternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::ModifiedItemsL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + const MSmlDataItemUidSet& items = iDataStore->ModifiedItems(); + + RMemWriteStream stream ( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( stream ); + items.ExternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::MovedItemsL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + const MSmlDataItemUidSet& items = iDataStore->MovedItems(); + + RMemWriteStream stream ( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( stream ); + items.ExternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::ResetChangeInfoL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + SetActive(); + iStatus = KRequestPending; + TRAPD(err, iDataStore->ResetChangeInfoL( iStatus )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->ResetChangeInfoL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::CommitChangeInfoL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + + if ( iItems ) + { + delete iItems; + iItems = NULL; + } + iItems = new (ELeave) CNSmlDataItemUidSet(); + iItems->InternalizeL( readStream ); + + CleanupStack::PopAndDestroy( &readStream ); + + SetActive(); + iStatus = KRequestPending; + TRAPD(err, iDataStore->CommitChangeInfoL( iStatus, *iItems )); + if ( err ) + { + // we are on active state, call request completed (RunL) + LOGGER_WRITE_1("iDataStore->CommitChangeInfoL leaved with err: %d", err); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, err ); + } + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::CloseStore() + { + TRACE_FUNC_ENTRY; + DoCloseStore(); + REComSession::FinalClose(); + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::SetSyncTimeStampL() + { + TRACE_FUNC_ENTRY; + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + TInt relationId = readStream.ReadInt32L(); + TInt providerId = readStream.ReadInt32L(); + CleanupStack::PopAndDestroy( &readStream ); + + CSconSyncRelationship::SetTimeStampL( iFs, TUid::Uid(relationId), providerId); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::GetSyncTimeStampL() + { + TRACE_FUNC_ENTRY; + TInt providerId = iMessage.Int0(); + TInt relationId = iMessage.Int1(); + + TDateTime time; + CSconSyncRelationship::GetTimeStampL( iFs, TUid::Uid(relationId), providerId, time); + + // write timestamp + TPckgC timeBuf(time); + iMessage.WriteL( 2, timeBuf, 0); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::ExportStoreFormatL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + if ( !iDataProvider ) + { + User::Leave( KErrNotReady ); + } + CBufFlat* buffer = CBufFlat::NewL( KDefaultExpandSize ); + CleanupStack::PushL( buffer ); + RBufWriteStream stream( *buffer ); + CleanupClosePushL( stream ); + + const CSmlDataStoreFormat& storeFormat = iDataProvider->StoreFormatL(); + TRAP_IGNORE( TLogDataStoreFormat::LogDataStoreFormatL( _L("iDataProvider->StoreFormatL()"), storeFormat )); + + storeFormat.ExternalizeL( stream ); + + stream.CommitL(); + CleanupStack::PopAndDestroy( &stream ); + buffer->Compress(); + + RMemWriteStream chunkStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( chunkStream ); + + chunkStream.WriteInt32L( buffer->Size() ); + chunkStream.WriteL( buffer->Ptr(0), buffer->Size()); + chunkStream.CommitL(); + CleanupStack::PopAndDestroy( &chunkStream ); + + CleanupStack::PopAndDestroy( buffer ); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::SetRemoteStoreFormatL() + { + TRACE_FUNC_ENTRY; + LeaveIfNoInstanceL(); + + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + + if ( iStoreFormat ) + { + delete iStoreFormat; + iStoreFormat = NULL; + } + iStoreFormat = CSmlDataStoreFormat::NewLC( iStringPool, readStream); + CleanupStack::Pop( iStoreFormat ); + TRAP_IGNORE( TLogDataStoreFormat::LogDataStoreFormatL( _L("iDataProvider->SetRemoteStoreFormatL()"), *iStoreFormat )); + iDataStore->SetRemoteStoreFormatL( *iStoreFormat ); + + CleanupStack::PopAndDestroy( &readStream ); + + CompleteRequest( KErrNone ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::LeaveIfNoInstanceL() + { + if ( !iDataStore ) + { + LOGGER_WRITE("DataStore instance was not ready, leaving KErrNotReady"); + User::Leave( KErrNotReady ); + } + } + +void CSconAsyncHandler::DoCloseStore() + { + TRACE_FUNC_ENTRY; + delete iItems; + iItems = NULL; + delete iWriteData; + iWriteData = NULL; + if ( iDataProvider && iContext ) + { + TInt providerId = iDataProvider->Identifier(); + TInt contextId = iContext->SyncTaskKey(); + TRAP_IGNORE( CSconSyncRelationship::SetTimeStampL( iFs, TUid::Uid(contextId), providerId) ); + } + delete iDataStore; + iDataStore = NULL; + delete iDataProvider; + iDataProvider = NULL; + delete iContext; + iContext = NULL; + delete iStoreFormat; + iStoreFormat = NULL; + + CleanOldStoresL(); + + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::CleanOldStoresL() + { + TRACE_FUNC_ENTRY; + TFileName path; + User::LeaveIfError( iFs.PrivatePath( path ) ); + CDir* dir; + iFs.GetDir( path, KEntryAttNormal, ESortByDate, dir ); + CleanupStack::PushL( dir ); + TInt storesCount(0); + LOGGER_WRITE_1("count: %d", dir->Count() ); + for ( TInt i=dir->Count()-1; i >= 0; i-- ) + { + LOGGER_WRITE_1("dir[%d]", i); + TEntry entry = (*dir)[i]; + LOGGER_WRITE_1("file: %S", &entry.iName); + _LIT(KContextStoreName, "contextstore"); + _LIT(KTimeStoreName, "timestore"); + if ( entry.iName.Find(KContextStoreName) == 0 ) + { + storesCount++; + LOGGER_WRITE_1("storeNro: %d", storesCount); +#ifdef _DEBUG + TTime time = entry.iModified; + TDateTime dt = time.DateTime(); + _LIT(KFormat, "%d.%d %02d:%02d"); + TFileName mod; + mod.Format(KFormat, dt.Day()+1, dt.Month()+1, dt.Hour()+1,dt.Minute() ); + LOGGER_WRITE_1("time: %S", &mod); +#endif + if ( storesCount > KMaxStoresCount ) + { + LOGGER_WRITE_1("delete contextstore: '%S'", &entry.iName ); + iFs.Delete( entry.iName ); + TFileName timeStoreFile; + timeStoreFile = entry.iName.Right(15); + timeStoreFile.Insert(0, KTimeStoreName); + LOGGER_WRITE_1("delete timeStoreFile: %S", &timeStoreFile); + iFs.Delete( timeStoreFile ); + } + } + + } + CleanupStack::PopAndDestroy( dir ); + TRACE_FUNC_EXIT; + } + +void CSconAsyncHandler::CompleteRequest( TInt aError ) + { + TRACE_FUNC; + iTimeOut->Cancel(); + LOGGER_WRITE_1("iMessage.Complete( %d )", aError); + iMessage.Complete( aError ); + }