--- a/webengine/widgetengine/src/Preferences.cpp Tue Aug 31 16:17:46 2010 +0300
+++ b/webengine/widgetengine/src/Preferences.cpp Wed Sep 01 12:28:30 2010 +0100
@@ -17,7 +17,7 @@
// INCLUDE FILES
#include <e32std.h>
-#include <s32file.h>
+#include <S32FILE.H>
#include <f32file.h>
#include <uri16.h>
#include <e32hashtab.h>
@@ -34,6 +34,8 @@
_LIT( KKeyFormat, "%d.%S" );
_LIT( KPrefsFile,"prefs.dat" );
+_LIT( KPrefsTmpFile,"prefs.dat.tmp" );
+_LIT( KPrefsBakFile, "prefs.dat.bak" );
// ----------------------------------------------------------------------------
@@ -47,7 +49,8 @@
m_basepath(0),
m_filepath(0)
{
- m_preferences = new RPtrHashMap<TDesC,PrefElement>();
+ m_preferences = new RPtrHashMap<TDesC,PrefElement>();
+ m_asynsave = new (ELeave) CAsyncCallBack(TCallBack(SavePref,this),CActive::EPriorityIdle);
}
// ----------------------------------------------------------------------------
@@ -57,8 +60,19 @@
//
// ----------------------------------------------------------------------------
WidgetPreferences::~WidgetPreferences()
-{
- //TRAP_IGNORE( saveL() );
+{
+ if(m_asynsave && m_asynsave->IsActive())
+ {
+ m_asynsave->Cancel();
+ TRAPD(err, saveL());
+ if(err!= KErrNone)
+ {
+ deleteAllPrefFiles();
+ }
+ }
+ delete m_asynsave;
+ m_asynsave = NULL;
+
if (m_preferences) {
m_preferences->ResetAndDestroy();
m_preferences->Close();
@@ -263,10 +277,10 @@
CleanupStack::Pop(); // k
- // Save update to persistent storage
- saveL();
+ // Save update to persistent storage
+ m_asynsave->Cancel();
+ m_asynsave->CallBack();
}
-
}
// ----------------------------------------------------------------------------
@@ -306,7 +320,10 @@
CleanupStack::PopAndDestroy(); // k
// Save update to persistent storage
- saveL();
+ TRAPD(err, saveL());
+ if(err!= KErrNone) {
+ deleteAllPrefFiles();
+ }
}
}
@@ -323,46 +340,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 +525,49 @@
// ----------------------------------------------------------------------------
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(3); // readStream, filePath, fs
+}
- CleanupStack::PopAndDestroy(); //readStream
+// ----------------------------------------------------------------------------
+// WidgetPreferences::SavePref
+// Save preferences for persistent storage
+//
+//
+//
+TInt WidgetPreferences::SavePref(TAny* aPtr)
+{
+ WidgetPreferences* self = (WidgetPreferences*)aPtr;
+ TRAPD(err, self->saveL());
+ if(err!= KErrNone)
+ {
+ self->deleteAllPrefFiles();
}
-
- CleanupStack::PopAndDestroy( 2 ); //fs,filePath
- }
+ return 0;
}
// ----------------------------------------------------------------------------
@@ -488,3 +627,4 @@
}
+