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, |
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. |
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 |