diff -r 000000000000 -r 3ad9d5175a89 remotestoragefw/remotefileengine/src/rsfwlookupstatemachine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/remotestoragefw/remotefileengine/src/rsfwlookupstatemachine.cpp Thu Dec 17 09:07:59 2009 +0200 @@ -0,0 +1,330 @@ +/* +* 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 file lookup +* +*/ + + +#include "rsfwlookupstatemachine.h" +#include "rsfwfileentry.h" +#include "rsfwfiletable.h" +#include "rsfwinterface.h" +#include "rsfwfileengine.h" +#include "mdebug.h" +#include "rsfwdirentattr.h" +#include "rsfwvolumetable.h" + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::CRsfwLookupStateMachine +// ---------------------------------------------------------------------------- +// +CRsfwLookupStateMachine::CRsfwLookupStateMachine() + { + iKidCreated = ETrue; + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::~CRsfwLookupStateMachine +// ---------------------------------------------------------------------------- +// +CRsfwLookupStateMachine::~CRsfwLookupStateMachine() + { + delete iDirEntAttr; + if (iPath) + { + delete iPath; + } + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::CompleteRequestL +// ---------------------------------------------------------------------------- +// +CRsfwRfeStateMachine::TState* CRsfwLookupStateMachine::CompleteRequestL(TInt aError) + { + TRfeLookupOutArgs* outArgs = static_cast(iOutArgs); + if (aError == KUpdateNotRequired) + { // discard + aError = KErrNone; + } + + if (!aError) + { + outArgs->iFid = iKidFep->Fid(); + } + CompleteAndDestroyState()->SetErrorCode(aError); + return CompleteAndDestroyState(); + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::CompleteL +// ---------------------------------------------------------------------------- +// +CRsfwLookupStateMachine::TState* CRsfwLookupStateMachine::CompleteL() + { + // from CRsfwFileEngine::UpdateFileAttributes/UpdateDirAttributes +#ifdef _DEBUG + if (iDirEntAttr) + { + DEBUGSTRING(("Kid attributes: attr=0x%x, size=%d, time=", + iDirEntAttr->Att(), + iDirEntAttr->Size())); + DEBUGTIME((iDirEntAttr->Modified())); + } +#endif + + if (iKidCreated) + { + /* from CRsfwFileEngine::DoLookupL */ + // Create a file entry for this kid + if (!Volumes()->EnsureMetadataCanBeAddedL(Node())) + { + User::Leave(KErrNoMemory); + } + iKidFep = CRsfwFileEntry::NewL(iKidName, Node()); + if (iDirEntAttr->Att() & KEntryAttDir) + { + iKidFep->SetType(KNodeTypeDir); + } + else + { + iKidFep->SetType(KNodeTypeFile); + } + + iKidFep->SetAttributesL(*iDirEntAttr, ETrue); + + // Remember that we have this kid + FileEngine()->iFileTable->AddL(iKidFep); + Node()->AddKid(*iKidFep); + // If we really find a new kid that we were not aware of + // we must set the parent as locally dirty + // (this should not happen too often) + Node()->SetLocallyDirty(); + } + + // We now have a valid kid entry + return CompleteRequestL(KErrNone); + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::TUpdateKidAttributesTryFirstTypeState +// ---------------------------------------------------------------------------- +// +CRsfwLookupStateMachine:: +TUpdateKidAttributesTryFirstTypeState:: +TUpdateKidAttributesTryFirstTypeState(CRsfwLookupStateMachine* aParent) + : iOperation(aParent) + { + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::EnterL +// ---------------------------------------------------------------------------- +// +void CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::EnterL() + { + DEBUGSTRING(("CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::EnterL")); + TRfeLookupInArgs* inArgs = + static_cast(iOperation->iInArgs); + TRfeLookupOutArgs* outArgs = + static_cast(iOperation->iOutArgs); + iOperation->iNodeType = inArgs->iNodeType; + iOperation->iKidName.Set(inArgs->iName); + + TInt err = KErrNone; + iOperation->iKidFep = NULL; + + if (!iOperation->Node()) + { + User::Leave(KErrNotFound); + } + + DEBUGSTRING16(("looking up '%S' in fid=%d", + &(iOperation->iKidName), + iOperation->Node()->Fid().iNodeId)); + + // We'd better be looking up in a directory + if (iOperation->Node()->Type() != KNodeTypeDir) + { + User::Leave(KErrNotFound); + } + + // Try to get the entry from the parent directory + iOperation->iKidFep = + iOperation->Node()->FindKidByName(iOperation->iKidName); + if (!iOperation->iKidFep) + { + DEBUGSTRING(("no such kid!")); + // Didn't find it + // if the parent directory's cache entry is still valid + // we return "not found" + if ((iOperation->FileEngine()->UseCachedAttributes(*iOperation->Node())) && + (iOperation->FileEngine()->UseCachedData(*iOperation->Node()))) + { + User::Leave(KErrNotFound); + } + + iOperation->iPath = + iOperation->FileEngine()->FullNameL(*iOperation->Node()); + if (iOperation->iNodeType == KNodeTypeUnknown) + { + iOperation->FileEngine()-> + UpdateAttributesL(*iOperation->iPath, + iOperation->iKidName, + iOperation->iDirEntAttr, + KNodeTypeFile, + iOperation); + } + else + { + iOperation->FileEngine()-> + UpdateAttributesL(*iOperation->iPath, + iOperation->iKidName, + iOperation->iDirEntAttr, + iOperation->iNodeType, + iOperation); + } + + if (err) + { + // communication to the server failed, + //e.g. we are in disconnected mode + User::Leave(err); + } + } + else + { + // We now have a valid kid entry + outArgs->iFid = iOperation->iKidFep->Fid(); + iOperation->HandleRemoteAccessResponse(0, KUpdateNotRequired); + } + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::CompleteL +// ---------------------------------------------------------------------------- +// +CRsfwLookupStateMachine::TState* +CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::CompleteL() + { + DEBUGSTRING(("CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::CompleteL")); + return iOperation->CompleteL(); + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::ErrorL +// If we were looking for a file return KErrNotFound +// if for directory KErrPathNotFound. +// File Server seems to always call Entry() (-->lookup()) before other file +// operations so as long as we return the right variant of "not found" +// error here other places do not matter. +// ---------------------------------------------------------------------------- +// +CRsfwLookupStateMachine::TState* +CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::ErrorL(TInt aCode) + { + DEBUGSTRING(("CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState::ErrorL %d", aCode)); + if (aCode == KUpdateNotRequired) + { + iOperation->iKidCreated = EFalse; + return iOperation->CompleteL(); + } + else if (iOperation->iNodeType == KNodeTypeUnknown) + { + return new CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState( + iOperation); + } + else if ((aCode != KErrNotFound) && (aCode != KErrPathNotFound)) + { + return iOperation->CompleteRequestL(aCode); + } + else if (iOperation->iNodeType == KNodeTypeDir) + { + return iOperation->CompleteRequestL(KErrPathNotFound); + } + else + { + return iOperation->CompleteRequestL(KErrNotFound); + } + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::TUpdateKidAttributesTrySecondTypeState +// ---------------------------------------------------------------------------- +// +CRsfwLookupStateMachine:: +TUpdateKidAttributesTrySecondTypeState:: +TUpdateKidAttributesTrySecondTypeState(CRsfwLookupStateMachine* aParent) + : iOperation(aParent) + { + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::EnterL +// ---------------------------------------------------------------------------- +// +void CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::EnterL() + { + DEBUGSTRING(("CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::EnterL")); + // We only come here if nodetype is unknown and + // we already tried to lookup as a file + iOperation->FileEngine()->UpdateAttributesL(*iOperation->iPath, + iOperation->iKidName, + iOperation->iDirEntAttr, + KNodeTypeDir, iOperation); + } + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::CompleteL +// ---------------------------------------------------------------------------- +// +CRsfwLookupStateMachine::TState* +CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::CompleteL() + { + DEBUGSTRING(("CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::CompleteL")); + // from CRsfwFileEngine::UpdateFileAttributes/UpdateDirAttributes + return iOperation->CompleteL(); + } + + +// ---------------------------------------------------------------------------- +// CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::ErrorL +// If we were looking for a file return KErrNotFound, +// if for directory KErrPathNotFound. +// File Server seems to always call Entry() (-->lookup()) before other file +// operations so as long as we return the right variant of "not found" +// error here other places do not matter. +// ---------------------------------------------------------------------------- +// +CRsfwLookupStateMachine::TState* +CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::ErrorL(TInt aCode) + { + DEBUGSTRING(("CRsfwLookupStateMachine::TUpdateKidAttributesTrySecondTypeState::ErrorL %d", aCode)); + // from CRsfwFileEngine::Lookup() + // No such kid + + // cache the last failed lookup results + iOperation->FileEngine()->SetFailedLookup(*iOperation->iPath, + iOperation->iKidName); + + if (iOperation->iNodeType == KNodeTypeDir) + { + return iOperation->CompleteRequestL(KErrPathNotFound); + } + else + { + return iOperation->CompleteRequestL(KErrNotFound); + } + } +