browserutilities/feedsengine/FeedsServer/Api/src/Transaction.cpp
changeset 0 dd21522fd290
child 36 0ed94ceaa377
--- /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 <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;
+    }