omads/omadsextensions/adapters/mms/src/mmsdatastore.cpp
changeset 19 2691f6aa1921
parent 4 e6e896426eac
child 20 e1de7d03f843
equal deleted inserted replaced
4:e6e896426eac 19:2691f6aa1921
     1 /*
       
     2 * Copyright (c) 2005-2009 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:  Part of SyncML Data Synchronization Plug In Adapter
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>      
       
    20 #include <msvstd.h>       
       
    21 #include <msvapi.h>       
       
    22 #include <msvids.h>
       
    23 #include <mtclreg.h> 
       
    24 #include <mmsconst.h>
       
    25 #include <centralrepository.h>
       
    26 #include <mmscodecclient.h>
       
    27 #include <sysutil.h>
       
    28 #include <MmsEngineInternalCRKeys.h>
       
    29 
       
    30 #include "mmsdatastore.h"
       
    31 #include "omadsfolderobject.h"
       
    32 #include "mmsadaptermsvapi.h"
       
    33 #include "mmsdataproviderdefs.h"
       
    34 #include "logger.h"
       
    35 
       
    36 _LIT8( KMmsMimeType, "application/vnd.wap.mms-message" );
       
    37 _LIT8( KMmsMimeVersion, "1.2" );
       
    38 _LIT8( KFolderMimeType, "application/vnd.omads-folder+xml" );
       
    39 _LIT8( KFolderMimeVersion, "1.2" );
       
    40 
       
    41 const TInt KDataBufferSize = 1024;
       
    42 const TUint KMMS_Flag_Read = 0x01;
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CMmsDataStore::CMmsDataStore
       
    46 // C++ default constructor can NOT contain any code, that might leave.
       
    47 // -----------------------------------------------------------------------------
       
    48 CMmsDataStore::CMmsDataStore():
       
    49     iHasHistory(EFalse),
       
    50     iDataBaseOpened(EFalse),
       
    51     iKey(TKeyArrayFix(_FOFF(TSnapshotItem, ItemId()), ECmpTInt))
       
    52     { 
       
    53     }
       
    54   
       
    55 // -----------------------------------------------------------------------------
       
    56 // CMmsDataStore::ConstructL
       
    57 // Symbian 2nd phase constructor, can leave.
       
    58 // -----------------------------------------------------------------------------
       
    59 void CMmsDataStore::ConstructL(CMsvSession &aMsvSession)
       
    60     {
       
    61     LOGGER_ENTERFN("CMmsDataStore::ConstructL");
       
    62     
       
    63     iMsvSession = &aMsvSession;
       
    64     
       
    65     // Waiter object to be used with CodecClient
       
    66     iMsvWait = CMsvOperationActiveSchedulerWait::NewLC();
       
    67     CleanupStack::Pop( iMsvWait );
       
    68     iCodecClient = CMmsCodecClient::NewL( *iMsvSession );
       
    69     iMsvApi = CMmsAdapterMsvApi::NewL( *iMsvSession );
       
    70     
       
    71     // Item UID sets, used to transfer change info
       
    72     iNewItems = new (ELeave) CNSmlDataItemUidSet;
       
    73     iDeletedItems = new (ELeave) CNSmlDataItemUidSet;
       
    74     iUpdatedItems = new (ELeave) CNSmlDataItemUidSet;
       
    75     iMovedItems = new (ELeave) CNSmlDataItemUidSet;
       
    76     iSoftDeletedItems = new (ELeave) CNSmlDataItemUidSet;
       
    77     
       
    78     iFolderObjectParser = COMADSFolderObject::NewL();
       
    79     
       
    80     LOGGER_LEAVEFN("CMmsDataStore::ConstructL");
       
    81     }
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CMmsDataStore::NewL
       
    85 // Two-phased constructor.
       
    86 // -----------------------------------------------------------------------------
       
    87 CMmsDataStore* CMmsDataStore::NewL( CMsvSession &aMsvSession)
       
    88     {
       
    89     CMmsDataStore* self = new (ELeave) CMmsDataStore;
       
    90     
       
    91     CleanupStack::PushL( self );
       
    92     self->ConstructL( aMsvSession );
       
    93     CleanupStack::Pop( self );
       
    94 
       
    95     return self;    
       
    96     }
       
    97 
       
    98     
       
    99 // -----------------------------------------------------------------------------
       
   100 // CMmsDataStore::~CMmsDataStore
       
   101 // Destructor
       
   102 // -----------------------------------------------------------------------------
       
   103 CMmsDataStore::~CMmsDataStore()
       
   104     {
       
   105     LOGGER_ENTERFN("CMmsDataStore::~CMmsDataStore()");
       
   106     
       
   107     delete iDataBuffer;
       
   108     
       
   109     delete iChangeFinder;
       
   110     delete iFolderObjectParser;
       
   111     
       
   112     delete iNewItems;
       
   113     delete iDeletedItems;
       
   114     delete iUpdatedItems;
       
   115     delete iMovedItems;
       
   116     delete iSoftDeletedItems;
       
   117  
       
   118     delete iMsvApi;
       
   119     delete iCodecClient;
       
   120     delete iMsvWait;
       
   121             
       
   122     LOGGER_LEAVEFN("CMmsDataStore::~CMmsDataStore()");
       
   123     }
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 // CMmsDataStore::DoOpenL
       
   127 // Opens database. This operation is performed SYNCHRONOUSLY
       
   128 // -----------------------------------------------------------------------------
       
   129 void CMmsDataStore::DoOpenL( const TDesC& /*aStoreName*/,
       
   130     MSmlSyncRelationship& aContext, TRequestStatus& aStatus )
       
   131     {
       
   132     LOGGER_ENTERFN("CMmsDataStore::DoOpenL");
       
   133     
       
   134     iCallerStatus = &aStatus;
       
   135     *iCallerStatus = KRequestPending;
       
   136     
       
   137     if ( iDataBaseOpened )
       
   138         {
       
   139         User::RequestComplete( iCallerStatus, KErrInUse );
       
   140         LOGGER_WRITE("CMmsDataStore::DoOpenL failed with KErrInUse.");
       
   141         return;
       
   142         }
       
   143     
       
   144     *iContext = aContext;
       
   145 
       
   146     // Create ChangeFinder object
       
   147     if ( iChangeFinder )
       
   148         {
       
   149         delete iChangeFinder;
       
   150         iChangeFinder = NULL;
       
   151         }
       
   152     iChangeFinder = CChangeFinder::NewL( aContext, iKey, iHasHistory, KMmsDataProviderImplUid );
       
   153     
       
   154     // Set current snapshot, this will be compared against the old one   
       
   155     RegisterSnapshotL();
       
   156     
       
   157     iDataBaseOpened = ETrue;
       
   158     iCurrentState = EMmsOpenAndWaiting;
       
   159     User::RequestComplete( iCallerStatus, KErrNone );   
       
   160     
       
   161     LOGGER_LEAVEFN("CMmsDataStore::DoOpenL");
       
   162     }
       
   163 
       
   164 // -----------------------------------------------------------------------------
       
   165 // CMmsDataStore::DoCancelRequest
       
   166 // Not supported, does nothing.
       
   167 // -----------------------------------------------------------------------------
       
   168 void CMmsDataStore::DoCancelRequest()
       
   169     {
       
   170     LOGGER_ENTERFN("CMmsDataStore::DoCancelRequestL");
       
   171     LOGGER_LEAVEFN("CMmsDataStore::DoCancelRequestL");
       
   172     }
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // CMmsDataStore::DoStoreName
       
   176 // Returns the name of the DataStore
       
   177 // -----------------------------------------------------------------------------
       
   178 const TDesC& CMmsDataStore::DoStoreName() const
       
   179     {
       
   180     LOGGER_ENTERFN("CMmsDataStore::DoStoreName");
       
   181     
       
   182     if ( iDataBaseOpened )
       
   183         {
       
   184         LOGGER_LEAVEFN( "CMmsDataStore::DoStoreName" );
       
   185         LOGGER_MSG_EC( "Database name: %S", &KNSmlDefaultLocalDbName );
       
   186         return KNSmlDefaultLocalDbName;
       
   187         }
       
   188 
       
   189     LOGGER_LEAVEFN( "CMmsDataStore::DoStoreName" );
       
   190     return KNullDesC;
       
   191     }
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CMmsDataStore::DoBeginTransactionL
       
   195 // Transactions are not supported.
       
   196 // -----------------------------------------------------------------------------
       
   197 void CMmsDataStore::DoBeginTransactionL()
       
   198     {
       
   199     LOGGER_ENTERFN("CMmsDataStore::DoBeginTransactionL");
       
   200     LOGGER_WRITE( "CMmsDataStore::DoBeginTransactionL leaved with KErrNotSupported." );
       
   201     User::Leave( KErrNotSupported );
       
   202     }
       
   203 
       
   204 // -----------------------------------------------------------------------------
       
   205 // CMmsDataStore::DoCommitTransactionL
       
   206 // Transactions are not supported.
       
   207 // -----------------------------------------------------------------------------
       
   208 void CMmsDataStore::DoCommitTransactionL( TRequestStatus& aStatus )
       
   209     {
       
   210     LOGGER_ENTERFN( "CMmsDataStore::DoCommitTransactionL" ); 
       
   211     LOGGER_WRITE( "CMmsDataStore::DoCommitTransactionL failed with KErrNotSupported." );
       
   212     
       
   213     iCallerStatus = &aStatus;
       
   214     User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   215     }
       
   216 
       
   217 // -----------------------------------------------------------------------------
       
   218 // CMmsDataStore::DoRevertTransaction
       
   219 // Transactions are not supported.
       
   220 // -----------------------------------------------------------------------------
       
   221 void CMmsDataStore::DoRevertTransaction( TRequestStatus& aStatus )
       
   222     {
       
   223     LOGGER_ENTERFN( "CMmsDataStore::DoRevertTransaction" ); 
       
   224     iCallerStatus = &aStatus;
       
   225     User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   226     LOGGER_LEAVEFN( "CMmsDataStore::DoRevertTransaction" );
       
   227     }
       
   228 
       
   229 // -----------------------------------------------------------------------------
       
   230 // CMmsDataStore::DoBeginBatchL
       
   231 // Batching is not supported.
       
   232 // -----------------------------------------------------------------------------
       
   233 void CMmsDataStore::DoBeginBatchL()
       
   234     {
       
   235     LOGGER_ENTERFN( "CMmsDataStore::DoBeginBatchL" );
       
   236     LOGGER_WRITE( "CMmsDataStore::DoBeginBatchL leaved with KErrNotSupported." );
       
   237     User::Leave( KErrNotSupported );    
       
   238     }
       
   239 
       
   240 // -----------------------------------------------------------------------------
       
   241 // CMmsDataStore::DoCommitBatchL
       
   242 // Batching is not supported
       
   243 // -----------------------------------------------------------------------------
       
   244 //
       
   245 void CMmsDataStore::DoCommitBatchL( RArray<TInt>& /*aResultArray*/, TRequestStatus& aStatus )
       
   246     {
       
   247     LOGGER_ENTERFN( "CMmsDataStore::DoCommitBatchL" );  
       
   248     LOGGER_WRITE( "CMmsDataStore::DoCommitBatchL failed with KErrNotSupported" );
       
   249     iCallerStatus = &aStatus;
       
   250     User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   251     }
       
   252 
       
   253 // -----------------------------------------------------------------------------
       
   254 // CMmsDataStore::DoCancelBatch
       
   255 // Batching is not supported
       
   256 // -----------------------------------------------------------------------------
       
   257 void CMmsDataStore::DoCancelBatch()
       
   258     {
       
   259     LOGGER_ENTERFN( "CMmsDataStore::DoCancelBatch" );
       
   260     LOGGER_LEAVEFN( "CMmsDataStore::DoCancelBatch" );
       
   261     }
       
   262 
       
   263 // -----------------------------------------------------------------------------
       
   264 // CMmsDataStore::DoSetRemoteStoreFormatL
       
   265 // Not supported
       
   266 // -----------------------------------------------------------------------------
       
   267 //
       
   268 void CMmsDataStore::DoSetRemoteStoreFormatL( const CSmlDataStoreFormat& /*aServerDataStoreFormat*/ )
       
   269     {
       
   270     LOGGER_ENTERFN("CMmsDataStore::DoSetRemoteStoreFormatL");
       
   271     LOGGER_LEAVEFN("CMmsDataStore::DoSetRemoteStoreFormatL");
       
   272     }
       
   273 
       
   274 // -----------------------------------------------------------------------------
       
   275 // CMmsDataStore::DoSetRemoteMaxObjectSize
       
   276 // Not supported
       
   277 // -----------------------------------------------------------------------------
       
   278 void CMmsDataStore::DoSetRemoteMaxObjectSize( TInt /*aServerMaxObjectSize*/ )
       
   279     {
       
   280     LOGGER_ENTERFN("CMmsDataStore::DoSetRemoteMaxObjectSize");
       
   281     LOGGER_LEAVEFN("CMmsDataStore::DoSetRemoteMaxObjectSize");
       
   282     }
       
   283 
       
   284 // -----------------------------------------------------------------------------
       
   285 // CMmsDataStore::DoMaxObjectSize
       
   286 // Reads the maximum MMS Message size from the central repository
       
   287 // -----------------------------------------------------------------------------
       
   288 TInt CMmsDataStore::DoMaxObjectSize() const
       
   289     {
       
   290     LOGGER_ENTERFN( "CMmsDataStore::DoMaxObjectSize" );
       
   291     
       
   292     CRepository* repository( NULL );
       
   293     TInt error( KErrNone );
       
   294     TInt maxSendSize( 0 );
       
   295     
       
   296     // Create central repository instance
       
   297     TRAP( error, repository = CRepository::NewL( KCRUidMmsEngine ) );  
       
   298     if ( error == KErrNone )
       
   299         {
       
   300         // Obtain the size from the central repository.
       
   301         // In the case of error we'll set the value to zero ("anything goes").
       
   302         error = repository->Get( KMmsEngineMaximumSendSize, maxSendSize );
       
   303         if ( error != KErrNone )
       
   304             {
       
   305             maxSendSize = 0;
       
   306             }
       
   307         
       
   308         delete repository;
       
   309         }
       
   310     else
       
   311         {
       
   312         LOGGER_MSG_EC( "CRepository::NewL leaved with %d", error );
       
   313         }       
       
   314         
       
   315     LOGGER_LEAVEFN( "CMmsDataStore::DoMaxObjectSize" );
       
   316     return maxSendSize;
       
   317     }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CMmsDataStore::DoOpenItemL
       
   321 // Opens item in the DataStore, reads it (either completely or partially) 
       
   322 // to the temporary buffer where it can be later read to the remote database.
       
   323 // -----------------------------------------------------------------------------
       
   324 void CMmsDataStore::DoOpenItemL( TSmlDbItemUid aUid, TBool& aFieldChange, 
       
   325     TInt& aSize, TSmlDbItemUid& aParent, TDes8& aMimeType, 
       
   326     TDes8& aMimeVer, TRequestStatus& aStatus )
       
   327     {
       
   328     LOGGER_ENTERFN( "CMmsDataStore::DoOpenItemL" );
       
   329 
       
   330     LOGGER_MSG_EC( "Opening item %d.", aUid );
       
   331     
       
   332     // Store these for later use
       
   333     iCallerStatus = &aStatus;
       
   334     *iCallerStatus = KRequestPending;
       
   335     
       
   336     // Check that we're in a proper state
       
   337     if ( iCurrentState != EMmsOpenAndWaiting )
       
   338         {
       
   339         LOGGER_MSG_EC( "CMmsDataStore::DoOpenItemL, invalid state %d.", iCurrentState );
       
   340         User::RequestComplete( iCallerStatus, KErrNotReady );
       
   341         return;
       
   342         }
       
   343         
       
   344     TBool userFolderFound( EFalse );
       
   345     TTime timeStamp;
       
   346     TPtrC folderName;
       
   347     userFolderFound = iMsvApi->FindUserFolderL( aUid, folderName, timeStamp );
       
   348     
       
   349     if ( userFolderFound )
       
   350         {
       
   351         // Allocate new buffer
       
   352         SAFEDELETE( iDataBuffer );
       
   353         iDataBuffer = CBufFlat::NewL( KDataBufferSize );
       
   354         
       
   355         iFolderObjectParser->SetName( folderName );
       
   356         iFolderObjectParser->SetCreatedDate( timeStamp.DateTime() );
       
   357         iFolderObjectParser->SetModifiedDate( timeStamp.DateTime() );
       
   358         iFolderObjectParser->ExportFolderXmlL( *iDataBuffer ); 
       
   359        
       
   360         iParentId = KMsvMyFoldersEntryIdValue;
       
   361         
       
   362         iCurrentState = EFolderOpen;
       
   363         iReadPosition = 0;
       
   364         
       
   365         aSize = iDataBuffer->Size();
       
   366         }
       
   367     else // Open MMS message
       
   368         {
       
   369         TInt error( KErrNone );
       
   370         
       
   371         CMsvEntry* entry( NULL );
       
   372         TRAP( error, entry = iMsvSession->GetEntryL(aUid) );
       
   373         if ( error != KErrNone )
       
   374             {
       
   375             User::RequestComplete( iCallerStatus, KErrNotFound ); 
       
   376             LOGGER_MSG_EC("iMsvSession->GetEntryL failed with %d.", error);
       
   377             return;
       
   378             }
       
   379         
       
   380         TMsvEntry messageEntry = entry->Entry();
       
   381         SAFEDELETE( entry );
       
   382     
       
   383         iCurrentId = aUid;
       
   384         iParentId = messageEntry.Parent();
       
   385         iReadCounter = 0;
       
   386     
       
   387         // Check whether we need to send the whole item
       
   388         if ( iChangeFinder->UpdatePartialL( aUid ) )
       
   389             {
       
   390             LOGGER_WRITE("EMmsItemOpenFieldUpdate");
       
   391             aSize = 1;
       
   392             iCurrentState = EMmsItemOpenFieldUpdate;
       
   393             }
       
   394         else    
       
   395             {
       
   396             // Read the whole item from the message store to the buffer
       
   397             TUint32 flags( 0 );
       
   398             TRAP( error, iCodecClient->InitializeChunkedRetrievingL(
       
   399                 iCurrentId,
       
   400                 iParentId,
       
   401                 flags,
       
   402                 iUnread,
       
   403                 aSize,
       
   404                 iMsvWait->iStatus) );
       
   405             
       
   406             if ( error != KErrNone ) 
       
   407                 {
       
   408                 User::RequestComplete( iCallerStatus, error );
       
   409                 LOGGER_MSG_EC("iCodecClient->InitializeChunkedRetrievingL failed with %d.", error); 
       
   410                 return;         
       
   411                 }
       
   412             
       
   413             // Wait until the message has been processed
       
   414             iMsvWait->Start();
       
   415             
       
   416             if ( iMsvWait->iStatus != KErrNone )
       
   417                 {
       
   418                 User::RequestComplete( iCallerStatus, iMsvWait->iStatus.Int() );
       
   419                 LOGGER_MSG_EC( "iCodecClient->InitializeChunkedRetrievingL failed with %d",
       
   420                     iMsvWait->iStatus.Int() ); 
       
   421                 return;
       
   422                 }   
       
   423             aSize++; // Status byte will be added also, reserve one additional byte for that.
       
   424             iCurrentState = EMmsItemOpen;
       
   425             }
       
   426         } // Open MMS message
       
   427     
       
   428     aParent = iParentId;
       
   429     
       
   430     aFieldChange = iCurrentState == EMmsItemOpenFieldUpdate ? ETrue : EFalse;
       
   431     
       
   432     if ( iCurrentState == EFolderOpen ) // Message folder
       
   433         {
       
   434         TInt targetLength = KFolderMimeType().Length();
       
   435         if ( aMimeType.MaxLength() < targetLength )
       
   436             {
       
   437             targetLength = aMimeType.MaxLength();
       
   438             }
       
   439         aMimeType.Copy( KFolderMimeType().Ptr(), targetLength );
       
   440 
       
   441         // Set mime version (do not exceed the allocated buffer)
       
   442         targetLength = KFolderMimeVersion().Length();
       
   443         if ( aMimeVer.MaxLength() < targetLength )
       
   444             {
       
   445             targetLength = aMimeVer.MaxLength();
       
   446             }
       
   447         aMimeVer.Copy( KFolderMimeVersion().Ptr(), targetLength );
       
   448         }
       
   449     else // EMmsMessage
       
   450         {   
       
   451         TInt targetLength = KMmsMimeType().Length();
       
   452         if ( aMimeType.MaxLength() < targetLength )
       
   453             {
       
   454             targetLength = aMimeType.MaxLength();
       
   455             }
       
   456         aMimeType.Copy( KMmsMimeType().Ptr(), targetLength );
       
   457 
       
   458         // Set mime version (do not exceed the allocated buffer)
       
   459         targetLength = KMmsMimeVersion().Length();
       
   460         if ( aMimeVer.MaxLength() < targetLength )
       
   461             {
       
   462             targetLength = aMimeVer.MaxLength();
       
   463             }
       
   464         aMimeVer.Copy( KMmsMimeVersion().Ptr(), targetLength );
       
   465         }
       
   466     
       
   467     LOGGER_WRITE_1("aSize: %d", aSize);
       
   468     
       
   469     // Signal we're complete
       
   470     User::RequestComplete( iCallerStatus, KErrNone ); 
       
   471 
       
   472     LOGGER_LEAVEFN("CMmsDataStore::DoOpenItemL");
       
   473     }
       
   474 
       
   475 // -----------------------------------------------------------------------------
       
   476 // CMmsDataStore::DoCreateItemL
       
   477 // Create new item to the message store.
       
   478 // Return the id number of the newly created item
       
   479 // -----------------------------------------------------------------------------
       
   480 void CMmsDataStore::DoCreateItemL( TSmlDbItemUid& aUid, TInt aSize, TSmlDbItemUid aParent, 
       
   481     const TDesC8& aMimeType, const TDesC8& /*aMimeVer*/, TRequestStatus& aStatus )
       
   482     {
       
   483     LOGGER_ENTERFN( "CMmsDataStore::DoCreateItemL" );
       
   484     LOGGER_MSG_EC( "Parent folder: %d.", aParent );
       
   485     
       
   486     // Store some variables for further use
       
   487     iCallerStatus = &aStatus;
       
   488     *iCallerStatus = KRequestPending;
       
   489     
       
   490     // Ensure that we're in proper state
       
   491     if ( iCurrentState != EMmsOpenAndWaiting )
       
   492         {
       
   493         LOGGER_MSG_EC( "Invalid state %d.", iCurrentState );
       
   494         }
       
   495         
       
   496     TBool createFolder( EFalse );
       
   497     LOG( aMimeType );
       
   498     if ( aMimeType.Compare( KFolderMimeType() ) == 0 )  
       
   499         {
       
   500         createFolder = ETrue;
       
   501         }
       
   502     else if ( aMimeType.Compare( KMmsMimeType() ) != 0 )
       
   503         {
       
   504         User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   505         LOGGER_WRITE("Bad MIME type");
       
   506         return;
       
   507         }
       
   508     
       
   509     // Ensure that we've got enough disk space for the item
       
   510     if ( iCodecClient->DiskSpaceBelowCriticalLevelL( aSize ) )
       
   511         {
       
   512         User::RequestComplete( iCallerStatus, KErrDiskFull );
       
   513         LOGGER_WRITE( "Disk full" );
       
   514         return;
       
   515         }
       
   516         
       
   517     if( createFolder )
       
   518         {
       
   519         if ( aParent != KMsvMyFoldersEntryIdValue )
       
   520             {
       
   521             User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   522             LOGGER_WRITE( "Bad parent folder" );
       
   523             return;
       
   524             }
       
   525         SAFEDELETE( iDataBuffer );
       
   526         iDataBuffer = CBufFlat::NewL( KDataBufferSize );
       
   527         iCurrentState = EFolderCreating;
       
   528         iCreatedUid = &aUid;
       
   529         iWrittenDataLength = 0;
       
   530         }
       
   531     else
       
   532         {
       
   533         // There is some problems on chunked data adding, so get all data to internal buffer
       
   534         iCreatedUid = &aUid;
       
   535         iCurrentState = EMmsItemCreating;
       
   536         iWriteCounter = 0;
       
   537         iWrittenDataLength = 0;
       
   538         if ( iDataBuffer )
       
   539             {
       
   540             iDataBuffer->ResizeL( aSize );
       
   541             }
       
   542         else
       
   543             {
       
   544             iDataBuffer = CBufFlat::NewL( KDataBufferSize );
       
   545             iDataBuffer->ResizeL( aSize );
       
   546             }
       
   547         }
       
   548         
       
   549     iParentId = aParent; 
       
   550     
       
   551     // Signal we're complete
       
   552     User::RequestComplete( iCallerStatus, KErrNone );
       
   553     
       
   554     LOGGER_LEAVEFN("CMmsDataStore::DoCreateItemL");
       
   555     }
       
   556 
       
   557 // -----------------------------------------------------------------------------
       
   558 // CMmsDataStore::DoReplaceItemL
       
   559 // Begin the replace operation, ensure that the item really exists
       
   560 // -----------------------------------------------------------------------------
       
   561 void CMmsDataStore::DoReplaceItemL( TSmlDbItemUid aUid, TInt aSize, TSmlDbItemUid aParent, 
       
   562     TBool /*aFieldChange*/, TRequestStatus& aStatus )
       
   563     {
       
   564     LOGGER_ENTERFN("CMmsDataStore::DoReplaceItemL");
       
   565     LOGGER_MSG_EC("Replacing item %d.", aUid);
       
   566     LOGGER_MSG_EC("Parent folder: %d.", aParent);
       
   567     
       
   568     // Store some variables for further use
       
   569     iCallerStatus = &aStatus;
       
   570     *iCallerStatus = KRequestPending;
       
   571     
       
   572     // Ensure proper state
       
   573     if ( iCurrentState != EMmsOpenAndWaiting )
       
   574         {
       
   575         LOGGER_MSG_EC("Invalid state %d.", iCurrentState);
       
   576         }
       
   577 
       
   578     // Ensure that we've got enough disk space for the item
       
   579     if ( iCodecClient->DiskSpaceBelowCriticalLevelL( aSize ) )
       
   580         {
       
   581         User::RequestComplete( iCallerStatus, KErrDiskFull );
       
   582         LOGGER_WRITE("Disk full");
       
   583         return;
       
   584         }
       
   585              
       
   586     // Find entry
       
   587     CMsvEntry* entry(NULL);
       
   588     TRAPD( err, entry = iMsvSession->GetEntryL( aUid ) );
       
   589     if ( err != KErrNone )
       
   590         {
       
   591         User::RequestComplete( iCallerStatus, KErrNotFound );
       
   592         LOGGER_MSG_EC("CMsvSession::GetEntryL failed with %d.", err)
       
   593         return;
       
   594         }
       
   595 
       
   596     TMsvEntry tEntry = entry->Entry();
       
   597     delete entry;
       
   598     
       
   599     // Check entry type
       
   600     TBool updateFolder(EFalse);
       
   601     if ( tEntry.iType == KUidMsvFolderEntry )
       
   602         {
       
   603         updateFolder = ETrue;
       
   604         LOGGER_WRITE("Type: folder");
       
   605         }
       
   606         
       
   607    if ( ( updateFolder && aParent != KMsvMyFoldersEntryIdValue )
       
   608         || ( !updateFolder && !iMsvApi->ValidFolderL( aParent )
       
   609         || ( aParent != tEntry.Parent() ) ) )
       
   610         {
       
   611         User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   612         LOGGER_MSG_EC("Bad parent folder, message entry parent is %d", tEntry.Parent());
       
   613         return;    
       
   614         }           
       
   615     
       
   616     // Store these for further use
       
   617     iParentId = aParent;
       
   618     iCurrentId = aUid;
       
   619     
       
   620     if ( updateFolder )
       
   621         {
       
   622         SAFEDELETE( iDataBuffer );
       
   623         iDataBuffer = CBufFlat::NewL( KDataBufferSize );
       
   624         iCurrentState = EFolderUpdating;
       
   625         iWrittenDataLength = 0;
       
   626         }
       
   627     else
       
   628         {
       
   629         iCurrentState = EMmsItemUpdating;
       
   630         iWriteCounter = 0;
       
   631         iWrittenDataLength = 0;
       
   632         if ( iDataBuffer )
       
   633             {
       
   634             iDataBuffer->ResizeL( aSize );
       
   635             }
       
   636         else
       
   637             {
       
   638             iDataBuffer = CBufFlat::NewL( KDataBufferSize );
       
   639             iDataBuffer->ResizeL( aSize );
       
   640             }
       
   641         }
       
   642     
       
   643     // Signal we're complete
       
   644     User::RequestComplete( iCallerStatus, KErrNone );
       
   645 
       
   646     LOGGER_LEAVEFN("CMmsDataStore::DoReplaceItemL");
       
   647     }
       
   648 
       
   649 // -----------------------------------------------------------------------------
       
   650 // CMmsDataStore::DoReadItemL
       
   651 // Read specified amount of data from the temporary buffer
       
   652 // -----------------------------------------------------------------------------
       
   653 void CMmsDataStore::DoReadItemL( TDes8& aBuffer )
       
   654     {
       
   655     LOGGER_ENTERFN("CMmsDataStore::DoReadItemL");
       
   656     
       
   657     if ( iCurrentState == EFolderOpen )
       
   658         {   
       
   659         // This is how much we've got left in the buffer
       
   660         TInt left = iDataBuffer->Size() - iReadPosition;
       
   661     
       
   662         // Make sure that there's something to read
       
   663         if ( left > 0 )
       
   664             {
       
   665             // This is how much there's space in the destination buffer
       
   666             TInt destSize = aBuffer.MaxSize();
       
   667 
       
   668             // This is how much we can read
       
   669             TInt toRead = destSize < left ? destSize : left;
       
   670 
       
   671             // Read the data from the buffer, then update the position
       
   672             iDataBuffer->Read( iReadPosition, aBuffer, toRead );
       
   673             iReadPosition += toRead;
       
   674             }
       
   675         else
       
   676             {
       
   677             LOGGER_WRITE("All data read");
       
   678             User::Leave( KErrEof );
       
   679             }
       
   680         }
       
   681     
       
   682     else if ( iCurrentState == EMmsItemOpenFieldUpdate )
       
   683         {
       
   684         if ( iReadCounter++ == 0 )
       
   685             {
       
   686             TUint8 status = ResolveStatusBits( iUnread );
       
   687             aBuffer.Append( &status, 1 );
       
   688             }
       
   689         else
       
   690             {
       
   691             LOGGER_WRITE("Field update done");
       
   692             User::Leave( KErrEof );             
       
   693             }   
       
   694         }
       
   695         
       
   696     else if ( iCurrentState == EMmsItemOpen )
       
   697         {
       
   698         if ( iReadCounter++ == 0 )
       
   699             {
       
   700             TUint8 status = ResolveStatusBits( iUnread );
       
   701             aBuffer.Append( &status, 1 );
       
   702             iReadPosition = 0;
       
   703             iLastDataChunk = EFalse;
       
   704             iReadAllData = EFalse;
       
   705             }
       
   706         else if ( iReadAllData )
       
   707             {
       
   708             User::Leave( KErrEof );
       
   709             }
       
   710             
       
   711         TInt error = ReadDataRecursively( aBuffer );
       
   712         if ( error != KErrNone )
       
   713             {
       
   714             User::Leave( error );
       
   715             }           
       
   716         }
       
   717     
       
   718     else
       
   719         {
       
   720         LOGGER_MSG_EC("CMmsDataStore::DoReadItemL: bad state %d", iCurrentState);
       
   721         User::Leave( KErrNotReady );
       
   722         }   
       
   723 
       
   724     LOGGER_LEAVEFN("CMmsDataStore::DoReadItemL");   
       
   725     }
       
   726 
       
   727 // -----------------------------------------------------------------------------
       
   728 // CMmsDataStore::DoWriteItemL
       
   729 // Write specified amount of data to the temporary buffer
       
   730 // -----------------------------------------------------------------------------
       
   731 void CMmsDataStore::DoWriteItemL( const TDesC8& aData )
       
   732     {
       
   733     LOGGER_ENTERFN("CMmsDataStore::DoWriteItemL");
       
   734     LOGGER_MSG_EC("%d",iWriteCounter);
       
   735     
       
   736     TInt dataLength = aData.Length();
       
   737     LOGGER_MSG_EC("Data length: %d", dataLength);
       
   738     
       
   739     if ( !( dataLength > 0 ) ) // Should never happen...
       
   740         {
       
   741         LOGGER_WRITE("Error: no data");
       
   742         User::Leave( KErrArgument );
       
   743         }
       
   744 
       
   745     if ( iCodecClient->DiskSpaceBelowCriticalLevelL( dataLength ) )
       
   746         {
       
   747         LOGGER_WRITE("Error: disk full");
       
   748         User::Leave( KErrDiskFull );
       
   749         }
       
   750         
       
   751     TInt error( KErrNone );
       
   752     
       
   753     if ( iCurrentState == EFolderCreating || iCurrentState == EFolderUpdating )
       
   754         {
       
   755         // Add data to buffer
       
   756         iDataBuffer->InsertL( iWrittenDataLength, aData );
       
   757         iWrittenDataLength += aData.Size();
       
   758         }
       
   759       
       
   760     else if ( iCurrentState == EMmsItemCreating )
       
   761         {
       
   762         if ( iWriteCounter++ == 0 )
       
   763             {
       
   764             iUnread = aData[0] & KMMS_Flag_Read ? EFalse : ETrue;
       
   765             if ( dataLength > 1 )
       
   766                 {
       
   767                 TPtrC8 data = aData.Mid(1);
       
   768                 iDataBuffer->Write( iWrittenDataLength, data );
       
   769                 iWrittenDataLength += data.Length();
       
   770                 }
       
   771             }
       
   772         else
       
   773             {
       
   774             TPtrC8 data = aData.Mid(0);
       
   775             iDataBuffer->Write( iWrittenDataLength, data );
       
   776             iWrittenDataLength += dataLength;
       
   777             }    
       
   778         }
       
   779         
       
   780     else if ( iCurrentState == EMmsItemUpdating )
       
   781         {
       
   782         if ( iWriteCounter++ == 0 )
       
   783             {
       
   784             iUnread = aData[0] & KMMS_Flag_Read ? EFalse : ETrue;
       
   785             if ( dataLength > 1 )
       
   786                 {
       
   787                 TPtrC8 data = aData.Mid(1);
       
   788                 iDataBuffer->Write( iWrittenDataLength, data );
       
   789                 iWrittenDataLength += data.Length();
       
   790                 }
       
   791             else // just status update
       
   792                 {
       
   793                 UpdateMmsStatusL( iCurrentId, iUnread );
       
   794                 LOGGER_MSG_EC("Message status updated: %d", iUnread);
       
   795                 }    
       
   796             }
       
   797         else
       
   798             {
       
   799             TPtrC8 data = aData.Mid(0);    
       
   800             iDataBuffer->Write( iWrittenDataLength, data );
       
   801             iWrittenDataLength += dataLength;
       
   802             }    
       
   803         }
       
   804         
       
   805     else
       
   806         {
       
   807         LOGGER_MSG_EC("Wrong state %d", iCurrentState);
       
   808         User::Leave( KErrNotReady );
       
   809         }
       
   810         
       
   811     if ( error != KErrNone )
       
   812         {
       
   813         LOGGER_MSG_EC("iCodecClient->NextDataPart() failed with %d", error);
       
   814         User::Leave( error );
       
   815         }  
       
   816 
       
   817     LOGGER_LEAVEFN("CMmsDataStore::DoWriteItemL");  
       
   818     }
       
   819 
       
   820 // -----------------------------------------------------------------------------
       
   821 // CMmsDataStore::DoCommitItemL
       
   822 // Commits item from temporary buffer to the message store
       
   823 // -----------------------------------------------------------------------------
       
   824 void CMmsDataStore::DoCommitItemL( TRequestStatus& aStatus )
       
   825     {
       
   826     LOGGER_ENTERFN("CMmsDataStore::DoCommitItemL");
       
   827     
       
   828     // Store some variables
       
   829     iCallerStatus = &aStatus;
       
   830     *iCallerStatus = KRequestPending;
       
   831     
       
   832     TInt error(KErrNone);
       
   833     
       
   834     if ( iCurrentState == EFolderCreating || iCurrentState == EFolderUpdating )
       
   835         {
       
   836         error = iFolderObjectParser->ImportFolderXml( iDataBuffer->Ptr(0) );
       
   837         if ( error != KErrNone )
       
   838             {
       
   839             User::RequestComplete( iCallerStatus, error );
       
   840             LOGGER_MSG_EC("ImportFolderXml failed with %d", error);
       
   841             return;
       
   842             }
       
   843          
       
   844          const TDesC& name = iFolderObjectParser->GetName();
       
   845          if ( name.Length() <= 0 )
       
   846             {
       
   847             User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   848             LOGGER_WRITE("Folder name is empty");
       
   849             return;
       
   850             }
       
   851             
       
   852          if ( iCurrentState == EFolderCreating )
       
   853             {
       
   854             TMsvId id;
       
   855             error = iMsvApi->AddUserFolderL( id, name );
       
   856             if ( error == KErrNone )
       
   857                 {
       
   858                 *iCreatedUid = id;
       
   859                 iCurrentId = id;
       
   860                 }
       
   861             else
       
   862                 {
       
   863                 LOGGER_MSG_EC("iMsvApi->AddFolderL failed with %d", error);
       
   864                 }    
       
   865             }
       
   866          else
       
   867             {
       
   868             error = iMsvApi->UpdateUserFolderL( iCurrentId, name );
       
   869             if ( error != KErrNone )
       
   870                 {
       
   871                 LOGGER_MSG_EC("iMsvApi->UpdateFolderL failed with %d", error);
       
   872                 }
       
   873             }
       
   874         }
       
   875     else if ( iCurrentState == EMmsItemCreating )
       
   876         {
       
   877         LOGGER_WRITE("Create MMS item");
       
   878         TMsvId newId(0);
       
   879         TUint32 flags(0);
       
   880         
       
   881         error = iCodecClient->CreateNewMessageEntryL( iParentId, newId );
       
   882         if ( !error )
       
   883             {
       
   884             iCodecClient->AddMML( *iDataBuffer, iParentId, flags, iUnread, newId, iMsvWait->iStatus );
       
   885             // Wait until the message has been processed
       
   886             iMsvWait->Start();
       
   887             error = iMsvWait->iStatus.Int();
       
   888             LOGGER_WRITE_1("error: %d", error);
       
   889             LOGGER_WRITE_1("AddMML newId: %d", newId);
       
   890             *iCreatedUid = newId;
       
   891             iCurrentId = newId;
       
   892             }
       
   893         }
       
   894     else if ( iCurrentState == EMmsItemUpdating )
       
   895         {
       
   896         if ( iWrittenDataLength > 0 ) // if no data then just field update
       
   897             {
       
   898             TUint32 flags(0);
       
   899             iCodecClient->ReplaceMML( iCurrentId, *iDataBuffer, flags, iUnread, iMsvWait->iStatus );
       
   900             iMsvWait->Start();
       
   901             error = iMsvWait->iStatus.Int();
       
   902             }
       
   903         else
       
   904             {
       
   905             UpdateMmsStatusL( iCurrentId, iUnread );   
       
   906             }
       
   907         }
       
   908     else
       
   909         {
       
   910         User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   911         LOGGER_MSG_EC("Bad state: %d", iCurrentState);
       
   912         return;
       
   913         }
       
   914     
       
   915     delete iDataBuffer;
       
   916     iDataBuffer = NULL;
       
   917     
       
   918     if ( error == KErrNone ) // Update Change Finder
       
   919         {
       
   920         TMsvId service;
       
   921         TMsvEntry msgEntry;
       
   922         
       
   923         // Inform ChangeFinder of added item
       
   924         TSnapshotItem snapshotItem( iCurrentId, iParentId, iUnread );
       
   925         error = iMsvSession->GetEntry( iCurrentId, service, msgEntry );
       
   926         
       
   927         if ( error == KErrNone )
       
   928             {
       
   929             snapshotItem.SetLastChangedDate( msgEntry.iDate );
       
   930             if ( iCurrentState == EFolderCreating || iCurrentState == EFolderUpdating )
       
   931                 {
       
   932                 snapshotItem.SetFolderNameL( msgEntry.iDetails );
       
   933                 }
       
   934             
       
   935             if ( iCurrentState == EFolderCreating || iCurrentState == EMmsItemCreating )
       
   936                 {
       
   937                 iChangeFinder->ItemAddedL( snapshotItem );
       
   938                 }
       
   939             else
       
   940                 {
       
   941                 iChangeFinder->ItemUpdatedL( snapshotItem );
       
   942                 }
       
   943             }
       
   944         else
       
   945             {
       
   946             LOGGER_MSG_EC( "CMsvSession::GetEntry failed with %d", error );
       
   947             }
       
   948         }
       
   949     
       
   950     // Send message if parent folder is Outbox
       
   951     if ( iParentId == KMsvGlobalOutBoxIndexEntryId &&
       
   952         iCurrentState == EMmsItemCreating &&
       
   953         error == KErrNone )
       
   954         {
       
   955         LOGGER_WRITE("Sending message...");
       
   956         iCodecClient->SendMML( iCurrentId, iMsvWait->iStatus );
       
   957         iMsvWait->Start();
       
   958         error = iMsvWait->iStatus.Int();
       
   959         }
       
   960     
       
   961     LOGGER_WRITE_1("error: %d", error);
       
   962     // We'll be waiting for next event, signal we're done
       
   963     iCurrentState = EMmsOpenAndWaiting;
       
   964     User::RequestComplete( iCallerStatus, error );
       
   965     
       
   966     LOGGER_LEAVEFN("CMmsDataStore::DoCommitItemL");
       
   967     }
       
   968 
       
   969 // -----------------------------------------------------------------------------
       
   970 // CMmsDataStore::DoCloseItem
       
   971 // Closes open item in the data store
       
   972 // -----------------------------------------------------------------------------
       
   973 void CMmsDataStore::DoCloseItem()
       
   974     {
       
   975     LOGGER_ENTERFN("CMmsDataStore::DoCloseItem");
       
   976     SAFEDELETE(iDataBuffer);
       
   977     if ( iCurrentState == EFolderOpen )
       
   978         {
       
   979         iCurrentState = EMmsOpenAndWaiting;
       
   980         }
       
   981     else if ( iCurrentState == EMmsItemOpen )
       
   982         {
       
   983         iCodecClient->ReleaseData();
       
   984         iCurrentState = EMmsOpenAndWaiting; 
       
   985         }
       
   986     else if ( iCurrentState == EMmsItemOpenFieldUpdate )
       
   987         {
       
   988         iCurrentState = EMmsOpenAndWaiting;
       
   989         }
       
   990     else 
       
   991         {
       
   992         LOGGER_MSG_EC("Invalid state %d.", iCurrentState);
       
   993         }
       
   994     
       
   995     LOGGER_LEAVEFN("CMmsDataStore::DoCloseItem");
       
   996     }
       
   997 
       
   998 // -----------------------------------------------------------------------------
       
   999 // CMmsDataStore::DoMoveItemL
       
  1000 // Moves item from one folder to another in the message store
       
  1001 // -----------------------------------------------------------------------------
       
  1002 void CMmsDataStore::DoMoveItemL( TSmlDbItemUid aUid,
       
  1003     TSmlDbItemUid aNewParent, TRequestStatus& aStatus )
       
  1004     {
       
  1005     LOGGER_ENTERFN("CMmsDataStore::DoMoveItemL");
       
  1006     
       
  1007     LOGGER_MSG_EC("Moving item %d.", aUid);
       
  1008     
       
  1009     // Store some variables for further use
       
  1010     iCallerStatus = &aStatus;
       
  1011     *iCallerStatus = KRequestPending;
       
  1012 
       
  1013     // Check that we're in proper state
       
  1014     if ( iCurrentState != EMmsOpenAndWaiting ) 
       
  1015         {
       
  1016         LOGGER_MSG_EC("CMmsDataStore::DoMoveItemL, invalid state %d.", iCurrentState);
       
  1017         }
       
  1018 
       
  1019     // Ensure that we have this item in the message store   
       
  1020     if ( !MmsItemExists( aUid ) )
       
  1021         {
       
  1022         User::RequestComplete( iCallerStatus, KErrNotSupported ); 
       
  1023         LOGGER_WRITE("MMS item not found");
       
  1024         return;
       
  1025         }
       
  1026     
       
  1027     iCodecClient->MoveMML( aUid, aNewParent, iMsvWait->iStatus );
       
  1028     iMsvWait->Start();  
       
  1029     
       
  1030     // Inform ChangeFinder of the moved item
       
  1031     TMsvId service;
       
  1032     TMsvEntry msgEntry;
       
  1033     User::LeaveIfError( iMsvSession->GetEntry( aUid, service, msgEntry ) );
       
  1034     TBool unread = msgEntry.Unread();
       
  1035     TSnapshotItem snapshotItem( aUid, aNewParent, unread );
       
  1036     iChangeFinder->ItemMovedL( snapshotItem );
       
  1037 
       
  1038     // Signal we're done
       
  1039     User::RequestComplete( iCallerStatus, KErrNone );
       
  1040     
       
  1041     LOGGER_LEAVEFN("CMmsDataStore::DoMoveItemL");
       
  1042     }
       
  1043 
       
  1044 // -----------------------------------------------------------------------------
       
  1045 // CMmsDataStore::DoDeleteItemL
       
  1046 // Removes item from the message store
       
  1047 // -----------------------------------------------------------------------------
       
  1048 void CMmsDataStore::DoDeleteItemL( TSmlDbItemUid aUid, TRequestStatus& aStatus  )
       
  1049     {
       
  1050     LOGGER_ENTERFN("CMmsDataStore::DoDeleteItemL");
       
  1051     LOGGER_MSG_EC("Deleting item %d.", aUid);
       
  1052     
       
  1053     // Store some variables for further use
       
  1054     iCallerStatus = &aStatus;
       
  1055     *iCallerStatus = KRequestPending;
       
  1056     
       
  1057     TInt error(KErrNone);
       
  1058     
       
  1059     // Check that we're in proper state
       
  1060     if ( iCurrentState != EMmsOpenAndWaiting ) 
       
  1061         {
       
  1062         LOGGER_MSG_EC("CMmsDataStore::DoDeleteItemL, invalid state %d.", iCurrentState);        
       
  1063         }
       
  1064         
       
  1065     // Check if this is a user folder
       
  1066     if ( iMsvApi->FindUserFolderL( aUid ) )
       
  1067         {
       
  1068         LOGGER_WRITE("Folder");
       
  1069         error = DeleteAllMessagesInFolderL( aUid );
       
  1070         if ( error != KErrNone )
       
  1071             {
       
  1072             User::RequestComplete( iCallerStatus, error );    
       
  1073             LOGGER_MSG_EC("Deleting MMS messages in folder failed with %d", error); 
       
  1074             return;
       
  1075             }
       
  1076         error = iMsvApi->DeleteUserFolderL(aUid);  
       
  1077         if ( error != KErrNone )
       
  1078             {
       
  1079             // Note: folder is not deleted if contains other message items (like MMS)
       
  1080             // In this case DeleteUserFolderL returns KErrInUse.    
       
  1081             LOGGER_MSG_EC("Deleting folder failed with %d", error); 
       
  1082             }       
       
  1083         }
       
  1084     else if ( MmsItemExists( aUid ) )
       
  1085         {
       
  1086         // Tell CodecClient to delete this message
       
  1087         error = iCodecClient->DeleteMM( aUid );
       
  1088         if ( error != KErrNone )
       
  1089             {
       
  1090             User::RequestComplete( iCallerStatus, error );    
       
  1091             LOGGER_MSG_EC("CMmsCodecClient::DeleteMM failed with %d", error);   
       
  1092             return;
       
  1093             }
       
  1094         // Inform ChangeFinder of the removed item
       
  1095         iChangeFinder->ItemDeletedL( aUid );
       
  1096         }
       
  1097     else
       
  1098         {
       
  1099         User::RequestComplete( iCallerStatus, KErrNotFound ); 
       
  1100         LOGGER_MSG_EC("Item %d is not folder or MMS message", aUid);
       
  1101         return;
       
  1102         }
       
  1103     
       
  1104     LOGGER_WRITE_1("complete error: %d", error);
       
  1105     // Signal we're done
       
  1106     User::RequestComplete( iCallerStatus, error );
       
  1107     LOGGER_LEAVEFN("CMmsDataStore::DoDeleteItemL");
       
  1108     }
       
  1109 
       
  1110 // -----------------------------------------------------------------------------
       
  1111 // CMmsDataStore::DoSoftDeleteItemL
       
  1112 // Soft delete isn't supported.
       
  1113 // -----------------------------------------------------------------------------
       
  1114 void CMmsDataStore::DoSoftDeleteItemL( TSmlDbItemUid /*aUid*/, TRequestStatus& aStatus )
       
  1115     {
       
  1116     LOGGER_ENTERFN("CMmsDataStore::DoSoftDeleteItemL"); 
       
  1117     
       
  1118     // Store some variables for further use
       
  1119     iCallerStatus = &aStatus;
       
  1120     *iCallerStatus = KRequestPending;
       
  1121 
       
  1122     // Signal we're done
       
  1123     User::RequestComplete( iCallerStatus, KErrNotSupported );
       
  1124     
       
  1125     LOGGER_LEAVEFN("CMmsDataStore::DoSoftDeleteItemL");
       
  1126     }
       
  1127 
       
  1128 // -----------------------------------------------------------------------------
       
  1129 // CMmsDataStore::DoDeleteAllItemsL
       
  1130 // Deletes all items in the standard folders of message store
       
  1131 // -----------------------------------------------------------------------------
       
  1132 void CMmsDataStore::DoDeleteAllItemsL( TRequestStatus& aStatus )
       
  1133     {
       
  1134     LOGGER_ENTERFN("CMmsDataStore::DoDeleteAllItemsL");
       
  1135     
       
  1136     // Store some variables for further use 
       
  1137     iCallerStatus = &aStatus;
       
  1138     *iCallerStatus = KRequestPending;
       
  1139     
       
  1140    // Check that we're in proper state
       
  1141     if ( iCurrentState != EMmsOpenAndWaiting ) 
       
  1142         {
       
  1143         LOGGER_MSG_EC("CMmsDataStore::DoDeleteAllItemsL, invalid state %d.", iCurrentState);
       
  1144         }
       
  1145         
       
  1146     TInt error(KErrNone);
       
  1147     TInt result(KErrNone);      
       
  1148     
       
  1149     // Delete all messages in the standard folders (except outbox)
       
  1150     error = DeleteAllMessagesInFolderL( KMsvGlobalInBoxIndexEntryId );
       
  1151     if ( error != KErrNone )
       
  1152         {
       
  1153         result = error;
       
  1154         }
       
  1155        
       
  1156     error = DeleteAllMessagesInFolderL( KMsvDraftEntryId );
       
  1157     if ( error != KErrNone )
       
  1158         {
       
  1159         result = error;
       
  1160         }   
       
  1161     
       
  1162     error = DeleteAllMessagesInFolderL( KMsvSentEntryId );
       
  1163     if ( error != KErrNone )
       
  1164         {
       
  1165         result = error;
       
  1166         }
       
  1167         
       
  1168     error = CleanUserFoldersL();
       
  1169     if ( error != KErrNone )
       
  1170         {
       
  1171         result = error;
       
  1172         }
       
  1173             
       
  1174     iChangeFinder->ResetL();
       
  1175     
       
  1176     User::RequestComplete( iCallerStatus, result );
       
  1177     
       
  1178     LOGGER_LEAVEFN("CMmsDataStore::DoDeleteAllItemsL");
       
  1179     }
       
  1180 
       
  1181 // -----------------------------------------------------------------------------
       
  1182 // CMmsDataStore::DeleteAllMessagesInFolderL
       
  1183 // Deletes all items in the specified folder in message store
       
  1184 // -----------------------------------------------------------------------------
       
  1185 TInt CMmsDataStore::DeleteAllMessagesInFolderL( TMsvId aId )
       
  1186     {
       
  1187     LOGGER_ENTERFN("CMmsDataStore::DeleteAllMessagesInFolderL");
       
  1188     LOGGER_MSG_EC("Folder: %d", aId);
       
  1189     
       
  1190     TInt error(KErrNone);
       
  1191     
       
  1192     // Get the root folder
       
  1193     CMsvEntry* msvEntry = iMsvSession->GetEntryL(aId);
       
  1194     CleanupStack::PushL(msvEntry);
       
  1195     
       
  1196     // Find all of it's childs
       
  1197     CMsvEntrySelection* messages = msvEntry->ChildrenWithTypeL(KUidMsvMessageEntry);
       
  1198     CleanupStack::PopAndDestroy(msvEntry);
       
  1199     CleanupStack::PushL(messages);
       
  1200         
       
  1201     TMsvId service;
       
  1202     TMsvEntry msg;
       
  1203     TMsvId id;
       
  1204     
       
  1205     // We are only interested of the MM content
       
  1206     for ( TInt index=0; index < messages->Count(); index++ )
       
  1207         {
       
  1208         id = messages->At( index );
       
  1209         LOGGER_MSG_EC("Message item %d:", id);
       
  1210         
       
  1211         error = iMsvSession->GetEntry( id, service, msg );
       
  1212         if ( error != KErrNone )
       
  1213             {
       
  1214             LOGGER_MSG_EC("GetEntry failed with %d", error);
       
  1215             break;
       
  1216             }
       
  1217         
       
  1218         if ( msg.iMtm == KUidMsgTypeMultimedia )
       
  1219             {
       
  1220             error = iCodecClient->DeleteMM( id );
       
  1221             if ( error != KErrNone )
       
  1222                 {
       
  1223                 LOGGER_MSG_EC("DeleteMM failed with %d", error);
       
  1224                 break;
       
  1225                 }
       
  1226             // Update Change Finder
       
  1227             iChangeFinder->ItemDeletedL( id );
       
  1228             LOGGER_WRITE("MMS message deleted");    
       
  1229             }
       
  1230         }
       
  1231     CleanupStack::PopAndDestroy(messages); 
       
  1232     
       
  1233     LOGGER_LEAVEFN("CMmsDataStore::DeleteAllMessagesInFolderL");
       
  1234 
       
  1235     return error;
       
  1236     }
       
  1237 
       
  1238 
       
  1239 // -----------------------------------------------------------------------------
       
  1240 // CMmsDataStore::DoHasSyncHistory
       
  1241 // This method returns ETrue if Data Store has history information. 
       
  1242 // Slow-sync will be used if Data Store does not have history information.
       
  1243 // -----------------------------------------------------------------------------
       
  1244 TBool CMmsDataStore::DoHasSyncHistory() const
       
  1245     {
       
  1246     LOGGER_ENTERFN("CMmsDataStore::DoHasSyncHistory");
       
  1247     LOGGER_LEAVEFN("CMmsDataStore::DoHasSyncHistory");      
       
  1248         
       
  1249     // iHasHistory is initialized in DoOpenL method
       
  1250     return iHasHistory;
       
  1251     }
       
  1252 
       
  1253 // -----------------------------------------------------------------------------
       
  1254 // CMmsDataStore::DoAddedItems
       
  1255 // This method returns UIDs of added items. Those items are added after previous
       
  1256 // synchronization with current synchronization relationship. 
       
  1257 // -----------------------------------------------------------------------------
       
  1258 const MSmlDataItemUidSet& CMmsDataStore::DoAddedItems() const
       
  1259     {
       
  1260     LOGGER_ENTERFN("CMmsDataStore::DoAddedItems");  
       
  1261     
       
  1262     // Ensure that we're in a proper state
       
  1263     if ( iCurrentState != EMmsOpenAndWaiting )
       
  1264         {
       
  1265         LOGGER_MSG_EC("CMmsDataStore::DoAddedItems, invalid state %d.", iCurrentState);
       
  1266         }
       
  1267     
       
  1268     TInt error(KErrNone);
       
  1269 
       
  1270     // Clear new-items array
       
  1271     iNewItems->Reset();
       
  1272   
       
  1273     // Search for new items
       
  1274     TRAP( error, iChangeFinder->FindNewItemsL(*iNewItems) )
       
  1275     if ( error != KErrNone )
       
  1276         {
       
  1277         LOGGER_MSG_EC("CMmsDataStore::DoAddedItems, iChangeFinder->FindNewItemsL leaved with %d.", error);
       
  1278         }
       
  1279     
       
  1280     LOGGER_MSG_EC("New item count: %d.", iNewItems->ItemCount());
       
  1281     LOGGER_LEAVEFN("CMmsDataStore::DoAddedItems");      
       
  1282     
       
  1283     return *iNewItems;
       
  1284     }
       
  1285 
       
  1286 // -----------------------------------------------------------------------------
       
  1287 // CMmsDataStore::DoDeletedItems
       
  1288 //
       
  1289 // -----------------------------------------------------------------------------
       
  1290 const MSmlDataItemUidSet& CMmsDataStore::DoDeletedItems() const
       
  1291     {
       
  1292     LOGGER_ENTERFN("CMmsDataStore::DoDeletedItemsL");   
       
  1293     
       
  1294     // Ensure that we're in a proper state
       
  1295     if ( iCurrentState != EMmsOpenAndWaiting )
       
  1296         {
       
  1297         LOGGER_MSG_EC("CMmsDataStore::DoDeletedItems, invalid state %d.", iCurrentState);
       
  1298         }
       
  1299     
       
  1300     TInt error(KErrNone);
       
  1301     
       
  1302     // Clear deleted-items array
       
  1303     iDeletedItems->Reset();
       
  1304     
       
  1305     // Search for deleted items
       
  1306     TRAP( error, iChangeFinder->FindDeletedItemsL( *iDeletedItems ) );
       
  1307     if ( error != KErrNone )
       
  1308         {
       
  1309         LOGGER_MSG_EC("CMmsDataStore::DoDeletedItems, iChangeFinder->FindDeletedItemsL leaved with %d.", error);
       
  1310         }           
       
  1311     
       
  1312     LOGGER_MSG_EC("Deleted item count: %d.", iDeletedItems->ItemCount());
       
  1313     LOGGER_LEAVEFN("CMmsDataStore::DoDeletedItemsL");
       
  1314     return *iDeletedItems;
       
  1315     }
       
  1316 
       
  1317 // -----------------------------------------------------------------------------
       
  1318 // CMmsDataStore::DoSoftDeletedItems
       
  1319 // Not directly supported, equals to "hard" delete
       
  1320 // -----------------------------------------------------------------------------
       
  1321 const MSmlDataItemUidSet& CMmsDataStore::DoSoftDeletedItems() const
       
  1322     {
       
  1323     LOGGER_ENTERFN("CMmsDataStore::DoSoftDeletedItems");
       
  1324     LOGGER_LEAVEFN("CMmsDataStore::DoSoftDeletedItems");
       
  1325 
       
  1326     iSoftDeletedItems->Reset();
       
  1327     return *iSoftDeletedItems;
       
  1328     }
       
  1329 
       
  1330 // -----------------------------------------------------------------------------
       
  1331 // CMmsDataStore::DoModifiedItems
       
  1332 // Finds all modified items in the data store
       
  1333 // -----------------------------------------------------------------------------
       
  1334 const MSmlDataItemUidSet& CMmsDataStore::DoModifiedItems() const
       
  1335     {
       
  1336     LOGGER_ENTERFN("CMmsDataStore::DoModifiedItems");   
       
  1337     
       
  1338     // Ensure that we're in a proper state
       
  1339     if ( iCurrentState != EMmsOpenAndWaiting )
       
  1340         {
       
  1341         LOGGER_MSG_EC("CMmsDataStore::DoModifiedItems, invalid state %d.", iCurrentState);
       
  1342         }
       
  1343     
       
  1344     TInt error(KErrNone);
       
  1345     
       
  1346     // Clear updated-items array
       
  1347     iUpdatedItems->Reset();
       
  1348     
       
  1349     // Search for updated items
       
  1350     TRAP( error, iChangeFinder->FindChangedItemsL( *iUpdatedItems ) )
       
  1351     if ( error != KErrNone )
       
  1352         {
       
  1353         LOGGER_MSG_EC("CMmsDataStore::DoModifiedItems, iChangeFinder->FindChangedItemsL leaved with %d.", error);
       
  1354         }
       
  1355     
       
  1356     LOGGER_MSG_EC("Modified item count: %d.", iUpdatedItems->ItemCount());
       
  1357     LOGGER_LEAVEFN("CMmsDataStore::DoModifiedItems");       
       
  1358     return *iUpdatedItems;
       
  1359     }
       
  1360 
       
  1361 // -----------------------------------------------------------------------------
       
  1362 // CMmsDataStore::DoMovedItems
       
  1363 // Finds all moved items in the data store
       
  1364 // -----------------------------------------------------------------------------
       
  1365 const MSmlDataItemUidSet& CMmsDataStore::DoMovedItems() const
       
  1366     {
       
  1367     LOGGER_ENTERFN("CMmsDataStore::DoMovedItems");  
       
  1368     
       
  1369     // Ensure that we're in a proper state
       
  1370     if ( iCurrentState != EMmsOpenAndWaiting )
       
  1371         {
       
  1372         LOGGER_MSG_EC("CMmsDataStore::DoMovedItems, invalid state %d.", iCurrentState);
       
  1373         }
       
  1374     
       
  1375     TInt error(KErrNone);
       
  1376     
       
  1377     // Clear moved-items array
       
  1378     iMovedItems->Reset();
       
  1379     
       
  1380     // Search for moved items
       
  1381     TRAP( error, iChangeFinder->FindMovedItemsL( *iMovedItems ) );
       
  1382     if ( error != KErrNone )
       
  1383         {
       
  1384         LOGGER_MSG_EC("CMmsDataStore::DoMovedItems, iChangeFinder->FindMovedItemsL leaved with %d.", error);
       
  1385         }
       
  1386     
       
  1387     LOGGER_MSG_EC("Moved item count: %d.", iMovedItems->ItemCount());
       
  1388     LOGGER_LEAVEFN("CMmsDataStore::DoMovedItems");
       
  1389     return *iMovedItems;    
       
  1390     }
       
  1391 
       
  1392 // -----------------------------------------------------------------------------
       
  1393 // CMmsDataStore::DoResetChangeInfoL
       
  1394 // Resets change history in the data store. All content is considered
       
  1395 // new in the data store point of view.
       
  1396 // -----------------------------------------------------------------------------
       
  1397 void CMmsDataStore::DoResetChangeInfoL( TRequestStatus& aStatus )
       
  1398     {
       
  1399     LOGGER_ENTERFN("CMmsDataStore::DoResetChangeInfoL");    
       
  1400     
       
  1401     iCallerStatus = &aStatus;
       
  1402     *iCallerStatus = KRequestPending;
       
  1403     
       
  1404     // Check that we're in proper state
       
  1405     if ( iCurrentState != EMmsOpenAndWaiting ) 
       
  1406         {
       
  1407         LOGGER_MSG_EC("CMmsDataStore::DoResetChangeInfoL, invalid state %d.", iCurrentState);
       
  1408         }   
       
  1409             
       
  1410     // Reset change info in ChangeFinder
       
  1411     iChangeFinder->ResetL();
       
  1412     iHasHistory = EFalse;
       
  1413     
       
  1414     // Signal we're done
       
  1415     User::RequestComplete( iCallerStatus, KErrNone ); 
       
  1416     
       
  1417     LOGGER_LEAVEFN("CMmsDataStore::DoResetChangeInfoL");
       
  1418     }
       
  1419         
       
  1420 // -----------------------------------------------------------------------------
       
  1421 // CMmsDataStore::DoCommitChangeInfoL
       
  1422 // Commits change info. These items are no longer reported, when change
       
  1423 // information is being queried.
       
  1424 // -----------------------------------------------------------------------------
       
  1425 void CMmsDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus, const MSmlDataItemUidSet& aItems )
       
  1426     {
       
  1427     LOGGER_ENTERFN("CMmsDataStore::DoCommitChangeInfoL");
       
  1428     
       
  1429     iCallerStatus = &aStatus;
       
  1430     *iCallerStatus = KRequestPending;
       
  1431     
       
  1432     // Ensure that we're in a proper state
       
  1433     if ( iCurrentState != EMmsOpenAndWaiting ) 
       
  1434         {
       
  1435         LOGGER_MSG_EC("CMmsDataStore::DoCommitChangeInfoL, invalid state %d.", iCurrentState);
       
  1436         }
       
  1437 
       
  1438     // Notify ChangeFinder
       
  1439     iChangeFinder->CommitChangesL(aItems);
       
  1440     iHasHistory = ETrue;
       
  1441         
       
  1442     // Signal we're done
       
  1443     User::RequestComplete(iCallerStatus, KErrNone);
       
  1444         
       
  1445     LOGGER_LEAVEFN("CMmsDataStore::DoCommitChangeInfoL");
       
  1446     }
       
  1447         
       
  1448     
       
  1449 // -----------------------------------------------------------------------------
       
  1450 // CMmsDataStore::DoCommitChangeInfoL
       
  1451 // Commits change info. There is no more nothing to report when change
       
  1452 // information is being queried. 
       
  1453 // -----------------------------------------------------------------------------
       
  1454 void CMmsDataStore::DoCommitChangeInfoL(TRequestStatus& aStatus)
       
  1455     {
       
  1456     LOGGER_ENTERFN("CMmsDataStore::DoCommitChangeInfoL");
       
  1457     
       
  1458     iCallerStatus = &aStatus;
       
  1459     *iCallerStatus = KRequestPending;
       
  1460     
       
  1461     // Ensure that we're in a proper state
       
  1462     if ( iCurrentState != EMmsOpenAndWaiting ) 
       
  1463         {
       
  1464         LOGGER_MSG_EC("CMmsDataStore::DoCommitChangeInfoL, invalid state %d.", iCurrentState);
       
  1465         }
       
  1466     
       
  1467     // Notify ChangeFinder
       
  1468     iChangeFinder->CommitChangesL();
       
  1469     iHasHistory = ETrue;
       
  1470         
       
  1471     // Signal we're done
       
  1472     User::RequestComplete( iCallerStatus, KErrNone );
       
  1473     
       
  1474     LOGGER_LEAVEFN("CMmsDataStore::DoCommitChangeInfoL");
       
  1475     }
       
  1476         
       
  1477 
       
  1478 // -----------------------------------------------------------------------------
       
  1479 // CMmsDataStore::RegisterSnapshotL
       
  1480 // Sets Changefinder to compare against current message store content
       
  1481 // -----------------------------------------------------------------------------
       
  1482 void CMmsDataStore::RegisterSnapshotL() const
       
  1483     {
       
  1484     CSnapshotArray* snapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity );
       
  1485     CleanupStack::PushL(snapshot);
       
  1486     
       
  1487     // Use only standard folders (except outbox)
       
  1488     RegisterFolderL(snapshot, KMsvGlobalInBoxIndexEntryId);
       
  1489     RegisterFolderL(snapshot, KMsvDraftEntryId);
       
  1490     RegisterFolderL(snapshot, KMsvSentEntryId);
       
  1491     RegisterFolderL(snapshot, KMsvGlobalOutBoxIndexEntryId);    
       
  1492     RegisterUserFoldersL(snapshot);
       
  1493     
       
  1494     // Set new snapshot to compare against
       
  1495     iChangeFinder->SetNewSnapshot(snapshot);
       
  1496 
       
  1497     // Changefinder takes ownership of the snapshot
       
  1498     CleanupStack::Pop(snapshot);
       
  1499     }
       
  1500 
       
  1501 // -----------------------------------------------------------------------------
       
  1502 // CMmsDataStore::RegisterFolderL
       
  1503 // Adds a single folder into the snapshot array
       
  1504 // -----------------------------------------------------------------------------
       
  1505 TInt CMmsDataStore::RegisterFolderL(CSnapshotArray* aSnapshot, const TMsvId& aId) const
       
  1506     {
       
  1507     // Get the root folder
       
  1508     CMsvEntry* msvEntry = iMsvSession->GetEntryL(aId);
       
  1509     CleanupStack::PushL( msvEntry );
       
  1510     
       
  1511     // Find all of it's childs
       
  1512     CMsvEntrySelection* messages = msvEntry->ChildrenWithTypeL( KUidMsvMessageEntry );
       
  1513     CleanupStack::PopAndDestroy( msvEntry );
       
  1514     CleanupStack::PushL( messages );
       
  1515     
       
  1516     TMsvId id;
       
  1517     TMsvEntry msg;
       
  1518     
       
  1519     // We are only interested of the MM content
       
  1520     for ( TInt index=0; index<messages->Count(); index++ )
       
  1521         {
       
  1522         TInt result = iMsvSession->GetEntry( messages->At( index ), id, msg );
       
  1523         User::LeaveIfError( result );
       
  1524         
       
  1525         // We're only interested about the multimedia content
       
  1526         if ( msg.iMtm == KUidMsgTypeMultimedia )
       
  1527             {
       
  1528             // Create snapshot item
       
  1529             TKeyArrayFix key(iKey);
       
  1530             TSnapshotItem item( (TUint) msg.Id() );
       
  1531             
       
  1532             item.SetLastChangedDate( msg.iDate );
       
  1533             item.SetParentId( msg.Parent() );
       
  1534             item.SetUnread( msg.Unread() ? ETrue : EFalse );
       
  1535             
       
  1536             // Add to snapshot
       
  1537             aSnapshot->InsertIsqL( item, key );
       
  1538             }
       
  1539         }
       
  1540 
       
  1541     CleanupStack::PopAndDestroy( messages );
       
  1542     return KErrNone;
       
  1543     }
       
  1544     
       
  1545 // -----------------------------------------------------------------------------
       
  1546 // CMmsDataStore::MmsItemExists
       
  1547 // Returns ETrue if MMS item exists in the message store, otherwise EFalse
       
  1548 // -----------------------------------------------------------------------------    
       
  1549 TBool CMmsDataStore::MmsItemExists( TMsvId aUid )
       
  1550     {
       
  1551     CMsvEntry* entry(NULL);
       
  1552     
       
  1553     // Try to open this item
       
  1554     TRAPD( error, entry = iMsvSession->GetEntryL( aUid ) );
       
  1555     if ( error != KErrNone )
       
  1556         {
       
  1557         return EFalse;
       
  1558         }
       
  1559         
       
  1560     TMsvEntry tEntry = entry->Entry();
       
  1561     TBool result(EFalse);
       
  1562     
       
  1563     if ( tEntry.iType == KUidMsvMessageEntry && tEntry.iMtm == KUidMsgTypeMultimedia )
       
  1564         {
       
  1565         result = ETrue;
       
  1566         }
       
  1567     
       
  1568     delete entry;
       
  1569     
       
  1570     return result;
       
  1571     }
       
  1572     
       
  1573 // -----------------------------------------------------------------------------
       
  1574 // CMmsDataStore::ResolveStatusBits
       
  1575 // Creates status bit field according to TMsvEntry parameter
       
  1576 // -----------------------------------------------------------------------------
       
  1577 TUint8 CMmsDataStore::ResolveStatusBits(TBool aUnread)
       
  1578     {
       
  1579     // Reset the status byte, then find the correct flags
       
  1580     TUint8 data(0);
       
  1581     
       
  1582     // Set status according to the Read/Unread information iCurrentEntry   
       
  1583     if ( aUnread )
       
  1584         {
       
  1585         // Status unset
       
  1586         data &= (~KMMS_Flag_Read);
       
  1587         }
       
  1588     else
       
  1589         { 
       
  1590         // Status set
       
  1591         data |= KMMS_Flag_Read;
       
  1592         }
       
  1593     
       
  1594     return data;
       
  1595     }   
       
  1596     
       
  1597 // -----------------------------------------------------------------------------
       
  1598 // CMmsDataStore::ReadDataRecursively
       
  1599 // Write specified amount of data to the temporary buffer
       
  1600 // -----------------------------------------------------------------------------    
       
  1601 TInt CMmsDataStore::ReadDataRecursively( TDes8& aBuffer )
       
  1602     {
       
  1603     LOGGER_ENTERFN("CMmsDataStore::ReadDataRecursively");
       
  1604     
       
  1605     TInt error(KErrNone);
       
  1606     
       
  1607     TInt freeBuffer = aBuffer.MaxLength() - aBuffer.Length();
       
  1608     
       
  1609     if ( freeBuffer == 0 )
       
  1610         {
       
  1611         LOGGER_WRITE("Destination buffer filled.");
       
  1612         return KErrNone;
       
  1613         }
       
  1614     
       
  1615     if ( iReadPosition == 0 )
       
  1616         {
       
  1617         if ( iLastDataChunk )
       
  1618             {
       
  1619             LOGGER_WRITE("All MMS data read");
       
  1620             iReadAllData = ETrue;
       
  1621             return KErrNone;
       
  1622             }
       
  1623         else
       
  1624             {
       
  1625             error = iCodecClient->GetNextDataPart( iReadDataChunk, iLastDataChunk );
       
  1626             if ( error != KErrNone )
       
  1627                 {
       
  1628                 LOGGER_MSG_EC("iCodecClient->GetNextDataPart failed with %d", error);
       
  1629                 return error;
       
  1630                 }
       
  1631             else
       
  1632                 {
       
  1633                 LOGGER_MSG_EC("iCodecClient->GetNextDataPart succeeded, length %d", iReadDataChunk.Length());
       
  1634                 }   
       
  1635             }   
       
  1636         }
       
  1637         
       
  1638     TInt left = iReadDataChunk.Length() - iReadPosition;    
       
  1639     
       
  1640     if ( freeBuffer < left )
       
  1641         {
       
  1642         TPtrC8 data = iReadDataChunk.Mid(iReadPosition, freeBuffer);
       
  1643         aBuffer.Append(data);
       
  1644         iReadPosition += freeBuffer;
       
  1645         return KErrNone; 
       
  1646         }
       
  1647     else
       
  1648         {
       
  1649         if ( left > 0 )
       
  1650             {
       
  1651             TPtrC8 data = iReadDataChunk.Mid(iReadPosition, left);
       
  1652             aBuffer.Append(data);
       
  1653             }
       
  1654         error = iCodecClient->ReleaseData();
       
  1655         if ( error != KErrNone )
       
  1656             {
       
  1657             return error;
       
  1658             }
       
  1659         iReadPosition = 0;
       
  1660         return ReadDataRecursively( aBuffer );
       
  1661         }           
       
  1662     }   
       
  1663     
       
  1664 // -----------------------------------------------------------------------------
       
  1665 // CMmsDataStore::UpdateMmsStatusL
       
  1666 // Updates MMS message status
       
  1667 // -----------------------------------------------------------------------------
       
  1668 void CMmsDataStore::UpdateMmsStatusL( TMsvId aId, TBool aUnread )
       
  1669     {
       
  1670     CMsvEntry* msvEntry = iMsvSession->GetEntryL( aId );
       
  1671     const TMsvEntry& oldEntry = msvEntry->Entry();
       
  1672     
       
  1673     TMsvEntry newEntry( oldEntry );
       
  1674     newEntry.SetUnread( aUnread );
       
  1675     
       
  1676     CleanupStack::PushL( msvEntry );
       
  1677     msvEntry->ChangeL( newEntry );
       
  1678     CleanupStack::PopAndDestroy( msvEntry );   
       
  1679     }
       
  1680     
       
  1681 // -----------------------------------------------------------------------------
       
  1682 // CMmsDataStore::RegisterUserFoldersL
       
  1683 // Adds user folder messages into the snapshot array
       
  1684 // -----------------------------------------------------------------------------
       
  1685 TInt CMmsDataStore::RegisterUserFoldersL( CSnapshotArray* aSnapshot ) const
       
  1686     {
       
  1687     LOGGER_ENTERFN("CMmsDataStore::RegisterUserFoldersL");     
       
  1688     
       
  1689     // Get the folder   
       
  1690     CMsvEntry* msvEntry = iMsvSession->GetEntryL( KMsvMyFoldersEntryIdValue );
       
  1691     CleanupStack::PushL(msvEntry);
       
  1692     
       
  1693     // Find all of it's childs
       
  1694     CMsvEntrySelection* folders = msvEntry->ChildrenWithTypeL( KUidMsvFolderEntry );
       
  1695     CleanupStack::PopAndDestroy( msvEntry ); 
       
  1696     CleanupStack::PushL( folders );
       
  1697 
       
  1698     for ( TInt index = 0; index < folders->Count(); index++ )
       
  1699         {
       
  1700         TMsvId folderId = folders->At(index);
       
  1701         
       
  1702         if ( folderId != KMsvMyFoldersTemplatesFolderId )
       
  1703             {
       
  1704             TMsvId service;
       
  1705             TMsvEntry folderEntry;
       
  1706             TInt result = iMsvSession->GetEntry( folderId, service, folderEntry );
       
  1707             User::LeaveIfError( result );
       
  1708             
       
  1709             TKeyArrayFix key(iKey);
       
  1710             TBool unread(EFalse);
       
  1711             TSnapshotItem item( (TUint) folderId, folderEntry.Parent(), unread );
       
  1712             item.SetLastChangedDate( folderEntry.iDate );
       
  1713             item.SetFolderNameL( folderEntry.iDetails );
       
  1714             
       
  1715             aSnapshot->InsertIsqL( item, key );
       
  1716             
       
  1717             RegisterFolderL( aSnapshot, folderId );
       
  1718             }
       
  1719         }
       
  1720     
       
  1721     CleanupStack::PopAndDestroy( folders );
       
  1722     
       
  1723     // Register also MMS messages directly under My Folders
       
  1724     RegisterFolderL( aSnapshot, KMsvMyFoldersEntryIdValue );
       
  1725     
       
  1726     LOGGER_LEAVEFN("CMmsDataStore::RegisterUserFoldersL");     
       
  1727     
       
  1728     return KErrNone;
       
  1729     }
       
  1730 
       
  1731 // -----------------------------------------------------------------------------
       
  1732 // CMmsDataStore::CleanUserFoldersL
       
  1733 // Cleans all user folders from MMS messages
       
  1734 // -----------------------------------------------------------------------------
       
  1735 TInt CMmsDataStore::CleanUserFoldersL() 
       
  1736     {
       
  1737     LOGGER_ENTERFN("CMmsDataStore::CleanUserFoldersL");      
       
  1738     
       
  1739     // Get the folder   
       
  1740     CMsvEntry* msvEntry = iMsvSession->GetEntryL( KMsvMyFoldersEntryIdValue );
       
  1741     CleanupStack::PushL(msvEntry);
       
  1742     
       
  1743     // Find all of it's childs
       
  1744     CMsvEntrySelection* folders = msvEntry->ChildrenWithTypeL( KUidMsvFolderEntry );
       
  1745     CleanupStack::PopAndDestroy( msvEntry ); 
       
  1746     CleanupStack::PushL( folders );
       
  1747     
       
  1748     TInt error(KErrNone);
       
  1749     TInt result(KErrNone);
       
  1750 
       
  1751     for ( TInt index = 0; index < folders->Count(); index++ )
       
  1752         {
       
  1753         TMsvId folderId = folders->At(index);
       
  1754         
       
  1755         if ( folderId != KMsvMyFoldersTemplatesFolderId )
       
  1756             {
       
  1757             error = DeleteAllMessagesInFolderL(folderId);
       
  1758             if ( error != KErrNone )
       
  1759                 {
       
  1760                 LOGGER_MSG_EC("Deleting messages in folder failed with %d", error); 
       
  1761                 result = error;
       
  1762                 }
       
  1763             error = iMsvApi->DeleteUserFolderL( folderId );
       
  1764             if ( error != KErrNone && error != KErrInUse )
       
  1765                 {
       
  1766                 // Note: folder is not deleted if contains other message items (like MMS)
       
  1767                 // In this case DeleteUserFolderL returns KErrInUse.
       
  1768                 LOGGER_MSG_EC("iMsvApi->DeleteUserFolderL failed with %d", error);
       
  1769                 result = error;
       
  1770                 }
       
  1771             }
       
  1772         }
       
  1773     
       
  1774     CleanupStack::PopAndDestroy( folders );
       
  1775     
       
  1776     // Delete all messages directly under My Folders
       
  1777     DeleteAllMessagesInFolderL( KMsvMyFoldersEntryIdValue );
       
  1778     
       
  1779     LOGGER_LEAVEFN("CSmsDataStore::CleanUserFoldersL");
       
  1780     
       
  1781     return result;       
       
  1782     }
       
  1783