diff -r 000000000000 -r dd21522fd290 browserutilities/feedsengine/FeedsServer/Api/src/Transaction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browserutilities/feedsengine/FeedsServer/Api/src/Transaction.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,1393 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Main class for client side request handling. + * +*/ + + +#include "FeedsServerMsg.h" +#include "Transaction.h" +#include "FeedsEntity.h" +#include "FeedsInterface.h" +#include +#include +#include "FeedsMap.h" +#include "Packed.h" +#include "PackedFeed.h" +#include "PackedFolder.h" +#include "Logger.h" + +const TInt KSettingsBufSize = 50; + +// ----------------------------------------------------------------------------- +// CFeedsMap::NewL +// +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CTransaction* CTransaction::NewL(MTransactionObserver& aObserver, TInt aUniqueId, + TInt aFolderListId) + { + CTransaction * self = NewLC(aObserver,aUniqueId,aFolderListId); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CTransaction::NewLC +// +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CTransaction* CTransaction::NewLC(MTransactionObserver& aObserver, TInt aUniqueId, + TInt aFolderListId) + { + CTransaction * self = new (ELeave) CTransaction(aObserver,aUniqueId,aFolderListId); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// ----------------------------------------------------------------------------- +// CTransaction::CTransaction +// +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CTransaction::CTransaction(MTransactionObserver& aObserver,TInt aUniqueId,TInt aFolderListId): +CActive(EPriorityStandard), iObserver(aObserver), iRequestBuffPtr(NULL, 0), +iFolderListId(aFolderListId),iNotifyOnCancel(ETrue),iId(aUniqueId),iServerResponseTypePkg(iServerResponseType), +iResponsePtr(NULL, 0),iResponseEntryIdPkg(iResponseEntryId) + { + } + +// ----------------------------------------------------------------------------- +// CTransaction::ConstructL +// +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CTransaction::ConstructL() + { + CActiveScheduler::Add (this); + + iRequestBuff = CBufFlat::NewL (128); + iSettingsResponseBuffer = CBufFlat::NewL (128); + iAutoDelete = CIdle::NewL (CActive::EPriorityIdle); + } + +// ----------------------------------------------------------------------------- +// CTransaction::~CTransaction +// +// Deconstructor. +// ----------------------------------------------------------------------------- +// +CTransaction::~CTransaction() + { + delete iFeedsEntity; + delete iResponseBuffer; + delete iPacked; + + iNotifyOnCancel = EFalse; + Cancel (); + + delete iRequestBuff; + delete iAutoDelete; + delete iFeedsEntity; + delete iSettingsResponseBuffer; + } + +// ----------------------------------------------------------------------------- +// CTransaction::DoCancel +// +// Implements cancellation of an outstanding request. +// ----------------------------------------------------------------------------- +// +void CTransaction::DoCancel() + { + // iNotifyOnCancel is set to false in the destructor. + // A virtual method, RequestCompletedL(), + // that is implemented in a subclass can't be called through the destructor of the parent class. + if ( iNotifyOnCancel) + { + TRAPD( err, RequestCompletedL(KErrCancel) ) + ; + if ( err != KErrNone) + { + } + } + } + +// ----------------------------------------------------------------------------- +// CTransaction::RunL +// +// Handles an active object's request completion event. +// ----------------------------------------------------------------------------- +// +void CTransaction::RunL() + { + RequestCompletedL (iStatus.Int ()); + } + +// ----------------------------------------------------------------------------- +// CTransaction::RunError +// +// Handles an active object's errors. +// ----------------------------------------------------------------------------- +// +TInt CTransaction::RunError(TInt aError) + { + TRAPD( err, RequestCompletedL(aError) ); + return err; + } + +// ----------------------------------------------------------------------------- +// CTransaction::Start +// +// Starts the handler. +// ----------------------------------------------------------------------------- +// +void CTransaction::Start() + { + SetActive (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::AutoDelete +// +// Starts an CIdle to delete the instance after the callstack has unrolled. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CTransaction::AutoDelete() + { + iAutoDelete->Start (TCallBack (DelayedDelete, this)); + } + +// ----------------------------------------------------------------------------- +// CTransaction::DelayedDelete +// +// Deletes the instance after the callstack has unrolled. +// ----------------------------------------------------------------------------- +// +TInt CTransaction::DelayedDelete(TAny* aPtr) + { + CTransaction* self = static_cast(aPtr); + + delete self; + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CTransaction::Type +// +// Returns the handler's type. +// ----------------------------------------------------------------------------- +// +EXPORT_C CTransaction::TTransactionType CTransaction::Type() + { + return iType; + } + +// ----------------------------------------------------------------------------- +// CTransaction::DebugPrintTables +// +// Print tables of database. +// ----------------------------------------------------------------------------- +// +void CTransaction::DebugPrintTables() + { + // Set the request type. + iType = EPrintDBTables; + + iObserver.SendAsyncCommand(EFeedsServerPrintDBTables, + TIpcArgs(), iStatus); + + Start(); + } + +// ----------------------------------------------------------------------------- +// CTransaction::DisconnectManualUpdateConnection +// +// Disconnect connection provided by client for manual update. +// ----------------------------------------------------------------------------- +// +void CTransaction::DisconnectManualUpdateConnection() + { + // Set the request type. + iType = EDisconnectManualUpdateConnection; + + iObserver.SendAsyncCommand (EFeedsServerDisconnectManualUpdateConnection, + TIpcArgs (), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::ChangeServerSettingsL +// +// Handles the upating of a the feeds server settings. +// ----------------------------------------------------------------------------- +// +void CTransaction::ChangeServerSettingsL(const TFeedsServerSetting& aNewSetting) + { + // Set the request type. + iType = EChangeSettings; + + RBufWriteStream stream; + + // Package the request. + stream.Open(*iRequestBuff); + CleanupClosePushL(stream); + + // Write out the settings. + // NOTE: Be sure to adjust KSettingsBufSize if more settings are added. + // TODO: Also write out a version number -- do this with all R-Class messages. + stream.WriteInt32L( iFolderListId ); + stream.WriteUint8L(aNewSetting.iAutoUpdate); + stream.WriteUint16L(aNewSetting.iAutoUpdateFreq); + stream.WriteUint32L(aNewSetting.iAutoUpdateAP); + stream.WriteUint8L(aNewSetting.iAutoUpdateWhileRoaming); + + iRequestBuff->Compress(); + CleanupStack::PopAndDestroy(/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerChangeSettings, + TIpcArgs (&iRequestBuffPtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::WatchSettingsL +// +// Sets up a notifier to execute when the settings change. +// ----------------------------------------------------------------------------- +// +void CTransaction::WatchSettingsL() + { + RBufWriteStream stream; + + // Set the request type. + iType = EWatchForSettingChanges; + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + // Write out the folder list id. + stream.WriteInt32L (iFolderListId); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerWatchSettings, + TIpcArgs (&iRequestBuffPtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::FetchServerSettingsL +// +// Handles the fetching of the feeds server settings. +// ----------------------------------------------------------------------------- +// +void CTransaction::FetchServerSettingsL() + { + RBufWriteStream stream; + + // Set the request type. + iType = EFetchSettings; + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + stream.WriteInt32L ( iFolderListId); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + iRequestBuffPtr.Set ( iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iSettingsResponseBuffer->ExpandL(0, KSettingsBufSize); + iResponsePtr.Set((TUint8 *) iSettingsResponseBuffer->Ptr(0).Ptr(), KSettingsBufSize, + KSettingsBufSize); + + // Make the request. + iObserver.SendAsyncCommand (EFeedsServerGetSettings, TIpcArgs ( + &iRequestBuffPtr, &iResponsePtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::FetchServerSettingsSyncL +// +// Handles the fetching of the feeds server settings synchronously. +// ----------------------------------------------------------------------------- +// +void CTransaction::FetchServerSettingsSyncL() + { + TInt status(0); + CBufFlat* requestBuff = NULL; + TPtr8 requestBuffPtr(NULL, 0); + CBufFlat* responseBuff = NULL; + TPtr8 responsePtr(NULL, 0); + RBufWriteStream stream; + + requestBuff = CBufFlat::NewL(128); + CleanupStack::PushL(requestBuff); + + // Package the request. + stream.Open(*requestBuff); + CleanupClosePushL(stream); + + stream.WriteInt32L( iFolderListId ); + + requestBuff->Compress(); + requestBuffPtr.Set( requestBuff->Ptr(0) ); + CleanupStack::PopAndDestroy(/*stream*/); + + responseBuff = CBufFlat::NewL(128); + CleanupStack::PushL(responseBuff); + + // Make the request. + responseBuff->ExpandL(0, KSettingsBufSize); + responsePtr.Set((TUint8 *) responseBuff->Ptr(0).Ptr(), KSettingsBufSize, + KSettingsBufSize); + + status = iFeedInterface->SendReceiveSync(EFeedsServerGetSettings, TIpcArgs(&requestBuffPtr, &responsePtr)); + + // Extract the settings if everything went ok. + if (status == KErrNone) + { + iSetting = SettingsFromResponseBuffPtrL(*responseBuff); + } + + CleanupStack::PopAndDestroy(responseBuff); + CleanupStack::PopAndDestroy(requestBuff); + } + +// ----------------------------------------------------------------------------- +// CTransaction::Settings +// +// return pointer to setting map,Caller takes ownership +// ----------------------------------------------------------------------------- +// +EXPORT_C TFeedsServerSetting CTransaction::Settings() + { + return iSetting; + } + +// ----------------------------------------------------------------------------- +// CTransaction::CancelAllL +// +// Request the FeedsServer to cancel all activities that can be cancelled. +// ----------------------------------------------------------------------------- +// +void CTransaction::CancelAllL() + { + // Set the request type. + iType = ECancelAll; + + // Make the request. + iObserver.SendAsyncCommand (EFeedsServerCancelAll, TIpcArgs (), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::SettingsFromResponseBufferL +// +// Reads server response buffer and intialises iSetting; +// ----------------------------------------------------------------------------- +// +void CTransaction::SettingsFromResponseBufferL() + { + RBufReadStream stream; + + stream.Open(*iSettingsResponseBuffer, 0); + CleanupClosePushL(stream); + + // Read the settings. + // NOTE: Be sure to adjust KSettingsBufSize if more settings are added. + iSetting.iAutoUpdate = stream.ReadUint8L(); + iSetting.iAutoUpdateFreq = stream.ReadUint16L(); + iSetting.iAutoUpdateAP = stream.ReadUint32L(); + iSetting.iAutoUpdateWhileRoaming = stream.ReadUint8L(); + + CleanupStack::PopAndDestroy(/*stream*/); + } + +// ----------------------------------------------------------------------------- +// CTransaction::RequestCompletedL +// +// Called to handle the response. +// ----------------------------------------------------------------------------- +// +void CTransaction::RequestCompletedL(TInt aStatusCode) + { + // Notify the observer if an error occurred. + this->iTranStatus = aStatusCode; + if ( aStatusCode != KErrNone) + { + iObserver.RequestHandlerCompleted (*this, aStatusCode); + return; + } + + switch (iType) + { + case EFetchSettings: + { + TRAPD(err,SettingsFromResponseBufferL()); + iObserver.RequestHandlerCompleted (*this, err); + return; + } + case EFetchFeed: + { + if ( iServerResponseType != EFeedsServerConnectionNeeded &&iServerResponseType != EFeedsServerManualUpdateDone) + { + // Append the response chunk to the packed folder. + if ( iServerResponseType == EFeedsServerTokensPayload) + { + iPacked->AppendTokenChunkL (iResponsePtr); + } + else + { + iPacked->AppendStringTableChunkL (iResponsePtr); + } + + // If there is more data coming request the next chunk. + if ( iServerResponseType != EFeedsServerPayloadDone) + { + // Reset the response. + iResponsePtr.Zero (); + + // Clear the request buffer too. + iRequestBuffPtr.Set (NULL, 0); + + // Get the next chunk asynchronously. + iObserver.SendAsyncCommand (EFeedsServerGetFeed, TIpcArgs ( + &iRequestBuffPtr, &iServerResponseTypePkg, + &iResponsePtr), iStatus); + + Start (); + } + + // Otherwise process the completed folder. + else + { + // Create the new folder and notify the observer. + iFeedsEntity = CFeedsEntity::NewL ((CPackedFeed*)iPacked,iFeedInterface); + delete iPacked; + iPacked = NULL; + iObserver.RequestHandlerCompleted (*this, KErrNone); + } + } + else + if ( iServerResponseType == EFeedsServerConnectionNeeded) + { + // Ask client for connection + TInt connectionPtr; + TInt sockSvrHandle; + TBool newConn; + TApBearerType bearerType; + TRAPD( err, iObserver.NetworkConnectionNeededL( &connectionPtr, sockSvrHandle, newConn, bearerType ) ); + + if ( err == KErrNone) + { + // Prepare RConnection name + RConnection* connPtr= REINTERPRET_CAST( RConnection*, connectionPtr ); + TName name; + connPtr->Name ( name); + + // Package the request. + RBufWriteStream stream; + // + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + // + stream.WriteUint16L ( name.Length ()); + stream.WriteL ( name); + // + stream.WriteUint16L ( bearerType); + // + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + // Reset the response. + iResponsePtr.Zero (); + + // Send the request + iObserver.SendAsyncCommand ( + EFeedsServerSetConnection, + TIpcArgs (&iRequestBuffPtr, + &iServerResponseTypePkg, &iResponsePtr), + iStatus); + // + Start (); + } + else + { + iObserver.CancelAllCommandsL (); + User::Leave ( err); + } + } + // EFeedsServerManualUpdateDone + else + { + iObserver.RequestHandlerCompleted (*this, KErrNone); + } + } + break; + case EFetchRootFolderItem: + { + // Append the response chunk to the packed folder. + if ( iServerResponseType == EFeedsServerTokensPayload) + { + iPacked->AppendTokenChunkL (iResponsePtr); + } + else + { + iPacked->AppendStringTableChunkL (iResponsePtr); + } + + // If there is more data coming request the next chunk. + if ( iServerResponseType != EFeedsServerPayloadDone) + { + // Reset the response. + iResponsePtr.Zero (); + + // Clear the request buffer too. + iRequestBuffPtr.Set (NULL, 0); + + // Get the next chunk asynchronously. + iObserver.SendAsyncCommand (EFeedsServerGetRootFolder, + TIpcArgs (&iRequestBuffPtr, &iServerResponseTypePkg, + &iResponsePtr), iStatus); + + Start (); + } + + // Otherwise process the completed folder. + else + { + // Create the new folder and notify the observer. + iFeedsEntity = CFeedsEntity::NewL ((CPackedFolder*)iPacked,iFeedInterface); + delete iPacked; + iPacked = NULL; + + iObserver.RequestHandlerCompleted (*this, KErrNone); + } + + break; + } + + case EUpdateFolderItem: + { + if ( iServerResponseType == EFeedsServerConnectionNeeded) + { + // Ask client for connection + TInt connectionPtr; + TInt sockSvrHandle; + TBool newConn; + TApBearerType bearerType; + TRAPD( err, iObserver.NetworkConnectionNeededL( &connectionPtr, sockSvrHandle, newConn, bearerType ) ); + + if ( err == KErrNone) + { + // Prepare RConnection name + RConnection* connPtr= REINTERPRET_CAST( RConnection*, connectionPtr ); + TName name; + connPtr->Name ( name); + + // Package the request. + RBufWriteStream stream; + // + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + // + stream.WriteUint16L ( name.Length ()); + stream.WriteL ( name); + // + stream.WriteUint16L ( bearerType); + // + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + // Reset the response. + iResponsePtr.Zero (); + + // Send the request + iObserver.SendAsyncCommand (EFeedsServerSetConnection, + TIpcArgs (&iRequestBuffPtr, + &iServerResponseTypePkg, &iResponsePtr), + iStatus); + // + Start (); + } + else + { + iObserver.CancelAllCommandsL (); + User::Leave ( err); + } + } + // EFeedsServerManualUpdateDone + else + { + iObserver.RequestHandlerCompleted (*this, KErrNone); + } + + break; + } + + case EImportOPML: + { + iObserver.RequestHandlerCompleted (*this, KErrNone); + break; + } + + case EExportOPML: + { + iObserver.RequestHandlerCompleted (*this, KErrNone); + break; + } + + default: + iObserver.RequestHandlerCompleted (*this, KErrNone); + break; + } + + } + +// ----------------------------------------------------------------------------- +// CTransaction::GetId +// +// Returns the id of the id of the transaction. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CTransaction::GetId() + { + return iId; + } + +// ----------------------------------------------------------------------------- +// CTransaction::GetStatusCode +// +// Returns the status code of the transaction. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CTransaction::GetStatusCode() + { + return iTranStatus; + } + +// ----------------------------------------------------------------------------- +// CTransaction::Cancel +// +// Cancels the transaction. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CTransaction::CancelRequest() + { + //TODO + } + +// ----------------------------------------------------------------------------- +// CTransaction::FetchFeedL +// +// Fetch the given feed. +// ----------------------------------------------------------------------------- +// +void CTransaction::FetchFeedL(const TDesC& aUrl, TBool aForceUpdate, + TBool aNoCache) + { + FetchFeedHelperL (aUrl, 0, aForceUpdate, aNoCache); + } + +// ----------------------------------------------------------------------------- +// CTransaction::FetchFeedL +// +// Fetch the given feed. +// ----------------------------------------------------------------------------- +// +void CTransaction::FetchFeedL(TInt aFeedId, TBool aForceUpdate, + TBool aNoCache) + { + FetchFeedHelperL (KNullDesC, aFeedId, aForceUpdate, aNoCache); + } + +// ----------------------------------------------------------------------------- +// CTransaction::FetchFeedHelperL +// +// Fetch the given feed. +// ----------------------------------------------------------------------------- +// +void CTransaction::FetchFeedHelperL(const TDesC& aUrl, TInt aFeedId, + TBool aForceUpdate, TBool aNoCache) + { + RBufWriteStream stream; + + // Set the request type. + iType = EFetchFeed; + + // Create the buffer to hold the response. + iResponseBuffer = HBufC8::NewL (KMaxFeedsServerMessage); + iResponsePtr.Set ((TUint8 *) iResponseBuffer->Ptr(), KMaxFeedsServerMessage, KMaxFeedsServerMessage); + + // Do some other init. + iServerResponseType = EFeedsServerInitPayload; + iPacked = CPackedFeed::NewL (); + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + // If the url was provided then write it out. + if ( aUrl.Length ()> 0) + { + // What follows is a url. + stream.WriteUint8L (ETrue); + + stream.WriteUint16L (aUrl.Length ()); + stream.WriteL (aUrl); + + stream.WriteInt32L ( iFolderListId); + } + + // Otherwise write out the feed's id. + else + { + // What follows is a feed id. + stream.WriteUint8L (EFalse); + + stream.WriteUint16L (aFeedId); + } + + // Write the load flags. + stream.WriteUint8L (aForceUpdate); + stream.WriteUint8L (aNoCache); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Wrap the request buffer. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + // Get the first chunk asynchronously. + iObserver.SendAsyncCommand (EFeedsServerGetFeed, TIpcArgs ( + &iRequestBuffPtr, &iServerResponseTypePkg, &iResponsePtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::UpdateItemStatusL +// +// Handles the upating of a the feed's item-status. +// ----------------------------------------------------------------------------- +// +void CTransaction::UpdateItemStatusL(TInt aFeedId, + const RArray& aItemIds, const RArray& aItemStatus, + TInt aUnreadCount) + { + RBufWriteStream stream; + + // Set the request type. + iType = EUpdateItemStatus; + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + stream.WriteUint16L (aFeedId); + + // Write the entries. + stream.WriteUint16L (aItemStatus.Count ()); + for (TInt i = 0; i < aItemStatus.Count (); i++) + { + stream.WriteUint16L (aItemIds[i]); + stream.WriteUint16L (aItemStatus[i]); + } + + stream.WriteUint16L (aUnreadCount); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerChangeFeedItemStatus, + TIpcArgs (&iRequestBuffPtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::FetchFolderItemL +// +// Fetch the root folder associated with the given folder list id. +// ----------------------------------------------------------------------------- +// +void CTransaction::FetchFolderItemL(TBool aItemTitleNeed) + { + FEED_LOG(_L("Feeds"), _L("Feeds_Api.log"), + EFileLoggingModeAppend, _L("CTransaction::FetchFolderItemL")); + + RBufWriteStream stream; + + // Set the request type. + iType = EFetchRootFolderItem; + + // Create the buffer to hold the response. + iResponseBuffer = HBufC8::NewL (KMaxFeedsServerMessage); + iResponsePtr.Set ((TUint8 *) iResponseBuffer->Ptr(), KMaxFeedsServerMessage, KMaxFeedsServerMessage); + + // Do some other init. + iServerResponseType = EFeedsServerInitPayload; + iPacked = CPackedFolder::NewL (); + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + // Write the folder list id. + stream.WriteInt32L (iFolderListId); + stream.WriteUint8L ( aItemTitleNeed); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Wrap the request buffer. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + // Get the first chunk asynchronously. + iObserver.SendAsyncCommand (EFeedsServerGetRootFolder, TIpcArgs ( + &iRequestBuffPtr, &iServerResponseTypePkg, &iResponsePtr), iStatus); + + Start (); + FEED_LOG(_L("Feeds"), _L("Feeds_Api.log"), + EFileLoggingModeAppend, _L("//CTransaction::FetchFolderItemL")); + + } + +// ----------------------------------------------------------------------------- +// CTransaction::AddFolderItemL +// +// Add a new folder item. +// ----------------------------------------------------------------------------- +// +void CTransaction::AddFolderItemL(const TDesC& aTitle,const TDesC& aUrl, TBool aIsFolder, const CFeedsEntity& aParent, TInt aFreq) + { + RBufWriteStream stream; + + // Set the request type. + iType = EAddFolderItem; + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + stream.WriteInt32L (iFolderListId); + stream.WriteUint16L (aParent.GetId ()); + stream.WriteUint16L (aIsFolder); + + stream.WriteUint16L (aTitle.Length ()); + stream.WriteL (aTitle); + + stream.WriteUint16L (aUrl.Length ()); + stream.WriteL (aUrl); + stream.WriteUint32L (aFreq); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerAddFolderItem, TIpcArgs ( + &iRequestBuffPtr, &iResponseEntryIdPkg), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::ChangeFolderItemL +// +// Change a new folder item. +// ----------------------------------------------------------------------------- +// +void CTransaction::ChangeFolderItemL(const CFeedsEntity& aFeedsEntity, + const TDesC& aTitle, const TDesC& aUrl, TInt aFreq) + { + RBufWriteStream stream; + + // Set the request type. + iType = EChangeFolderItem; + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + stream.WriteInt32L (iFolderListId); + stream.WriteUint16L (aFeedsEntity.GetId ()); + + stream.WriteUint16L (aTitle.Length ()); + stream.WriteL (aTitle); + + stream.WriteUint16L (aUrl.Length ()); + stream.WriteL (aUrl); + stream.WriteUint32L (aFreq); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerChangeFolderItem, + TIpcArgs (&iRequestBuffPtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::DeleteFolderItemL +// +// Delete one or more folder items. +// ----------------------------------------------------------------------------- +// +void CTransaction::DeleteFolderItemL( + const RPointerArray& aFeedsEntities) + { + RBufWriteStream stream; + + // Set the request type. + iType = EDeleteFolderItem; + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + stream.WriteInt32L (iFolderListId); + + // Write the entries. + stream.WriteUint16L (aFeedsEntities.Count ()); + for (TInt i = 0; i < aFeedsEntities.Count (); i++) + { + stream.WriteUint16L (aFeedsEntities[i]->GetId ()); + } + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set(iRequestBuff->Ptr(0).Ptr(), iRequestBuff->Size()); + + iObserver.SendAsyncCommand(EFeedsServerDeleteFolderItems, + TIpcArgs(&iRequestBuffPtr), iStatus); + + Start(); + } + +// ----------------------------------------------------------------------------- +// CTransaction::ExportFolderItemL +// +// Export one or more folder items. +// ----------------------------------------------------------------------------- +// +void CTransaction::ExportFolderItemL( + const RPointerArray& aFeedsEntities, + const TDesC &aExportFileName) + { + + if ( aExportFileName.Length ()<=0) + { + User::Leave (KErrArgument); + } + + if ( aFeedsEntities.Count ()<=0) + { + User::Leave (KErrArgument); + } + + // Set the request type. + iType = EExportOPML; + + // Package the request. + RBufWriteStream stream; + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + stream.WriteUint16L (aExportFileName.Length ()); + stream.WriteL (aExportFileName); + + stream.WriteInt32L (iFolderListId); + + // Write the entries. + stream.WriteUint16L (aFeedsEntities.Count ()); + for (TInt i = 0; i < aFeedsEntities.Count (); i++) + { + stream.WriteUint16L (aFeedsEntities[i]->GetId ()); + } + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerExportOPML, + TIpcArgs (&iRequestBuffPtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::MoveFolderItemsToL +// +// Move one or more folder items to a different parent folder. +// ----------------------------------------------------------------------------- +// +void CTransaction::MoveFolderItemsToL( + const RPointerArray& aFeedsEntities, + const CFeedsEntity& aParent) + { + RBufWriteStream stream; + + // Set the request type. + iType = EMoveFolderItemTo; + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + stream.WriteInt32L (iFolderListId); + + // Write the entries. + stream.WriteUint16L (aParent.GetId ()); + + stream.WriteUint16L (aFeedsEntities.Count ()); + for (TInt i = 0; i < aFeedsEntities.Count (); i++) + { + stream.WriteUint16L (aFeedsEntities[i]->GetId ()); + } + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerMoveFolderItemsTo, + TIpcArgs (&iRequestBuffPtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::MoveFolderItemsL +// +// Move one or more folder items to a new position. +// ----------------------------------------------------------------------------- +// +void CTransaction::MoveFolderItemsL( + const RPointerArray& aFeedsEntities, TInt aIndex) + { + RBufWriteStream stream; + + // Set the request type. + iType = EMoveFolderItem; + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + stream.WriteInt32L ( iFolderListId ); + + // Write the entries. + stream.WriteUint16L (aIndex); + + stream.WriteUint16L (aFeedsEntities.Count ()); + for (TInt i = 0; i < aFeedsEntities.Count (); i++) + { + stream.WriteUint16L (aFeedsEntities[i]->GetId ()); + } + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerMoveFolderItems, + TIpcArgs (&iRequestBuffPtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::UpdateFolderItemsL +// +// Update one or more feed. +// ----------------------------------------------------------------------------- +// +void CTransaction::UpdateFolderItemsL( + const RPointerArray& aFeedsEntities) + { + RBufWriteStream stream; + + // Set the request type. + iType = EUpdateFolderItem; + + // Create the buffer to hold the response. + iResponseBuffer = HBufC8::NewL (KMaxFeedsServerMessage); + iResponsePtr.Set ((TUint8 *) iResponseBuffer->Ptr(), KMaxFeedsServerMessage, KMaxFeedsServerMessage); + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + // Write out the folder list id. + stream.WriteInt32L (iFolderListId); + + // Write out the update all flag. + stream.WriteUint8L (EFalse); + + // Write the entries. + stream.WriteUint16L (aFeedsEntities.Count ()); + for (TInt i = 0; i < aFeedsEntities.Count (); i++) + { + stream.WriteUint16L (aFeedsEntities[i]->iFeedId); + } + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerUpdateFolderItems, TIpcArgs ( + &iRequestBuffPtr, &iServerResponseTypePkg, &iResponsePtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::UpdateFolderItemsL +// +// Update all of the feeds associated with the given folder list id. +// ----------------------------------------------------------------------------- +// +void CTransaction::UpdateFolderItemsL() + { + RBufWriteStream stream; + + // Set the request type. + iType = EUpdateFolderItem; + + // Create the buffer to hold the response. + iResponseBuffer = HBufC8::NewL (KMaxFeedsServerMessage); + iResponsePtr.Set ((TUint8 *) iResponseBuffer->Ptr(), KMaxFeedsServerMessage, KMaxFeedsServerMessage); + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + // Write out the folder list id. + stream.WriteInt32L (iFolderListId); + + // Write out the update all flag. + stream.WriteUint8L (ETrue); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerUpdateFolderItems, TIpcArgs ( + &iRequestBuffPtr, &iServerResponseTypePkg, &iResponsePtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::WatchFolderListL +// +// Sets up a notifier to execute when the folder list changes. +// ----------------------------------------------------------------------------- +// +void CTransaction::WatchFolderListL() + { + RBufWriteStream stream; + + // Set the request type. + iType = EWatchForChanges; + + // Package the request. + stream.Open (*iRequestBuff); + CleanupClosePushL (stream); + + // Write out the folder list id. + stream.WriteInt32L (iFolderListId); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set (iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + iObserver.SendAsyncCommand (EFeedsServerWatchFolderList, + TIpcArgs (&iRequestBuffPtr), iStatus); + + Start (); + } + +// ----------------------------------------------------------------------------- +// CTransaction::ImportOPMLL +// +// Import OPML file passed from the client. +// ----------------------------------------------------------------------------- +// +void CTransaction::ImportOPMLL( const TDesC& aPath, + TBool aClearFolderList) + { + + TIpcArgs ipcArgs; + RBufWriteStream stream; + + if ( aPath.Length ()<= 0) + User::Leave (KErrArgument); + + // Set the request type. + iType = EImportOPML; + + // Create the buffer to hold the response. + iResponseBuffer = HBufC8::NewL (KMaxFeedsServerMessage); + iResponsePtr.Set ((TUint8 *) iResponseBuffer->Ptr(), KMaxFeedsServerMessage, KMaxFeedsServerMessage); + + // correct the path seperator + TBuf path( aPath); + for (TInt i = 0; i < aPath.Length (); i++) + { + if ( path[i] == '/') + { + path[i] = '\\'; + } + } + // Package the request. + + stream.Open ( *iRequestBuff); + CleanupClosePushL ( stream); + + stream.WriteInt32L ( iFolderListId); + stream.WriteUint8L ( aClearFolderList); + + stream.WriteUint16L (aPath.Length ()); + stream.WriteL (path); + + iRequestBuff->Compress (); + CleanupStack::PopAndDestroy (/*stream*/); + + // Make the request. + iRequestBuffPtr.Set ( iRequestBuff->Ptr(0).Ptr (), iRequestBuff->Size ()); + + ipcArgs.Set (KFeedsServerPackedRequestArg, &iRequestBuffPtr); + + iObserver.SendAsyncCommand ( EFeedsServerImportOPML, ipcArgs, iStatus); + + Start (); + } + + +// ----------------------------------------------------------------------------- +// CTransaction::OrphanFeedsEntity +// +// Returns the feedsEntity -- the caller takes ownership. Only returns a valid +// folder item after a sucessful call to FetchFeed/FeedFolderItemL +// ----------------------------------------------------------------------------- +// +CFeedsEntity* CTransaction::OrphanFeedsEntity() + { + CFeedsEntity* item = NULL; + + item = iFeedsEntity; + iFeedsEntity = NULL; + + return item; + } + +// ----------------------------------------------------------------------------- +// CTransaction::GetType +// +// Returns transaction type +// ----------------------------------------------------------------------------- +// +EXPORT_C CTransaction::TTransactionType CTransaction::GetType() + { + return iType; + } + +// ----------------------------------------------------------------------------- +// CTransaction::SettingsFromResponseBuffPtrL +// +// Extract the current settings from the servers response. +// ----------------------------------------------------------------------------- +// +TFeedsServerSetting CTransaction::SettingsFromResponseBuffPtrL( + CBufFlat& aResponseBuffer) + { + RBufReadStream stream; + TFeedsServerSetting setting; + + // Unpack the response. + stream.Open(aResponseBuffer, 0); + CleanupClosePushL(stream); + + // Read the settings. + // NOTE: Be sure to adjust KSettingsBufSize if more settings are added. + setting.iAutoUpdate = stream.ReadUint8L(); + setting.iAutoUpdateFreq = stream.ReadUint16L(); + setting.iAutoUpdateAP = stream.ReadUint32L(); + setting.iAutoUpdateWhileRoaming = stream.ReadUint8L(); + + CleanupStack::PopAndDestroy(/*stream*/); + + return setting; + } + +// ----------------------------------------------------------------------------- +// CTransaction::GetSetting +// +// Extract the current settings from the local variable. +// ----------------------------------------------------------------------------- +// +void CTransaction::GetSetting(TFeedsServerSetting& aSetting) + { + aSetting = iSetting; + }