--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/upnp/upnpstack/upnphttptransfer/src/httptransferbase.cpp Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,605 @@
+/** @file
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Base class for downloader / uploader classes
+*
+*/
+
+
+// System include files
+#include <escapeutils.h>
+
+// User include files
+#include "httptransferbase.h"
+#include "httptransferobserver.h"
+#include "httpfile.h"
+#include "httptransferworker.h"
+#include "httpworkerobserver.h"
+
+// Definitions
+enum TTransferStates
+ {
+ ETransferNextFile
+ };
+
+// ======== MEMBER FUNCTIONS ========
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::CHttpTransferBase()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+CHttpTransferBase::CHttpTransferBase() : CActive( EPriorityStandard )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::~CHttpTransferBase()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+CHttpTransferBase::~CHttpTransferBase()
+ {
+ if( IsActive() )
+ {
+ CActive::Cancel();
+ }
+
+ // Reset array and destroy all the items in it
+ iFileQueue.ResetAndDestroy();
+ iWorkerArray.ResetAndDestroy();
+ iWaitQueue.ResetAndDestroy();
+ }
+
+// --------------------------------------------------------------------------
+// CHttpDownloader::CancelAll
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CHttpTransferBase::CancelAll()
+ {
+ // Reset arrays and destroy all the items in them
+ iFileQueue.ResetAndDestroy();
+ iWaitQueue.ResetAndDestroy();
+
+ for( TInt i=0; i < iWorkerArray.Count(); i++ )
+ {
+ if ( iWorkerArray[i]->ProcessOnGoing() )
+ {
+ iWorkerArray[i]->CancelTransfer();
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::Cancel
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C TInt CHttpTransferBase::CancelTransfer( TAny* aKey )
+ {
+ TInt retval = KErrNotFound;
+
+ // Find the item corresponding aKey and delete it and
+ // remove from the wait queue
+ for ( TInt i = 0; i < iWaitQueue.Count(); i++ )
+ {
+ if ( iWaitQueue[i]->Key() == aKey )
+ {
+ retval = KErrNone;
+ delete iWaitQueue[i];
+ iWaitQueue.Remove(i);
+ iWaitQueue.Compress();
+ }
+ }
+
+ // Find the item corresponding aKey and delete it and
+ // remove from the file queue
+ for ( TInt i = 0; i < iFileQueue.Count(); i++ )
+ {
+ if ( iFileQueue[i]->Key() == aKey )
+ {
+ retval = KErrNone;
+ delete iFileQueue[i];
+ iFileQueue.Remove(i);
+ iFileQueue.Compress();
+ }
+ }
+
+ // Check if some of the ongoing processes has to be canceled
+ for ( TInt i = 0; i < iWorkerArray.Count(); i++ )
+ {
+ if ( iWorkerArray[i]->ProcessOnGoing() )
+ {
+ if ( iWorkerArray[i]->Key() == aKey )
+ {
+ retval = KErrNone;
+ iWorkerArray[i]->CancelTransfer();
+ }
+ }
+ }
+
+ return retval;
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::TrackProgress
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C TInt CHttpTransferBase::TrackProgress( TAny* aKey, TBool aValue )
+ {
+ TInt retval = KErrNotFound;
+
+ // Find the corresponding file from iWaitQueue
+ for ( TInt i = 0; i < iWaitQueue.Count(); i++ )
+ {
+ if ( iWaitQueue[i]->Key() == aKey )
+ {
+ retval = KErrNone;
+ iWaitQueue[i]->TrackProgress( aValue );
+ }
+ }
+
+ // Find the corresponding instance of CHttpFile from iFileQueue and
+ // switch the tracking of the progress on
+ for ( TInt i = 0; i < iFileQueue.Count(); i++)
+ {
+ if ( iFileQueue[i]->Key() == aKey )
+ {
+ retval = KErrNone;
+ iFileQueue[i]->TrackProgress( aValue );
+ }
+ }
+
+ // Check if processed files have to be tracked
+ for ( TInt i = 0; i < iWorkerArray.Count(); i++ )
+ {
+ if ( iWorkerArray[i]->ProcessOnGoing() &&
+ iWorkerArray[i]->Key() == aKey )
+ {
+ retval = KErrNone;
+ iWorkerArray[i]->TrackProgress( aValue );
+ }
+ }
+
+ return retval;
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::SetHeaderL
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CHttpTransferBase::SetHeaderL( TAny* aKey,
+ const TDesC8& aFieldName,
+ const TDesC8& aFieldValue )
+ {
+ TBool keyExists = EFalse;
+
+ // Go through iWaitQueue and if there is file mathich the key set headers
+ for ( TInt i = 0; i < iWaitQueue.Count(); i++ )
+ {
+ if ( iWaitQueue[i]->Key() == aKey )
+ {
+ keyExists = ETrue;
+ iWaitQueue[i]->SetHeaderL( aFieldName, aFieldValue );
+ }
+ }
+
+ // Go through workers and set the headers to the downloaded file which
+ // has matching key
+ for ( TInt i = 0; i < iWorkerArray.Count(); i++ )
+ {
+ if ( iWorkerArray[i]->Key() == aKey )
+ {
+ // if the worker is not waiting -> leave
+ if ( !iWorkerArray[i]->IsWaiting() )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ ( iWorkerArray[i]->ProcessedFile() )->
+ SetHeaderL( aFieldName, aFieldValue );
+ keyExists = ETrue;
+ }
+ }
+
+ if ( !keyExists )
+ {
+ User::Leave( KErrNotFound );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::CreateAndQueueHttpFile()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CHttpTransferBase::CreateAndQueueHttpFileL( const TDesC8& aUri,
+ const TDesC& aTargetPath,
+ TAny* aKey )
+ {
+ CHttpFile* httpfile = CHttpFile::NewL( aKey, aUri, aTargetPath );
+ iFileQueue.Append( httpfile );
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::CreateAndQueueHttpFile()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CHttpTransferBase::CreateAndQueueHttpFileL( const TDesC8& aUri,
+ const RFile& aFileHandle,
+ TAny* aKey )
+ {
+ CHttpFile* httpfile = CHttpFile::NewL( aKey, aUri, aFileHandle );
+ iFileQueue.Append( httpfile );
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::NextFile
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+CHttpFile* CHttpTransferBase::NextFile()
+ {
+ CHttpFile* newFile = NULL;
+
+ // If iFileQueue has files
+ if ( iFileQueue.Count() > 0 )
+ {
+ // Set the new processed file
+ newFile = iFileQueue[0];
+
+ // Set the queue
+ iFileQueue.Remove(0);
+ iFileQueue.Compress();
+ }
+
+ return newFile;
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::StartTransferL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CHttpTransferBase::StartTransferL( TAny* aKey )
+ {
+ TBool keyExists = EFalse;
+
+ // go through workerarray and if there is worker which has
+ // corresponding key -> start the transfer
+ for(TInt i=0; i < iWorkerArray.Count(); i++ )
+ {
+ if ( iWorkerArray[i]->Key() == aKey )
+ {
+ iWorkerArray[i]->StartProcessL();
+ keyExists = ETrue;
+ }
+ }
+
+ // Leave if the key does not exist
+ if ( !keyExists )
+ {
+ User::Leave( KErrNotFound );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::SetProperty()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CHttpTransferBase::SetPropertyL( TAny* aKey,
+ THttpPropertyType aProperty,
+ const TDesC& aValue )
+ {
+
+ switch ( aProperty )
+ {
+ // This case is used to set targetUri. This is used in upnp upload
+ case ETargetURI:
+ {
+ TBool keyExists = EFalse;
+ HBufC8* uri = EscapeUtils::ConvertFromUnicodeToUtf8L( aValue );
+ CleanupStack::PushL( uri );
+
+ for ( TInt i=0; i < iWorkerArray.Count(); i++ )
+ {
+ if ( iWorkerArray[i]->Key() == aKey )
+ {
+ ( iWorkerArray[i]->ProcessedFile() )->
+ SetUriL( uri->Des() );
+ keyExists = ETrue;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( uri );
+
+ // the key was not found
+ if ( !keyExists )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ break;
+ }
+
+ default:
+ {
+
+ break;
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::GetPropertyL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C const HBufC* CHttpTransferBase::GetPropertyL(
+ TAny* aKey,
+ THttpPropertyType aProperty )
+ {
+ const HBufC* retval = NULL;
+
+ switch ( aProperty )
+ {
+ // Client can receive the path of the transferred file using this
+ case ETargetPath:
+ {
+ TBool keyExists = EFalse;
+
+ // Goes through workerarray and returns the path of the file
+ // which matches the key
+ for ( TInt i = 0; i < iWorkerArray.Count(); i++ )
+ {
+ if ( iWorkerArray[i]->Key() == aKey )
+ {
+ retval = iWorkerArray[i]->Path();
+ keyExists = ETrue;
+ }
+ }
+
+ // the key was not found
+ if ( !keyExists )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ break;
+ }
+
+ default:
+ {
+
+ break;
+ }
+ }
+
+ return retval;
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::InsertFileIntoWaitQueueL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CHttpTransferBase::InsertFileIntoWaitQueueL(
+ TAny* aKey,
+ const TDesC& aTargetPath,
+ const TDesC8& aUri )
+ {
+ // Checks first if the key already exists in iWaitQueue or in iFileQueue
+ // if does -> leave
+ for ( TInt i = 0; i < iWaitQueue.Count(); i++ )
+ {
+ if ( iWaitQueue[i]->Key() == aKey )
+ {
+ User::Leave( KErrAlreadyExists );
+ }
+ }
+
+ for ( TInt i = 0; i < iFileQueue.Count(); i++ )
+ {
+ if ( iFileQueue[i]->Key() == aKey )
+ {
+ User::Leave( KErrAlreadyExists );
+ }
+ }
+
+ // if key is valid create CHttpFile and insert it to iWaitQueue
+ CHttpFile* httpfile = CHttpFile::NewL( aKey, aUri, aTargetPath );
+ iWaitQueue.Append( httpfile );
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::InsertFileIntoWaitQueueL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CHttpTransferBase::InsertFileIntoWaitQueueL(
+ TAny* aKey,
+ const RFile& aFileHandle,
+ const TDesC8& aUri )
+ {
+ // Checks first if the key already exists in iWaitQueue or in iFileQueue
+ // if does -> leave
+ for ( TInt i = 0; i < iWaitQueue.Count(); i++ )
+ {
+ if ( iWaitQueue[i]->Key() == aKey )
+ {
+ User::Leave( KErrAlreadyExists );
+ }
+ }
+
+ for ( TInt i = 0; i < iFileQueue.Count(); i++ )
+ {
+ if ( iFileQueue[i]->Key() == aKey )
+ {
+ User::Leave( KErrAlreadyExists );
+ }
+ }
+
+ // if key is valid create CHttpFile and insert it to iWaitQueue
+ CHttpFile* httpfile = CHttpFile::NewL( aKey, aUri, aFileHandle );
+ iWaitQueue.Append( httpfile );
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::MoveToFileQueue()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CHttpTransferBase::MoveToTransferQueueL( TAny* aKey )
+ {
+ TBool keyExists = EFalse;
+ CHttpFile* waitFile = NULL;
+
+ for ( TInt i = 0; i < iWaitQueue.Count(); i++ )
+ {
+ if ( iWaitQueue[i]->Key() == aKey )
+ {
+ keyExists = ETrue;
+
+ // Removes the file from iWaitQueue
+ waitFile = iWaitQueue[i];
+
+ // Set the queue
+ iWaitQueue.Remove(i);
+ iWaitQueue.Compress();
+ }
+ }
+
+ // If the key does not exist -> leaves
+ if ( !keyExists )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ // Appends the file to iFileQueue
+ iFileQueue.Append( waitFile );
+
+ // start the transfer
+ ActivateNewTransferRequest();
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::ActivateNewTransferRequest()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CHttpTransferBase::ActivateNewTransferRequest()
+ {
+ if ( !IsActive() )
+ {
+ SetActive();
+ TRequestStatus* pStatus = &iStatus;
+ User::RequestComplete( pStatus, ETransferNextFile );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::ProcessNextFileL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CHttpTransferBase::ProcessNextFileL()
+ {
+ // Check that there is workers available
+ for ( TInt i = 0; i < iWorkerArray.Count(); i++ )
+ {
+ if ( !iWorkerArray[i]->ProcessOnGoing() )
+ {
+ CHttpFile* nextFile = NULL;
+
+ nextFile = NextFile();
+
+ if ( nextFile )
+ {
+ // sets the file and sets the state to EWaitingForStart
+ iWorkerArray[i]->SetFileL( *nextFile );
+
+ // Set worker which is handled to pointer so that
+ // if it leaves the worker can be terminated
+ iActiveWorker = iWorkerArray[i];
+
+ iObserver->ReadyForTransferL( nextFile->Key() );
+
+ iActiveWorker = NULL;
+ }
+ }
+ }
+ }
+
+
+// From base class CActive
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::DoCancel()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CHttpTransferBase::DoCancel()
+ {
+ CancelAll();
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::RunL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CHttpTransferBase::RunL()
+ {
+ ProcessNextFileL();
+ }
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::RunError()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+TInt CHttpTransferBase::RunError( TInt aError )
+ {
+ // Terminate worker which leaved
+ if ( iActiveWorker )
+ {
+ // Cancels the transfer and
+ // informs the client through TransferCompleted()
+ iObserver->TransferCompleted( iActiveWorker->Key(), aError );
+ iActiveWorker->CancelTransfer();
+ iActiveWorker = NULL;
+ }
+
+ return KErrNone;
+ }
+
+
+// From base class MHttpWorkerObserver
+
+// --------------------------------------------------------------------------
+// CHttpTransferBase::ProcessNextFileL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CHttpTransferBase::WorkerCompleted()
+ {
+ ActivateNewTransferRequest();
+ }
+
+// end of file