webengine/widgetengine/src/Preferences.cpp
changeset 0 dd21522fd290
child 13 10e98eab6f85
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class represents the Widget Preferences object
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include <e32std.h>
       
    20 #include <S32FILE.H>
       
    21 #include <f32file.h>
       
    22 #include <uri16.h>
       
    23 #include <e32hashtab.h>
       
    24 #include "Preferences.h"
       
    25 
       
    26 
       
    27 // EXTERNAL DATA STRUCTURES
       
    28 
       
    29 // EXTERNAL FUNCTION PROTOTYPES
       
    30 
       
    31 // CONSTANTS
       
    32 const TInt KMaxIntLength = 10;
       
    33 const TInt KMaxKeyValueSize = 4096; //4 k
       
    34 
       
    35 _LIT( KKeyFormat, "%d.%S" );
       
    36 _LIT( KPrefsFile,"prefs.dat" );
       
    37 
       
    38 
       
    39 // ----------------------------------------------------------------------------
       
    40 // WidgetPreferences::WidgetPreferences
       
    41 // C++ Constructor
       
    42 //
       
    43 //
       
    44 // ----------------------------------------------------------------------------
       
    45 WidgetPreferences::WidgetPreferences() :m_widgetid(0),
       
    46                                         m_widgetbundleid(0),
       
    47                                         m_basepath(0),
       
    48                                         m_filepath(0)
       
    49 {
       
    50     m_preferences = new RPtrHashMap<TDesC,PrefElement>();    
       
    51 }
       
    52 
       
    53 // ----------------------------------------------------------------------------
       
    54 // WidgetPreferences::~WidgetPreferences
       
    55 // Destructor
       
    56 //
       
    57 //
       
    58 // ----------------------------------------------------------------------------
       
    59 WidgetPreferences::~WidgetPreferences()
       
    60 {
       
    61     TRAP_IGNORE( saveL() );
       
    62     if (m_preferences) {
       
    63         m_preferences->ResetAndDestroy();
       
    64         m_preferences->Close();
       
    65         delete m_preferences;        
       
    66     }
       
    67     delete m_basepath;
       
    68     delete m_widgetbundleid;        
       
    69     delete m_filepath; 
       
    70 }
       
    71 
       
    72 // ----------------------------------------------------------------------------
       
    73 // WidgetPreferences::setBasePathL
       
    74 //
       
    75 //
       
    76 // ----------------------------------------------------------------------------
       
    77 void WidgetPreferences::setBasePathL(const TDesC& aValue)
       
    78 {
       
    79     m_basepath = aValue.AllocL();    
       
    80 }
       
    81 
       
    82 // ----------------------------------------------------------------------------
       
    83 // WidgetPreferences::setWidgetId
       
    84 //
       
    85 //
       
    86 // ----------------------------------------------------------------------------
       
    87 void WidgetPreferences::setWidgetId(TInt aValue)
       
    88 {
       
    89     m_widgetid = aValue;
       
    90 }
       
    91 
       
    92 // ----------------------------------------------------------------------------
       
    93 // WidgetPreferences::setBundleIdL
       
    94 //
       
    95 //
       
    96 // ----------------------------------------------------------------------------
       
    97 void WidgetPreferences::setWidgetBundleId(const TDesC& aValue)
       
    98 {
       
    99     m_widgetbundleid = aValue.AllocL();
       
   100 }
       
   101 
       
   102 // ----------------------------------------------------------------------------
       
   103 // WidgetPreferences::setBundleIdL
       
   104 //
       
   105 //
       
   106 // ----------------------------------------------------------------------------
       
   107 TDesC& WidgetPreferences::getWidgetBundleId()
       
   108 {
       
   109    return *m_widgetbundleid;
       
   110 }
       
   111 
       
   112 // ----------------------------------------------------------------------------
       
   113 // WidgetPreferences::PreferenceL
       
   114 // Get preference for a key
       
   115 //
       
   116 //
       
   117 // ----------------------------------------------------------------------------
       
   118 TInt WidgetPreferences::preferenceL( const TDesC& akey, TPtrC& avalue)
       
   119 {
       
   120 
       
   121     TInt rSuccess = KErrNotFound;
       
   122     TInt size = 0;
       
   123     
       
   124     if ( !m_basepath || (m_basepath->Length() <= 0) )
       
   125         return rSuccess;
       
   126 
       
   127  
       
   128     if ( akey.Length() <= KMaxKeyValueSize ) {
       
   129     
       
   130         HBufC* k = HBufC::NewLC( akey.Length() + KMaxIntLength + 1 );
       
   131         k->Des().Format( KKeyFormat, m_widgetid, &akey );
       
   132         
       
   133         PrefElement* pref = m_preferences->Find( *k );
       
   134                     
       
   135         if ( !pref ) {
       
   136             CleanupStack::PopAndDestroy( k );
       
   137             return rSuccess;
       
   138         }
       
   139             
       
   140         size = pref->valueSize();            
       
   141 
       
   142         if ( size > KMaxKeyValueSize ) {
       
   143             // return contents from temp file whose name is stored 
       
   144             // in the m_value member of m_preferences
       
   145             RFs fs;
       
   146 
       
   147             if ( fs.Connect() == KErrNone ) {
       
   148                 CleanupClosePushL( fs );
       
   149                 HBufC* filePath = HBufC::NewLC( pref->value().Length() );
       
   150                 TPtr fName( filePath->Des() );
       
   151                 fName.Append( pref->value() );
       
   152 
       
   153                 RFileReadStream readStream;
       
   154 
       
   155                 if ( readStream.Open( fs, *filePath, EFileRead ) == KErrNone ) {
       
   156                     CleanupClosePushL( readStream );
       
   157                     TInt len( readStream.ReadInt32L() );
       
   158                     if ( len > 0 ) {                                       
       
   159                         HBufC* v = HBufC::NewLC( len );
       
   160                         TPtr ptrvalue = v->Des();
       
   161                         readStream.ReadL( ptrvalue, len );    
       
   162                         avalue.Set( *v );
       
   163                         CleanupStack::Pop( v );
       
   164                         rSuccess = KErrNone;
       
   165                     }     
       
   166                     CleanupStack::PopAndDestroy();//readStream
       
   167                 }   
       
   168 
       
   169                 CleanupStack::PopAndDestroy( 2 ); //filePath,fs
       
   170             }
       
   171         }        
       
   172         else if ( size >= 0 ) {
       
   173             avalue.Set( pref->value() );
       
   174             rSuccess = KErrNone;
       
   175         }
       
   176 
       
   177         CleanupStack::PopAndDestroy( k );
       
   178     }
       
   179 
       
   180     return rSuccess;
       
   181 
       
   182 }
       
   183 
       
   184 // ----------------------------------------------------------------------------
       
   185 // WidgetPreferences::SetPreferenceL
       
   186 // set Preference for a key
       
   187 //
       
   188 //
       
   189 // ----------------------------------------------------------------------------
       
   190 void WidgetPreferences::setPreferenceL( const TDesC& akey, const TDesC& avalue)
       
   191 {
       
   192     if ( !m_basepath || (m_basepath->Length() <= 0) )
       
   193         return;
       
   194 
       
   195     if ( akey.Length() <= KMaxKeyValueSize ) {
       
   196         
       
   197         HBufC* k = HBufC::NewLC( akey.Length() + KMaxIntLength + 1 );
       
   198         k->Des().Format( KKeyFormat, m_widgetid, &akey );
       
   199 
       
   200         // if hash has the key and its value
       
   201         // delete the old value later when the new value was successfully updated
       
   202         PrefElement* prefExisting = NULL;
       
   203         prefExisting = m_preferences->Find( *k );                            
       
   204 
       
   205         if ( avalue.Length() <= KMaxKeyValueSize ) {
       
   206             PrefElement* pref = new (ELeave) PrefElement;   
       
   207             CleanupStack::PushL( pref );   
       
   208             pref->setValueL( avalue );
       
   209             pref->setValueSize( avalue.Length() );
       
   210             m_preferences->InsertL( k, pref );
       
   211             CleanupStack::Pop(); //pref   
       
   212         }
       
   213         else {
       
   214             // create a temp file and save the value in temp file. 
       
   215             // m_value member of PrefElement contains the temp file name.
       
   216             RFs fs;
       
   217             RFile file;
       
   218             if ( fs.Connect() == KErrNone ) {
       
   219                 CleanupClosePushL( fs );
       
   220 
       
   221                 // create and write to file
       
   222                 TFileName tempFileName;
       
   223                 file.Temp( fs, *m_basepath, tempFileName, EFileWrite|EFileShareExclusive );
       
   224                 CleanupClosePushL( file );
       
   225                 HBufC* filePath = HBufC::NewLC( tempFileName.Length() );
       
   226                 TPtr fName( filePath->Des() );
       
   227                 fName.Append( tempFileName );
       
   228                 RFileWriteStream writeStream( file );
       
   229                 CleanupClosePushL( writeStream );        
       
   230                 TRAPD( err, 
       
   231                     writeStream.WriteInt32L( avalue.Length() );
       
   232                     writeStream.WriteL( avalue );             
       
   233                     writeStream.CommitL(); );
       
   234                 // If an error occured while writing to the file, delete the temp file
       
   235                 // This should be the case when disk is full
       
   236                 if ( err != KErrNone )
       
   237                     {
       
   238                     CleanupStack::PopAndDestroy( ); //writeStream
       
   239                     file.Close();
       
   240                     fs.Delete( *filePath );
       
   241                     User::Leave( err );
       
   242                     }
       
   243 
       
   244                 // create new preference element
       
   245                 PrefElement* pref = new ( ELeave ) PrefElement;
       
   246                 CleanupStack::PushL( pref );  
       
   247                 pref->setValueSize( avalue.Length() );
       
   248                 pref->setValueL( *filePath );               
       
   249                 // update new preference element
       
   250                 m_preferences->InsertL( k, pref );
       
   251 
       
   252                 CleanupStack::Pop( pref );
       
   253                 CleanupStack::PopAndDestroy( ); //writeStream
       
   254                 CleanupStack::PopAndDestroy( 3 ); //filePath,file,fs
       
   255             }           
       
   256         }        
       
   257 
       
   258         // now the new value is updated, it's safe to delete the old value
       
   259         if ( prefExisting ) {
       
   260             prefExisting->setCleanFileFlag( ETrue );
       
   261             delete prefExisting;
       
   262         }
       
   263 
       
   264         CleanupStack::Pop();   // k
       
   265     }
       
   266 
       
   267 }
       
   268 
       
   269 // ----------------------------------------------------------------------------
       
   270 // WidgetPreferences::removePreferenceL
       
   271 // remove Preference for a key
       
   272 //
       
   273 //
       
   274 // ----------------------------------------------------------------------------
       
   275 void WidgetPreferences::removePreferenceL( const TDesC& akey, const TDesC& avalue)
       
   276 {
       
   277     if ( !m_basepath || (m_basepath->Length() <= 0) )
       
   278         return;
       
   279 
       
   280     // double check value is NULL
       
   281     if ( avalue != KNullDesC ) {
       
   282         return;
       
   283         }
       
   284 
       
   285     if ( akey.Length() <= KMaxKeyValueSize ) {
       
   286         
       
   287         HBufC* k = HBufC::NewLC( akey.Length() + KMaxIntLength + 1 );
       
   288         k->Des().Format( KKeyFormat, m_widgetid, &akey );
       
   289 
       
   290         // if hash has the key and its value
       
   291         // delete the old value later when the new value was successfully updated
       
   292         PrefElement* prefExisting = NULL;
       
   293         prefExisting = m_preferences->Find( *k );                            
       
   294 
       
   295         m_preferences->Remove(k);
       
   296 
       
   297         // now the new value is updated, it's safe to delete the old value
       
   298         if ( prefExisting ) {
       
   299             prefExisting->setCleanFileFlag( ETrue );
       
   300             delete prefExisting;
       
   301         }
       
   302 
       
   303         CleanupStack::PopAndDestroy();   // k
       
   304     }
       
   305 }
       
   306 
       
   307 // ----------------------------------------------------------------------------
       
   308 // WidgetPreferences::SaveL
       
   309 // SAve preferences to persistent storage
       
   310 //
       
   311 //
       
   312 // ----------------------------------------------------------------------------
       
   313 void WidgetPreferences::saveL()
       
   314 {
       
   315     if ( !m_basepath || (m_basepath->Length() <= 0) )
       
   316         return;
       
   317 
       
   318     RFs fs;
       
   319 
       
   320     if ( fs.Connect() == KErrNone ) {
       
   321         
       
   322         CleanupClosePushL( fs );
       
   323         HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
       
   324 
       
   325         TPtr fName( filePath->Des() );
       
   326         fName.Append( *m_basepath );
       
   327         fName.Append( KPrefsFile );
       
   328 
       
   329         RFileWriteStream writeStream;
       
   330         TInt fileerror = writeStream.Replace( fs, *filePath, EFileWrite );
       
   331 
       
   332         if ( fileerror != KErrNone ) {
       
   333             fs.CreatePrivatePath( EDriveC );
       
   334             fileerror = writeStream.Create( fs, *filePath, EFileWrite|EFileShareExclusive );
       
   335         }
       
   336 
       
   337         if ( fileerror == KErrNone ) {
       
   338             CleanupClosePushL( writeStream );
       
   339             writeStream.WriteInt32L( m_preferences->Count() );
       
   340             
       
   341             TPtrHashMapIter<TDesC,PrefElement> it( *m_preferences );
       
   342             const TDesC* key;
       
   343             const PrefElement* pref;
       
   344 
       
   345             while ( ( key = it.NextKey() ) != 0 ) {
       
   346                 pref = it.CurrentValue();
       
   347                 writeStream.WriteInt32L( key->Length() );
       
   348                 writeStream.WriteL( *key );
       
   349                 writeStream.WriteInt32L( pref->value().Length() );
       
   350                 writeStream.WriteL( pref->value() );
       
   351                 writeStream.WriteInt32L( pref->valueSize() );
       
   352             }
       
   353 
       
   354             writeStream.CommitL();
       
   355             CleanupStack::PopAndDestroy(); //writeStream
       
   356         }
       
   357 
       
   358         CleanupStack::PopAndDestroy( 2 ); //fs,filePath
       
   359     }
       
   360 
       
   361 }
       
   362 
       
   363 // ----------------------------------------------------------------------------
       
   364 // WidgetPreferences::LoadL
       
   365 // Load preferences from persistent storage
       
   366 //
       
   367 //
       
   368 // ----------------------------------------------------------------------------
       
   369 void WidgetPreferences::loadL()
       
   370 {
       
   371     RFs fs;
       
   372     if ( !m_basepath || (m_basepath->Length() <= 0) )
       
   373         return;
       
   374 
       
   375     if ( fs.Connect() == KErrNone ) {
       
   376         CleanupClosePushL( fs );
       
   377         HBufC* filePath = HBufC::NewLC( m_basepath->Length() + KPrefsFile().Length() );
       
   378 
       
   379         TPtr fName( filePath->Des() );
       
   380         fName.Append( *m_basepath );
       
   381         fName.Append( KPrefsFile );
       
   382 
       
   383         RFileReadStream readStream;
       
   384 
       
   385         if ( readStream.Open( fs, *filePath, EFileRead ) == KErrNone ) {
       
   386             CleanupClosePushL( readStream );
       
   387             TInt count( readStream.ReadInt32L() );
       
   388 
       
   389             for( TInt i = 0; i < count; i++ ) {
       
   390                 TInt len = readStream.ReadInt32L();
       
   391 
       
   392                 if ( len > 0 ) {
       
   393                     HBufC* key = HBufC::NewLC( len );
       
   394                     TPtr ptrkey = key->Des();
       
   395                     readStream.ReadL( ptrkey, len );
       
   396                     len = readStream.ReadInt32L();
       
   397 
       
   398                     if ( len <= KMaxKeyValueSize ) {
       
   399                         HBufC* value = HBufC::NewLC( len );
       
   400                         TPtr ptrvalue = value->Des();
       
   401                         readStream.ReadL( ptrvalue, len );
       
   402                         PrefElement* pref = new ( ELeave ) PrefElement;
       
   403                         CleanupStack::PushL( pref );
       
   404                         pref->setValueL( ptrvalue );
       
   405                         TInt size = readStream.ReadInt32L();
       
   406                         pref->setValueSize( size );
       
   407                         m_preferences->InsertL( key, pref );
       
   408                         CleanupStack::Pop(); //pref 
       
   409                         CleanupStack::PopAndDestroy(); //value
       
   410                         CleanupStack::Pop(); //key
       
   411                     }
       
   412                     else {
       
   413                         CleanupStack::PopAndDestroy( key );
       
   414                     }
       
   415                 }
       
   416                 else {
       
   417                     break;
       
   418                 }
       
   419             }
       
   420 
       
   421             CleanupStack::PopAndDestroy(); //readStream
       
   422         }
       
   423 
       
   424         CleanupStack::PopAndDestroy( 2 ); //fs,filePath
       
   425     }
       
   426 }
       
   427     
       
   428 // ----------------------------------------------------------------------------
       
   429 // PrefElement::PrefElement
       
   430 // C++ constructor
       
   431 //
       
   432 //
       
   433 // ----------------------------------------------------------------------------    
       
   434 PrefElement::PrefElement() : m_value (0), m_valuesize (0), m_cleanFileFlag (EFalse)
       
   435 {
       
   436 }
       
   437 
       
   438     
       
   439 // ----------------------------------------------------------------------------
       
   440 // PrefElement::~PrefElement
       
   441 // Destructor
       
   442 //
       
   443 //
       
   444 // ----------------------------------------------------------------------------
       
   445 PrefElement::~PrefElement()
       
   446 {
       
   447     // When we update the existing key with newer value:
       
   448     // if the value > 4k, which means a file was created to store the value;
       
   449     // we need to delete the old file.
       
   450     // If called from ~Preferences(), we shouldn't do this -- cleanFileFlag is false
       
   451     if ( m_cleanFileFlag && m_valuesize > KMaxKeyValueSize ) {
       
   452         HBufC* filePathExisting = HBufC::NewLC( value().Length() );
       
   453         TPtr fName( filePathExisting->Des() );
       
   454         fName.Append( value() );
       
   455 
       
   456         RFs fs;
       
   457         if ( fs.Connect() == KErrNone ) {
       
   458             fs.Delete(*filePathExisting);
       
   459             fs.Close();
       
   460         }              
       
   461 
       
   462         CleanupStack::PopAndDestroy(); //filePathExisting
       
   463     }
       
   464 
       
   465     delete m_value;
       
   466 }
       
   467 
       
   468 
       
   469 // ----------------------------------------------------------------------------
       
   470 // PrefElement::setValueL
       
   471 // set value for a preference
       
   472 //
       
   473 //
       
   474 // ----------------------------------------------------------------------------
       
   475 void PrefElement::setValueL( const TDesC& value )
       
   476 {
       
   477     if ( m_value ) {
       
   478         delete m_value;
       
   479     }
       
   480 
       
   481     m_value  = value.AllocL();
       
   482 }
       
   483 
       
   484