camappengine/asynchfilesavequeue/src/asynchatom.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:23:23 +0100
branchRCL_3
changeset 21 27fe719c32e6
parent 0 9b3e960ffc8a
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201031 Kit: 201035

/*
* Copyright (c) 2002-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:  Asynchronous FSQ Atom
*
*/



// INCLUDE FILES
#include <asynchfsq.h>
#include <sysutil.h> // for disk space query
#include <bautils.h> // for deleting files
#include "asynchatom.h"

// CONSTANTS

// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CAsynchFSQAtom::CAsynchFSQAtom
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CAsynchFSQAtom::CAsynchFSQAtom() : CActive( EPriorityNormal )
    {
    LOGTEXT( _L( "CAsynchFSQAtom::CAsynchFSQAtom() entering" ) );
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CAsynchFSQAtom::ConstructL( CAsynchFSQ* aOwner, 
                                 TInt aPriority,
                                 TFSQActionType aActionType,  
                                 TDesC8& aData, 
                                 const TDesC& aPath, 
                                 const TDesC& aURL, 
                                 TFSQSchemaType aSchema, 
                                 const TDesC& aUserName, 
                                 const TDesC& aPassword )
    {
    LOGTEXT( _L( "CAsynchFSQAtom::ConstructL() entering" ) );
    iOwner = aOwner;
    iState = EPending;
    iDelayedFileName = NULL;
    SetPriority(aPriority);
    iSchema = aSchema;
    
    // prep to copy
    iData = NULL;
    iPath = NULL;
    iURL = NULL;
    iUserName = NULL;
    iPassword = NULL;
    
    // copy
    iActionType = aActionType;
    
    iData = &aData;  
    if ( aPath != KNullDesC ) 
        {
        iPath = HBufC::NewL( aPath.Length() ); 
        iPath->Des().Append( aPath ); 
        }
    if ( aURL != KNullDesC )
        {
        iURL = HBufC::NewL( aURL.Length() ); 
        iURL->Des().Append( aURL ); 
        }
    if ( aUserName != KNullDesC )
        {
        iUserName = HBufC::NewL( aUserName.Length() ); 
        iUserName->Des().Append( aUserName ); 
        }
    if ( aPassword != KNullDesC )
        {
        iPassword = HBufC::NewL( aPassword.Length() ); 
        iPassword->Des().Append( aPassword ); 
        }
    
    LOGTEXT( _L( "CAsynchFSQAtom::ConstructL() adding AO" ) );
    CActiveScheduler::Add( this );
    LOGTEXT( _L( "CAsynchFSQAtom::ConstructL() exiting" ) );
    }

// -----------------------------------------------------------------------------
// CAsynchFSQAtom::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CAsynchFSQAtom* CAsynchFSQAtom::NewL( CAsynchFSQ* aOwner, 
                                      TInt aPriority,
                                      TFSQActionType aActionType,  
                                      TDesC8& aData, 
                                      const TDesC& aPath, 
                                      const TDesC& aURL, 
                                      TFSQSchemaType aSchema, 
                                      const TDesC& aUserName, 
                                      const TDesC& aPassword )
    {
    LOGTEXT( _L( "CAsynchFSQAtom::NewL() entering" ) );
    CAsynchFSQAtom* self = new( ELeave ) CAsynchFSQAtom();   
    CleanupStack::PushL( self );
    self->ConstructL(  aOwner, 
                       aPriority,
                       aActionType,  
                       aData, 
                       aPath, 
                       aURL, 
                       aSchema, 
                       aUserName, 
                       aPassword  );
                       
    CleanupStack::Pop();
    return self;
    }

// -----------------------------------------------------------------------------
// CAsynchFSQAtom::~CAsynchFSQAtom   
// Destructor for the atom class
// -----------------------------------------------------------------------------
//
CAsynchFSQAtom::~CAsynchFSQAtom()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() entering" ) );
    
    LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() canceling" ) );
    Cancel();
    LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() canceled" ) );
    
    // Close file
    iFile.Close(); 
    
    // Close file system
    iFs.Close();
    
    // Free leftover data
    if( iData )
        {
        LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() deleting iData" ) );
        delete iData;
        iData = NULL;
        }

    if( iPath )
        {
        LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() deleting iPath" ) );
        delete iPath;
        iPath = NULL;
        }
        
    if( iURL )
        {
        LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() deleting iURL" ) );
        delete iURL;
        iURL = NULL;
        }
        
    if( iUserName )
        {
        LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() deleting iUserName" ) );
        delete iUserName;
        iUserName = NULL;
        }
        
    if( iPassword )
        {
        LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() deleting iPassword" ) );
        delete iPassword;
        iPassword = NULL;
        }                
        
    if( iDelayedFileName )
        {
        LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() deleting iDelayedFileName" ) );
        delete iDelayedFileName;
        iPassword = NULL;
        }      
        
    LOGTEXT( _L( "CAsynchFSQAtom::~CAsynchFSQAtom() exiting" ) );
    }

// -----------------------------------------------------------------------------
// CAsynchFSQAtom::Go
// -----------------------------------------------------------------------------
//
TInt CAsynchFSQAtom::Go()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::Go() entering" ) );
    TInt err = KErrNone;
    
    if (( iState != EPending )||( IsActive() ))
        {
        err = KErrInUse;
        }
    else
        {
        // set new state
        switch ( iActionType )
	        {
    	    case EFileSave:
            case EFileSaveAndWebUpload:
    	        {
    	        LOGTEXT( _L( "CAsynchFSQAtom::Go() iState => ESaving" ) );
    	        iState = ESaving;
    	        break;	        
    	        }
    	    case EWebUpload:
    	        {
    	        LOGTEXT( _L( "CAsynchFSQAtom::Go() iState => EUploading" ) );
    	        iState = EUploading;
    	        break;	        
    	        }
    	    default:
    	        {
       	        LOGTEXT( _L( "CAsynchFSQAtom::Go() undefined activity requested" ) );
                err = KErrNotSupported;
    	        break;
    	        }
	        }	        
    
        // initiate AO activity
        LOGTEXT( _L( "CAsynchFSQAtom::Go() setting active" ) );
        SetActive();
        TRequestStatus* statusPtr = &iStatus;
        User::RequestComplete( statusPtr, KErrNone );
        LOGTEXT( _L( "CAsynchFSQAtom::Go() request completed" ) );
        }
        
    LOGTEXT( _L( "CAsynchFSQAtom::Go() returning" ) );
    return err;
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::GetState
// -----------------------------------------------------------------------------
//
TFSQAtomState CAsynchFSQAtom::GetState()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::GetState() entering & returning" ) );
    return iState;
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::DoesLocalSave
// -----------------------------------------------------------------------------
//
TBool CAsynchFSQAtom::DoesLocalSave()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::DoesLocalSave() entering" ) );
    TBool ret = EFalse;
    if (( iActionType == EFileSave )||( iActionType == EFileSaveAndWebUpload ))
        {
        ret = ETrue;
        }
    LOGTEXT2( _L( "CAsynchFSQAtom::DoesLocalSave() returning, ret=%d" ),ret );
    return ret;
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::GetPath
// -----------------------------------------------------------------------------
//
const TDesC& CAsynchFSQAtom::GetPath() const
    {
    LOGTEXT( _L( "CAsynchFSQAtom::GetPath() entering & returning" ) );
    return *iPath;
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::DeleteLocal
// -----------------------------------------------------------------------------
//
TInt CAsynchFSQAtom::DeleteLocal()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::DeleteLocal() entering" ) );
    TInt err = KErrNone;
    
    // delete or delayed delete
    if (( iState == EPending ) || ( iState == ESaving )||( iState == ESavePending ))
        {
        LOGTEXT( _L( "CAsynchFSQAtom::DeleteLocal() delayed delete" ) );
        // we are currently saving, so we have to delete later
        iDelayedLocalDelete = ETrue;
        }
    else
        {
        LOGTEXT( _L( "CAsynchFSQAtom::DeleteLocal() deleting now" ) );
        // delete now
        err = KErrNotFound;
        RFs fs;
        TInt connectError = fs.Connect();
        BaflUtils ba;
        if( !connectError && ba.FileExists( fs, *iPath ) )
            {
            err = KErrNone;
            ba.DeleteFile( fs, *iPath );
            }
        fs.Close();
        }
    
    LOGTEXT2( _L( "CAsynchFSQAtom::DeleteLocal() returning, err=%d" ),err );
    return err;
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::RenameLocal
// -----------------------------------------------------------------------------
//
TInt CAsynchFSQAtom::RenameLocal( const TDesC& aNew )
    {
    LOGTEXT( _L( "CAsynchFSQAtom::RenameLocal() entering" ) );
    TInt err = KErrNone;
    
    // delete or delayed delete
    if (( iState == EPending ) || ( iState == ESaving )||( iState == ESavePending ))
        {
        LOGTEXT( _L( "CAsynchFSQAtom::RenameLocal() delayed rename" ) );
        // we are currently saving, so we have to delete later
        iDelayedLocalRename = ETrue;
        TRAP( err,
            iDelayedFileName = HBufC::NewL( aNew.Length() );
            iDelayedFileName->Des().Append( aNew );
            );
        }
    else
        {
        LOGTEXT( _L( "CAsynchFSQAtom::RenameLocal() renaming now" ) );
        err = KErrNotFound;
        RFs fs;
        TInt connectError = fs.Connect();
        BaflUtils ba;
        if( !connectError && ba.FileExists( fs, *iPath ) )
            {
            err = KErrNone;
            ba.RenameFile( fs, *iPath, aNew );
            }
        fs.Close();
        }
    
    LOGTEXT2( _L( "CAsynchFSQAtom::RenameLocal() returning, err=%d" ),err );
    return err;
    }    
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::SaveL
// -----------------------------------------------------------------------------
//
void CAsynchFSQAtom::SaveL()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::SaveL() entering" ) );
    iError = KErrNone;
    
    if ( iState != ESaving )
        {
        // the state machine is lost
        LOGTEXT( _L( "CAsynchFSQAtom::SaveL() bad state, leaving..." ) );
        User::Leave( KErrGeneral );
        }

    // Init
    iError = iFs.Connect();
    LOGTEXT2( _L( "CAsynchFSQAtom::SaveL() fsSession.Connect iError=%d" ),iError );
    
    // Get drive number
    TInt drive = 0;
    if( !iError )
        {
        iError = RFs::CharToDrive( iPath->Des()[0], drive );
        LOGTEXT2( _L( "CAsynchFSQAtom::SaveL() CharToDrive iError=%d" ),iError );
        }

    // Check disk space
    if ( !iError )
        {
        TBool fullDisk = EFalse;
        TRAPD( utilErr,
               fullDisk = SysUtil::DiskSpaceBelowCriticalLevelL( 
                          &iFs, iData->Length(), drive ) );
        if( utilErr )
            {
            LOGTEXT2( _L( "CAsynchFSQAtom::SaveL() SysUtil iError=%d" ),iError );
            iError = utilErr;
            }
        else if( fullDisk )
            {
            iError = KErrDiskFull;
            }
        }
   
    // Attempt to create the file
    if( !iError )
        {    
        if ( iOverwrite )
            {
            iError = iFile.Replace( iFs, iPath->Des(), EFileWrite );
            LOGTEXT2( _L( "CAsynchFSQAtom::SaveL() file.Replace iError=%d" ),iError );
            }
        else
            {
            iError = iFile.Create( iFs, iPath->Des(), EFileWrite );
            LOGTEXT2( _L( "CAsynchFSQAtom::SaveL() file.Open iError=%d" ),iError );
            }
        }
        
    // Write the file
    if( !iError )
        {
        LOGTEXT( _L( "CAsynchFSQAtom::SaveL() about to write" ) );
        SetActive();
        iFile.Write( *iData, iStatus );
        LOGTEXT( _L( "CAsynchFSQAtom::SaveL() write requested" ) );
        }
    
    // Update state
    LOGTEXT( _L( "CAsynchFSQAtom::SaveL() iState => ESavePending" ) );
    iState = ESavePending;
    
    // leave if error
    if ( iError )
        {
        LOGTEXT2( _L( "CAsynchFSQAtom::SaveL() Leaving with iError=%d" ),iError );
        User::Leave( iError );
        }
    
    LOGTEXT2( _L( "CAsynchFSQAtom::SaveL() exiting, iError=%d" ), iError );
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::SaveCleanupL
// -----------------------------------------------------------------------------
//
void CAsynchFSQAtom::SaveCleanupL()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() entering" ) );
        
    if ( iState != ESavePending )
        {
        // the state machine is lost
        LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() bad state, leaving..." ) );
        User::Leave( KErrGeneral );
        }
        
    // Flush file.
    if( !iError )
        {
        LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() flushing" ) );
        iError = iFile.Flush();
        LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() flushed" ) );
        }
        
    // Close file
    iFile.Close(); 
        
    // Delayed rename, if needed
    if (( !iError ) && ( iDelayedLocalRename ))
        {
        LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() doing delayed rename" ) );
        BaflUtils ba;
        if( ba.FileExists( iFs, *iPath ) )
            {
            iError = KErrNone;
            TPtrC newPath = *iDelayedFileName;
            ba.RenameFile( iFs, *iPath, newPath );
            }
        iDelayedLocalRename = EFalse;
        }
        
    // Delayed delete, if needed
    if (( !iError ) && ( iDelayedLocalDelete ))
        {
        LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() doing delayed delete" ) );
        iError = KErrNotFound;
        BaflUtils ba;
        if( ba.FileExists( iFs, *iPath ) )
            {
            iError = KErrNone;
            ba.DeleteFile( iFs, *iPath );
            }
        iDelayedLocalDelete = EFalse;
        LOGTEXT2( _L( "CAsynchFSQAtom::SaveCleanupL() delete done, iError=%d" ), iError );
        }
        
    // Close file system
    iFs.Close();
        
    // Update state
    switch ( iActionType )
	    {
	    case EFileSave:
	        {
            LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() iState => EComplete" ) );
            iState = EComplete;            
	        break;	        
	        }
	    case EFileSaveAndWebUpload:
	        {
            LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() iState => EUploading" ) );
            iState = EUploading;            
            
            // re-initiate AO activity
            LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() setting active" ) );
            SetActive();
            TRequestStatus* statusPtr = &iStatus;
            User::RequestComplete( statusPtr, KErrNone );
            LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() request completed" ) );
	        break;	        
	        }     	        
	    default:
	        {
	        // the state machine is lost
	        LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() bad action, leaving" ) );
	        User::Leave( KErrGeneral );
	        break;        
	        }	        
	    }	
    
    // report completion
    LOGTEXT2( _L( "CAsynchFSQAtom::SaveCleanupL() notifying, iError=%d" ), iError );
    iOwner->Notify( iError );
        
    LOGTEXT( _L( "CAsynchFSQAtom::SaveCleanupL() exiting" ));
    }    
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::UploadL
// -----------------------------------------------------------------------------
//
void CAsynchFSQAtom::UploadL()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::UploadL() entering" ) );
    iError = KErrNone;
        
    if ( iState != EUploading )
        {
        // the state machine is lost
        LOGTEXT( _L( "CAsynchFSQAtom::UploadL() bad state, leaving..." ) );
        User::Leave( KErrGeneral );
        }
    
    // This activity is not yet supported, so just feign completion
    LOGTEXT( _L( "CAsynchFSQAtom::UploadL() iState => EComplete" ) );
    iState = EUploadPending;
    
    // re-initiate AO activity
    LOGTEXT( _L( "CAsynchFSQAtom::UploadL() setting active" ) );
    SetActive();
    TRequestStatus* statusPtr = &iStatus;
    User::RequestComplete( statusPtr, KErrNone );
    LOGTEXT( _L( "CAsynchFSQAtom::UploadL() request completed" ) );
    
    LOGTEXT( _L( "CAsynchFSQAtom::UploadL() exiting" ) );
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::UploadCleanup
// -----------------------------------------------------------------------------
//
void CAsynchFSQAtom::UploadCleanupL()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::UploadCleanupL() entering" ) );
    
    if ( iState != ESaving )
        {
        // the state machine is lost
        LOGTEXT( _L( "CAsynchFSQAtom::UploadCleanupL() bad state, leaving..." ) );
        User::Leave( KErrGeneral );
        }
    
    // This activity is not yet supported, so just feign completion
    LOGTEXT( _L( "CAsynchFSQAtom::UploadCleanupL() iState => EComplete" ) );
    iState = EComplete;
    
    // report completion
    LOGTEXT2( _L( "CAsynchFSQAtom::UploadCleanupL() notifying, iError=%d" ), iError );
    iOwner->Notify( iError );
    
    LOGTEXT( _L( "CAsynchFSQAtom::UploadCleanupL() exiting" ) );
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::ActionsLeft
// -----------------------------------------------------------------------------
//
TInt CAsynchFSQAtom::ActionsLeft()
    {
    TInt actionsLeft = 0;
    
    // logically, this section is liable to change if more
    // action types are added to the class
    switch ( iState )
	    {
	    case EPending:
	        {
	        if ( iActionType == EFileSaveAndWebUpload )
	            {
	            actionsLeft = 2;
	            }
	        else
	            {
	            actionsLeft = 1;
	            }
	        break;
	        }
	    case ESaving:
	    case ESavePending:
	        {
	        if ( iActionType == EFileSave )
	            {
	            actionsLeft = 1;
	            }
	        else
	            {
	            actionsLeft = 2;
	            }
	        break;	        
	        }
	    case EUploading:
	    case EUploadPending:
	        {
	        actionsLeft = 1;
	        break;
	        }	        	        
	    case EComplete:
	        {
	        actionsLeft = 0;
	        break;
	        }	        	        
	    }	
    
    LOGTEXT2( _L( "CAsynchFSQAtom::ActionsLeft() returning, actionsLeft=%d" ), actionsLeft );
    return actionsLeft;
    }

    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::RunL
// -----------------------------------------------------------------------------
//
void CAsynchFSQAtom::RunL()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::RunL() entering" ) );

    switch ( iState )
	    {
	    case ESaving:
	        {
	        SaveL();
	        break;	        
	        }
	    case ESavePending:
	        {
	        SaveCleanupL();
	        break;	        
	        }
	    case EUploading:
	        {
	        UploadL();
	        break;	        
	        }	        	        
	    case EUploadPending:
	        {
	        UploadCleanupL();
	        break;
	        }	        	        
	    default:
	        {
	        // the state machine is lost
	        LOGTEXT( _L( "CAsynchFSQAtom::RunL() bad state, leaving..." ) );
	        User::Leave( KErrGeneral );
	        break;        
	        }	        
	    }	

    LOGTEXT( _L( "CAsynchFSQAtom::RunL() exiting" ) );
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::RunError
// -----------------------------------------------------------------------------
//
TInt CAsynchFSQAtom::RunError( TInt aError )
    {
    LOGTEXT2( _L( "CAsynchFSQAtom::RunError() entering, aError=%d" ), aError );
    // notify and wait for teardown
    iState = EComplete;
    iOwner->Notify( aError );
    LOGTEXT( _L( "CAsynchFSQAtom::RunError() returning" ) );
    return KErrNone;
    }
    
// -----------------------------------------------------------------------------
// CAsynchFSQAtom::DoCancel
// -----------------------------------------------------------------------------
//
void CAsynchFSQAtom::DoCancel()
    {
    LOGTEXT( _L( "CAsynchFSQAtom::DoCancel() entering" ) );

    LOGTEXT( _L( "CAsynchFSQAtom::DoCancel() exit" ) );
    }
    

//  End of File