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