PECengine/StorageManager2/ClientSrc/CPEngStorageManager.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2002 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 "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:  Implementation of class CPEngStorageManager
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32base.h>
       
    21 #include <s32mem.h>
       
    22 #include "CPEngStorageManager.h"
       
    23 #include "CPEngStoreEntry.h"
       
    24 #include "PEngHashTool.h"
       
    25 #include "PEngStorageGlobals.h"
       
    26 #include "PEngStorageServerCommon.h"
       
    27 #include "MPEngStorageManagerWatcher.h"
       
    28 #include "CPEngSessionSlotId.h"
       
    29 
       
    30 #include "PEngMessagePacker.h"
       
    31 
       
    32 //  Debug prints
       
    33 #include    "PresenceDebugPrint.h"
       
    34 
       
    35 // ============================ MEMBER FUNCTIONS ===============================
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // CPEngStorageManager::CPEngStoreEntry
       
    39 // C++ default constructor can NOT contain any code, that might leave.
       
    40 // -----------------------------------------------------------------------------
       
    41 //
       
    42 CPEngStorageManager::CPEngStorageManager(
       
    43     MPEngStorageManagerWatcher& aWatcher )
       
    44         :   iAccessCount( 1 ), // init count to 1
       
    45         iStorageManagerWatcher( aWatcher ),
       
    46         iSessionSlot( aWatcher.SessionSlotId() )
       
    47     {
       
    48     // Increase handler count
       
    49     iStorageManagerWatcher.Open();      // CSI: 65 #
       
    50     }
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // CPEngStorageManager::BaseConstructL
       
    54 // Symbian 2nd phase Base constructor can leave.
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 void CPEngStorageManager::ConstructL(
       
    58     RPEngStorageClient& aStorageMainClient )
       
    59     {
       
    60     // connect to the Server with the Sub Session
       
    61     HBufC8* sessionName = iSessionSlot.PackLC();
       
    62     User::LeaveIfError( iSubFolderClient.Connect( aStorageMainClient, *sessionName ) );
       
    63     CleanupStack::PopAndDestroy(); // sessionName
       
    64     }
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CPEngStorageManager::NewL
       
    68 // Two-phased constructor.
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 CPEngStorageManager* CPEngStorageManager::NewL(
       
    72     MPEngStorageManagerWatcher& aWatcher,
       
    73     RPEngStorageClient& aStorageMainClient )
       
    74     {
       
    75     CPEngStorageManager* self = CPEngStorageManager::NewLC( aWatcher, aStorageMainClient );
       
    76 
       
    77     CleanupStack::Pop( ); // self
       
    78     return self;
       
    79     }
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // CPEngStorageManager::NewL
       
    83 // Two-phased constructor.
       
    84 // -----------------------------------------------------------------------------
       
    85 //
       
    86 CPEngStorageManager* CPEngStorageManager::NewLC(
       
    87     MPEngStorageManagerWatcher& aWatcher,
       
    88     RPEngStorageClient& aStorageMainClient )
       
    89     {
       
    90     CPEngStorageManager* self =
       
    91         new ( ELeave ) CPEngStorageManager( aWatcher );
       
    92 
       
    93     CleanupClosePushL( *self );
       
    94     self->ConstructL( aStorageMainClient );
       
    95 
       
    96     return self;
       
    97     }
       
    98 
       
    99 // Destructor
       
   100 CPEngStorageManager::~CPEngStorageManager()
       
   101     {
       
   102     // Use same Panic as CObject is using for Reference counted objects
       
   103     __ASSERT_ALWAYS( iAccessCount == 0,
       
   104                      User::Panic( KPEngSMEuserCBasePanic,
       
   105                                   KPEngSMEuserCBasePanicReason ) );
       
   106 
       
   107     iSubFolderClient.Close();
       
   108     // close handle to watcher
       
   109     iStorageManagerWatcher.Close();
       
   110     }
       
   111 
       
   112 
       
   113 // -----------------------------------------------------------------------------
       
   114 // ==== Functions from the MPEngStorageManager base classes ====================
       
   115 // -----------------------------------------------------------------------------
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CPEngStorageManager::Open()
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 void CPEngStorageManager::Open()
       
   122     {
       
   123     iAccessCount++;
       
   124     }
       
   125 
       
   126 
       
   127 // -----------------------------------------------------------------------------
       
   128 // CPEngStorageManager::Close()
       
   129 // -----------------------------------------------------------------------------
       
   130 //
       
   131 void CPEngStorageManager::Close()
       
   132     {
       
   133     iAccessCount--;
       
   134     if ( iAccessCount == 0 )
       
   135         {
       
   136         delete this;
       
   137         }
       
   138     }
       
   139 
       
   140 
       
   141 // -----------------------------------------------------------------------------
       
   142 // CPEngStorageManager::StoreL()
       
   143 // -----------------------------------------------------------------------------
       
   144 //
       
   145 void CPEngStorageManager::StoreL( const CPEngStoreEntry& aStoreEntry )
       
   146     {
       
   147     PENG_DP( D_PENG_LIT( "CPEngStorageManager::StoreL() [%S][%d]" ),
       
   148              &aStoreEntry.StorageId(), aStoreEntry.StorageType() );
       
   149 
       
   150     // Etrue to obey lock of the store entry
       
   151     StoreEntryL( aStoreEntry, ETrue );
       
   152     }
       
   153 
       
   154 
       
   155 // -----------------------------------------------------------------------------
       
   156 // CPEngStorageManager::StoreExclusiveL()
       
   157 // -----------------------------------------------------------------------------
       
   158 //
       
   159 void CPEngStorageManager::StoreExclusiveL( const CPEngStoreEntry& aStoreEntry )
       
   160     {
       
   161     PENG_DP( D_PENG_LIT( "CPEngStorageManager::StoreExclusiveL() [%S][%d]" ),
       
   162              &aStoreEntry.StorageId(), aStoreEntry.StorageType() );
       
   163 
       
   164 
       
   165     // EFalse to obey lock of the store entry
       
   166     StoreEntryL( aStoreEntry, EFalse );
       
   167     }
       
   168 
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // CPEngStorageManager::RetrieveL()
       
   172 // -----------------------------------------------------------------------------
       
   173 //
       
   174 TInt CPEngStorageManager::RetrieveL( CPEngStoreEntry& aStoreEntry,
       
   175                                      TBool aObeyVersion /* ETrue */ )
       
   176     {
       
   177     PENG_DP( D_PENG_LIT( "CPEngStorageManager::RetrieveL() [%S][%d]" ),
       
   178              &aStoreEntry.StorageId(), aStoreEntry.StorageType() );
       
   179 
       
   180     // Get Entry size for all parts
       
   181     TPEngStorageType entryType ( aStoreEntry.StorageType() );
       
   182     // Initialize size with some room for version numbers
       
   183     TUint32 entrySize( KStoreVersionSize + aStoreEntry.EntrySize() );
       
   184     if ( entrySize <= 0 )
       
   185         {
       
   186         entrySize = KStoreEntryDefaultSize;
       
   187         }
       
   188     // do not believe and correct entry size
       
   189     entrySize += entrySize / KStoreEntryRetrieveOverlap;
       
   190 
       
   191     // create buffer with estimated size
       
   192     HBufC8* buffer = HBufC8::NewLC( entrySize );
       
   193     TPtr8 ptr = buffer->Des();
       
   194 
       
   195     // get Buffer from Server, positive response is size of needed buffer, it it's too small
       
   196     TInt err( 1 ); // to make at least one round in following loop
       
   197     while ( err > KErrNone )
       
   198         {
       
   199         err = iSubFolderClient.Retrieve( aStoreEntry.StorageId(),
       
   200                                          aStoreEntry.StorageType(),
       
   201                                          ptr );
       
   202 
       
   203         // check if we need to realloc buffer
       
   204         if ( err > KErrNone )
       
   205             {
       
   206             // realloc buffer and once more, be careful with Clean up stack
       
   207             CleanupStack::PopAndDestroy(); // buffer
       
   208             buffer = HBufC8::NewLC( err );
       
   209             ptr.Set( buffer->Des() );
       
   210             }
       
   211         }
       
   212 
       
   213     if ( err == KErrNotFound )
       
   214         {
       
   215         CleanupStack::PopAndDestroy(  ); // buffer
       
   216         // set store Version back to the Zero,so following store wont fail
       
   217         aStoreEntry.iEntryVersion = KErrNone;
       
   218         return KErrNotFound;
       
   219         }
       
   220 
       
   221     User::LeaveIfError( err );
       
   222 
       
   223     RDesReadStream drs( buffer->Des() );
       
   224     CleanupClosePushL( drs );
       
   225 
       
   226     // store version of the entry
       
   227     TInt32 retrievedVersion = drs.ReadInt32L();
       
   228 
       
   229     // check if internalizing is even necessary
       
   230     if ( aObeyVersion && ( retrievedVersion == aStoreEntry.iEntryVersion ) )
       
   231         {
       
   232         CleanupStack::PopAndDestroy( 2 );//buffer, drs
       
   233         return KErrNone;
       
   234         }
       
   235 
       
   236     entrySize = ptr.Size();
       
   237 
       
   238     // Internalize all parts of the store entry
       
   239     TPEngStorageType currentType( EPEngStorageBasicFirst );
       
   240     while ( !( currentType & EPEngStorageBasicLast ) )
       
   241         {
       
   242         if ( entryType & currentType )
       
   243             {
       
   244             TInt strmPartType = drs.ReadInt32L();
       
   245             TInt strmPartLength = drs.ReadInt32L();
       
   246 
       
   247             if ( currentType != strmPartType )
       
   248                 {
       
   249                 PENG_DP( D_PENG_LIT( "CPEngStorageManager::RetrieveL() [%S][%d] - type order mismatch: strmPartType %d currentType %d" ),
       
   250                          &aStoreEntry.StorageId(), aStoreEntry.StorageType(), strmPartType, currentType );
       
   251                 User::Panic( KPEngSMPanic, EPEngSM_TypeOrderMismatch );
       
   252                 }
       
   253 
       
   254             if ( strmPartLength != KErrNotFound )
       
   255                 {
       
   256                 MStreamBuf* rawStream = drs.Source();
       
   257                 TStreamPos readStartPos = rawStream->TellL( MStreamBuf::ERead );
       
   258 
       
   259                 aStoreEntry.InternalizeL( drs, currentType );
       
   260 
       
   261                 TStreamPos readEndPos = rawStream->TellL( MStreamBuf::ERead );
       
   262                 TInt readLength = readEndPos - readStartPos;
       
   263 
       
   264                 // panic client if did not internalize properly
       
   265                 if ( readLength != strmPartLength )
       
   266                     {
       
   267                     PENG_DP( D_PENG_LIT( "CPEngStorageManager::RetrieveL() [%S][%d] - internalize length mismatch: readLength %d strmPartLength %d" ),
       
   268                              &aStoreEntry.StorageId(), aStoreEntry.StorageType(), strmPartType, currentType );
       
   269 
       
   270                     User::Panic( KPEngSMPanic, EPEngSM_InternalizeLengthMismatch );
       
   271                     }
       
   272                 }
       
   273             }
       
   274 
       
   275         currentType = static_cast<TPEngStorageType>( currentType << 1 ); // rotate once to left
       
   276         }
       
   277 
       
   278     // update version after successful internalize
       
   279     aStoreEntry.iEntryVersion = retrievedVersion;
       
   280     aStoreEntry.iSize = entrySize;
       
   281     CleanupStack::PopAndDestroy( 2 );//buffer, drs
       
   282     return KErrNone;
       
   283     }
       
   284 
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CPEngStorageManager::Delete()
       
   288 // -----------------------------------------------------------------------------
       
   289 //
       
   290 TInt CPEngStorageManager::Delete(
       
   291     const CPEngStoreEntry& aStoreEntry )
       
   292     {
       
   293     PENG_DP( D_PENG_LIT( "CPEngStorageManager::Delete() [%S][%d] - By entry " ),
       
   294              &aStoreEntry.StorageId(), aStoreEntry.StorageType() );
       
   295 
       
   296     return iSubFolderClient.Delete( aStoreEntry.StorageId(), aStoreEntry.StorageType() );
       
   297     }
       
   298 
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // CPEngStorageManager::Delete()
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 TInt CPEngStorageManager::Delete( const TDesC& aStoreEntryId )
       
   305     {
       
   306     PENG_DP( D_PENG_LIT( "CPEngStorageManager::Delete() [%S] - By entry id" ), &aStoreEntryId );
       
   307     // set as type everything
       
   308     return iSubFolderClient.Delete( aStoreEntryId , EPEngMixedPermanentCached );
       
   309     }
       
   310 
       
   311 
       
   312 // -----------------------------------------------------------------------------
       
   313 // CPEngStorageManager::LockedL()
       
   314 // -----------------------------------------------------------------------------
       
   315 //
       
   316 TBool CPEngStorageManager::LockedL(
       
   317     const CPEngStoreEntry& aStoreEntry,
       
   318     TPengStorageLockPriority aPriority /*EStorageLockLevelBasic*/ ) const
       
   319     {
       
   320     PENG_DP( D_PENG_LIT( "CPEngStorageManager::LockedL() [%S][%d] - Priority %d" ),
       
   321              &aStoreEntry.StorageId(), aStoreEntry.StorageType(), aPriority );
       
   322 
       
   323     TInt ret( iSubFolderClient.StoreEntryLocked( aStoreEntry.StorageId(),
       
   324                                                  aStoreEntry.StorageType(),
       
   325                                                  aPriority ) );
       
   326     User::LeaveIfError( ret );
       
   327     return ( ret == 0 ? EFalse : ETrue );
       
   328     }
       
   329 
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 // CPEngStorageManager::LockedL()
       
   333 // -----------------------------------------------------------------------------
       
   334 //
       
   335 TBool CPEngStorageManager::Locked(
       
   336     const CPEngStoreEntry& aStoreEntry,
       
   337     TPengStorageLockPriority aPriority /*EStorageLockLevelBasic*/ ) const
       
   338     {
       
   339     PENG_DP( D_PENG_LIT( "CPEngStorageManager::Locked() [%S][%d] - Priority %d" ),
       
   340              &aStoreEntry.StorageId(), aStoreEntry.StorageType(), aPriority );
       
   341 
       
   342     TInt ret( iSubFolderClient.StoreEntryLocked( aStoreEntry.StorageId(),
       
   343                                                  aStoreEntry.StorageType(),
       
   344                                                  aPriority ) );
       
   345     return ( ret <= 0 ? EFalse : ETrue );
       
   346     }
       
   347 
       
   348 
       
   349 // -----------------------------------------------------------------------------
       
   350 // CPEngStorageManager::Lock()
       
   351 // -----------------------------------------------------------------------------
       
   352 //
       
   353 TInt CPEngStorageManager::Lock(
       
   354     const CPEngStoreEntry& aStoreEntry,
       
   355     TPengStorageLockPriority aPriority /*EStorageLockLevelBasic*/,
       
   356     TBool aCreateEntry /* = ETrue */ ) const
       
   357     {
       
   358     PENG_DP( D_PENG_LIT( "CPEngStorageManager::Locked() [%S][%d] - Priority %d" ),
       
   359              &aStoreEntry.StorageId(), aStoreEntry.StorageType(), aPriority );
       
   360 
       
   361     return iSubFolderClient.LockStoreEntry( aStoreEntry.StorageId(),
       
   362                                             aStoreEntry.StorageType(),
       
   363                                             aPriority,
       
   364                                             aCreateEntry );
       
   365     }
       
   366 
       
   367 // -----------------------------------------------------------------------------
       
   368 // CPEngStorageManager::Unlock()
       
   369 // -----------------------------------------------------------------------------
       
   370 //
       
   371 TInt CPEngStorageManager::Unlock( const CPEngStoreEntry& aStoreEntry ) const
       
   372     {
       
   373     PENG_DP( D_PENG_LIT( "CPEngStorageManager::Unlock() store id: %S, StoreTypeL %d " ),
       
   374              &aStoreEntry.StorageId(), aStoreEntry.StorageType() );
       
   375     return iSubFolderClient.UnlockStoreEntry( aStoreEntry.StorageId(), aStoreEntry.StorageType() );
       
   376     }
       
   377 
       
   378 
       
   379 // -----------------------------------------------------------------------------
       
   380 // CPEngStorageManager::NotifyChangedSId()
       
   381 // -----------------------------------------------------------------------------
       
   382 //
       
   383 TInt CPEngStorageManager::NotifyChangedSId( const TDesC& aChangedSId,
       
   384                                             TPEngStorageType aSidStorageType )
       
   385     {
       
   386     return iSubFolderClient.NotifyChangedSIdBlind( aChangedSId, aSidStorageType );
       
   387     }
       
   388 
       
   389 
       
   390 // -----------------------------------------------------------------------------
       
   391 // CPEngStorageManager::BufferServerSideNotifications()
       
   392 // -----------------------------------------------------------------------------
       
   393 //
       
   394 TInt CPEngStorageManager::BufferServerSideNotifications( TInt aCount )
       
   395     {
       
   396     PENG_DP( D_PENG_LIT( "CPEngStorageManager::BufferServerSideNotifications() - Count %d" ),
       
   397              aCount );
       
   398     return iSubFolderClient.BufferServerSideNotifications( aCount );
       
   399     }
       
   400 
       
   401 
       
   402 // -----------------------------------------------------------------------------
       
   403 // CPEngStorageManager::ReleaseServerSideBuffering()
       
   404 // -----------------------------------------------------------------------------
       
   405 //
       
   406 TInt CPEngStorageManager::ReleaseServerSideBuffering( TInt aCount )
       
   407     {
       
   408     PENG_DP( D_PENG_LIT( "CPEngStorageManager::ReleaseServerSideBuffering() - count %d" ),
       
   409              aCount );
       
   410     return iSubFolderClient.ReleaseServerSideBuffering( aCount );
       
   411     }
       
   412 
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CPEngStorageManager::StorageManagerWatcher()
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 MPEngStorageManagerWatcher& CPEngStorageManager::StorageManagerWatcher()
       
   419     {
       
   420     return iStorageManagerWatcher;
       
   421     }
       
   422 
       
   423 
       
   424 // -----------------------------------------------------------------------------
       
   425 // CPEngStorageManager::SessionSlotId()
       
   426 // -----------------------------------------------------------------------------
       
   427 //
       
   428 const CPEngSessionSlotId& CPEngStorageManager::SessionSlotId() const
       
   429     {
       
   430     return iSessionSlot;
       
   431     }
       
   432 
       
   433 
       
   434 // =============================================================================
       
   435 // =============== New private Functions of the class ==========================
       
   436 // =============================================================================
       
   437 
       
   438 // -----------------------------------------------------------------------------
       
   439 // CPEngStorageManager::BaseStoragePath
       
   440 // Stores Store Entry given as an argument.
       
   441 // Based on the passed parameter is obeyed lock or not.
       
   442 // (other items were commented in a header).
       
   443 // -----------------------------------------------------------------------------
       
   444 //
       
   445 void CPEngStorageManager::StoreEntryL( const CPEngStoreEntry& aStoreEntry,
       
   446                                        TBool aObeyLock )
       
   447     {
       
   448     // count how much space wee need for storing
       
   449     TUint32 entrySize( KStoreVersionSize + aStoreEntry.EntrySize() );
       
   450     // do not believe and correct entry size
       
   451     entrySize += entrySize / KStoreEntrySizeTolerance;
       
   452 
       
   453     // get buffer for transfer
       
   454     CBufFlat* buf = CBufFlat::NewL( entrySize );
       
   455     CleanupStack::PushL( buf );
       
   456     RBufWriteStream ws;
       
   457     CleanupClosePushL( ws );
       
   458     ws.Open( *buf );                                // CSI: 65 #
       
   459 
       
   460     // get all parts of the store entry, and Externalize them
       
   461     TPEngStorageType entryType ( aStoreEntry.StorageType() );
       
   462     TPEngStorageType currentType( EPEngStorageBasicFirst );
       
   463 
       
   464     // Write current version of the entry, increased by one, for server info
       
   465     ws.WriteInt32L( aStoreEntry.iEntryVersion + 1 );
       
   466 
       
   467     // Write actual data
       
   468     while ( !( currentType & EPEngStorageBasicLast ) )
       
   469         {
       
   470         if ( entryType & currentType )
       
   471             {
       
   472 
       
   473             //Write first type and type length "holder"
       
   474             ws.WriteInt32L( currentType );
       
   475             ws.WriteInt32L( KErrNotFound );
       
   476 
       
   477             MStreamBuf* rawStream = ws.Sink();
       
   478 
       
   479             //Do the write and cache locally the write start and points
       
   480             TStreamPos typeStartPos = rawStream->TellL( MStreamBuf::EWrite );
       
   481             aStoreEntry.ExternalizeL( ws, currentType );
       
   482             TStreamPos typeEndPos = rawStream->TellL( MStreamBuf::EWrite );
       
   483 
       
   484             //Caculate write length
       
   485             TInt typeLength = typeEndPos - typeStartPos;
       
   486 
       
   487             //Patch the length holder
       
   488             //-4 below: Length holder is TInt32 (4 bytes) just before the actual data
       
   489             typeStartPos -= 4;
       
   490             rawStream->SeekL( MStreamBuf::EWrite, typeStartPos );
       
   491             ws.WriteInt32L( typeLength );
       
   492             rawStream->SeekL( MStreamBuf::EWrite, typeEndPos );
       
   493             }
       
   494 
       
   495         // rotate once to left
       
   496         currentType = static_cast<TPEngStorageType>( currentType << 1 );
       
   497         }
       
   498 
       
   499     buf->Compress();
       
   500     entrySize = buf->Size();
       
   501     // update store type, depends if lock shall be obeyed
       
   502     entryType = static_cast<TPEngStorageType>
       
   503                 ( aObeyLock ?  entryType : ( entryType | EPEngStorageLockIgnored ) );
       
   504 
       
   505     // store data to the server
       
   506     User::LeaveIfError( iSubFolderClient.Store( aStoreEntry.StorageId(),
       
   507                                                 entryType , buf->Ptr( 0 ) ) );
       
   508 
       
   509     // update version after successful update by 1
       
   510     ( const_cast<CPEngStoreEntry&> ( aStoreEntry ) ).iEntryVersion =
       
   511         aStoreEntry.iEntryVersion  % KMaxTInt + 1;
       
   512 
       
   513     ( const_cast<CPEngStoreEntry&> ( aStoreEntry ) ).iSize = entrySize;
       
   514 
       
   515     CleanupStack::PopAndDestroy( 2 );// ws & buffer
       
   516     }
       
   517 
       
   518 //  End of File
       
   519