webengine/widgetengine/src/Preferences.cpp
branchRCL_3
changeset 49 919f36ff910f
parent 48 79859ed3eea9
equal deleted inserted replaced
48:79859ed3eea9 49:919f36ff910f
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 // INCLUDE FILES
    18 // INCLUDE FILES
    19 #include <e32std.h>
    19 #include <e32std.h>
    20 #include <s32file.h>
    20 #include <S32FILE.H>
    21 #include <f32file.h>
    21 #include <f32file.h>
    22 #include <uri16.h>
    22 #include <uri16.h>
    23 #include <e32hashtab.h>
    23 #include <e32hashtab.h>
    24 #include "Preferences.h"
    24 #include "Preferences.h"
    25 
    25 
    32 const TInt KMaxIntLength = 10;
    32 const TInt KMaxIntLength = 10;
    33 const TInt KMaxKeyValueSize = 4096; //4 k
    33 const TInt KMaxKeyValueSize = 4096; //4 k
    34 
    34 
    35 _LIT( KKeyFormat, "%d.%S" );
    35 _LIT( KKeyFormat, "%d.%S" );
    36 _LIT( KPrefsFile,"prefs.dat" );
    36 _LIT( KPrefsFile,"prefs.dat" );
       
    37 _LIT( KPrefsTmpFile,"prefs.dat.tmp" );
       
    38 _LIT( KPrefsBakFile, "prefs.dat.bak" );
    37 
    39 
    38 
    40 
    39 // ----------------------------------------------------------------------------
    41 // ----------------------------------------------------------------------------
    40 // WidgetPreferences::WidgetPreferences
    42 // WidgetPreferences::WidgetPreferences
    41 // C++ Constructor
    43 // C++ Constructor
    45 WidgetPreferences::WidgetPreferences() :m_widgetid(0),
    47 WidgetPreferences::WidgetPreferences() :m_widgetid(0),
    46                                         m_widgetbundleid(0),
    48                                         m_widgetbundleid(0),
    47                                         m_basepath(0),
    49                                         m_basepath(0),
    48                                         m_filepath(0)
    50                                         m_filepath(0)
    49 {
    51 {
    50     m_preferences = new RPtrHashMap<TDesC,PrefElement>();    
    52     m_preferences = new RPtrHashMap<TDesC,PrefElement>();
       
    53     m_asynsave = new (ELeave) CAsyncCallBack(TCallBack(SavePref,this),CActive::EPriorityIdle);
    51 }
    54 }
    52 
    55 
    53 // ----------------------------------------------------------------------------
    56 // ----------------------------------------------------------------------------
    54 // WidgetPreferences::~WidgetPreferences
    57 // WidgetPreferences::~WidgetPreferences
    55 // Destructor
    58 // Destructor
    56 //
    59 //
    57 //
    60 //
    58 // ----------------------------------------------------------------------------
    61 // ----------------------------------------------------------------------------
    59 WidgetPreferences::~WidgetPreferences()
    62 WidgetPreferences::~WidgetPreferences()
    60 {
    63 {       
    61     //TRAP_IGNORE( saveL() );
    64     if(m_asynsave && m_asynsave->IsActive())
       
    65         {
       
    66         m_asynsave->Cancel();
       
    67         TRAPD(err, saveL());
       
    68         if(err!= KErrNone) 
       
    69             {
       
    70             deleteAllPrefFiles();
       
    71             }      
       
    72         }    
       
    73     delete m_asynsave;
       
    74     m_asynsave = NULL;
       
    75     
    62     if (m_preferences) {
    76     if (m_preferences) {
    63         m_preferences->ResetAndDestroy();
    77         m_preferences->ResetAndDestroy();
    64         m_preferences->Close();
    78         m_preferences->Close();
    65         delete m_preferences;        
    79         delete m_preferences;        
    66     }
    80     }
   261             delete prefExisting;
   275             delete prefExisting;
   262         }
   276         }
   263 
   277 
   264         CleanupStack::Pop();   // k
   278         CleanupStack::Pop();   // k
   265 
   279 
   266         // Save update to persistent storage
   280     // Save update to persistent storage
   267 		saveL();
   281     m_asynsave->Cancel();
   268     }
   282     m_asynsave->CallBack();
   269 
   283     }
   270 }
   284 }
   271 
   285 
   272 // ----------------------------------------------------------------------------
   286 // ----------------------------------------------------------------------------
   273 // WidgetPreferences::removePreferenceL
   287 // WidgetPreferences::removePreferenceL
   274 // remove Preference for a key
   288 // remove Preference for a key
   304         }
   318         }
   305 
   319 
   306         CleanupStack::PopAndDestroy();   // k
   320         CleanupStack::PopAndDestroy();   // k
   307 
   321 
   308         // Save update to persistent storage
   322         // Save update to persistent storage
   309 		saveL();
   323 	TRAPD(err, saveL());
       
   324     if(err!= KErrNone) {
       
   325         deleteAllPrefFiles();
       
   326         }
   310     }
   327     }
   311 }
   328 }
   312 
   329 
   313 // ----------------------------------------------------------------------------
   330 // ----------------------------------------------------------------------------
   314 // WidgetPreferences::SaveL
   331 // WidgetPreferences::SaveL
   321     if ( !m_basepath || (m_basepath->Length() <= 0) )
   338     if ( !m_basepath || (m_basepath->Length() <= 0) )
   322         return;
   339         return;
   323 
   340 
   324     RFs fs;
   341     RFs fs;
   325 
   342 
   326     if ( fs.Connect() == KErrNone ) {
       
   327         
   343         
   328         CleanupClosePushL( fs );
   344     // Connect to file server
   329         HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
   345     User::LeaveIfError(fs.Connect());
   330 
   346     CleanupClosePushL( fs );
   331         TPtr fName( filePath->Des() );
   347         
   332         fName.Append( *m_basepath );
   348     // Form filenames
   333         fName.Append( KPrefsFile );
   349     HBufC* tmpFilePath = HBufC::NewLC( m_basepath->Length() + KPrefsTmpFile().Length() );
   334 
   350     HBufC* bakFilePath = HBufC::NewLC( m_basepath->Length() + KPrefsBakFile().Length() );
   335         RFileWriteStream writeStream;
   351     HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
   336         TInt fileerror = writeStream.Replace( fs, *filePath, EFileWrite );
   352 
   337 
   353     TPtr fName( tmpFilePath->Des() );
   338         if ( fileerror != KErrNone ) {
   354     fName.Append( *m_basepath );
   339             fs.CreatePrivatePath( EDriveC );
   355     fName.Append( KPrefsTmpFile );
   340             fileerror = writeStream.Create( fs, *filePath, EFileWrite|EFileShareExclusive );
   356     
   341         }
   357     fName.Set( bakFilePath->Des() );
   342 
   358     fName.Append( *m_basepath );
   343         if ( fileerror == KErrNone ) {
   359     fName.Append( KPrefsBakFile );
   344             CleanupClosePushL( writeStream );
   360     
   345             writeStream.WriteInt32L( m_preferences->Count() );
   361     fName.Set( filePath->Des() );
   346             
   362     fName.Append( *m_basepath );
   347             TPtrHashMapIter<TDesC,PrefElement> it( *m_preferences );
   363     fName.Append( KPrefsFile );
   348             const TDesC* key;
   364 
   349             const PrefElement* pref;
   365 	  RFileWriteStream writeStream;
   350 
   366     writeStream.PushL();
   351             while ( ( key = it.NextKey() ) != 0 ) {
   367     
   352                 pref = it.CurrentValue();
   368 	// Try to create the temp file
   353                 writeStream.WriteInt32L( key->Length() );
   369 	if(writeStream.Replace(fs, *tmpFilePath, EFileWrite|EFileShareExclusive) != KErrNone) {
   354                 writeStream.WriteL( *key );
   370 		// Make sure the private path exists
   355                 writeStream.WriteInt32L( pref->value().Length() );
   371 		fs.CreatePrivatePath( EDriveC );
   356                 writeStream.WriteL( pref->value() );
   372 		
   357                 writeStream.WriteInt32L( pref->valueSize() );
   373 		// Try again to create the file
       
   374 		User::LeaveIfError(writeStream.Create(fs, *tmpFilePath, EFileWrite|EFileShareExclusive));
       
   375 	}
       
   376 
       
   377     // Try to externalize the data to the stream
       
   378     TRAPD(err, externalizeL(writeStream));
       
   379     
       
   380     // Close the stream
       
   381     CleanupStack::PopAndDestroy(); // writeStream
       
   382     	     
       
   383     // If no error at this point then we're guaranteed to have a valid file
       
   384     if(err!=KErrNone)
       
   385     	{
       
   386     	// Delete the temp file
       
   387     	fs.Delete(*tmpFilePath);
       
   388     	
       
   389     	// And leave with the error code
       
   390     	User::Leave(err);
       
   391     	}
       
   392     	
       
   393     // Backup any old valid file just in case
       
   394     fs.Delete(*bakFilePath);
       
   395     fs.Rename(*filePath, *bakFilePath);
       
   396     
       
   397     // Rename the temp file to be the actual settings file
       
   398     err = fs.Rename(*tmpFilePath, *filePath);
       
   399     if(err!=KErrNone)
       
   400     	{
       
   401     	// If we had a backup settings file, try to return it
       
   402     	fs.Rename(*bakFilePath, *filePath);
       
   403     	User::Leave(err);
       
   404     	}
       
   405 
       
   406 	// Cleanup
       
   407 	CleanupStack::PopAndDestroy(4); // filePath, bakFilePath, tmpFilePath, fs
       
   408 
       
   409 }
       
   410 
       
   411 // ----------------------------------------------------------------------------
       
   412 // WidgetPreferences::externalizeL
       
   413 //
       
   414 //
       
   415 // ----------------------------------------------------------------------------
       
   416 
       
   417 void WidgetPreferences::externalizeL(RWriteStream& aStream) const
       
   418 {
       
   419     aStream.WriteInt32L( m_preferences->Count() );
       
   420 	
       
   421     TPtrHashMapIter<TDesC,PrefElement> it( *m_preferences );
       
   422     const TDesC* key;
       
   423     const PrefElement* pref;
       
   424 
       
   425     while ( ( key = it.NextKey() ) != 0 ) {
       
   426         pref = it.CurrentValue();
       
   427         aStream.WriteInt32L( key->Length() );
       
   428         aStream.WriteL( *key );
       
   429         aStream.WriteInt32L( pref->value().Length() );
       
   430         aStream.WriteL( pref->value() );
       
   431         aStream.WriteInt32L( pref->valueSize() );
       
   432     }
       
   433     aStream.CommitL();
       
   434     
       
   435 }
       
   436 
       
   437 // ----------------------------------------------------------------------------
       
   438 // WidgetPreferences::internalizeL
       
   439 //
       
   440 //
       
   441 // ----------------------------------------------------------------------------
       
   442 void WidgetPreferences::internalizeL(RReadStream& aStream)
       
   443 {
       
   444     TInt count( aStream.ReadInt32L() );
       
   445     for( TInt i = 0; i < count; i++ ) {
       
   446         
       
   447         TInt len = aStream.ReadInt32L();
       
   448 
       
   449         if ( len > 0 ) {
       
   450             HBufC* key = HBufC::NewLC( len );
       
   451             TPtr ptrkey = key->Des();
       
   452             aStream.ReadL( ptrkey, len );
       
   453             len = aStream.ReadInt32L();
       
   454 
       
   455             if ( len <= KMaxKeyValueSize ) {
       
   456                 HBufC* value = HBufC::NewLC( len );
       
   457                 TPtr ptrvalue = value->Des();
       
   458                 aStream.ReadL( ptrvalue, len );
       
   459                 PrefElement* pref = new ( ELeave ) PrefElement;
       
   460                 CleanupStack::PushL( pref );
       
   461                 pref->setValueL( ptrvalue );
       
   462                 TInt size = aStream.ReadInt32L();
       
   463                 pref->setValueSize( size );
       
   464                 m_preferences->InsertL( key, pref );
       
   465                 CleanupStack::Pop(); //pref
       
   466                 CleanupStack::PopAndDestroy(); //value
       
   467                 CleanupStack::Pop(); //key
   358             }
   468             }
   359 
   469             else {
   360             writeStream.CommitL();
   470                 CleanupStack::PopAndDestroy( key );
   361             CleanupStack::PopAndDestroy(); //writeStream
   471              }
   362         }
   472 
   363 
   473          }
   364         CleanupStack::PopAndDestroy( 2 ); //fs,filePath
   474 
   365     }
   475         else {
       
   476             break;
       
   477         }
       
   478      }
       
   479 
       
   480  }
       
   481 
       
   482 // ----------------------------------------------------------------------------
       
   483 // WidgetPreferences::deleteAllPrefFiles
       
   484 //
       
   485 //
       
   486 // ----------------------------------------------------------------------------
       
   487 void WidgetPreferences::deleteAllPrefFiles(){
       
   488 
       
   489    if ( !m_basepath || (m_basepath->Length() <= 0) ) 
       
   490          return;
       
   491 
       
   492 
       
   493    RFs fs;
       
   494    // Deleting bkUp and main prefs file.
       
   495    User::LeaveIfError(fs.Connect());
       
   496    CleanupClosePushL( fs );
       
   497    
       
   498    HBufC* bkFilePath = HBufC::NewLC( m_basepath->Length() + KPrefsBakFile().Length() );
       
   499 
       
   500    TPtr fName( bkFilePath->Des() );
       
   501    fName.Append( *m_basepath );
       
   502    fName.Append( KPrefsBakFile );
       
   503  
       
   504    fs.Delete( *bkFilePath  );
       
   505          
       
   506    CleanupStack::PopAndDestroy(); 
       
   507 
       
   508    HBufC* prefFilePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
       
   509 
       
   510    TPtr fNamePr( prefFilePath->Des() );
       
   511    fNamePr.Append( *m_basepath );
       
   512    fNamePr.Append( KPrefsFile);
       
   513  
       
   514    fs.Delete( *prefFilePath  );
       
   515          
       
   516    CleanupStack::PopAndDestroy(2);
   366 
   517 
   367 }
   518 }
   368 
   519 
   369 // ----------------------------------------------------------------------------
   520 // ----------------------------------------------------------------------------
   370 // WidgetPreferences::LoadL
   521 // WidgetPreferences::LoadL
   372 //
   523 //
   373 //
   524 //
   374 // ----------------------------------------------------------------------------
   525 // ----------------------------------------------------------------------------
   375 void WidgetPreferences::loadL()
   526 void WidgetPreferences::loadL()
   376 {
   527 {
       
   528    if ( !m_basepath || (m_basepath->Length() <= 0) ) 
       
   529          return;
       
   530     
       
   531     // Try to connect to file server
   377     RFs fs;
   532     RFs fs;
   378     if ( !m_basepath || (m_basepath->Length() <= 0) )
   533     User::LeaveIfError(fs.Connect());
   379         return;
   534     CleanupClosePushL( fs );
   380 
   535     
   381     if ( fs.Connect() == KErrNone ) {
   536     // Form settings file name
   382         CleanupClosePushL( fs );
   537     HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
   383         HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
   538     TPtr fName( filePath->Des() );
   384 
   539     fName.Append( *m_basepath );
   385         TPtr fName( filePath->Des() );
   540     fName.Append( KPrefsFile );
   386         fName.Append( *m_basepath );
   541 
   387         fName.Append( KPrefsFile );
   542     // Open stream
   388 
   543     RFileReadStream readStream;
   389         RFileReadStream readStream;
   544     readStream.PushL();
   390 
   545     TInt err = readStream.Open( fs, *filePath, EFileRead );
   391         if ( readStream.Open( fs, *filePath, EFileRead ) == KErrNone ) {
   546     if(err!=KErrNone) {
   392             CleanupClosePushL( readStream );
   547         User::Leave(err);
   393             TInt count( readStream.ReadInt32L() );
   548     }
   394 
   549     
   395             for( TInt i = 0; i < count; i++ ) {
   550     // Read the data from the stream
   396                 TInt len = readStream.ReadInt32L();
   551     internalizeL(readStream);
   397 
   552 
   398                 if ( len > 0 ) {
   553     CleanupStack::PopAndDestroy(3); // readStream, filePath, fs
   399                     HBufC* key = HBufC::NewLC( len );
   554 }
   400                     TPtr ptrkey = key->Des();
   555 
   401                     readStream.ReadL( ptrkey, len );
   556 // ----------------------------------------------------------------------------
   402                     len = readStream.ReadInt32L();
   557 // WidgetPreferences::SavePref
   403 
   558 // Save preferences for persistent storage
   404                     if ( len <= KMaxKeyValueSize ) {
   559 //
   405                         HBufC* value = HBufC::NewLC( len );
   560 //
   406                         TPtr ptrvalue = value->Des();
   561 // 
   407                         readStream.ReadL( ptrvalue, len );
   562 TInt WidgetPreferences::SavePref(TAny* aPtr)
   408                         PrefElement* pref = new ( ELeave ) PrefElement;
   563 {   
   409                         CleanupStack::PushL( pref );
   564     WidgetPreferences* self = (WidgetPreferences*)aPtr;
   410                         pref->setValueL( ptrvalue );
   565     TRAPD(err, self->saveL());
   411                         TInt size = readStream.ReadInt32L();
   566     if(err!= KErrNone)
   412                         pref->setValueSize( size );
   567         {
   413                         m_preferences->InsertL( key, pref );
   568         self->deleteAllPrefFiles();
   414                         CleanupStack::Pop(); //pref 
   569         }
   415                         CleanupStack::PopAndDestroy(); //value
   570     return 0;
   416                         CleanupStack::Pop(); //key
       
   417                     }
       
   418                     else {
       
   419                         CleanupStack::PopAndDestroy( key );
       
   420                     }
       
   421                 }
       
   422                 else {
       
   423                     break;
       
   424                 }
       
   425             }
       
   426 
       
   427             CleanupStack::PopAndDestroy(); //readStream
       
   428         }
       
   429 
       
   430         CleanupStack::PopAndDestroy( 2 ); //fs,filePath
       
   431     }
       
   432 }
   571 }
   433     
   572     
   434 // ----------------------------------------------------------------------------
   573 // ----------------------------------------------------------------------------
   435 // PrefElement::PrefElement
   574 // PrefElement::PrefElement
   436 // C++ constructor
   575 // C++ constructor
   486 
   625 
   487     m_value  = value.AllocL();
   626     m_value  = value.AllocL();
   488 }
   627 }
   489 
   628 
   490 
   629 
       
   630