webengine/widgetengine/src/Preferences.cpp
changeset 37 cb62a4f66ebe
parent 27 60c5402cb945
child 65 5bfc169077b2
child 84 800203832575
--- a/webengine/widgetengine/src/Preferences.cpp	Thu Dec 17 09:20:16 2009 +0200
+++ b/webengine/widgetengine/src/Preferences.cpp	Thu Jan 07 13:31:38 2010 +0200
@@ -34,6 +34,8 @@
 
 _LIT( KKeyFormat, "%d.%S" );
 _LIT( KPrefsFile,"prefs.dat" );
+_LIT( KPrefsTmpFile,"prefs.dat.tmp" );
+_LIT( KPrefsBakFile, "prefs.dat.bak" );
 
 
 // ----------------------------------------------------------------------------
@@ -264,7 +266,11 @@
         CleanupStack::Pop();   // k
 
         // Save update to persistent storage
-		saveL();
+        TRAPD(err, saveL());
+        if(err!= KErrNone)
+            {
+            deleteAllPrefFiles();
+            }
     }
 
 }
@@ -306,7 +312,10 @@
         CleanupStack::PopAndDestroy();   // k
 
         // Save update to persistent storage
-		saveL();
+	TRAPD(err, saveL());
+    if(err!= KErrNone) {
+        deleteAllPrefFiles();
+        }
     }
 }
 
@@ -323,46 +332,180 @@
 
     RFs fs;
 
-    if ( fs.Connect() == KErrNone ) {
+        
+    // Connect to file server
+    User::LeaveIfError(fs.Connect());
+    CleanupClosePushL( fs );
         
-        CleanupClosePushL( fs );
-        HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
+    // Form filenames
+    HBufC* tmpFilePath = HBufC::NewLC( m_basepath->Length() + KPrefsTmpFile().Length() );
+    HBufC* bakFilePath = HBufC::NewLC( m_basepath->Length() + KPrefsBakFile().Length() );
+    HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
+
+    TPtr fName( tmpFilePath->Des() );
+    fName.Append( *m_basepath );
+    fName.Append( KPrefsTmpFile );
+    
+    fName.Set( bakFilePath->Des() );
+    fName.Append( *m_basepath );
+    fName.Append( KPrefsBakFile );
+    
+    fName.Set( filePath->Des() );
+    fName.Append( *m_basepath );
+    fName.Append( KPrefsFile );
+
+	  RFileWriteStream writeStream;
+    writeStream.PushL();
+    
+	// Try to create the temp file
+	if(writeStream.Replace(fs, *tmpFilePath, EFileWrite|EFileShareExclusive) != KErrNone) {
+		// Make sure the private path exists
+		fs.CreatePrivatePath( EDriveC );
+		
+		// Try again to create the file
+		User::LeaveIfError(writeStream.Create(fs, *tmpFilePath, EFileWrite|EFileShareExclusive));
+	}
 
-        TPtr fName( filePath->Des() );
-        fName.Append( *m_basepath );
-        fName.Append( KPrefsFile );
+    // Try to externalize the data to the stream
+    TRAPD(err, externalizeL(writeStream));
+    
+    // Close the stream
+    CleanupStack::PopAndDestroy(); // writeStream
+    	     
+    // If no error at this point then we're guaranteed to have a valid file
+    if(err!=KErrNone)
+    	{
+    	// Delete the temp file
+    	fs.Delete(*tmpFilePath);
+    	
+    	// And leave with the error code
+    	User::Leave(err);
+    	}
+    	
+    // Backup any old valid file just in case
+    fs.Delete(*bakFilePath);
+    fs.Rename(*filePath, *bakFilePath);
+    
+    // Rename the temp file to be the actual settings file
+    err = fs.Rename(*tmpFilePath, *filePath);
+    if(err!=KErrNone)
+    	{
+    	// If we had a backup settings file, try to return it
+    	fs.Rename(*bakFilePath, *filePath);
+    	User::Leave(err);
+    	}
 
-        RFileWriteStream writeStream;
-        TInt fileerror = writeStream.Replace( fs, *filePath, EFileWrite );
+	// Cleanup
+	CleanupStack::PopAndDestroy(4); // filePath, bakFilePath, tmpFilePath, fs
+
+}
 
-        if ( fileerror != KErrNone ) {
-            fs.CreatePrivatePath( EDriveC );
-            fileerror = writeStream.Create( fs, *filePath, EFileWrite|EFileShareExclusive );
-        }
+// ----------------------------------------------------------------------------
+// WidgetPreferences::externalizeL
+//
+//
+// ----------------------------------------------------------------------------
+
+void WidgetPreferences::externalizeL(RWriteStream& aStream) const
+{
+    aStream.WriteInt32L( m_preferences->Count() );
+	
+    TPtrHashMapIter<TDesC,PrefElement> it( *m_preferences );
+    const TDesC* key;
+    const PrefElement* pref;
 
-        if ( fileerror == KErrNone ) {
-            CleanupClosePushL( writeStream );
-            writeStream.WriteInt32L( m_preferences->Count() );
-            
-            TPtrHashMapIter<TDesC,PrefElement> it( *m_preferences );
-            const TDesC* key;
-            const PrefElement* pref;
+    while ( ( key = it.NextKey() ) != 0 ) {
+        pref = it.CurrentValue();
+        aStream.WriteInt32L( key->Length() );
+        aStream.WriteL( *key );
+        aStream.WriteInt32L( pref->value().Length() );
+        aStream.WriteL( pref->value() );
+        aStream.WriteInt32L( pref->valueSize() );
+    }
+    aStream.CommitL();
+    
+}
+
+// ----------------------------------------------------------------------------
+// WidgetPreferences::internalizeL
+//
+//
+// ----------------------------------------------------------------------------
+void WidgetPreferences::internalizeL(RReadStream& aStream)
+{
+    TInt count( aStream.ReadInt32L() );
+    for( TInt i = 0; i < count; i++ ) {
+        
+        TInt len = aStream.ReadInt32L();
+
+        if ( len > 0 ) {
+            HBufC* key = HBufC::NewLC( len );
+            TPtr ptrkey = key->Des();
+            aStream.ReadL( ptrkey, len );
+            len = aStream.ReadInt32L();
 
-            while ( ( key = it.NextKey() ) != 0 ) {
-                pref = it.CurrentValue();
-                writeStream.WriteInt32L( key->Length() );
-                writeStream.WriteL( *key );
-                writeStream.WriteInt32L( pref->value().Length() );
-                writeStream.WriteL( pref->value() );
-                writeStream.WriteInt32L( pref->valueSize() );
+            if ( len <= KMaxKeyValueSize ) {
+                HBufC* value = HBufC::NewLC( len );
+                TPtr ptrvalue = value->Des();
+                aStream.ReadL( ptrvalue, len );
+                PrefElement* pref = new ( ELeave ) PrefElement;
+                CleanupStack::PushL( pref );
+                pref->setValueL( ptrvalue );
+                TInt size = aStream.ReadInt32L();
+                pref->setValueSize( size );
+                m_preferences->InsertL( key, pref );
+                CleanupStack::Pop(); //pref
+                CleanupStack::PopAndDestroy(); //value
+                CleanupStack::Pop(); //key
             }
+            else {
+                CleanupStack::PopAndDestroy( key );
+             }
 
-            writeStream.CommitL();
-            CleanupStack::PopAndDestroy(); //writeStream
+         }
+
+        else {
+            break;
         }
+     }
 
-        CleanupStack::PopAndDestroy( 2 ); //fs,filePath
-    }
+ }
+
+// ----------------------------------------------------------------------------
+// WidgetPreferences::deleteAllPrefFiles
+//
+//
+// ----------------------------------------------------------------------------
+void WidgetPreferences::deleteAllPrefFiles(){
+
+   if ( !m_basepath || (m_basepath->Length() <= 0) ) 
+         return;
+
+
+   RFs fs;
+   // Deleting bkUp and main prefs file.
+   User::LeaveIfError(fs.Connect());
+   CleanupClosePushL( fs );
+   
+   HBufC* bkFilePath = HBufC::NewLC( m_basepath->Length() + KPrefsBakFile().Length() );
+
+   TPtr fName( bkFilePath->Des() );
+   fName.Append( *m_basepath );
+   fName.Append( KPrefsBakFile );
+ 
+   fs.Delete( *bkFilePath  );
+         
+   CleanupStack::PopAndDestroy(); 
+
+   HBufC* prefFilePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
+
+   TPtr fNamePr( prefFilePath->Des() );
+   fNamePr.Append( *m_basepath );
+   fNamePr.Append( KPrefsFile);
+ 
+   fs.Delete( *prefFilePath  );
+         
+   CleanupStack::PopAndDestroy(2);
 
 }
 
@@ -374,61 +517,32 @@
 // ----------------------------------------------------------------------------
 void WidgetPreferences::loadL()
 {
+   if ( !m_basepath || (m_basepath->Length() <= 0) ) 
+         return;
+    
+    // Try to connect to file server
     RFs fs;
-    if ( !m_basepath || (m_basepath->Length() <= 0) )
-        return;
-
-    if ( fs.Connect() == KErrNone ) {
-        CleanupClosePushL( fs );
-        HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
-
-        TPtr fName( filePath->Des() );
-        fName.Append( *m_basepath );
-        fName.Append( KPrefsFile );
-
-        RFileReadStream readStream;
-
-        if ( readStream.Open( fs, *filePath, EFileRead ) == KErrNone ) {
-            CleanupClosePushL( readStream );
-            TInt count( readStream.ReadInt32L() );
-
-            for( TInt i = 0; i < count; i++ ) {
-                TInt len = readStream.ReadInt32L();
-
-                if ( len > 0 ) {
-                    HBufC* key = HBufC::NewLC( len );
-                    TPtr ptrkey = key->Des();
-                    readStream.ReadL( ptrkey, len );
-                    len = readStream.ReadInt32L();
+    User::LeaveIfError(fs.Connect());
+    CleanupClosePushL( fs );
+    
+    // Form settings file name
+    HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
+    TPtr fName( filePath->Des() );
+    fName.Append( *m_basepath );
+    fName.Append( KPrefsFile );
 
-                    if ( len <= KMaxKeyValueSize ) {
-                        HBufC* value = HBufC::NewLC( len );
-                        TPtr ptrvalue = value->Des();
-                        readStream.ReadL( ptrvalue, len );
-                        PrefElement* pref = new ( ELeave ) PrefElement;
-                        CleanupStack::PushL( pref );
-                        pref->setValueL( ptrvalue );
-                        TInt size = readStream.ReadInt32L();
-                        pref->setValueSize( size );
-                        m_preferences->InsertL( key, pref );
-                        CleanupStack::Pop(); //pref 
-                        CleanupStack::PopAndDestroy(); //value
-                        CleanupStack::Pop(); //key
-                    }
-                    else {
-                        CleanupStack::PopAndDestroy( key );
-                    }
-                }
-                else {
-                    break;
-                }
-            }
+    // Open stream
+    RFileReadStream readStream;
+    readStream.PushL();
+    TInt err = readStream.Open( fs, *filePath, EFileRead );
+    if(err!=KErrNone) {
+        User::Leave(err);
+    }
+    
+    // Read the data from the stream
+    internalizeL(readStream);
 
-            CleanupStack::PopAndDestroy(); //readStream
-        }
-
-        CleanupStack::PopAndDestroy( 2 ); //fs,filePath
-    }
+    CleanupStack::PopAndDestroy(3); // readStream, filePath, fs
 }
     
 // ----------------------------------------------------------------------------
@@ -488,3 +602,4 @@
 }
 
 
+