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