diff -r 0ed94ceaa377 -r cb62a4f66ebe webengine/widgetengine/src/Preferences.cpp --- 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 it( *m_preferences ); + const TDesC* key; + const PrefElement* pref; - if ( fileerror == KErrNone ) { - CleanupClosePushL( writeStream ); - writeStream.WriteInt32L( m_preferences->Count() ); - - TPtrHashMapIter 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 @@ } +