--- /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 <s32file.h>
+#include <bautils.h>
+#include <connect/sbdefs.h>
+
+#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;
+ }