diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/upnphttptransfer/src/httptransferbase.cpp --- /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 + +// 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