contextframework/cfw/src/cfscriptengine/cfpersistentdata.cpp
changeset 0 2e3d3ce01487
child 58 0818dd463d41
child 72 56a7be608841
--- /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;
+    }