/*
* 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 <S32Mem.h>
#include <es_sock.h>
#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<CTransaction*>(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<TInt>& aItemIds, const RArray<TFeedItemStatus>& 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<const CFeedsEntity>& 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<const CFeedsEntity>& 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<const CFeedsEntity>& 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<const CFeedsEntity>& 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<const CFeedsEntity>& 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<KMaxFileName> 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;
}