diff -r 000000000000 -r b497e44ab2fc syncmlfw/ds/hostserver/dshostclient/src/nsmldshostclientsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/syncmlfw/ds/hostserver/dshostclient/src/nsmldshostclientsession.cpp Thu Dec 17 09:07:52 2009 +0200 @@ -0,0 +1,1335 @@ +/* +* Copyright (c) 2005 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: Client Session for DS Host Servers +* +*/ + + +// ------------------------------------------------------------------------------------------------ +// Includes +// ------------------------------------------------------------------------------------------------ +#include +#include +#include + +#include +#include +#include "nsmldbcaps.h" +#include "nsmldshostclientsession.h" +#include "nsmldshostconstants.h" +#include "NSmldbcapsSerializer.h" +#include "nsmldsdpinformation.h" +#include "nsmldshostitem.h" +#include "nsmldsitemmodificationset.h" +#include "nsmlfilter.h" + +// ------------------------------------------------------------------------------------------------ +// Constants +// ------------------------------------------------------------------------------------------------ +_LIT8( KNSmlFilterTypeEXCLUSIVE, "EXCLUSIVE" ); +_LIT8( KNSmlFilterTypeINCLUSIVE, "INCLUSIVE" ); +_LIT8( KNSmlFilterTypeCGI, "syncml::filtertype-cgi" ); + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient - public methods +// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::Connect +// Connects client to Host Servers. +// ------------------------------------------------------------------------------------------------ +TInt RNSmlDSHostClient::Connect( const TDesC& aServerName, const TVersion& aVersion ) + { + iMode = ENSmlNormalMode; + TInt result( CreateSession( aServerName, aVersion ) ); + + if ( result == KErrNotFound || result == KErrServerTerminated ) + { + result = LaunchServer( aServerName ); + if ( result == KErrNone || result == KErrAlreadyExists ) + { + result = CreateSession( aServerName, aVersion ); + } + } + return result; + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::Close +// Closes connection between client and Host Server. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::Close() + { + iChunk.Close(); + RSessionBase::Close(); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CreateChunk +// Creates chunk that is used to transfer data between client and server. +// ------------------------------------------------------------------------------------------------ +TInt RNSmlDSHostClient::CreateChunk() const + { + return iChunk.CreateGlobal( KNullDesC, KNSmlDSHostChunkMinSize, KNSmlDSHostChunkMaxSize ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::SendChunkHandle +// Sends Chunk handle to SyncML DS Host Servers. +// ------------------------------------------------------------------------------------------------ +TInt RNSmlDSHostClient::SendChunkHandle() const + { + TIpcArgs args; + args.Set(0, iChunk); + const TInt error = SendReceive( ENSmlHandleChunk, args ); + return error; + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CreateDataProvidersL +// Creates Data Providers. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CreateDataProvidersL( const RArray& aIds, RArray& aResultArray ) + { + AdjustChunkIfNeededLC( sizeof( TInt32 ) * ( aIds.Count() + 1 ) ); + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + writeStream.WriteInt32L( aIds.Count() ); + + for ( TInt i = 0; i < aIds.Count(); i++ ) + { + writeStream.WriteInt32L( aIds[i] ); + } + + writeStream.CommitL(); + CleanupStack::PopAndDestroy(); // writeStream + + User::LeaveIfError( SendReceive( ENSmlDPOpen, TIpcArgs() ) ); + + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + TInt count( readStream.ReadInt32L() ); + + for ( TInt j = 0; j < count; j++ ) + { + aResultArray.AppendL( readStream.ReadInt32L() ); + } + + CleanupStack::PopAndDestroy(2); // readStream, AdjustChunkIfNeededLC + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CreateAllDataProvidersL +// Creates all possible Data Providers. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CreateAllDataProvidersL( RArray& aIds, const RArray& aExceptIds ) + { + AdjustChunkIfNeededLC( sizeof( TInt32 ) * ( aIds.Count() + 1 ) ); + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + writeStream.WriteInt32L( aExceptIds.Count() ); + + for ( TInt i = 0; i < aExceptIds.Count(); i++ ) + { + writeStream.WriteInt32L( aExceptIds[ i ] ); + } + + writeStream.CommitL(); + CleanupStack::PopAndDestroy(); // writeStream + + User::LeaveIfError( SendReceive( ENSmlDPOpenExcept, TIpcArgs() ) ); + + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + TInt count( readStream.ReadInt32L() ); + + for ( TInt j = 0; j < count; j++ ) + { + aIds.AppendL( readStream.ReadInt32L() ); + } + + CleanupStack::PopAndDestroy(2); // readStream, AdjustChunkIfNeededLC + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::DataProviderInformationL +// +// ------------------------------------------------------------------------------------------------ +TNSmlDPInformation* RNSmlDSHostClient::DataProviderInformationL( const TSmlDataProviderId aId, TInt& aResultCode ) const + { + TNSmlDPInformation* info = NULL; + aResultCode = SendReceive( ENSmlDPInformation, TIpcArgs( aId ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, const_cast( this ) ) ); + if ( aResultCode == KErrNone ) + { + CNSmlDPInformation* dpi = CNSmlDPInformation::NewLC(); + + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + dpi->InternalizeL( readStream ); + + CleanupStack::PopAndDestroy(); //readStream + CleanupStack::Pop( dpi ); + info = dpi->InformationD(); + } + CleanupStack::PopAndDestroy(); //CancelAdjust + return info; + } +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::SupportsOperation +// Asks if Data Provider supports some operation. +// ------------------------------------------------------------------------------------------------ +TBool RNSmlDSHostClient::SupportsOperationL( TUid aOpId, const TSmlDataProviderId aId, TInt& aResultCode ) const + { + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + writeStream.WriteInt32L( aOpId.iUid ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy(); // writeStream + + TPckgBuf pckg; + + aResultCode = SendReceive( ENSmlDPSupportsOperation, TIpcArgs( aId, TIpcArgs::ENothing, &pckg ) ); + return pckg(); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::StoreFormatL +// Creates Data Store format of Data Provider. +// ------------------------------------------------------------------------------------------------ +CNSmlDbCaps* RNSmlDSHostClient::StoreFormatL( const TSmlDataProviderId aId, TInt& aResultCode ) + { + TNSmlDbCapsSerializer ser; + CNSmlDbCaps* dbcaps = NULL; + + aResultCode = SendReceive( ENSmlDPStoreFormat, TIpcArgs( aId ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, this ) ); + + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + dbcaps = ser.InternalizeL( readStream ); + CleanupStack::PopAndDestroy(); // readStream + } + CleanupStack::PopAndDestroy(); //CancelAdjust + + return dbcaps; + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::ListStoresL +// Creates list of Data Store names of Data Provider. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::ListStoresL( CDesCArray* aNameList, const TSmlDataProviderId aId, TInt& aResultCode ) + { + aNameList->Reset(); + aResultCode = SendReceive( ENSmlDPlListStores, TIpcArgs( aId ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, this ) ); + + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + TInt32 i(0), storeCount( readStream.ReadInt32L() ); + + for (; i < storeCount; i++ ) + { + TInt32 length( readStream.ReadInt32L() ); + HBufC* store = HBufC::NewLC( readStream, length ); + + aNameList->AppendL( *store ); + CleanupStack::PopAndDestroy( store ); + } + CleanupStack::PopAndDestroy(); // readStream + } + + CleanupStack::PopAndDestroy(); //CancelAdjust + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::DefaultStoreL +// Creates default name for Data Store of Data Provider. +// ------------------------------------------------------------------------------------------------ +HBufC* RNSmlDSHostClient::DefaultStoreL( const TSmlDataProviderId aId, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDPDefaultStore, TIpcArgs( aId ) ); + if ( aResultCode ) + { + return NULL; + } + + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + + TInt tempLength( readStream.ReadInt32L() ); + HBufC* tempName = HBufC::NewL( readStream, tempLength ); + + CleanupStack::PopAndDestroy(); // readStream + return tempName; + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::SupportedServerFiltersL +// This method returns the set of filters that can be used to send to the Sync Partner. +// ------------------------------------------------------------------------------------------------ +RPointerArray* RNSmlDSHostClient::SupportedServerFiltersL( const TSmlDataProviderId aId, + TSyncMLFilterMatchType& aMatchType, TSyncMLFilterChangeInfo& aChangeInfo, TInt& aResultCode ) const + { + TPckgBuf pckg; + + aResultCode = SendReceive( ENSmlServerFilters, TIpcArgs( aId, TIpcArgs::ENothing, &pckg ) ); + aMatchType = pckg(); + + if ( aResultCode ) + { + return NULL; + } + + aChangeInfo = ESyncMLDefault; + + RPointerArray* array = new ( ELeave ) RPointerArray(); + CleanupRPtrArrayPushL( array ); + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + + CleanupClosePushL( readStream ); + InternalizeFiltersL( readStream, *array ); + CleanupStack::PopAndDestroy(); // readStream + CleanupStack::Pop(); //array + + return array; + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CheckServerFiltersL +// This method updates dynamic filters up-to-date. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CheckServerFiltersL( const TSmlDataProviderId aId, RPointerArray& aFilters, TSyncMLFilterChangeInfo& aChangeInfo, TInt& aResultCode ) const + { + TStreamBuffers* sb = StreamBufferLC(); + sb->iWrite->WriteInt32L( aChangeInfo ); + ExternalizeFiltersL( *sb->iWrite, aFilters ); + sb->iWrite->CommitL(); + + AdjustChunkIfNeededLC( sb->iBuffer->Size() ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + writeStream.WriteL( *sb->iRead ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy(); // writeStream + + aResultCode = SendReceive( ENSmlUpdateServerFilters, TIpcArgs( aId ) ); + + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + + aChangeInfo = static_cast( readStream.ReadInt32L() ); + InternalizeFiltersL( readStream, aFilters ); + CleanupStack::PopAndDestroy(3); // readStream, AdjustChunkIfNeededLC, sb + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CheckSupportedServerFiltersL +// This method checks what filters are supported by server +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CheckSupportedServerFiltersL( const TSmlDataProviderId aId, + const CNSmlDbCaps& aServerDataStoreFormat, const CArrayFix& aFilterInfoArr, + RPointerArray& aFilters, TSyncMLFilterChangeInfo& aChangeInfo, TInt& aResultCode ) const + { + TNSmlDbCapsSerializer ser; + TStreamBuffers* sb = StreamBufferLC(); + + sb->iWrite->WriteInt32L( aChangeInfo ); + ser.ExternalizeL( aServerDataStoreFormat, aFilterInfoArr, *sb->iWrite ); + ExternalizeFiltersL( *sb->iWrite, aFilters ); + sb->iWrite->CommitL(); + + AdjustChunkIfNeededLC( sb->iBuffer->Size() ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + writeStream.WriteL( *sb->iRead ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy(); // writeStream + + aResultCode = SendReceive( ENSmlCheckSupportedServerFilters, TIpcArgs( aId ) ); + + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + aChangeInfo = static_cast( readStream.ReadInt32L() ); + InternalizeFiltersL( readStream, aFilters ); + CleanupStack::PopAndDestroy(); //readStream + } + + CleanupStack::PopAndDestroy(2); //AdjustChunkIfNeededLC, sb + } + +// ------------------------------------------------------------------------------------------------ +// CNSmlDSHostClient::GetFilterL +// Get Filters. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::GetFilterL( const TSmlDataProviderId aId, const TDesC& aStoreName, const RPointerArray& aFilterArray, CNSmlFilter*& aFilter, TSyncMLFilterMatchType aMatchType, TInt& aResultCode ) + { + TStreamBuffers* sb = StreamBufferLC(); + sb->iWrite->WriteInt32L( aMatchType ); + ExternalizeFiltersL( *sb->iWrite, aFilterArray ); + sb->iWrite->CommitL(); + + AdjustChunkIfNeededLC( sb->iBuffer->Size() ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + writeStream.WriteL( *sb->iRead ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy(); // writeStream + + aResultCode = SendReceive( ENSmlFilters, TIpcArgs( aId, &aStoreName ) ); + if ( aResultCode == KErrNone ) + { + GetFilterFromChunkL( aFilter ); + } + + CleanupStack::PopAndDestroy(2); //AdjustChunkIfNeededLC, sb + } + +// ------------------------------------------------------------------------------------------------ +// CNSmlDSHostClient::GetFilterFromChunkL +// creates filter from chunk +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::GetFilterFromChunkL( CNSmlFilter*& aFilter ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + TSyncMLFilterType filterType( static_cast( readStream.ReadInt32L() ) ); + HBufC* query = HBufC::NewLC( readStream, readStream.ReadUint32L() ); + HBufC* recordMimeType = HBufC::NewLC( readStream, readStream.ReadUint32L() ); + HBufC* fieldMimeType = HBufC::NewLC( readStream, readStream.ReadUint32L() ); + + RStringPool pool; + pool.OpenL(); + CleanupClosePushL( pool ); + + //properties + RPointerArray properties; + CleanupStack::PushL( PtrArrCleanupItemRArr( + CSmlDataProperty, &properties ) ); + + TInt count( readStream.ReadUint32L() ); + for ( TInt i = 0; i < count; i++ ) + { + CSmlDataProperty* prop = CSmlDataProperty::NewLC( pool, readStream ); + properties.AppendL( prop ); + CleanupStack::Pop( prop ); + } + + aFilter = CNSmlFilter::NewLC(); + + if ( filterType == ESyncMLTypeInclusive ) + { + aFilter->SetFilterTypeL( KNSmlFilterTypeINCLUSIVE ); + } + else if ( filterType == ESyncMLTypeExclusive ) + { + aFilter->SetFilterTypeL( KNSmlFilterTypeEXCLUSIVE ); + } + + HBufC8* tmpbuf = NULL; + NSmlUnicodeConverter::HBufC8InUTF8LC( *recordMimeType, tmpbuf ); + aFilter->SetFilterMetaTypeL( *tmpbuf ); + CleanupStack::PopAndDestroy(); + NSmlUnicodeConverter::HBufC8InUTF8LC( *fieldMimeType, tmpbuf ); + aFilter->SetFieldMetaTypeL( *tmpbuf ); + CleanupStack::PopAndDestroy(); + NSmlUnicodeConverter::HBufC8InUTF8LC( *query, tmpbuf ); + aFilter->SetRecordL( KNSmlFilterTypeCGI, *tmpbuf ); + CleanupStack::PopAndDestroy(); + + AddFilterPropertiesL( properties, *aFilter ); + + CleanupStack::Pop(); // aFilter + CleanupStack::PopAndDestroy(6); // pool, properties, fieldMimeType, recordMimeType, query, readStream + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::AddFilterPropertiesL +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::AddFilterPropertiesL( const RPointerArray& properties, CNSmlFilter& aFilter ) const + { + TNSmlDbCapsSerializer ser; + for ( TInt i = 0; i < properties.Count(); i++ ) + { + const CSmlDataProperty* prop = properties[i]; + + CNSmlDevInfProp* dip = aFilter.AddFieldDataPropLC( prop->Field().Name().DesC() ); + ser.SetFromL( *prop, *dip ); + CleanupStack::Pop(); // dip + } + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::OpenL +// Opens the data store specified by aStoreName asynchronously. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::OpenL( const TSmlDataProviderId aId, const TDesC& aStoreName, const TDesC& aServerId, const TDesC& aRemoteDB, TInt& aResultCode ) const + { + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + + writeStream.WriteUint32L( aServerId.Length() ); + writeStream << aServerId; + writeStream.WriteUint32L( aRemoteDB.Length() ); + writeStream << aRemoteDB; + + CleanupStack::PopAndDestroy(); // writeStream + + aResultCode = SendReceive( ENSmlDSOpen, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CancelRequest +// Cancel the current asynchronous request. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CancelRequest( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDSCancelRequest, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::BeginTransaction +// Starts the transaction mode. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::BeginTransaction( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + iMode = ENSmlTransactionMode; + aResultCode = SendReceive( ENSmlDSBeginTransaction, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CommitTransaction +// Method will be called at the end of a successful transaction. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CommitTransaction( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + iMode = ENSmlNormalMode; + aResultCode = SendReceive( ENSmlDSCommitTransaction, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::RevertTransaction +// Method will be called to abort an ongoing transaction. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::RevertTransaction( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + iMode = ENSmlNormalMode; + aResultCode = SendReceive( ENSmlDSRevertTransaction, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::BeginBatch +// Starts the batch mode. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::BeginBatch( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + iMode = ENSmlBatchMode; + iAddedUidsBuffer.Reset(); + aResultCode = SendReceive( ENSmlDSBeginBatch, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CommitBatchL +// Method will be called at the end of the batch mode. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CommitBatchL( RArray& aResultArray, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + iMode = ENSmlNormalMode; + + RArray addUids; + CleanupClosePushL( addUids ); + + aResultCode = SendReceive( ENSmlDSCommitBatch, TIpcArgs( aId, &aStoreName ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, this ) ); + + if ( aResultCode == KErrNone ) + { + // First read results + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + TInt resultCount( readStream.ReadInt32L() ); + for ( TInt j = 0; j < resultCount; j++ ) + { + aResultArray.AppendL( readStream.ReadInt32L() ); + } + // Second read uids references that are added + TInt uidsCount( readStream.ReadInt32L() ); + for ( TInt j = 0; j < uidsCount; j++ ) + { + addUids.AppendL( readStream.ReadInt32L() ); + } + CleanupStack::PopAndDestroy(); // readStream + + if ( addUids.Count() != iAddedUidsBuffer.Count() ) + { + User::Leave( KErrUnknown ); + } + else + { + for ( TInt i = 0; i < addUids.Count(); i++ ) + { + *( iAddedUidsBuffer[ i ] ) = addUids[ i ]; + } + } + } + + CleanupStack::PopAndDestroy(2); //CancelAdjust, addUids + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CancelBatchL +// Method will be called to abort an ongoing batch mode. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CancelBatch( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + iMode = ENSmlNormalMode; + aResultCode = SendReceive( ENSmlDSCancelBatch, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::SetRemoteDataStoreFormatL +// Sets the Sync Partner Data Format. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::SetRemoteDataStoreFormatL( const CNSmlDbCaps& aServerDataStoreFormat, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + TNSmlDbCapsSerializer ser; + TStreamBuffers* sb = StreamBufferLC(); + ser.ExternalizeL( aServerDataStoreFormat, *sb->iWrite ); + sb->iWrite->CommitL(); + AdjustChunkIfNeededLC( sb->iBuffer->Size() ); + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + writeStream.WriteL( *sb->iRead ); + CleanupStack::PopAndDestroy(); // writeStream + + aResultCode = SendReceive( ENSmlDSSetDataStoreFormat, TIpcArgs( aId, &aStoreName ) ); + CleanupStack::PopAndDestroy(2); // AdjustChunkIfNeededLC, sb + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::SetRemoteMaxObjectSizeL +// Sets the SyncML server Sync Partner maximum object size. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::SetRemoteMaxObjectSizeL( TInt aServerMaxObjectSize, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + writeStream.WriteInt32L( aServerMaxObjectSize ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy(); // writeStream + + aResultCode = SendReceive( ENSmlDSRemoteMaxObjSize, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::MaxObjectSize +// Gets the Data Store maximum object size which is reported to the SyncML partner. +// ------------------------------------------------------------------------------------------------ +TInt RNSmlDSHostClient::MaxObjectSize( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + TPckgBuf pckg; + aResultCode = SendReceive( ENSmlMaxObjSize, TIpcArgs( aId, &aStoreName, &pckg ) ); + return pckg(); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::OpenItemL +// Opens item at Data Store. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::OpenItemL( TSmlDbItemUid aUid, TBool& aFieldChange, TInt& aSize, TSmlDbItemUid& aParent, HBufC8*& aMimeType, HBufC8*& aMimeVer, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + + CNSmlDSHostItem* item = CNSmlDSHostItem::NewLC(); + item->SetUid( aUid ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + item->ExternalizeL( writeStream ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy(); // writeStream + + aResultCode = SendReceive( ENSmlItemOpen, TIpcArgs( aId, &aStoreName ) ); + + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + item->InternalizeL( readStream ); + + CleanupStack::PopAndDestroy(); // readStream + + aFieldChange = item->FieldChange(); + aSize = item->Size(); + if ( item->ParentUid() != -2 ) + { + aParent = item->ParentUid(); + } + aMimeType = item->MimeType()->AllocLC(); + aMimeVer = item->MimeVer()->AllocLC(); + CleanupStack::Pop(2); //aMimeVer, aMimeType + } + + CleanupStack::PopAndDestroy(); // item + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CreateItemL +// Creates new item to Data Store. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CreateItemL( TSmlDbItemUid& aUid, TInt aSize, TSmlDbItemUid aParent, const TDesC8& aMimeType, const TDesC8& aMimeVer, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + CNSmlDSHostItem* item = CNSmlDSHostItem::NewLC(); + item->SetUid( aUid ); + item->SetSize( aSize ); + item->SetParentUid( aParent ); + item->SetMimeTypeL( aMimeType ); + item->SetMimeVerL( aMimeVer ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + item->ExternalizeL( writeStream ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy(); // writeStream + + aResultCode = SendReceive( ENSmlItemCreate, TIpcArgs( aId, &aStoreName ) ); + + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + item->InternalizeL( readStream ); + + CleanupStack::PopAndDestroy(); // readStream + + aUid = item->Uid(); + iAddedUidBuffer = &aUid; + if ( iMode == ENSmlBatchMode ) + { + iAddedUidsBuffer.AppendL( &aUid ); + } + iItemState = ENSmlItemCreating; + } + + CleanupStack::PopAndDestroy(); // item + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::ReplaceItemL +// Replaces old item at Data Store. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::ReplaceItemL( TSmlDbItemUid aUid, TInt aSize, TSmlDbItemUid aParent, TBool aFieldChange, TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + CNSmlDSHostItem* item = CNSmlDSHostItem::NewLC(); + item->SetUid( aUid ); + item->SetSize( aSize ); + item->SetParentUid( aParent ); + item->SetFieldChange( aFieldChange ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + item->ExternalizeL( writeStream ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy( 2 ); // writeStream, item + + aResultCode = SendReceive( ENSmlItemReplace, TIpcArgs( aId, &aStoreName ) ); + if ( aResultCode == KErrNone ) + { + iItemState = ENSmlItemUpdating; + } + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::ReadItemL +// Reads data from item at Data Store. Item must be opened before this method can be called. +// This method is called until aBuffer is not used totally or method leaves with KErrEof. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::ReadItemL( TDes8& aBuffer, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + RMemWriteStream writeStream; + RMemReadStream readStream; + CleanupClosePushL( writeStream ); + CleanupClosePushL( readStream ); + TInt size( aBuffer.MaxSize() ); + TInt bytesRead(0), pos(0); + aBuffer.Zero(); + + do + { + writeStream.Open( iChunk.Base(), iChunk.Size() ); + writeStream.WriteInt32L( size ); + + aResultCode = SendReceive( ENSmlItemRead, TIpcArgs( aId, &aStoreName ) ); + if ( aResultCode != KErrNone ) + { + break; + } + + readStream.Open( iChunk.Base(), iChunk.Size() ); + bytesRead = readStream.ReadInt32L(); + TInt ll( aBuffer.Length() ); + aBuffer.SetLength( ll + bytesRead ); + TPtr8 des = aBuffer.MidTPtr( pos ); + readStream.ReadL( des, bytesRead ); + pos += bytesRead; + + } while( size -= bytesRead ); + + CleanupStack::PopAndDestroy(2); //readStream, writeStream + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::WriteItemL +// Writes data to item to Data Provider. CreateItemL or ReplaceItemL method must be called before +// this method can be called. This method is called until all data to current item is written. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::WriteItemL( const TDesC8& aData, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + AdjustChunkLC( aData.Size() + sizeof( TInt32 ) ); + + TInt sizeOfChunk( iChunk.Size() - sizeof( TInt32 ) ); + + RMemWriteStream writeStream; + CleanupClosePushL( writeStream ); + + TInt sizeOfData( aData.Size() ), pos(0); + + do + { + TInt size( Min( sizeOfData, sizeOfChunk ) ); + writeStream.Open( iChunk.Base(), iChunk.Size() ); + + writeStream.WriteInt32L( size ); + writeStream.WriteL( aData.Mid( pos, size ) ); + writeStream.CommitL(); + aResultCode = SendReceive( ENSmlItemWrite, TIpcArgs( aId, &aStoreName ) ); + + if ( aResultCode != KErrNone ) + { + break; + } + + TInt32 bytesWritten(0); + TPckg bytesWrittenPckg( bytesWritten ); + bytesWrittenPckg.Copy( iChunk.Base(), sizeof( TInt32 ) ); + + if ( sizeOfData <= bytesWritten ) break; + + sizeOfData -= bytesWritten; + pos += bytesWritten; + + } while( sizeOfData > 0 ); + + + CleanupStack::PopAndDestroy(2); // writeStream, AdjustChunkLC + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CommitItem +// After item is written to Data Provider it can be saved to the Data Store. +// This method can be called just after WriteItemL method. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CommitItem( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + TPckgBuf pckg; + + if ( iItemState == ENSmlClosed || ( iItemState == ENSmlItemCreating && !iAddedUidBuffer ) ) + { + aResultCode = KErrArgument; + } + else + { + + aResultCode = SendReceive( ENSmlItemCommit, TIpcArgs( aId, &aStoreName, &pckg ) ); + + if ( iItemState == ENSmlItemCreating ) + { + *iAddedUidBuffer = pckg(); + } + } + + if (aResultCode == KErrNone) + { + iItemState = ENSmlClosed; + } + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CloseItem +// Closes opened item. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CloseItem( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + aResultCode = SendReceive( ENSmlItemClose, TIpcArgs( aId, &aStoreName ) ); + + if (aResultCode == KErrNone) + { + iItemState = ENSmlClosed; + } + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::MoveItemL +// Moves item to new location. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::MoveItemL( TSmlDbItemUid aUid, TSmlDbItemUid aNewParent, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + CNSmlDSHostItem* item = CNSmlDSHostItem::NewLC(); + item->SetUid( aUid ); + item->SetParentUid( aNewParent ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + item->ExternalizeL( writeStream ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy( 2 ); // writeStream, item + + aResultCode = SendReceive( ENSmlItemMove, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::DeleteItemL +// Deletes one item at Data Store permanently. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::DeleteItemL( TSmlDbItemUid aUid, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + CNSmlDSHostItem* item = CNSmlDSHostItem::NewLC(); + item->SetUid( aUid ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + item->ExternalizeL( writeStream ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy( 2 ); // writeStream, item + + aResultCode = SendReceive( ENSmlItemDelete, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::SoftDeleteItemL +// Soft deletes one item at Data Store. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::SoftDeleteItemL( TSmlDbItemUid aUid, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + CNSmlDSHostItem* item = CNSmlDSHostItem::NewLC(); + item->SetUid( aUid ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + item->ExternalizeL( writeStream ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy( 2 ); // writeStream, item + + aResultCode = SendReceive( ENSmlItemSoftDelete, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::DeleteAllItems +// Deletes all items at Data Store permanently. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::DeleteAllItems( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlItemDeleteAll, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::HasSyncHistory +// Checks if the Data Store has sync history. If not then slow sync is proposed to Sync Partner. +// ------------------------------------------------------------------------------------------------ +TBool RNSmlDSHostClient::HasSyncHistory( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + TPckgBuf pckg; + aResultCode = SendReceive( ENSmlDSSyncHistory, TIpcArgs( aId, &aStoreName, &pckg ) ); + return pckg(); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::AddedItemsL +// The Data Provider returns UIDs of items that are added after previous synchronization. +// If the Data Provider uses hierarchical synchronization then added folders must be placed +// first (from root to leaves) to UID set and finally items. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::AddedItemsL( RNSmlDbItemModificationSet& aUidSet, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDSItemsAdded, TIpcArgs( aId, &aStoreName ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, const_cast( this ) ) ); + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + aUidSet.InternalizeL( readStream ); + CleanupStack::PopAndDestroy(); // readStream + } + + CleanupStack::PopAndDestroy(); // CancelAdjust + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::DeletedItemsL +// The Data Provider returns UIDs of items that are deleted after previous synchronization. +// If the Data Provider uses hierarchical synchronization then deleted items must be placed +// first to UID set and folders after items (from leaves to root). +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::DeletedItemsL( RNSmlDbItemModificationSet& aUidSet, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDSItemsDeleted, TIpcArgs( aId, &aStoreName ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, const_cast( this ) ) ); + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + aUidSet.InternalizeL( readStream ); + CleanupStack::PopAndDestroy(); // readStream + } + + CleanupStack::PopAndDestroy(); // CancelAdjust + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::SoftDeleteItemsL +// The Data Provider returns UIDs of items that are soft deleted after previous synchronization. +// If the Data Provider uses hierarchical synchronization then soft deleted items must be placed +// first to UID set and folders after items (from leaves to root). +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::SoftDeleteItemsL( RNSmlDbItemModificationSet& aUidSet, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDSItemsSofDeleted, TIpcArgs( aId, &aStoreName ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, const_cast( this ) ) ); + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + aUidSet.InternalizeL( readStream ); + CleanupStack::PopAndDestroy(); // readStream + } + + CleanupStack::PopAndDestroy(); // CancelAdjust + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::ModifiedItemsL +// The Data Provider returns UIDs of items that are modified after previous synchronization. +// If the Data Provider uses hierarchical synchronization then modified folders must be placed +// first (from root to leaves) to UID set and finally items. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::ModifiedItemsL( RNSmlDbItemModificationSet& aUidSet, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDSItemsModified, TIpcArgs( aId, &aStoreName ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, const_cast( this ) ) ); + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + aUidSet.InternalizeL( readStream ); + CleanupStack::PopAndDestroy(); // readStream + } + + CleanupStack::PopAndDestroy(); // CancelAdjust + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::MovedItemsL +// The Data Provider returns UIDs of items that are moved after previous synchronization. +// If the Data Provider uses hierarchical synchronization then moved folders must be placed +// first (from root to leaves) to UID set and finally items. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::MovedItemsL( RNSmlDbItemModificationSet& aUidSet, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDSItemsMoved, TIpcArgs( aId, &aStoreName ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, const_cast( this ) ) ); + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + aUidSet.InternalizeL( readStream ); + CleanupStack::PopAndDestroy(); // readStream + } + + CleanupStack::PopAndDestroy(); // CancelAdjust + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::AllItemsL +// The Data Provider returns UIDs of items that are added, deleted, modified, softdeleted +// or moved after previous synchronization. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::AllItemsL( RNSmlDbItemModificationSet& aUidSet, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDSItemsAll, TIpcArgs( aId, &aStoreName ) ); + CleanupStack::PushL( TCleanupItem ( CancelAdjust, const_cast( this ) ) ); + if ( aResultCode == KErrNone ) + { + RMemReadStream readStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( readStream ); + aUidSet.InternalizeL( readStream ); + CleanupStack::PopAndDestroy(); // readStream + } + + CleanupStack::PopAndDestroy(); // CancelAdjust + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::ResetChangeInfo +// Reset change info from the Data Provider. The result of this method is that the Data Provider +// sends just ADD commands to Sync Partner. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::ResetChangeInfo( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDSResetChangeInfo, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CommitChangeInfoL +// This method is called after some changes are synchronized to Sync Partner. If some changes +// were synchronized correctly then those UIDs are included to aItems. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CommitChangeInfoL( const MSmlDataItemUidSet& aItems, const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) + { + TStreamBuffers* sb = StreamBufferLC(); + aItems.ExternalizeL( *sb->iWrite ); + sb->iWrite->CommitL(); + AdjustChunkIfNeededLC( sb->iBuffer->Size() ); + + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + writeStream.WriteL( *sb->iRead ); + writeStream.CommitL(); + + aResultCode = SendReceive( ENSmlDSCommitChanges, TIpcArgs( aId, &aStoreName ) ); + CleanupStack::PopAndDestroy(3); // writeStream, AdjustChunkIfNeededLC, sb + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CommitChangeInfo +// This method is called after some changes are synchronized to Sync Partner. This method is used if +// all changes were synchronized correctly. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CommitChangeInfo( const TSmlDataProviderId aId, const TDesC& aStoreName, TInt& aResultCode ) const + { + aResultCode = SendReceive( ENSmlDSCommitAllChanges, TIpcArgs( aId, &aStoreName ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::UpdateServerIdL +// Replaces the give old server ID with new one. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::UpdateServerIdL( TDesC& aOldServerId, TDesC& aNewValue, TInt& aResultCode ) + { + AdjustChunkIfNeededLC( aOldServerId.Length() + aNewValue.Length() + 2*sizeof(TInt32) + 5 ); + RMemWriteStream writeStream( iChunk.Base(), iChunk.Size() ); + CleanupClosePushL( writeStream ); + + writeStream.WriteUint32L( aOldServerId.Length() ); + writeStream << aOldServerId; + writeStream.WriteUint32L( aNewValue.Length() ); + writeStream << aNewValue; + + aResultCode = SendReceive( ENSmlDSUpdateServerId, TIpcArgs() ); + CleanupStack::PopAndDestroy(2); // writeStream, AdjustChunkIfNeededLC + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient - private methods +// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::LaunchServer +// Starts Host Server. +// ------------------------------------------------------------------------------------------------ +TInt RNSmlDSHostClient::LaunchServer( const TDesC& aServerName ) const + { + TInt result( KErrNone ); + + TParse parser; + if ( aServerName.Compare( KNSmlDSHostServer1Name ) == 0 ) + { + parser.Set( KNSmlDSHostServer1Exe, &KDC_PROGRAMS_DIR, NULL ); + } + else if ( aServerName.Compare( KNSmlDSHostServer2Name ) == 0 ) + { + parser.Set( KNSmlDSHostServer2Exe, &KDC_PROGRAMS_DIR, NULL ); + } + else + { + return KErrNotSupported; + } + + // DLL launch + RProcess server; + result = server.Create( parser.FullName(), KNullDesC ); + + // Loading failed. + if ( result != KErrNone ) + { + return result; + } + + TRequestStatus status; + server.Rendezvous( status ); + + if ( status != KRequestPending ) + { + server.Kill( 0 ); // abort startup + server.Close(); + return KErrGeneral; // status can be KErrNone: don't return status.Int() + } + else + { + server.Resume(); // logon OK - start the server + } + + User::WaitForRequest( status ); + + result = status.Int(); + + if ( status != KErrNone ) + { + server.Close(); + } + + return result; + } + + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::StreamBufferLC +// ------------------------------------------------------------------------------------------------ +RNSmlDSHostClient::TStreamBuffers* RNSmlDSHostClient::StreamBufferLC() const + { + TStreamBuffers* cleanup = new ( ELeave ) TStreamBuffers; + CleanupStack::PushL( TCleanupItem ( CleanupStreamBuffer, cleanup ) ); + cleanup->iBuffer = CBufFlat::NewL( 64 ); + cleanup->iWrite = new ( ELeave ) RBufWriteStream( *cleanup->iBuffer ); + cleanup->iRead = new ( ELeave ) RBufReadStream( *cleanup->iBuffer ); + return cleanup; + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CleanupStreamBuffer +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CleanupStreamBuffer( TAny* aP ) + { + TStreamBuffers* cleanup = reinterpret_cast( aP ); + + if ( cleanup->iWrite ) + { + cleanup->iWrite->Close(); + delete cleanup->iWrite; + } + + if ( cleanup->iRead ) + { + cleanup->iRead->Close(); + delete cleanup->iRead; + } + + delete cleanup->iBuffer; + delete cleanup; + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::AdjustChunkLC +// Ensures that chunk has at least required size or max size of reserved memory. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::AdjustChunkLC( TInt aRequiredSize ) const + { + const RNSmlDSHostClient* ptr = NULL; + + if ( iChunk.Size() < aRequiredSize ) + { + TInt maxSize( iChunk.MaxSize() ); + + if ( aRequiredSize > maxSize ) + { + aRequiredSize = maxSize; + } + + User::LeaveIfError( iChunk.Adjust( aRequiredSize ) ); + ptr = this; + } + + CleanupStack::PushL( TCleanupItem ( CancelAdjust, const_cast( ptr ) ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::AdjustChunkIfNeededLC +// Adjusts memory so that at least needed size is reserved. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::AdjustChunkIfNeededLC( TInt iNeededSize ) const + { + const RNSmlDSHostClient* ptr = NULL; + + if ( iChunk.Size() < iNeededSize ) + { + User::LeaveIfError( iChunk.Adjust( iNeededSize ) ); + ptr = this; + } + + CleanupStack::PushL( TCleanupItem ( CancelAdjust, const_cast( ptr ) ) ); + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::CancelAdjust +// restores chunk memory. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::CancelAdjust( TAny* aP ) + { + if ( aP ) + { + RNSmlDSHostClient* self = reinterpret_cast( aP ); + self->iChunk.Adjust( KNSmlDSHostChunkMinSize ); + } + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::InternalizeFiltersL +// Reads filters from stream. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::InternalizeFiltersL( RReadStream& aStream, RPointerArray& aFilters ) const + { + aFilters.ResetAndDestroy(); + + TInt count( aStream.ReadInt32L() ); + + for ( TInt i = 0; i < count; i++ ) + { + CSyncMLFilter* filter = CSyncMLFilter::NewLC( aStream ); + aFilters.AppendL( filter ); + CleanupStack::Pop(); // filter + } + } + +// ------------------------------------------------------------------------------------------------ +// RNSmlDSHostClient::ExternalizeFiltersL +// Writes filters to stream. +// ------------------------------------------------------------------------------------------------ +void RNSmlDSHostClient::ExternalizeFiltersL( RWriteStream& aStream, const RPointerArray& aFilters ) const + { + TInt count( aFilters.Count() ); + aStream.WriteInt32L( count ); + for ( TInt i(0); i < count; i++ ) + { + aFilters[i]->ExternalizeL( aStream ); + } + } + +// End of File