diff -r 000000000000 -r 2e3d3ce01487 contextframework/cfw/src/cfscriptengine/cfpersistentdata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contextframework/cfw/src/cfscriptengine/cfpersistentdata.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,376 @@ +/* +* Copyright (c) 2007-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: CCFPersistentData class implementation. +* +*/ + + + +// INCLUDES +#include +#include +#include + +#include "cfpersistentdata.h" +#include "cfoperationnode.h" +#include "cftrace.h" +#include "cfpendingpersistencytask.h" +#include "cfcommon.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CCFPersistentData::CCFPersistentData +// C++ default constructor can NOT contain any code, that might leave. +// --------------------------------------------------------------------------- +// +CCFPersistentData::CCFPersistentData( RFs& aFs, + const TUid& aOwner, + const TDesC& aName ): + CActive( EPriorityStandard ), + iFs( aFs ), + iOwner( aOwner ), + iName( aName ) + { + FUNC_LOG; + + CActiveScheduler::Add( this ); // Add to scheduler + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::ConstructL +// Symbian 2nd phase constructor can leave. +// --------------------------------------------------------------------------- +// +void CCFPersistentData::ConstructL() + { + FUNC_LOG; + + StartListeningL(); + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::NewL +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CCFPersistentData* CCFPersistentData::NewL( RFs& aFs, + const TUid& aOwner, + const TDesC& aName ) + { + FUNC_LOG; + + CCFPersistentData* self = NewLC( aFs, aOwner, aName ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::NewLC +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CCFPersistentData* CCFPersistentData::NewLC( RFs& aFs, + const TUid& aOwner, + const TDesC& aName ) + { + FUNC_LOG; + + CCFPersistentData* self = new( ELeave ) CCFPersistentData( aFs, + aOwner, aName ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +// Destructor +CCFPersistentData::~CCFPersistentData() + { + FUNC_LOG; + + Cancel(); // Cancel any request, if outstanding + iProperty.Close(); + iPendingTasks.ResetAndDestroy(); + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::DoCancel +// --------------------------------------------------------------------------- +// +void CCFPersistentData::DoCancel() + { + iProperty.Cancel(); + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::StartListeningL +// --------------------------------------------------------------------------- +// +void CCFPersistentData::StartListeningL() + { + Cancel(); // Cancel any request, just to be sure + + // Check the key current value + iProperty.Attach(KUidSystemCategory, conn::KUidBackupRestoreKey); + TInt backupStateValue = 0; + iProperty.Get(backupStateValue); + TUint backupState = backupStateValue & conn::KBURPartTypeMask; + if( backupState == conn::EBURNormal || backupState == conn::EBURUnset ) + { + iStoreRestoreDenied = EFalse; + } + else + { + iStoreRestoreDenied = ETrue; + } + + iProperty.Subscribe(iStatus); + SetActive(); // Tell scheduler a request is active + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::RunL +// --------------------------------------------------------------------------- +// +void CCFPersistentData::RunL() + { + TInt backupStateValue = 0; + iProperty.Get(backupStateValue); + TUint backupState = backupStateValue & conn::KBURPartTypeMask; + if( backupState == conn::EBURNormal || backupState == conn::EBURUnset ) + { + if( iStoreRestoreDenied ) + { + ProcessPendingTasksL(); + } + iStoreRestoreDenied = EFalse; + } + else + { + iStoreRestoreDenied = ETrue; + } + + iProperty.Subscribe(iStatus); + SetActive(); // Tell scheduler a request is active + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::RunError +// --------------------------------------------------------------------------- +// +TInt CCFPersistentData::RunError( TInt aError ) + { + return aError; + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::ProcessPendingTasksL +// --------------------------------------------------------------------------- +// +void CCFPersistentData::ProcessPendingTasksL() + { + FUNC_LOG; + + for (TInt i = iPendingTasks.Count(); i > 0; i--) + { + CCFPendingPersistencyTask* iTask = iPendingTasks[i]; + if ( iTask->Mode() == CCFPendingPersistencyTask::EStore ) + { + DoStoreL( iTask->FileName(), iTask->Operation() ); + } + else if ( iTask->Mode() == CCFPendingPersistencyTask::ERestore ) + { + DoRestoreL( iTask->FileName(), iTask->Operation() ); + } + } + iPendingTasks.ResetAndDestroy(); + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::RestoreL +// --------------------------------------------------------------------------- +// +void CCFPersistentData::RestoreL( + const TDesC& aFile, + CCFOperationNode& aOperation ) + { + FUNC_LOG; + + if ( !iStoreRestoreDenied ) + { + DoRestoreL( aFile, aOperation ); + } + else + { + // make store task pending + CCFPendingPersistencyTask* task = CCFPendingPersistencyTask::NewLC( + CCFPendingPersistencyTask::ERestore, aFile, aOperation ); + User::LeaveIfError( iPendingTasks.Append( task ) ); + CleanupStack::Pop( task ); + } + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::DoRestoreL +// --------------------------------------------------------------------------- +// +void CCFPersistentData::DoRestoreL( + const TDesC& aFile, + CCFOperationNode& aOperation ) + { + FUNC_LOG; + + HBufC* streamName = CreateStreamName( aFile ); + User::LeaveIfNull( streamName ); + CleanupStack::PushL( streamName ); + + RFileReadStream stream; + TInt err = stream.Open( iFs, *streamName, EFileShareReadersOnly | EFileRead ); + if ( err == KErrNone ) + { + stream.PushL(); // CLEANUP<< stream + aOperation.InternalizeL( stream ); + stream.Pop(); // CLEANUP>> stream + } + else if ( err != KErrNotFound ) + { + ERROR(err, "CCFPersistentData::RestoreL() error"); + } + stream.Close(); + CleanupStack::PopAndDestroy( streamName ); // CLEANUP>> streamName + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::StoreL +// --------------------------------------------------------------------------- +// +void CCFPersistentData::StoreL( + const TDesC& aFile, + CCFOperationNode& aOperation ) + { + FUNC_LOG; + + if ( !iStoreRestoreDenied ) + { + DoStoreL( aFile, aOperation ); + } + else + { + // make store task pending + CCFPendingPersistencyTask* task = CCFPendingPersistencyTask::NewLC( + CCFPendingPersistencyTask::EStore, aFile, aOperation ); + User::LeaveIfError( iPendingTasks.Append( task ) ); + CleanupStack::Pop( task ); + } + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::StoreL +// --------------------------------------------------------------------------- +// +void CCFPersistentData::DoStoreL( + const TDesC& aFile, + CCFOperationNode& aOperation ) + { + FUNC_LOG; + + HBufC* streamName = CreateStreamName( aFile ); + User::LeaveIfNull( streamName ); + CleanupStack::PushL( streamName ); + + BaflUtils::EnsurePathExistsL( iFs, *streamName ); + RFileWriteStream stream; + TInt err = stream.Replace( iFs, + *streamName, + EFileShareExclusive | EFileWrite ); + if ( err == KErrNone ) + { + stream.PushL(); + aOperation.ExternalizeL( stream ); + stream.Pop(); + } + else + { + ERROR(err, "CCFPersistentData::StoreL() error"); + } + stream.Close(); + CleanupStack::PopAndDestroy( streamName ); + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::Delete +// --------------------------------------------------------------------------- +// +void CCFPersistentData::Delete( const TDesC& aFile ) + { + FUNC_LOG; + + if ( !iStoreRestoreDenied ) + { + DoDelete( aFile ); + } + else + { + ERROR( KErrInUse, "Cannot delete file because of backup or restore!") + } + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::DoDelete +// --------------------------------------------------------------------------- +// +void CCFPersistentData::DoDelete( const TDesC& aFile ) + { + FUNC_LOG; + + HBufC* streamName = CreateStreamName( aFile ); + if( streamName ) + { + TInt err = BaflUtils::DeleteFile( iFs, *streamName ); + if( err != KErrNone ) + { + ERROR_1( err, "Failed to delete persistent data [%S]", &aFile ); + } + delete streamName; + streamName = NULL; + } + else + { + ERROR_1( KErrNoMemory, "Failed to delete persistent data [%S]", &aFile ); + } + } + +// --------------------------------------------------------------------------- +// CCFPersistentData::CreateStreamName +// --------------------------------------------------------------------------- +// +HBufC* CCFPersistentData::CreateStreamName( const TDesC& aFile ) + { + HBufC* name = HBufC::New( KMaxFileName ); + if( name ) + { + // Double check that we do not exceed KMaxFileName + if( aFile.Length() + KPersistenDataFormat().Length() < KMaxFileName ) + { + // Format name + TParsePtrC parse( aFile ); + TPtrC persistencyFileName( parse.Name() ); + TPtr namePtr( name->Des() ); + namePtr.Format( KPersistenDataFormat, + iOwner.iUid, &iName, &persistencyFileName ); + } + } + return name; + }