emailservices/emailclientapi/src/messageiterator.cpp
branchRCL_3
changeset 24 d189ee25cf9d
parent 8 e1b6206813b4
child 25 3533d4323edc
equal deleted inserted replaced
23:dcf0eedfc1a3 24:d189ee25cf9d
     1 /*
     1 /*
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    16 */
    16 */
    17 
    17 
    18 #include "emailmessage.h"
    18 #include "emailmessage.h"
    19 #include "messageiterator.h"
    19 #include "messageiterator.h"
    20 #include "emailapiutils.h"
    20 #include "emailapiutils.h"
    21 #include "cfsmailplugin.h"
    21 #include "CFSMailPlugin.h"
    22 #include "emailapiutils.h"
    22 #include "emailapiutils.h"
    23 #include "emailclientapi.hrh"
    23 #include "emailclientapi.hrh"
    24 #include "mfsmailiterator.h"
    24 #include "MFSMailIterator.h"
    25 
    25 
    26 // number of messages in chunk to retrive from protocol plugin. Actual chunk
    26 // number of messages in chunk to retrive from protocol plugin. Actual chunk
    27 // size is one less because last element is used for reference to next chunk
    27 // size is one less because last element is used for reference to next chunk
    28 // retrieval. See ReadNextChunkL() for details.
    28 // retrieval. See ReadNextChunkL() for details.
    29 const TInt KMessageChunkSize = 5;
    29 const TInt KMessageChunkSize = 5;
    30 
    30 
    31 const TInt KUndefined = -1;
    31 const TInt KUndefined = -1;
       
    32 
    32 // -----------------------------------------------------------------------------
    33 // -----------------------------------------------------------------------------
    33 // 
    34 // 
    34 // -----------------------------------------------------------------------------
    35 // -----------------------------------------------------------------------------
    35 CMessageIterator* CMessageIterator::NewL( 
    36 CMessageIterator* CMessageIterator::NewL( 
    36     MFSMailIterator* aIterator,
    37     MFSMailIterator* aIterator,
    48 CMessageIterator::~CMessageIterator()
    49 CMessageIterator::~CMessageIterator()
    49     {
    50     {
    50     iPluginData.ReleaseInstance();
    51     iPluginData.ReleaseInstance();
    51     TInt count = iMessageArray.Count();
    52     TInt count = iMessageArray.Count();
    52     iMessageArray.ResetAndDestroy();
    53     iMessageArray.ResetAndDestroy();
    53     for (TInt i = count; i < iFsMessageArray.Count(); i++)
    54     for ( TInt i = count; i < iFsMessageArray.Count(); i++ )
    54         {
    55         {
    55         delete iFsMessageArray[i];
    56         delete iFsMessageArray[i];
    56         }
    57         }
    57     iFsMessageArray.Reset();
    58     iFsMessageArray.Reset();
    58     delete iIterator;
    59     delete iIterator;
    71 // -----------------------------------------------------------------------------
    72 // -----------------------------------------------------------------------------
    72 void CMessageIterator::Release()
    73 void CMessageIterator::Release()
    73     {
    74     {
    74     delete this;
    75     delete this;
    75     }
    76     }
    76                 
    77 
    77 // -----------------------------------------------------------------------------
    78 // -----------------------------------------------------------------------------
    78 // Returns next message
    79 // Returns next message
    79 // Messages are retrieved from protocol plugin in chunks of x messages and
    80 // Messages are retrieved from protocol plugin in chunks of x messages and
    80 // when NextL has be called for x times, next chunk is retrieved. This
    81 // when NextL has be called for x times, next chunk is retrieved. This
    81 // is trade-off between RAM consumption and speed.
    82 // is trade-off between RAM consumption and speed.
    88         if ( !ReadNextChunkL() )
    89         if ( !ReadNextChunkL() )
    89             {
    90             {
    90             // No messages found, 
    91             // No messages found, 
    91             // Reset the cursor and return NULL
    92             // Reset the cursor and return NULL
    92             iCursor = KUndefined;
    93             iCursor = KUndefined;
    93             iStartMsgId = TFSMailMsgId();            
    94             iStartMsgId = TFSMailMsgId();
    94             return NULL;
    95             return NULL;
    95             }
    96             }
    96         // Items found, return the first item in the buffer
    97         // Items found, return the first item in the buffer
    97         iCursor = 0;
    98         iCursor = 0;
    98         }
    99         }
   109 // -----------------------------------------------------------------------------
   110 // -----------------------------------------------------------------------------
   110 MEmailMessage* CMessageIterator::PreviousL()
   111 MEmailMessage* CMessageIterator::PreviousL()
   111     {
   112     {
   112     if ( iCursor == KUndefined )
   113     if ( iCursor == KUndefined )
   113         {
   114         {
   114         iStartMsgId = TFSMailMsgId();            
   115         iStartMsgId = TFSMailMsgId();
   115         // Buffer empty, client should first call NextL
   116         // Buffer empty, client should first call NextL
   116         return NULL; 
   117         return NULL;
   117         }
   118         }
   118     // Iterate to the previous item
   119     // Iterate to the previous item
   119     iCursor--;
   120     iCursor--;
   120     return ReadFromChunkL();
   121     return ReadFromChunkL();
   121     }
   122     }
   122 
   123 
   123 // -----------------------------------------------------------------------------
   124 // -----------------------------------------------------------------------------
   124 // 
   125 // 
   125 // -----------------------------------------------------------------------------
   126 // -----------------------------------------------------------------------------
   126 TBool CMessageIterator::ReadNextChunkL( )
   127 TBool CMessageIterator::ReadNextChunkL()
   127     {
   128     {
       
   129     User::LeaveIfNull( iIterator );
       
   130     
   128     TBool chunkFound = EFalse;
   131     TBool chunkFound = EFalse;
   129 
   132 
   130     // Delete previous items if exist
   133     // Delete previous items if exist
   131     CleanCache();
   134     CleanCache();
   132     iHasMoreNextItems = iIterator->NextL(
   135     iHasMoreNextItems = iIterator->NextL(
   133             iStartMsgId,
   136             iStartMsgId,
   134             KMessageChunkSize, 
   137             KMessageChunkSize,
   135             iFsMessageArray );
   138             iFsMessageArray );
   136     if ( iFsMessageArray.Count() > 0)
   139     if ( iFsMessageArray.Count() > 0 )
   137         {
   140         {
   138         chunkFound = ETrue;
   141         chunkFound = ETrue;
   139         // Set the cursor to the first item 
   142         // Set the cursor to the first item 
   140         iCursor = 0;
   143         iCursor = 0;
   141         iHasMorePrevItems = ETrue;
   144         iHasMorePrevItems = ETrue;
   144     }
   147     }
   145 
   148 
   146 // -----------------------------------------------------------------------------
   149 // -----------------------------------------------------------------------------
   147 // 
   150 // 
   148 // -----------------------------------------------------------------------------
   151 // -----------------------------------------------------------------------------
   149 TBool CMessageIterator::ReadPreviousChunkL( )
   152 TBool CMessageIterator::ReadPreviousChunkL()
   150     {
   153     {
       
   154     User::LeaveIfNull( iIterator );
       
   155 
   151     TBool chunkFound = EFalse;
   156     TBool chunkFound = EFalse;
   152 
   157 
   153     // Delete previous items if exist
   158     // Delete previous items if exist
   154     CleanCache();
   159     CleanCache();
   155     RPointerArray<CFSMailMessage> tmp;
   160     RPointerArray<CFSMailMessage> tmp;
   156     iHasMorePrevItems = iIterator->PreviousL(
   161     iHasMorePrevItems = iIterator->PreviousL(
   157             iStartMsgId,
   162             iStartMsgId,
   158             KMessageChunkSize, 
   163             KMessageChunkSize, 
   159             tmp );
   164             tmp );
   160     TInt count = tmp.Count();
   165     TInt count = tmp.Count();
   161     if ( count > 0)
   166     if ( count > 0 )
   162         {
   167         {
   163         // It seems that items have been found
   168         // It seems that items have been found
   164         // Set the cursor to the end of array
   169         // Set the cursor to the end of array
   165         iCursor = count - 1;
   170         iCursor = count - 1;
   166         iHasMoreNextItems = ETrue;
   171         iHasMoreNextItems = ETrue;
   167         chunkFound = ETrue;
   172         chunkFound = ETrue;
   168         // Revise the order of the buffer.
   173         // Revise the order of the buffer.
   169         // Create complete cache, so it is easier to iterate, 
   174         // Create complete cache, so it is easier to iterate, 
   170         // as now we have to start from the end of cache
   175         // as now we have to start from the end of cache
   171         for (TInt i = count; i > 0; i--)
   176         for ( TInt i = count; i > 0; i-- )
   172             {
   177             {
   173             CFSMailMessage* msg = tmp[i-1];
   178             CFSMailMessage* msg = tmp[i-1];
   174             iFsMessageArray.AppendL( msg );
   179             iFsMessageArray.AppendL( msg );
   175             AddToCacheL( msg );
   180             AddToCacheL( msg );
   176             }        
   181             }
   177         }
   182         }
   178         
   183 
   179     return chunkFound;
   184     return chunkFound;
   180     }
   185     }
   181 
       
   182 
   186 
   183 // -----------------------------------------------------------------------------
   187 // -----------------------------------------------------------------------------
   184 // 
   188 // 
   185 // -----------------------------------------------------------------------------
   189 // -----------------------------------------------------------------------------
   186 MEmailMessage* CMessageIterator::ReadFromChunkL()
   190 MEmailMessage* CMessageIterator::ReadFromChunkL()
   205             // set the cursor to the previous item,
   209             // set the cursor to the previous item,
   206             // and return NULL.
   210             // and return NULL.
   207             iCursor--;
   211             iCursor--;
   208             return NULL;
   212             return NULL;
   209             }
   213             }
   210         }            
   214         }
   211     else if ( iCursor < 0 )
   215     else if ( iCursor < 0 )
   212         {
   216         {
   213         iStartMsgId = iFsMessageArray[0]->GetMessageId();
   217         iStartMsgId = iFsMessageArray[0]->GetMessageId();
   214         if ( iHasMorePrevItems )
   218         if ( iHasMorePrevItems )
   215             {
   219             {
   216             if ( !ReadPreviousChunkL() )
   220             if ( !ReadPreviousChunkL() )
   217                 {
   221                 {
   218                 // Buffer is empty now, client should call nextL, 
   222                 // Buffer is empty now, client should call nextL,
   219                 // and start reading from the start of the buffer
   223                 // and start reading from the start of the buffer
   220                 iCursor = KUndefined;   
   224                 iCursor = KUndefined;
   221                 return NULL;               
   225                 return NULL;
   222                 }
   226                 }
   223             }
   227             }
   224         else
   228         else
   225             {
   229             {
   226             // Buffer is empty now, client should call nextL, 
   230             // Buffer is empty now, client should call nextL,
   227             // and start reading from the start of the buffer
   231             // and start reading from the start of the buffer
   228             iCursor = KUndefined;   
   232             iCursor = KUndefined;   
   229             return NULL;
   233             return NULL;
   230             }
   234             }
   231         }
   235         }
   232    
   236 
   233     if ( iCursor < iFsMessageArray.Count() ) 
   237     if ( iCursor < iFsMessageArray.Count() )
   234         {
   238         {
   235         /* There are items to read in the cache */
   239         /* There are items to read in the cache */
   236         if ( iCursor >= iMessageArray.Count() )
   240         if ( iCursor >= iMessageArray.Count() )
   237             {
   241             {
   238             AddToCacheL( iFsMessageArray[iCursor] );
   242             AddToCacheL( iFsMessageArray[iCursor] );
   239             }
   243             }
   240         return iMessageArray[iCursor];
   244         return iMessageArray[iCursor];
   241         }
   245         }
   242     else
   246     else
   243         {
   247         {
   244         // No more items found, 
   248         // No more items found,
   245         // set the cursor to the previous item,
   249         // set the cursor to the previous item,
   246         // and return NULL.
   250         // and return NULL.
   247         iCursor--;
   251         iCursor--;
   248         return NULL;
   252         return NULL;
   249         }
   253         }
   250     }    
   254     }
   251     
       
   252 
   255 
   253 // -----------------------------------------------------------------------------
   256 // -----------------------------------------------------------------------------
   254 // 
   257 // 
   255 // -----------------------------------------------------------------------------
   258 // -----------------------------------------------------------------------------
   256 void CMessageIterator::AddToCacheL( CFSMailMessage* aFsMsg )
   259 void CMessageIterator::AddToCacheL( CFSMailMessage* aFsMsg )
   257     {
   260     {
   258     CEmailMessage* message = CEmailMessage::NewL( iPluginData, aFsMsg, EAPIOwns );
   261     CEmailMessage* message = CEmailMessage::NewL( iPluginData, aFsMsg, EAPIOwns );
   259     iMessageArray.AppendL(message);    
   262     iMessageArray.AppendL( message );
   260     }
   263     }
   261 
   264 
   262 // -----------------------------------------------------------------------------
   265 // -----------------------------------------------------------------------------
   263 // 
   266 // 
   264 // -----------------------------------------------------------------------------
   267 // -----------------------------------------------------------------------------
   265 void CMessageIterator::CleanCache()
   268 void CMessageIterator::CleanCache()
   266     {
   269     {
   267     // This is strange loop indeed
   270     // This is strange loop indeed
   268     // Both arrays has items that are deleted, iMessageArray has objects that point to iFsMessageArray
   271     // Both arrays has items that are deleted, iMessageArray has objects that point to iFsMessageArray
   269     // Index in both arrays goes syncronously
   272     // Index in both arrays goes syncronously
   270     // To prevent double destruction, first delete iMessageArray onjects and then the rest of the iFsMessageArray 
   273     // To prevent double destruction, first delete iMessageArray onjects and then the rest of the iFsMessageArray
   271     TInt count = iMessageArray.Count();
   274     TInt count = iMessageArray.Count();
   272     iMessageArray.ResetAndDestroy();
   275     iMessageArray.ResetAndDestroy();
   273     for (TInt i = count; i < iFsMessageArray.Count(); i++)
   276     for ( TInt i = count; i < iFsMessageArray.Count(); i++ )
   274         {
   277         {
   275         iFsMessageArray.Remove(count);
   278         iFsMessageArray.Remove( count );
   276         }
   279         }
   277     iFsMessageArray.Reset();    
   280     iFsMessageArray.Reset();    
   278     }
   281     }
   279 // -----------------------------------------------------------------------------
   282 // -----------------------------------------------------------------------------
   280 // 
   283 // 
   295 
   298 
   296 // -----------------------------------------------------------------------------
   299 // -----------------------------------------------------------------------------
   297 // 
   300 // 
   298 // -----------------------------------------------------------------------------
   301 // -----------------------------------------------------------------------------
   299 CMessageIterator::CMessageIterator( 
   302 CMessageIterator::CMessageIterator( 
   300     MFSMailIterator* aIterator, 
   303     MFSMailIterator* aIterator,
   301     CPluginData& aPluginData,
   304     CPluginData& aPluginData,
   302     TUint aCount ) : 
   305     TUint aCount ) :
   303     iIterator( aIterator ), 
   306     iIterator( aIterator ),
   304     iPluginData( aPluginData ), 
   307     iPluginData( aPluginData ),
   305     iStartMsgId( TFSMailMsgId() ),
   308     iStartMsgId( TFSMailMsgId() ),
   306     iState( EReadNextMessageChunk ),
   309     iState( EReadNextMessageChunk ),
   307     iFsMessageArray( KMessageChunkSize ),
   310     iFsMessageArray( KMessageChunkSize ),
   308     iCount( aCount ),
   311     iCount( aCount ),
   309     iCursor ( KUndefined ),
   312     iCursor ( KUndefined ),
   310     iFirstMsgId( TFSMailMsgId() ),
   313     iFirstMsgId( TFSMailMsgId() ),
   311     iHasMoreNextItems( ETrue ),
   314     iHasMoreNextItems( ETrue ),
   312     iHasMorePrevItems( ETrue )    
   315     iHasMorePrevItems( ETrue )
   313     {
   316     {
   314     }
   317     }
   315     
   318 
   316 // End of file.
   319 // End of file