remotestoragefw/remotefileengine/src/rsfwopenbypathstatemachine.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 09:07:59 +0200
changeset 0 3ad9d5175a89
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2005-2006 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:  State machine for opening a file or directory
*
*/


#include "rsfwopenbypathstatemachine.h"
#include "rsfwfileentry.h"
#include "rsfwfiletable.h"
#include "rsfwvolumetable.h"
#include "rsfwvolume.h"
#include "rsfwinterface.h"
#include "rsfwfileengine.h"
#include "rsfwlockmanager.h"
#include "mdebug.h"


// ----------------------------------------------------------------------------
// CRsfwOpenByPathStateMachine::CRsfwOpenByPathStateMachine
// ----------------------------------------------------------------------------
//
CRsfwOpenByPathStateMachine::CRsfwOpenByPathStateMachine()
    {
    }

// ----------------------------------------------------------------------------
// CRsfwOpenByPathStateMachine::~CRsfwOpenByPathStateMachine
// ----------------------------------------------------------------------------
//
CRsfwOpenByPathStateMachine::~CRsfwOpenByPathStateMachine()
    {
    delete iLockToken;
    }

// ----------------------------------------------------------------------------
// CRsfwOpenByPathStateMachine::CompleteRequestL
// ----------------------------------------------------------------------------
//
CRsfwRfeStateMachine::TState*
CRsfwOpenByPathStateMachine::CompleteRequestL(TInt aError)
    {
    DEBUGSTRING(("CRsfwOpenByPathStateMachine::CompleteRequestL %d", aError));
    TRfeOpenByPathOutArgs* outArgs =
        static_cast<TRfeOpenByPathOutArgs*>(iOutArgs);
    if(!aError)
        {
        if ((Node()->Type() == KNodeTypeFile) &&
            iRealOpen) 
            {
            // file opened successfully and was not already opened in create
            Node()->iFileTable->UpdateOpenFileCount(1);
            }
  
        outArgs->iPath.Copy(*iCacheName);
        iAttrp->iAtt = Node()->Att();
        iAttrp->iSize = Node()->Size();
        iAttrp->iModified = Node()->Modified();
        }

    CompleteAndDestroyState()->SetErrorCode(aError);
    return CompleteAndDestroyState();
    }

// ----------------------------------------------------------------------------
// CRsfwOpenByPathStateMachine::TRequestOpenModeState::TRequestOpenModeState
// ----------------------------------------------------------------------------
//
CRsfwOpenByPathStateMachine::TRequestOpenModeState::TRequestOpenModeState(
    CRsfwOpenByPathStateMachine* aParent)
    : iOperation(aParent)
    {
    iRequestedLock = EFalse;
    }

// ----------------------------------------------------------------------------
// CRsfwOpenByPathStateMachine::TRequestOpenModeState::EnterL
// ----------------------------------------------------------------------------
//
void CRsfwOpenByPathStateMachine::TRequestOpenModeState::EnterL()
    {
    
    DEBUGSTRING(("CRsfwOpenByPathStateMachine::TRequestOpenModeState::EnterL"));
    
    TRfeOpenByPathInArgs* inArgs =
        static_cast<TRfeOpenByPathInArgs*>(iOperation->iInArgs);
    TRfeOpenByPathOutArgs* outArgs =
        static_cast<TRfeOpenByPathOutArgs*>(iOperation->iOutArgs);
    iOperation->iRealOpen = inArgs->iTrueOpen;
    // Use inArgs->iFlags to pass desired locking information
    iOperation->iFlags = inArgs->iFlags;
    iOperation->iAttrp = &(outArgs->iAttr);

    if (!iOperation->Node())
        {
        User::Leave(KErrNotFound);
        }

    if (iOperation->Node()->Size() > iOperation->Volumes()->iMaxCacheSize)
        {
        DEBUGSTRING(("OPENBYPATH failed: file too large: file size %d, max cache size %d",
                     iOperation->Node()->Size(),
                     iOperation->Volumes()->iMaxCacheSize));
        User::Leave(KErrTooBig);
        }

    DEBUGSTRING(("opening fid %d with flags 0x%x",
                 iOperation->Node()->Fid().iNodeId,
                 iOperation->iFlags));

    if (!iOperation->FileEngine()->WriteDisconnected())
        {
        if (!(iOperation->Node()->IsLocked()) &&
            (iOperation->Node()->Type() != KNodeTypeDir) &&
            (iOperation->iFlags & EFileWrite))
            {
            DEBUGSTRING(("requesting lock"));
            // For the time being
            // if flag is 0 we are not interested in getting a lock
            iOperation->FileEngine()->LockManager()->ObtainLockL(
                iOperation->Node(),
                iOperation->iFlags,
                iOperation->iLockToken,
                iOperation);
            iRequestedLock = ETrue;
            }
        else
            {
            // IsLocked() || !(iOperation->iFlags & EFileWrite)
            iOperation->HandleRemoteAccessResponse(0, KErrNone);
            }
        }
    else
        {
        // if WriteDisconnected()
        iOperation->HandleRemoteAccessResponse(0, KErrNone);
        }
    }

// ----------------------------------------------------------------------------
// CRsfwOpenByPathStateMachine::TRequestOpenModeState::CompleteL
// ----------------------------------------------------------------------------
//
CRsfwOpenByPathStateMachine::TState*
CRsfwOpenByPathStateMachine::TRequestOpenModeState::CompleteL()
    {
     DEBUGSTRING(("CRsfwOpenByPathStateMachine::TRequestOpenModeState::CompleteL"));
    if (iRequestedLock)
        {
        //from CRsfwLockManager::ObtainLock()
#ifdef _DEBUG
        TPtrC p = iOperation->Node()->FullNameLC()->Des();
        DEBUGSTRING16(("ObtainLockL(): flags %d returned %d for file '%S'",
                       iOperation->iFlags,
                       KErrNone,
                       &p));
        CleanupStack::PopAndDestroy();
#endif // DEBUG
        iOperation->Node()->SetLockedL(
            iOperation->FileEngine()->LockManager(),
            iOperation->iLockToken);
        iOperation->iLockToken = NULL;
        }

    iOperation->iCacheName = iOperation->Node()->CacheFileName();

    // make sure that the relevant cache file is on place
    // (i.e. it has not been removed e.g. by other apps)
    iOperation->Node()->ValidateCacheFile();

    if (!iOperation->Node()->IsCached())
        {
        if (iOperation->FileEngine()->Disconnected())
            {
            if ((iOperation->Node()->Type() != KNodeTypeDir) &&
                !(iOperation->iFlags & EFileWrite))
                {
                // While disconnected,
                // write access of files returns "not found"
                return iOperation->CompleteRequestL(KErrNotFound);
                }
            }
        iOperation->FileEngine()->CreateContainerFileL(*(iOperation->Node()));
        iOperation->iCacheName = iOperation->Node()->CacheFileName();
        }
    else // is cached
        {
        if (iOperation->Node()->IsLocallyDirty())
            {
            // This is a directory which has at least one kid
            // that has been cached or flushed since the last opening
            // of the directory
            iOperation->FileEngine()->UpdateDirectoryContainerL(
                *(iOperation->Node()));
            }

        // If this is a cached file,
        // we must remove it from LRUlist as it is now open
        if (iOperation->iRealOpen)
            {
            iOperation->Node()->iFileTable->Volume()->iVolumeTable->
                RemoveFromLRUPriorityList(iOperation->Node());
            }
        }

    // if file or dir has just been opened, remove it from metadata LRU list
    iOperation->Node()->iFileTable->Volume()->iVolumeTable->
        RemoveFromMetadataLRUPriorityList(iOperation->Node());

    return iOperation->CompleteRequestL(KErrNone);
    }

// ----------------------------------------------------------------------------
// CRsfwOpenByPathStateMachine::TRequestOpenModeState::ErrorL
// fileEngine->RequestConnectionStateL() has returned with error
// ----------------------------------------------------------------------------
//
CRsfwOpenByPathStateMachine::TState*
CRsfwOpenByPathStateMachine::TRequestOpenModeState::ErrorL(TInt aCode)
    {
    DEBUGSTRING(("CRsfwOpenByPathStateMachine::TRequestOpenModeState::ErrorL %d", aCode));
    // from CRsfwFileEngine::DoOpenByPath()
    if (aCode == KErrNotSupported)
        {
        iRequestedLock = EFalse;
        // locks not supported is not an error state
        // instead we run the success state...
        return CompleteL();
        }

    //from CRsfwLockManager::ObtainLock()
#ifdef _DEBUG
    TPtrC p = iOperation->Node()->FullNameLC()->Des();
    DEBUGSTRING16(("ObtainLockL(): flags %d returned %d for file '%S'",
                   iOperation->iFlags,
                   aCode,
                   &p));
    CleanupStack::PopAndDestroy();
#endif

    return iOperation->CompleteRequestL(aCode);
    }