|
1 /* |
|
2 * Copyright (c) 2003 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: This module contains the implementation of CCbsDbImpTopicMessages class |
|
15 * member functions. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDE FILES |
|
22 |
|
23 #include <e32svr.h> |
|
24 |
|
25 #include <shareddataclient.h> |
|
26 |
|
27 #include "CbsServerPanic.h" |
|
28 #include "CbsStreamHelper.h" |
|
29 #include "CbsUtils.h" |
|
30 #include "CbsDbConstants.h" |
|
31 #include "CCbsDbImpTopicList.h" |
|
32 #include "CCbsDbImpTopicMessages.h" |
|
33 #include "CCbsRecEtel.h" |
|
34 #include "CCbsReceiverHelper.h" |
|
35 |
|
36 #include "CbsLogger.h" |
|
37 |
|
38 // CONSTANTS |
|
39 |
|
40 // Expected maximum number of locked messages at once. |
|
41 const TInt KDefaultSpaceForLockedMessages = 1; |
|
42 |
|
43 // CB message header size in bytes. |
|
44 const TInt KCbMessageHeaderSize = 16; |
|
45 |
|
46 // The space used for the header of messages stream |
|
47 const TInt KMessageRootStreamSize = 6; |
|
48 |
|
49 /// The space used by one message in the messages stream |
|
50 const TInt KMessageEntrySize = 3; |
|
51 |
|
52 // Default space reserved for topic messages in message stream |
|
53 const TInt KDefaultSpaceForMessages = 6; |
|
54 |
|
55 // Space for reading messages |
|
56 const TInt KReadMessageSize = 92; |
|
57 |
|
58 |
|
59 // ================= MEMBER FUNCTIONS ======================= |
|
60 |
|
61 // ----------------------------------------------------------------------------- |
|
62 // CCbsDbImpTopicMessages::CCbsDbImpTopicMessages |
|
63 // C++ default constructor can NOT contain any code, that |
|
64 // might leave. |
|
65 // ----------------------------------------------------------------------------- |
|
66 // |
|
67 CCbsDbImpTopicMessages::CCbsDbImpTopicMessages( |
|
68 CCbsDbImpTopicList& aTopicList, |
|
69 RFs& aFs ) |
|
70 :iTopicList( aTopicList ), |
|
71 iCacheValid( EFalse ), |
|
72 iCachedTopicNumber( 0 ), |
|
73 iFs( aFs ) |
|
74 { |
|
75 } |
|
76 |
|
77 // ----------------------------------------------------------------------------- |
|
78 // CCbsDbImpTopicMessages::ConstructL |
|
79 // Symbian 2nd phase constructor can leave. |
|
80 // ----------------------------------------------------------------------------- |
|
81 // |
|
82 void CCbsDbImpTopicMessages::ConstructL() |
|
83 { |
|
84 // Allocate the default size for the message list. |
|
85 iMessageList = |
|
86 new ( ELeave ) CArrayFixFlat< TCbsDbImpTopicMessagesCacheItem > |
|
87 ( KCbsDbMaxReceivedMessages + KCbsDbMaxSavedMessages ); |
|
88 |
|
89 // Allocate the array for locked messages. |
|
90 iLockedMessages = new ( ELeave ) CArrayFixFlat< TCbsDbMessageHandle > |
|
91 ( KDefaultSpaceForLockedMessages ); |
|
92 } |
|
93 |
|
94 // ----------------------------------------------------------------------------- |
|
95 // CCbsDbImpTopicMessages::NewL |
|
96 // Two-phased constructor. |
|
97 // ----------------------------------------------------------------------------- |
|
98 // |
|
99 CCbsDbImpTopicMessages* CCbsDbImpTopicMessages::NewL( |
|
100 CCbsDbImpTopicList& aTopicList, RFs& aFs ) |
|
101 { |
|
102 CCbsDbImpTopicMessages* self = |
|
103 new ( ELeave ) CCbsDbImpTopicMessages( aTopicList, aFs ); |
|
104 CleanupStack::PushL( self ); |
|
105 self->ConstructL(); |
|
106 CleanupStack::Pop(); |
|
107 return self; |
|
108 } |
|
109 |
|
110 |
|
111 // Destructor |
|
112 CCbsDbImpTopicMessages::~CCbsDbImpTopicMessages() |
|
113 { |
|
114 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::~CCbsDbImpTopicMessages()"); |
|
115 // Invalidate cache. |
|
116 InvalidateCache(); |
|
117 |
|
118 // And then delete the message list. |
|
119 delete iMessageList; |
|
120 |
|
121 // Delete locked messages. |
|
122 delete iLockedMessages; |
|
123 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::~CCbsDbImpTopicMessages()"); |
|
124 } |
|
125 |
|
126 // ----------------------------------------------------------------------------- |
|
127 // CCbsDbImpTopicMessages::InvalidateCache |
|
128 // Resets the cache to default values. |
|
129 // (other items were commented in a header). |
|
130 // ----------------------------------------------------------------------------- |
|
131 // |
|
132 void CCbsDbImpTopicMessages::InvalidateCache() |
|
133 { |
|
134 // Initialize members back to default. |
|
135 iCacheValid = EFalse; |
|
136 iCachedTopicNumber = 0; |
|
137 |
|
138 // Resize the message list. After the call is made, the |
|
139 // array is empty. |
|
140 if ( iMessageList ) |
|
141 { |
|
142 iMessageList->Reset(); |
|
143 } |
|
144 } |
|
145 |
|
146 // ----------------------------------------------------------------------------- |
|
147 // CCbsDbImpTopicMessages::InvalidateCacheIfTopic |
|
148 // Resets the cache to default values. |
|
149 // (other items were commented in a header). |
|
150 // ----------------------------------------------------------------------------- |
|
151 // |
|
152 void CCbsDbImpTopicMessages::InvalidateCacheIfTopic( |
|
153 const TCbsDbTopicNumber& aNumber ) |
|
154 { |
|
155 // Check the handle and then invalidate |
|
156 if ( iCachedTopicNumber == aNumber ) |
|
157 { |
|
158 InvalidateCache(); |
|
159 } |
|
160 } |
|
161 |
|
162 // ----------------------------------------------------------------------------- |
|
163 // CCbsDbImpTopicMessages::CreateDefaultTopicMessagesStreamL |
|
164 // Creates a default topic messages stream. |
|
165 // (other items were commented in a header). |
|
166 // ----------------------------------------------------------------------------- |
|
167 // |
|
168 TStreamId CCbsDbImpTopicMessages::CreateDefaultTopicMessagesStreamL( |
|
169 CStreamStore& aStore ) |
|
170 { |
|
171 // Create the stream. |
|
172 RStoreWriteStream outstream; |
|
173 TStreamId id = outstream.CreateLC( aStore ); // on CS |
|
174 |
|
175 // Write total amount of messages. |
|
176 outstream.WriteInt16L( 0 ); |
|
177 |
|
178 // Write total amount of space for messages. |
|
179 outstream.WriteInt16L( KDefaultSpaceForMessages ); |
|
180 |
|
181 for ( TInt index( 0 ); index < KDefaultSpaceForMessages; index++ ) |
|
182 { |
|
183 // "Saved"-flag |
|
184 CbsStreamHelper::WriteBoolL( outstream, EFalse ); |
|
185 // Write message stream id. |
|
186 outstream << TStreamId( 0 ); |
|
187 } |
|
188 |
|
189 outstream.CommitL(); |
|
190 CleanupStack::PopAndDestroy(); // outstream |
|
191 |
|
192 return id; |
|
193 } |
|
194 |
|
195 // ----------------------------------------------------------------------------- |
|
196 // CCbsDbImpTopicMessages::CreateDefaultTopicMessagesStreamL |
|
197 // Delete all topics messages. |
|
198 // (other items were commented in a header). |
|
199 // ----------------------------------------------------------------------------- |
|
200 // |
|
201 void CCbsDbImpTopicMessages::DeleteAllTopicMessagesL( |
|
202 CStreamStore& aSavedStore, |
|
203 CStreamStore& aUnsavedStore, |
|
204 RReadStream& aIn ) |
|
205 { |
|
206 // Read total amount of messages. |
|
207 TInt total( aIn.ReadInt16L() ); |
|
208 |
|
209 // Skip space for messages. |
|
210 aIn.ReadInt16L(); |
|
211 |
|
212 // Now, delete all streams.. |
|
213 for ( TInt index( 0 ); index < total; index++ ) |
|
214 { |
|
215 |
|
216 TBool isSaved( CbsStreamHelper::ReadBoolL( aIn ) ); |
|
217 TStreamId id; |
|
218 |
|
219 // Read stream id. |
|
220 aIn >> id; |
|
221 CStreamStore& store = isSaved ? aSavedStore : aUnsavedStore; |
|
222 store.DeleteL( id ); |
|
223 } |
|
224 } |
|
225 |
|
226 // ----------------------------------------------------------------------------- |
|
227 // CCbsDbImpTopicMessages::IsLockedMessagesInTopic |
|
228 // Determines whether or not there are any locked messages in |
|
229 // the topic. |
|
230 // (other items were commented in a header). |
|
231 // ----------------------------------------------------------------------------- |
|
232 // |
|
233 TBool CCbsDbImpTopicMessages::IsLockedMessagesInTopic( |
|
234 const TCbsDbTopicNumber& aNumber ) const |
|
235 { |
|
236 TBool result( EFalse ); |
|
237 |
|
238 // Checks whether or not there is a locked message in the topic. |
|
239 TInt count( iLockedMessages->Count() ); |
|
240 for ( TInt index( 0 ); index < count; index++ ) |
|
241 { |
|
242 if ( iTopicList.ExtractTopicNumber( |
|
243 iLockedMessages->At( index ) ) == aNumber ) |
|
244 { |
|
245 result = ETrue; |
|
246 } |
|
247 } |
|
248 return result; |
|
249 } |
|
250 |
|
251 // ----------------------------------------------------------------------------- |
|
252 // CCbsDbImpTopicMessages::IsLockedMessages |
|
253 // Determines whether there is at least one locked message. |
|
254 // Returns ETrue, if there are any locked messages in the |
|
255 // database. |
|
256 // (other items were commented in a header). |
|
257 // ----------------------------------------------------------------------------- |
|
258 // |
|
259 TBool CCbsDbImpTopicMessages::IsLockedMessages() const |
|
260 { |
|
261 return ( iLockedMessages->Count() > 0 ); |
|
262 } |
|
263 |
|
264 // ----------------------------------------------------------------------------- |
|
265 // CCbsDbImpTopicMessages::GetMessageCountL |
|
266 // Returns the total amount of messages the topic contains. |
|
267 // (other items were commented in a header). |
|
268 // ----------------------------------------------------------------------------- |
|
269 // |
|
270 void CCbsDbImpTopicMessages::GetMessageCountL( |
|
271 const TCbsDbTopicNumber& aNumber, |
|
272 TInt& aCount ) |
|
273 { |
|
274 // Load cache. |
|
275 LoadCacheL( aNumber ); |
|
276 |
|
277 // and then get the message count. |
|
278 aCount = iMessageList->Count(); |
|
279 } |
|
280 |
|
281 // ----------------------------------------------------------------------------- |
|
282 // CCbsDbImpTopicMessages::GetMessageL |
|
283 // Returns message information. |
|
284 // Returns the message matching the given |
|
285 // index value. Leaves if the index is not valid. |
|
286 // (other items were commented in a header). |
|
287 // ----------------------------------------------------------------------------- |
|
288 // |
|
289 void CCbsDbImpTopicMessages::GetMessageL( |
|
290 const TCbsDbTopicNumber& aNumber, |
|
291 TInt aIndex, |
|
292 TCbsDbMessage& aMessage ) |
|
293 { |
|
294 // Load the cache. |
|
295 LoadCacheL( aNumber ); |
|
296 |
|
297 // Check if the index is not valid. |
|
298 if ( ( aIndex < 0 ) || ( aIndex >= iMessageList->Count() ) ) |
|
299 { |
|
300 User::Leave( KErrNotFound ); |
|
301 } |
|
302 |
|
303 // Load the message. |
|
304 LoadMessageL( aIndex, aMessage ); |
|
305 } |
|
306 |
|
307 // ----------------------------------------------------------------------------- |
|
308 // CCbsDbImpTopicMessages::FindMessageByHandleL |
|
309 // Finds the message for given handle and returns it. |
|
310 // Returns the message matching the given |
|
311 // index value. |
|
312 // (other items were commented in a header). |
|
313 // ----------------------------------------------------------------------------- |
|
314 // |
|
315 void CCbsDbImpTopicMessages::FindMessageByHandleL( |
|
316 const TCbsDbMessageHandle& aHandle, |
|
317 TCbsDbMessage& aMessage ) |
|
318 { |
|
319 // Load cache |
|
320 LoadCacheL( iTopicList.ExtractTopicNumber( aHandle ) ); |
|
321 |
|
322 // Load message |
|
323 LoadMessageL( FindMessagePositionByHandleL( aHandle ), aMessage ); |
|
324 } |
|
325 |
|
326 // ----------------------------------------------------------------------------- |
|
327 // CCbsDbImpTopicMessages::GetMessageContentsL |
|
328 // Returns the contents of a message. |
|
329 // Stores the contents of the message to the buffer aContents. |
|
330 // If aContents is too small to contain the whole message |
|
331 // body, the message body is truncated. |
|
332 // (other items were commented in a header). |
|
333 // ----------------------------------------------------------------------------- |
|
334 // |
|
335 void CCbsDbImpTopicMessages::GetMessageContentsL( |
|
336 const TCbsDbMessageHandle& aHandle, |
|
337 TPtr& aContents, |
|
338 TUint aSize ) |
|
339 { |
|
340 LoadCacheL( iTopicList.ExtractTopicNumber( aHandle ) ); |
|
341 |
|
342 TInt position( FindMessagePositionByHandleL( aHandle ) ); |
|
343 |
|
344 TCbsDbMessage message; |
|
345 LoadMessageL( position, message ); |
|
346 |
|
347 LoadMessageContentsL( iMessageList->At( position ).iContentsId, |
|
348 aContents, message.iPermanent, aSize ); |
|
349 } |
|
350 |
|
351 // ----------------------------------------------------------------------------- |
|
352 // CCbsDbImpTopicMessages::DeleteMessageL |
|
353 // Deletes a message. Leaves if the message is protected |
|
354 // (other items were commented in a header). |
|
355 // ----------------------------------------------------------------------------- |
|
356 // |
|
357 void CCbsDbImpTopicMessages::DeleteMessageL( |
|
358 const TCbsDbMessageHandle& aHandle, |
|
359 const CCbsRecEtel& aReceiver ) |
|
360 { |
|
361 // Get the topic handle. |
|
362 LoadCacheL( iTopicList.ExtractTopicNumber( aHandle ) ); |
|
363 |
|
364 // Check if the message is locked. |
|
365 if ( IsMessageLocked( aHandle ) ) |
|
366 { |
|
367 // Yes, leave. |
|
368 User::Leave( KErrAccessDenied ); |
|
369 } |
|
370 else |
|
371 { |
|
372 // Otherwise, delete. |
|
373 TRAPD( error, DoDeleteMessageL( |
|
374 FindMessagePositionByHandleL( aHandle ) ) ); |
|
375 |
|
376 if ( error != KErrNone ) |
|
377 { |
|
378 // Failed. |
|
379 RevertFileOperationL( error ); |
|
380 } |
|
381 else |
|
382 { |
|
383 // Update the soft notification dialog, if topic is hotmarked |
|
384 UpdateSoftNotificationL( aHandle, aReceiver ); |
|
385 } |
|
386 } |
|
387 |
|
388 iTopicList.NotifyTopicModifiedL( |
|
389 iTopicList.ExtractTopicNumber( aHandle ) ); |
|
390 } |
|
391 |
|
392 // ----------------------------------------------------------------------------- |
|
393 // CCbsDbImpTopicMessages::AddMessageL |
|
394 // Creates a new message to the topic. |
|
395 // Stores a handle to the message in aHandle. |
|
396 // FFS critical level check is made prior to operation. |
|
397 // (other items were commented in a header). |
|
398 // ----------------------------------------------------------------------------- |
|
399 // |
|
400 void CCbsDbImpTopicMessages::AddMessageL( |
|
401 const TCbsDbTopicNumber& aNumber, |
|
402 TCbsDbMessage& aMessage, |
|
403 const TPtrC& aContents ) |
|
404 { |
|
405 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::AddMessageL()"); |
|
406 |
|
407 LoadCacheL( aNumber ); |
|
408 |
|
409 aMessage.iLength = aContents.Length(); |
|
410 CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::AddMessageL(): Content length: %d.", aMessage.iLength ); |
|
411 |
|
412 // Generate a new message handle. |
|
413 aMessage.iHandle = GenerateNewMessageHandle( aNumber ); |
|
414 |
|
415 // Make sure that the message is not inserted as permanent |
|
416 aMessage.iPermanent = EFalse; |
|
417 |
|
418 TRAPD( error, DoAddMessageL( aMessage, aContents ) ); |
|
419 if ( error != KErrNone ) |
|
420 { |
|
421 CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::AddMessageL(): DoAddMessageL() failed, error: %d.", error ); |
|
422 |
|
423 // Failed. |
|
424 RevertFileOperationL( error ); |
|
425 |
|
426 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::AddMessageL(): RevertFileOperationL() finished OK." ); |
|
427 } |
|
428 |
|
429 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::AddMessageL()"); |
|
430 } |
|
431 |
|
432 // ----------------------------------------------------------------------------- |
|
433 // CCbsDbImpTopicMessages::SaveMessageL |
|
434 // Saves a message. |
|
435 // This operation is called "keeping" in the UI. |
|
436 // The CBS server has a global limit for saved |
|
437 // messages. The function leaves, if this is exceeded. |
|
438 // A saved message has it's permanent-flag raised. |
|
439 // FFS critical level check is made prior to the operation. |
|
440 // (other items were commented in a header). |
|
441 // ----------------------------------------------------------------------------- |
|
442 // |
|
443 void CCbsDbImpTopicMessages::SaveMessageL( |
|
444 const TCbsDbMessageHandle& aHandle, |
|
445 const CCbsRecEtel& aReceiver ) |
|
446 { |
|
447 // Load cache. |
|
448 TCbsTopicNumber topicNumber( iTopicList.ExtractTopicNumber( aHandle ) ); |
|
449 LoadCacheL( topicNumber ); |
|
450 |
|
451 // Now find message by handle. |
|
452 TInt position( FindMessagePositionByHandleL( aHandle ) ); |
|
453 |
|
454 TCbsDbMessage message; |
|
455 LoadMessageL( position, message ); |
|
456 TStreamId contentsId( iMessageList->At( position ).iContentsId ); |
|
457 |
|
458 // This function should not be called if the message is already permanent. |
|
459 if ( message.iPermanent ) |
|
460 { |
|
461 User::Leave( KErrAlreadyExists ); |
|
462 } |
|
463 |
|
464 // Check that the limit for maximum saved messages/topic is not exceeded. |
|
465 TCbsDbTopic topic; |
|
466 iTopicList.FindTopicByNumberL( topicNumber, topic ); |
|
467 if ( iTopicList.TotalSavedMessages() >= KCbsDbMaxSavedMessages ) |
|
468 { |
|
469 User::Leave( KErrOverflow ); |
|
470 } |
|
471 |
|
472 // FFS critical level check (header is 16 bytes, message coded in Unicode) |
|
473 CbsUtils::FFSCriticalLevelCheckL( KCbMessageHeaderSize + |
|
474 2 * message.iLength, iFs ); |
|
475 |
|
476 // Create a temporary buffer for message body and load the contents into |
|
477 // the buffer. |
|
478 HBufC* buffer = HBufC::NewLC( message.iLength ); // on CS |
|
479 TPtr contentPtr( buffer->Des() ); |
|
480 LoadMessageContentsL( contentsId, contentPtr, EFalse, message.iLength ); |
|
481 |
|
482 // Delete message's previous header and body streams. |
|
483 TCbsDbImpTopicMessagesCacheItem item( iMessageList->At( position ) ); |
|
484 |
|
485 TRAPD( result, DoSaveMessageL( message, item, contentPtr, position ) ); |
|
486 CleanupStack::PopAndDestroy( buffer ); |
|
487 if ( result != KErrNone ) |
|
488 { |
|
489 RevertFileOperationL( result ); |
|
490 } |
|
491 else |
|
492 { |
|
493 iTopicList.NotifyTopicModifiedL( |
|
494 iTopicList.ExtractTopicNumber( aHandle ) ); |
|
495 |
|
496 // Update the soft notification dialog, if topic is hotmarked |
|
497 UpdateSoftNotificationL( aHandle, aReceiver ); |
|
498 } |
|
499 } |
|
500 |
|
501 // ----------------------------------------------------------------------------- |
|
502 // CCbsDbImpTopicMessages::DoSaveMessageL |
|
503 // Saves a message. |
|
504 // (other items were commented in a header). |
|
505 // ----------------------------------------------------------------------------- |
|
506 // |
|
507 void CCbsDbImpTopicMessages::DoSaveMessageL( |
|
508 TCbsDbMessage& aMessage, |
|
509 const TCbsDbImpTopicMessagesCacheItem& aItem, |
|
510 const TDesC& aContentPtr, |
|
511 TInt aPosition ) |
|
512 { |
|
513 CFileStore* store = iTopicList.UnsavedMessagesStore(); |
|
514 store->Delete( aItem.iId ); |
|
515 store->Delete( aItem.iContentsId ); |
|
516 |
|
517 TBool needToUpdateReadCounter( EFalse ); |
|
518 aMessage.iPermanent = ETrue; |
|
519 if ( !aMessage.iRead ) |
|
520 { |
|
521 needToUpdateReadCounter = ETrue; |
|
522 aMessage.iRead = ETrue; |
|
523 } |
|
524 |
|
525 // Create new streams for message header and body. |
|
526 TStreamId contentsStream( CreateMessageContentsStreamL( |
|
527 *iTopicList.TopicStoreL(), aContentPtr ) ); |
|
528 TStreamId messageStream( CreateMessageStreamL( |
|
529 *iTopicList.TopicStoreL(), aMessage, contentsStream ) ); |
|
530 |
|
531 // Update message's cache item information. |
|
532 TCbsDbImpTopicMessagesCacheItem& item = iMessageList->At( aPosition ); |
|
533 item.iContentsId = contentsStream; |
|
534 item.iId = messageStream; |
|
535 item.iIsSaved = ETrue; |
|
536 item.iMessage = aMessage; |
|
537 |
|
538 // Update topic messages stream; the cache item is saved into the stream. |
|
539 UpdateTopicMessagesStreamL( EFalse ); |
|
540 |
|
541 iTopicList.InformMessageSavedL( aMessage.iHandle ); |
|
542 if ( needToUpdateReadCounter ) |
|
543 { |
|
544 iTopicList.InformUnreadMessageReadL( aMessage.iHandle ); |
|
545 } |
|
546 |
|
547 // Commit changes to both files. |
|
548 iTopicList.CommitFilesL(); |
|
549 } |
|
550 |
|
551 // ----------------------------------------------------------------------------- |
|
552 // CCbsDbImpTopicMessages::ReadMessageL |
|
553 // Marks the message read |
|
554 // (other items were commented in a header). |
|
555 // ----------------------------------------------------------------------------- |
|
556 // |
|
557 void CCbsDbImpTopicMessages::ReadMessageL( |
|
558 const TCbsDbMessageHandle& aHandle, |
|
559 const CCbsRecEtel& aReceiver ) |
|
560 { |
|
561 //Checked that there is space for writing data on FFS. |
|
562 CbsUtils::FFSCriticalLevelCheckL( KReadMessageSize, iFs ); |
|
563 |
|
564 // Load cache. |
|
565 TCbsDbTopicNumber topicNum( iTopicList.ExtractTopicNumber( aHandle ) ); |
|
566 LoadCacheL( topicNum ); |
|
567 |
|
568 // Now find message by handle. |
|
569 TInt position( FindMessagePositionByHandleL( aHandle ) ); |
|
570 |
|
571 TCbsDbMessage message; |
|
572 LoadMessageL( position, message ); |
|
573 TStreamId contentsId( iMessageList->At( position ).iContentsId ); |
|
574 TStreamId id( iMessageList->At( position ).iId ); |
|
575 |
|
576 // Check if the message is already read, then there is nothing more to do. |
|
577 if ( !message.iRead ) |
|
578 { |
|
579 message.iRead = ETrue; |
|
580 |
|
581 TRAPD( error, DoReadMessageL( id, message, contentsId ) ); |
|
582 if ( error == KErrNone ) |
|
583 { |
|
584 iMessageList->At( position ).iMessage = message; |
|
585 |
|
586 iTopicList.NotifyTopicModifiedL( |
|
587 iTopicList.ExtractTopicNumber( aHandle ) ); |
|
588 |
|
589 // Update the soft notification dialog, if topic is hotmarked |
|
590 UpdateSoftNotificationL( aHandle, aReceiver ); |
|
591 } |
|
592 else |
|
593 { |
|
594 RevertFileOperationL( error ); |
|
595 } |
|
596 } |
|
597 } |
|
598 |
|
599 // ----------------------------------------------------------------------------- |
|
600 // CCbsDbImpTopicMessages::UpdateHandlesOfTopicMessagesL |
|
601 // Updates handles of messages in the topic with the number given in |
|
602 // aOldTopicNumber to match new topic number. |
|
603 // Traverses through the given topic processing |
|
604 // each message stream encountered. Since the topic number is |
|
605 // the primary key and previous message handles can be assumed |
|
606 // to be unique, updating the high word of the handle to |
|
607 // match the new topic number is adequate. |
|
608 // (other items were commented in a header). |
|
609 // ----------------------------------------------------------------------------- |
|
610 // |
|
611 void CCbsDbImpTopicMessages::UpdateHandlesOfTopicMessagesL( |
|
612 const TCbsDbTopicNumber& aOldTopicNumber, |
|
613 const TCbsDbTopicNumber& aNewTopicNumber ) |
|
614 { |
|
615 LoadCacheL( aOldTopicNumber ); |
|
616 |
|
617 TInt msgs( iMessageList->Count() ); |
|
618 |
|
619 for ( TInt i( 0 ); i < msgs; i++ ) |
|
620 { |
|
621 // Fetch message at this position |
|
622 TCbsDbMessage message; |
|
623 LoadMessageL( i, message ); |
|
624 TStreamId contentsStreamId( iMessageList->At( i ).iContentsId ); |
|
625 TStreamId messageStreamId( iMessageList->At( i ).iId ); |
|
626 |
|
627 // Insert new topic number as the high word of the handle |
|
628 message.iHandle = ( aNewTopicNumber << 16 ) | |
|
629 ( message.iHandle & 0xFFFF ); |
|
630 DoUpdateMessageL( messageStreamId, message, contentsStreamId ); |
|
631 } |
|
632 } |
|
633 |
|
634 // ----------------------------------------------------------------------------- |
|
635 // CCbsDbImpTopicMessages::LockMessageL |
|
636 // Unlocks one message and then locks another message. |
|
637 // Message that is locked can not be removed. Topic that |
|
638 // contains a locked message can not be removed. |
|
639 // Note that locking status is not persistent in the sense that |
|
640 // when the power is switched off and turned on, no messages |
|
641 // are automatically locked. |
|
642 // (other items were commented in a header). |
|
643 // ----------------------------------------------------------------------------- |
|
644 // |
|
645 void CCbsDbImpTopicMessages::LockMessageL( |
|
646 const TCbsDbMessageHandle& aUnlock, |
|
647 const TCbsDbMessageHandle& aLock ) |
|
648 { |
|
649 // Check if the message exists: leave if not found, ignore return value |
|
650 if ( aLock != 0 ) |
|
651 { |
|
652 TCbsDbMessage message; |
|
653 TInt position( FindMessagePositionByHandleL( aLock ) ); |
|
654 LoadMessageL( position, message ); |
|
655 } |
|
656 |
|
657 TBool unlockNull( ETrue ); |
|
658 |
|
659 if ( aUnlock != 0 ) |
|
660 { |
|
661 DeleteFromLocked( aUnlock ); |
|
662 unlockNull = EFalse; |
|
663 } |
|
664 |
|
665 if ( aLock != 0 ) |
|
666 { |
|
667 InsertToLockedL( aLock ) ; |
|
668 } |
|
669 |
|
670 if ( unlockNull == EFalse ) |
|
671 { |
|
672 LoadCacheL( iTopicList.ExtractTopicNumber( aUnlock ) ); |
|
673 } |
|
674 } |
|
675 |
|
676 // ----------------------------------------------------------------------------- |
|
677 // CCbsDbImpTopicMessages::GetNextAndPrevMsgHandleL |
|
678 // Returns the handles of the next and previous message |
|
679 // when given a current message. |
|
680 // (other items were commented in a header). |
|
681 // ----------------------------------------------------------------------------- |
|
682 // |
|
683 void CCbsDbImpTopicMessages::GetNextAndPrevMsgHandleL( |
|
684 const TCbsDbMessageHandle& aCurrentMsg, |
|
685 TCbsDbMessageHandle& aNextMsg, |
|
686 TCbsDbMessageHandle& aPrevMsg, |
|
687 TInt& aPosition) |
|
688 { |
|
689 LoadCacheL( iTopicList.ExtractTopicNumber( aCurrentMsg ) ); |
|
690 |
|
691 // Load the current message |
|
692 TInt index( FindMessagePositionByHandleL( aCurrentMsg ) ); |
|
693 |
|
694 // Reset position indications |
|
695 aPosition = 0; |
|
696 |
|
697 // Retrieve position indications and message handles |
|
698 if ( index == 0 ) |
|
699 { |
|
700 aPosition |= ECbsHead; |
|
701 } |
|
702 else |
|
703 { |
|
704 TCbsDbMessage prevMessage; |
|
705 LoadMessageL( index - 1, prevMessage ); |
|
706 aPrevMsg = prevMessage.iHandle; |
|
707 } |
|
708 |
|
709 // If index points to the last element of iMessageList, |
|
710 // raise flag ECbsTail. |
|
711 if ( index == iMessageList->Count()-1 ) |
|
712 { |
|
713 aPosition |= ECbsTail; |
|
714 } |
|
715 else |
|
716 { |
|
717 TCbsDbMessage nextMessage; |
|
718 LoadMessageL( index+1, nextMessage ); |
|
719 aNextMsg = nextMessage.iHandle; |
|
720 } |
|
721 } |
|
722 |
|
723 // ----------------------------------------------------------------------------- |
|
724 // CCbsDbImpTopicMessages::DoAddMessageL |
|
725 // Inserts a message into the database. |
|
726 // (other items were commented in a header). |
|
727 // ----------------------------------------------------------------------------- |
|
728 // |
|
729 void CCbsDbImpTopicMessages::DoAddMessageL( |
|
730 TCbsDbMessage& aMessage, |
|
731 const TDesC& aContents ) |
|
732 { |
|
733 // Cache is assumed to be loaded. Message is assumed not to |
|
734 // already exist in the DB. |
|
735 CFileStore* store = aMessage.iPermanent ? |
|
736 iTopicList.TopicStoreL() : iTopicList.UnsavedMessagesStore(); |
|
737 |
|
738 if ( aMessage.iPermanent ) |
|
739 { |
|
740 // About to write to FFS: make critical level check. |
|
741 // Message is in Unicode characters, so its size |
|
742 // is double the length. |
|
743 CbsUtils::FFSCriticalLevelCheckL( KCbMessageHeaderSize + |
|
744 2 * aMessage.iLength, iFs ); |
|
745 } |
|
746 else |
|
747 { |
|
748 CbsUtils::VolumeCriticalLevelCheckL( |
|
749 iTopicList.UnsavedMessagesFilename(), |
|
750 KCbMessageHeaderSize + 2 * aMessage.iLength, iFs ); |
|
751 } |
|
752 |
|
753 // Create stream for contents. |
|
754 TStreamId contentsStream( CreateMessageContentsStreamL( |
|
755 *store, aContents ) ); |
|
756 |
|
757 // Now we have to find the position to which the message should be |
|
758 // inserted. |
|
759 TInt positionToBeInserted( -1 ); |
|
760 |
|
761 TTime messageTime( aMessage.iDateTime ); |
|
762 TInt index( 0 ); |
|
763 |
|
764 // Go through all messages in topic and find the position. |
|
765 TInt count( iMessageList->Count() ); |
|
766 for ( ; index < count && positionToBeInserted == -1; index++ ) |
|
767 { |
|
768 TCbsDbMessage message; |
|
769 LoadMessageL( index, message ); |
|
770 |
|
771 TTime tmp( message.iDateTime ); |
|
772 |
|
773 if ( tmp <= messageTime ) |
|
774 { |
|
775 positionToBeInserted = index; |
|
776 } |
|
777 } |
|
778 |
|
779 // If we looped through, append |
|
780 if ( positionToBeInserted == -1 ) |
|
781 { |
|
782 positionToBeInserted = index; |
|
783 } |
|
784 |
|
785 // Create message stream. |
|
786 TStreamId messageStream( CreateMessageStreamL( *store, |
|
787 aMessage, contentsStream ) ); |
|
788 |
|
789 // Add to internal cache. |
|
790 TCbsDbImpTopicMessagesCacheItem item; |
|
791 |
|
792 item.iId = messageStream; |
|
793 item.iIsMessage = EFalse; |
|
794 item.iIsSaved = aMessage.iPermanent; |
|
795 |
|
796 iMessageList->InsertL( positionToBeInserted, item ); |
|
797 |
|
798 // Check if message should be deleted. |
|
799 DeleteReceivedIfNecessaryL(); |
|
800 |
|
801 // Update topic messages stream. |
|
802 UpdateTopicMessagesStreamL( EFalse ); |
|
803 |
|
804 // Update counters. |
|
805 iTopicList.InformNewMessageReceivedL( aMessage.iHandle ); |
|
806 |
|
807 // Commit changes to both stores. |
|
808 iTopicList.CommitFilesL(); |
|
809 |
|
810 // Inform observers. Done after commit to make sure there's |
|
811 // a message to inform of. |
|
812 iTopicList.NotifyNewMessageArrivedL( aMessage.iHandle ); |
|
813 } |
|
814 |
|
815 // ----------------------------------------------------------------------------- |
|
816 // CCbsDbImpTopicMessages::DoDeleteMessageL |
|
817 // Deletes a message from the database. |
|
818 // (other items were commented in a header). |
|
819 // ----------------------------------------------------------------------------- |
|
820 // |
|
821 void CCbsDbImpTopicMessages::DoDeleteMessageL( |
|
822 TInt aPosition ) |
|
823 { |
|
824 TCbsDbMessage message; |
|
825 LoadMessageL( aPosition, message ); |
|
826 |
|
827 // Delete the message, if it is possible. |
|
828 DeleteMessageByPositionL( aPosition ); |
|
829 DeleteReceivedIfNecessaryL(); |
|
830 UpdateTopicMessagesStreamL( ETrue ); |
|
831 |
|
832 // Inform the topic list about deletion. |
|
833 iTopicList.InformMessageDeletedL( message.iHandle, |
|
834 message.iPermanent, message.iRead ); |
|
835 |
|
836 iTopicList.CommitFilesL(); |
|
837 } |
|
838 |
|
839 // ----------------------------------------------------------------------------- |
|
840 // CCbsDbImpTopicMessages::DoUpdateMessageL |
|
841 // Updates the information for a message. |
|
842 // (other items were commented in a header). |
|
843 // ----------------------------------------------------------------------------- |
|
844 // |
|
845 void CCbsDbImpTopicMessages::DoUpdateMessageL( |
|
846 const TStreamId& aId, |
|
847 const TCbsDbMessage& aMessage, |
|
848 const TStreamId& aContentsId ) const |
|
849 { |
|
850 // Update the stream contents. |
|
851 CFileStore* store = aMessage.iPermanent ? |
|
852 iTopicList.TopicStoreL() : iTopicList.UnsavedMessagesStore(); |
|
853 |
|
854 RStoreWriteStream outstream; |
|
855 outstream.ReplaceLC( *store, aId ); // on CS |
|
856 |
|
857 WriteMessageInformationL( outstream, aMessage, aContentsId ); |
|
858 |
|
859 outstream.CommitL(); |
|
860 CleanupStack::PopAndDestroy(); // outstream |
|
861 } |
|
862 |
|
863 // ----------------------------------------------------------------------------- |
|
864 // CCbsDbImpTopicMessages::DoReadMessageL |
|
865 // Marks a message read by updating it in the database. |
|
866 // (other items were commented in a header). |
|
867 // ----------------------------------------------------------------------------- |
|
868 // |
|
869 void CCbsDbImpTopicMessages::DoReadMessageL( |
|
870 const TStreamId& aId, |
|
871 const TCbsDbMessage& aMessage, |
|
872 const TStreamId& aContentsId ) |
|
873 { |
|
874 DoUpdateMessageL( aId, aMessage, aContentsId ); |
|
875 iTopicList.InformUnreadMessageReadL( aMessage.iHandle ); |
|
876 iTopicList.CommitFilesL(); |
|
877 } |
|
878 |
|
879 // ----------------------------------------------------------------------------- |
|
880 // CCbsDbImpTopicMessages::DoDeleteL |
|
881 // Deletes messages that are not supposed to be in the topic. |
|
882 // Because of message locking it is possible that there are more |
|
883 // received messages than there should be. This method tries to |
|
884 // delete this kind of message. |
|
885 // (other items were commented in a header). |
|
886 // ----------------------------------------------------------------------------- |
|
887 // |
|
888 void CCbsDbImpTopicMessages::DoDeleteL() |
|
889 { |
|
890 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::DoDeleteL()"); |
|
891 |
|
892 // Delete temporary messages and update topic messages stream. |
|
893 if ( DeleteReceivedIfNecessaryL() ) |
|
894 { |
|
895 UpdateTopicMessagesStreamL( ETrue ); |
|
896 } |
|
897 iTopicList.CommitFilesL(); |
|
898 |
|
899 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::DoDeleteL()"); |
|
900 } |
|
901 |
|
902 // ----------------------------------------------------------------------------- |
|
903 // CCbsDbImpTopicMessages::FindMessageByKeyL |
|
904 // Returns a handle to a message with the given key. |
|
905 // (other items were commented in a header). |
|
906 // ----------------------------------------------------------------------------- |
|
907 // |
|
908 TInt CCbsDbImpTopicMessages::FindMessageByKeyL( |
|
909 TCbsDbTopicNumber aNumber, |
|
910 TCbsDbMessageKey aKey, |
|
911 TCbsDbMessage& aMessage ) |
|
912 { |
|
913 TCbsDbMessage message; |
|
914 TInt count; |
|
915 TBool result( KErrNotFound ); |
|
916 |
|
917 // Find a message even if the update numbers don't match |
|
918 aKey &= 0xfff0; |
|
919 |
|
920 // Try to find a message with the same key in the topic. |
|
921 LoadCacheL( aNumber ); |
|
922 GetMessageCountL( aNumber, count ); |
|
923 |
|
924 for ( TInt index( 0 ); ( index < count ) && ( result != KErrNone ); index++ ) |
|
925 { |
|
926 LoadMessageL( index, message ); |
|
927 |
|
928 if ( (message.iKey & 0xfff0) == aKey ) |
|
929 { |
|
930 aMessage = message; |
|
931 result = KErrNone; // message was found |
|
932 } |
|
933 } |
|
934 return result; |
|
935 } |
|
936 |
|
937 // ----------------------------------------------------------------------------- |
|
938 // CCbsDbImpTopicMessages::FindMessagePositionByHandleL |
|
939 // Returns the position of a message with the given handle. |
|
940 // (other items were commented in a header). |
|
941 // ----------------------------------------------------------------------------- |
|
942 // |
|
943 TInt CCbsDbImpTopicMessages::FindMessagePositionByHandleL( |
|
944 const TCbsDbMessageHandle& aHandle ) |
|
945 { |
|
946 // Load the cache. |
|
947 LoadCacheL( iTopicList.ExtractTopicNumber( aHandle ) ); |
|
948 |
|
949 // Now, find the message |
|
950 TInt count( iMessageList->Count() ); |
|
951 |
|
952 TCbsDbMessage message; |
|
953 TBool found( EFalse ); |
|
954 |
|
955 // Go through messages. |
|
956 TInt index( 0 ); |
|
957 for ( ; ( index < count ) && !found; ) |
|
958 { |
|
959 // Load the message. |
|
960 LoadMessageL( index, message ); |
|
961 |
|
962 // Check if it is this one. |
|
963 if ( message.iHandle == aHandle ) |
|
964 { |
|
965 found = ETrue; |
|
966 } |
|
967 else |
|
968 { |
|
969 index++; |
|
970 } |
|
971 } |
|
972 |
|
973 if ( !found ) |
|
974 { |
|
975 User::Leave( KErrNotFound ); |
|
976 } |
|
977 |
|
978 return index; |
|
979 } |
|
980 |
|
981 // ----------------------------------------------------------------------------- |
|
982 // CCbsDbImpTopicMessages::LoadCacheL |
|
983 // Loads the cache, if it is not already loaded with this topic information. |
|
984 // The method does not load any message information to the cache |
|
985 // - only what is really necessary. |
|
986 // (other items were commented in a header). |
|
987 // ----------------------------------------------------------------------------- |
|
988 // |
|
989 void CCbsDbImpTopicMessages::LoadCacheL( |
|
990 const TCbsDbTopicNumber& aNumber ) |
|
991 { |
|
992 CBSLOGSTRING2("CBSSERVER: >>> CCbsDbImpTopicMessages::LoadCacheL(), topic number: %d.", aNumber ); |
|
993 |
|
994 // Check if the cache is valid. If not, load it. |
|
995 if ( !( iCacheValid && ( iCachedTopicNumber == aNumber ) ) ) |
|
996 { |
|
997 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadCacheL(): Calling InvalidateCache()..."); |
|
998 // Invalidate the old cache, if it is necessary. |
|
999 InvalidateCache(); |
|
1000 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadCacheL(): InvalidateCache() called OK."); |
|
1001 |
|
1002 // Load message queue ids. |
|
1003 TStreamId id; |
|
1004 iTopicList.GetTopicMessagesIdL( aNumber, id ); |
|
1005 |
|
1006 ReadTopicMessagesCacheItemsL( *iTopicList.TopicStoreL(), |
|
1007 id, *iMessageList, iSpaceForMessages ); |
|
1008 |
|
1009 // Cache is valid. |
|
1010 iCachedTopicNumber = aNumber; |
|
1011 iCacheValid = ETrue; |
|
1012 |
|
1013 // Check if it there are more topics than there should be. |
|
1014 TCbsDbTopic topic; |
|
1015 iTopicList.FindTopicByNumberL( aNumber, topic ); |
|
1016 if ( ( iMessageList->Count() - topic.iSavedMessages ) > |
|
1017 KCbsDbMaxReceivedMessages ) |
|
1018 { |
|
1019 TRAPD( error, DoDeleteL() ); |
|
1020 CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::LoadCacheL(): DoDeleteL() finished with %d.", error ); |
|
1021 |
|
1022 if ( error != KErrNone ) |
|
1023 { |
|
1024 RevertFileOperationL( error ); |
|
1025 } |
|
1026 } |
|
1027 } |
|
1028 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::LoadCacheL()"); |
|
1029 } |
|
1030 |
|
1031 // ----------------------------------------------------------------------------- |
|
1032 // CCbsDbImpTopicMessages::LoadMessageL |
|
1033 // Loads the message header to the cache. |
|
1034 // Note that it is assumed that the index is in proper range and |
|
1035 // the cache is already loaded. |
|
1036 // (other items were commented in a header). |
|
1037 // ----------------------------------------------------------------------------- |
|
1038 // |
|
1039 void CCbsDbImpTopicMessages::LoadMessageL( |
|
1040 TInt aIndex, |
|
1041 TCbsDbMessage& aMessage ) |
|
1042 { |
|
1043 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::LoadMessageL()"); |
|
1044 |
|
1045 // Check that the aIndex is in proper range and. |
|
1046 // that the cache is valid (just for sure). |
|
1047 if ( aIndex < 0 || aIndex >= iMessageList->Count() || |
|
1048 !iCacheValid ) |
|
1049 { |
|
1050 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): Leaving with KErrNotFound..."); |
|
1051 User::Leave( KErrNotFound ); |
|
1052 } |
|
1053 |
|
1054 // Check if the message information is already loaded. |
|
1055 if ( iMessageList->At( aIndex ).iIsMessage ) |
|
1056 { |
|
1057 // Yes, just make a fast copy. |
|
1058 aMessage = iMessageList->At( aIndex ).iMessage; |
|
1059 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): Msg already loaded, fast copy made."); |
|
1060 } |
|
1061 else |
|
1062 { |
|
1063 TStreamId id( TStreamId( 0 ) ); |
|
1064 // Choose the file store: saved messages are stored elsewhere |
|
1065 // than other messages. |
|
1066 CFileStore* store = iMessageList->At( aIndex ).iIsSaved ? |
|
1067 iTopicList.TopicStoreL() : |
|
1068 iTopicList.UnsavedMessagesStore(); |
|
1069 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): Store created."); |
|
1070 |
|
1071 // Then read the message. If the message stream cannot be |
|
1072 // found, delete the reference to the message |
|
1073 TRAPD( error, ReadMessageInformationL( *store, |
|
1074 iMessageList->At( aIndex ).iId, aMessage, id ) ); |
|
1075 |
|
1076 CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): ReadMessageInformationL() finished with %d.", error ); |
|
1077 |
|
1078 if( error == KErrNotFound ) |
|
1079 { |
|
1080 DeleteMessageByPositionL( aIndex ); |
|
1081 UpdateTopicMessagesStreamL( ETrue ); |
|
1082 iTopicList.CommitFilesL(); |
|
1083 } |
|
1084 |
|
1085 CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): Leaving if error code < 0: error %d...", error ); |
|
1086 User::LeaveIfError( error ); |
|
1087 |
|
1088 // And copy to the internal cache. |
|
1089 iMessageList->At( aIndex ).iIsMessage = ETrue; |
|
1090 iMessageList->At( aIndex ).iContentsId = id; |
|
1091 iMessageList->At( aIndex ).iMessage = aMessage; |
|
1092 } |
|
1093 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::LoadMessageL()"); |
|
1094 } |
|
1095 |
|
1096 // ----------------------------------------------------------------------------- |
|
1097 // CCbsDbImpTopicMessages::LoadMessageContentsL |
|
1098 // Loads message contents (as much as it fits). |
|
1099 // Restores the contents of a message |
|
1100 // by reading a stream specified in parameter aContentsId. |
|
1101 // Save status of message is required because saved and unsaved |
|
1102 // messages are stored on separate files. |
|
1103 // (other items were commented in a header). |
|
1104 // ----------------------------------------------------------------------------- |
|
1105 // |
|
1106 void CCbsDbImpTopicMessages::LoadMessageContentsL( |
|
1107 const TStreamId& aContentsId, |
|
1108 TPtr& aContents, |
|
1109 TBool aIsSaved, |
|
1110 TUint aSize ) const |
|
1111 { |
|
1112 CFileStore* store = aIsSaved ? |
|
1113 iTopicList.TopicStoreL() : |
|
1114 iTopicList.UnsavedMessagesStore(); |
|
1115 |
|
1116 // Read data to the buffer. |
|
1117 RStoreReadStream instream; |
|
1118 instream.OpenLC( *store, aContentsId ); // on CS |
|
1119 |
|
1120 // Read the data into a temporary buffer first. |
|
1121 // Then copy to the aContents descriptor only |
|
1122 // as much as it can take. |
|
1123 TUint length( instream.ReadInt16L() ); |
|
1124 if ( length > KCbsMaxCharsInMessage ) |
|
1125 { |
|
1126 User::Leave( KErrCorrupt ); |
|
1127 } |
|
1128 |
|
1129 HBufC* buf = HBufC::NewL( instream, length ); |
|
1130 if ( length > aSize ) |
|
1131 { |
|
1132 length = aSize; |
|
1133 } |
|
1134 |
|
1135 aContents.Copy( buf->Ptr(), length ); |
|
1136 delete buf; |
|
1137 |
|
1138 CleanupStack::PopAndDestroy(); // instream |
|
1139 } |
|
1140 |
|
1141 // ----------------------------------------------------------------------------- |
|
1142 // CCbsDbImpTopicMessages::GenerateNewMessageHandle |
|
1143 // Generates a new, unique handle for a message. |
|
1144 // The generation uses topic number as |
|
1145 // basis and then increments the handle value until an unique |
|
1146 // handle is found. |
|
1147 // (other items were commented in a header). |
|
1148 // ----------------------------------------------------------------------------- |
|
1149 // |
|
1150 TCbsDbMessageHandle CCbsDbImpTopicMessages::GenerateNewMessageHandle( |
|
1151 const TCbsDbTopicNumber& aNumber ) |
|
1152 { |
|
1153 // Start with a reasonable seed. We'll try the number |
|
1154 // of messages in topic, plus one. |
|
1155 TUint16 handleLow( TUint16( iMessageList->Count() + 1 ) ); |
|
1156 TCbsDbMessageHandle handle( 1 ); |
|
1157 TInt error( KErrNone ); |
|
1158 |
|
1159 while ( error == KErrNone ) |
|
1160 { |
|
1161 handleLow++; |
|
1162 if ( handleLow == 0 ) |
|
1163 { |
|
1164 handleLow++; |
|
1165 } |
|
1166 |
|
1167 // Generate a new message handle. |
|
1168 handle = iTopicList.GenerateMessageHandle( aNumber, |
|
1169 handleLow ); |
|
1170 |
|
1171 TRAP( error, ( FindMessagePositionByHandleL( handle ) ) ); |
|
1172 } |
|
1173 return handle; |
|
1174 } |
|
1175 |
|
1176 // ----------------------------------------------------------------------------- |
|
1177 // CCbsDbImpTopicMessages::DeleteReceivedIfNecessaryL |
|
1178 // Checks that if there are too many received messages in the internal cache, |
|
1179 // then they will be deleted if they are not locked. |
|
1180 // Note: Count() is changed in for-loop. |
|
1181 // (other items were commented in a header). |
|
1182 // ----------------------------------------------------------------------------- |
|
1183 // |
|
1184 TBool CCbsDbImpTopicMessages::DeleteReceivedIfNecessaryL() |
|
1185 { |
|
1186 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::DeleteReceivedIfNecessaryL()"); |
|
1187 |
|
1188 // So check if there are too many received messages in the topic. |
|
1189 // Thus delete if message is not locked. |
|
1190 |
|
1191 __ASSERT_DEBUG( iCacheValid, CbsServerPanic( ECbsCacheNotValid ) ); |
|
1192 |
|
1193 TInt totalReceived( 0 ); |
|
1194 TCbsDbMessage message; |
|
1195 TBool result( EFalse ); |
|
1196 TInt index( 0 ); |
|
1197 |
|
1198 for ( index = 0; index < iMessageList->Count(); index++ ) |
|
1199 { |
|
1200 LoadMessageL( index, message ); |
|
1201 |
|
1202 // Count the amount of received messages |
|
1203 if ( !message.iPermanent ) |
|
1204 { |
|
1205 totalReceived++; |
|
1206 |
|
1207 // If there are too many, then check that it can be deleted. |
|
1208 if ( totalReceived > KCbsDbMaxReceivedMessages && |
|
1209 !IsMessageLocked( message.iHandle ) ) |
|
1210 { |
|
1211 // Delete the message. |
|
1212 DeleteMessageByPositionL( index ); |
|
1213 iTopicList.InformMessageDeletedL |
|
1214 ( message.iHandle, |
|
1215 message.iPermanent, |
|
1216 message.iRead ); |
|
1217 result = ETrue; |
|
1218 |
|
1219 // They are always deleted from internal cache |
|
1220 index--; |
|
1221 totalReceived--; |
|
1222 } |
|
1223 } |
|
1224 } |
|
1225 |
|
1226 CBSLOGSTRING2("CBSSERVER: <<< CCbsDbImpTopicMessages::DeleteReceivedIfNecessaryL(), returning %d.", result ); |
|
1227 return result; |
|
1228 } |
|
1229 |
|
1230 // ----------------------------------------------------------------------------- |
|
1231 // CCbsDbImpTopicMessages::DeleteMessageByPositionL |
|
1232 // Deletes message by its position in the internal cache. |
|
1233 // Note that after the call the internal cache won't contain |
|
1234 // the item. |
|
1235 // (other items were commented in a header). |
|
1236 // ----------------------------------------------------------------------------- |
|
1237 // |
|
1238 void CCbsDbImpTopicMessages::DeleteMessageByPositionL( |
|
1239 TInt aIndex ) |
|
1240 { |
|
1241 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::DeleteMessageByPositionL()"); |
|
1242 |
|
1243 // Delete from cache and from file. |
|
1244 __ASSERT_DEBUG( iCacheValid, CbsServerPanic( ECbsCacheNotValid ) ); |
|
1245 |
|
1246 TCbsDbImpTopicMessagesCacheItem item( iMessageList->At( aIndex ) ); |
|
1247 |
|
1248 // Determine the file where the message is stored. |
|
1249 CFileStore* store = item.iIsSaved ? iTopicList.TopicStoreL() : |
|
1250 iTopicList.UnsavedMessagesStore(); |
|
1251 |
|
1252 iMessageList->Delete( aIndex ); |
|
1253 |
|
1254 store->Delete( item.iId ); |
|
1255 store->Delete( item.iContentsId ); |
|
1256 |
|
1257 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::DeleteMessageByPositionL()"); |
|
1258 } |
|
1259 |
|
1260 // ----------------------------------------------------------------------------- |
|
1261 // CCbsDbImpTopicMessages::IsMessageLocked |
|
1262 // Determines whether or not the message is locked. |
|
1263 // (other items were commented in a header). |
|
1264 // ----------------------------------------------------------------------------- |
|
1265 // |
|
1266 TBool CCbsDbImpTopicMessages::IsMessageLocked( |
|
1267 const TCbsDbMessageHandle& aHandle ) const |
|
1268 { |
|
1269 // Find out if the message is locked. |
|
1270 TBool found( EFalse ); |
|
1271 TInt count( iLockedMessages->Count() ); |
|
1272 for ( TInt index( 0 ); ( index < count ) && !found; index++ ) |
|
1273 { |
|
1274 if ( iLockedMessages->At( index ) == aHandle ) |
|
1275 { |
|
1276 found = ETrue; |
|
1277 } |
|
1278 } |
|
1279 |
|
1280 return found; |
|
1281 } |
|
1282 |
|
1283 // ----------------------------------------------------------------------------- |
|
1284 // CCbsDbImpTopicMessages::DeleteFromLocked |
|
1285 // Deletes from the locked messages. |
|
1286 // (other items were commented in a header). |
|
1287 // ----------------------------------------------------------------------------- |
|
1288 // |
|
1289 void CCbsDbImpTopicMessages::DeleteFromLocked( |
|
1290 const TCbsDbMessageHandle& aHandle ) |
|
1291 { |
|
1292 TBool deleted( EFalse ); |
|
1293 TInt count( iLockedMessages->Count() ); |
|
1294 |
|
1295 for ( TInt index( 0 ); ( index < count ) && !deleted; index++ ) |
|
1296 { |
|
1297 if ( iLockedMessages->At( index ) == aHandle ) |
|
1298 { |
|
1299 iLockedMessages->Delete( index ); |
|
1300 deleted = ETrue; |
|
1301 } |
|
1302 } |
|
1303 } |
|
1304 |
|
1305 // ----------------------------------------------------------------------------- |
|
1306 // CCbsDbImpTopicMessages::InsertToLockedL |
|
1307 // Adds a handle to the locked messages. |
|
1308 // (other items were commented in a header). |
|
1309 // ----------------------------------------------------------------------------- |
|
1310 // |
|
1311 void CCbsDbImpTopicMessages::InsertToLockedL( |
|
1312 const TCbsDbMessageHandle& aHandle ) |
|
1313 { |
|
1314 // Just append to the end. |
|
1315 iLockedMessages->AppendL( aHandle ); |
|
1316 } |
|
1317 |
|
1318 // ----------------------------------------------------------------------------- |
|
1319 // CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL |
|
1320 // Updates topic messages stream from the internal cache. |
|
1321 // (other items were commented in a header). |
|
1322 // ----------------------------------------------------------------------------- |
|
1323 // |
|
1324 void CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL( |
|
1325 TBool aDeleting ) |
|
1326 { |
|
1327 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL()"); |
|
1328 |
|
1329 __ASSERT_DEBUG( iCacheValid, CbsServerPanic( ECbsCacheNotValid ) ); |
|
1330 |
|
1331 TInt neededSpace( KMessageRootStreamSize + |
|
1332 iMessageList->Count() * KMessageEntrySize ); |
|
1333 |
|
1334 RSharedDataClient sharedData; |
|
1335 // About to write to FFS: make critical level check |
|
1336 if ( aDeleting ) |
|
1337 { |
|
1338 User::LeaveIfError( sharedData.Connect() ); |
|
1339 sharedData.RequestFreeDiskSpaceLC( neededSpace ); // on CS |
|
1340 } |
|
1341 else |
|
1342 { |
|
1343 CbsUtils::FFSCriticalLevelCheckL( neededSpace, iFs ); |
|
1344 } |
|
1345 |
|
1346 // Now, first check if the information fits well to the current stream. |
|
1347 if ( iSpaceForMessages >= iMessageList->Count() ) |
|
1348 { |
|
1349 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (3)"); |
|
1350 |
|
1351 // Write data to the old stream. |
|
1352 TStreamId id; |
|
1353 iTopicList.GetTopicMessagesIdL( iCachedTopicNumber, id ); |
|
1354 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (4)"); |
|
1355 |
|
1356 // Replace the existing stream. |
|
1357 RStoreWriteStream outstream; |
|
1358 outstream.ReplaceLC( *iTopicList.TopicStoreL(), id ); // on CS |
|
1359 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (5)"); |
|
1360 |
|
1361 WriteTopicMessagesStreamL( outstream ); |
|
1362 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (6)"); |
|
1363 |
|
1364 outstream.CommitL(); |
|
1365 CleanupStack::PopAndDestroy(); // outstream |
|
1366 } |
|
1367 else |
|
1368 { |
|
1369 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (7)"); |
|
1370 // Calculate the amount of space for messages. |
|
1371 if ( iSpaceForMessages == 0 ) |
|
1372 { |
|
1373 // Zero is not very good, lets put it greater. |
|
1374 iSpaceForMessages = KDefaultSpaceForMessages; |
|
1375 } |
|
1376 |
|
1377 // But no need for extra messages. |
|
1378 iSpaceForMessages = 2 * iSpaceForMessages; |
|
1379 if ( iSpaceForMessages > |
|
1380 ( KCbsDbMaxReceivedMessages + KCbsDbMaxSavedMessages ) ) |
|
1381 { |
|
1382 iSpaceForMessages = |
|
1383 KCbsDbMaxReceivedMessages + KCbsDbMaxSavedMessages; |
|
1384 } |
|
1385 if ( iMessageList->Count() > iSpaceForMessages ) |
|
1386 { |
|
1387 iSpaceForMessages = iMessageList->Count(); |
|
1388 } |
|
1389 |
|
1390 // And finally write the data to stream. |
|
1391 RStoreWriteStream outstream; |
|
1392 TStreamId id = outstream.CreateLC( *iTopicList.TopicStoreL() );// on CS |
|
1393 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (8)"); |
|
1394 |
|
1395 WriteTopicMessagesStreamL( outstream ); |
|
1396 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (9)"); |
|
1397 |
|
1398 outstream.CommitL(); |
|
1399 CleanupStack::PopAndDestroy(); // outstream |
|
1400 |
|
1401 // And then update topic messages stream. It will also delete |
|
1402 // the old stream. |
|
1403 iTopicList.UpdateTopicMessagesIdL( iCachedTopicNumber, id ); |
|
1404 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (10)"); |
|
1405 } |
|
1406 |
|
1407 // Free the reserved space |
|
1408 if ( aDeleting ) |
|
1409 { |
|
1410 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (11)"); |
|
1411 CleanupStack::PopAndDestroy(); // disk space |
|
1412 sharedData.Close(); |
|
1413 } |
|
1414 |
|
1415 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL()"); |
|
1416 } |
|
1417 |
|
1418 // ----------------------------------------------------------------------------- |
|
1419 // CCbsDbImpTopicMessages::WriteTopicMessagesStreamL |
|
1420 // Writes topic messages stream from the internal cache. |
|
1421 // (other items were commented in a header). |
|
1422 // ----------------------------------------------------------------------------- |
|
1423 // |
|
1424 void CCbsDbImpTopicMessages::WriteTopicMessagesStreamL( |
|
1425 RWriteStream& aOut ) |
|
1426 { |
|
1427 // Write total amount of messages. |
|
1428 TInt count( iMessageList->Count() ); |
|
1429 aOut.WriteInt16L( count ); |
|
1430 |
|
1431 // Write total amount of space for messages. |
|
1432 aOut.WriteInt16L( iSpaceForMessages ); |
|
1433 |
|
1434 TInt index( 0 ); |
|
1435 |
|
1436 for ( ; index < count; index++ ) |
|
1437 { |
|
1438 CbsStreamHelper::WriteBoolL( aOut, |
|
1439 iMessageList->At( index ).iIsSaved ); |
|
1440 |
|
1441 // Write message stream id. |
|
1442 aOut << iMessageList->At( index ).iId; |
|
1443 } |
|
1444 |
|
1445 for ( ; index < iSpaceForMessages; index++ ) |
|
1446 { |
|
1447 CbsStreamHelper::WriteBoolL( aOut, EFalse ); |
|
1448 |
|
1449 // Write null message stream id. |
|
1450 aOut << TStreamId( 0 ); |
|
1451 } |
|
1452 } |
|
1453 |
|
1454 // ----------------------------------------------------------------------------- |
|
1455 // CCbsDbImpTopicMessages::CreateMessageContentsStreamL |
|
1456 // Creates a new message content stream and writes |
|
1457 // the given contents into this stream. |
|
1458 // (other items were commented in a header). |
|
1459 // ----------------------------------------------------------------------------- |
|
1460 // |
|
1461 TStreamId CCbsDbImpTopicMessages::CreateMessageContentsStreamL( |
|
1462 CStreamStore& aStore, |
|
1463 const TDesC& aContents ) |
|
1464 { |
|
1465 // Create stream and write data to it. |
|
1466 RStoreWriteStream outstream; |
|
1467 TStreamId id( outstream.CreateLC( aStore ) ); // on CS |
|
1468 |
|
1469 // Just write the contents.. |
|
1470 TInt count( aContents.Length() ); |
|
1471 outstream.WriteInt16L( count ); |
|
1472 outstream << aContents; |
|
1473 |
|
1474 outstream.CommitL(); |
|
1475 CleanupStack::PopAndDestroy(); // outstream |
|
1476 |
|
1477 return id; |
|
1478 } |
|
1479 |
|
1480 // ----------------------------------------------------------------------------- |
|
1481 // CCbsDbImpTopicMessages::CreateMessageStreamL |
|
1482 // Creates a message stream and |
|
1483 // writes the message into that stream. |
|
1484 // (other items were commented in a header). |
|
1485 // ----------------------------------------------------------------------------- |
|
1486 // |
|
1487 TStreamId CCbsDbImpTopicMessages::CreateMessageStreamL( |
|
1488 CStreamStore& aStore, |
|
1489 TCbsDbMessage& aMessage, |
|
1490 const TStreamId& aContents ) |
|
1491 { |
|
1492 // Create stream and write data to it. |
|
1493 RStoreWriteStream outstream; |
|
1494 TStreamId id = outstream.CreateLC( aStore ); // on CS |
|
1495 |
|
1496 // Write the handle. |
|
1497 outstream.WriteInt32L( aMessage.iHandle ); |
|
1498 |
|
1499 // Write the message key. |
|
1500 outstream.WriteInt16L( aMessage.iKey ); |
|
1501 |
|
1502 // Write the language. |
|
1503 outstream.WriteInt16L( aMessage.iLanguage ); |
|
1504 |
|
1505 // Write the date and time. |
|
1506 outstream << aMessage.iDateTime; |
|
1507 |
|
1508 // Write the permanent status. |
|
1509 CbsStreamHelper::WriteBoolL( outstream, aMessage.iPermanent ); |
|
1510 |
|
1511 // Write the read status. |
|
1512 CbsStreamHelper::WriteBoolL( outstream, aMessage.iRead ); |
|
1513 |
|
1514 // Write the stream identifier to the contents. |
|
1515 outstream << aContents; |
|
1516 |
|
1517 outstream.CommitL(); |
|
1518 CleanupStack::PopAndDestroy(); // outstream |
|
1519 |
|
1520 return id; |
|
1521 } |
|
1522 |
|
1523 // ----------------------------------------------------------------------------- |
|
1524 // CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL |
|
1525 // Reads all cache items for a topic. |
|
1526 // Restores topic message cache from a stream. |
|
1527 // (other items were commented in a header). |
|
1528 // ----------------------------------------------------------------------------- |
|
1529 // |
|
1530 void CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL( |
|
1531 const CStreamStore& aStore, |
|
1532 const TStreamId& aId, |
|
1533 TCbsDbImpTopicMessagesCache& aCache, |
|
1534 TInt& aSpace ) |
|
1535 { |
|
1536 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL()"); |
|
1537 |
|
1538 RStoreReadStream instream; |
|
1539 instream.OpenLC( aStore, aId ); // on CS |
|
1540 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): instream.OpenLC() OK."); |
|
1541 |
|
1542 // Read total amount of messages. |
|
1543 TInt totalMessages( instream.ReadInt16L() ); |
|
1544 CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): totalMessages: %d.", totalMessages ); |
|
1545 |
|
1546 // Read total amount of space for messages. |
|
1547 aSpace = instream.ReadInt16L(); |
|
1548 CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): aSpace: %d.", aSpace ); |
|
1549 |
|
1550 // Sanity check: if the number of messages exceeds |
|
1551 // the worst case, leave. If the space for messages |
|
1552 // is smaller than number of messages, leave. |
|
1553 if ( totalMessages > KCbsDbMaxSavedMessages + KCbsDbMaxReceivedMessages |
|
1554 || aSpace < totalMessages ) |
|
1555 { |
|
1556 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): Stream corrupt, leaving with KErrCorrupt..."); |
|
1557 User::Leave( KErrCorrupt ); |
|
1558 } |
|
1559 |
|
1560 TCbsDbImpTopicMessagesCacheItem item; |
|
1561 |
|
1562 aCache.Reset(); |
|
1563 |
|
1564 for ( TInt index( 0 ); index < totalMessages; index++ ) |
|
1565 { |
|
1566 CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): Looping msgs, i: %d.", index ); |
|
1567 item.iIsSaved = CbsStreamHelper::ReadBoolL( instream ); |
|
1568 |
|
1569 // Read topic message stream id. |
|
1570 instream >> item.iId; |
|
1571 |
|
1572 // Initialize other fields. |
|
1573 item.iIsMessage = EFalse; |
|
1574 |
|
1575 // And finally, append the item to the array |
|
1576 aCache.AppendL( item ); |
|
1577 |
|
1578 CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): Msg appended to array."); |
|
1579 } |
|
1580 |
|
1581 CleanupStack::PopAndDestroy(); // instream |
|
1582 |
|
1583 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL()"); |
|
1584 } |
|
1585 |
|
1586 // ----------------------------------------------------------------------------- |
|
1587 // CCbsDbImpTopicMessages::ReadMessageInformationL |
|
1588 // Restore a message from a stream. |
|
1589 // (other items were commented in a header). |
|
1590 // ----------------------------------------------------------------------------- |
|
1591 // |
|
1592 void CCbsDbImpTopicMessages::ReadMessageInformationL( |
|
1593 const CStreamStore& aStore, |
|
1594 const TStreamId& aId, |
|
1595 TCbsDbMessage& aMessage, |
|
1596 TStreamId& aContentsId ) |
|
1597 { |
|
1598 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::ReadMessageInformationL()"); |
|
1599 |
|
1600 // Open the message information stream. |
|
1601 RStoreReadStream instream; |
|
1602 instream.OpenLC( aStore, aId ); // on CS |
|
1603 |
|
1604 // Read the handle. |
|
1605 aMessage.iHandle = instream.ReadInt32L(); |
|
1606 |
|
1607 // Read the message key. |
|
1608 aMessage.iKey = instream.ReadInt16L(); |
|
1609 |
|
1610 // Read the language. |
|
1611 aMessage.iLanguage = instream.ReadInt16L(); |
|
1612 |
|
1613 // Read the date and time. |
|
1614 TInt64 time; |
|
1615 instream >> time; |
|
1616 aMessage.iDateTime = time; |
|
1617 |
|
1618 // Read the permanent status. |
|
1619 aMessage.iPermanent = CbsStreamHelper::ReadBoolL( instream ); |
|
1620 |
|
1621 // Read the read status. |
|
1622 aMessage.iRead = CbsStreamHelper::ReadBoolL( instream ); |
|
1623 |
|
1624 // Read the stream identifier to the contents. |
|
1625 instream >> aContentsId; |
|
1626 |
|
1627 CleanupStack::PopAndDestroy(); // instream |
|
1628 |
|
1629 if ( aContentsId == TStreamId( 0 ) ) |
|
1630 { |
|
1631 aMessage.iLength = 0; |
|
1632 } |
|
1633 else |
|
1634 { |
|
1635 // Open message contents stream. |
|
1636 RStoreReadStream instreamContents; |
|
1637 |
|
1638 instreamContents.OpenLC( aStore, aContentsId ); // on CS |
|
1639 |
|
1640 // Read the length of the message. |
|
1641 aMessage.iLength = instreamContents.ReadInt16L(); |
|
1642 |
|
1643 CleanupStack::PopAndDestroy(); // instreamContents |
|
1644 } |
|
1645 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::ReadMessageInformationL()"); |
|
1646 } |
|
1647 |
|
1648 // ----------------------------------------------------------------------------- |
|
1649 // CCbsDbImpTopicMessages::WriteMessageInformationL |
|
1650 // Writes message information into a stream. |
|
1651 // (other items were commented in a header). |
|
1652 // ----------------------------------------------------------------------------- |
|
1653 // |
|
1654 void CCbsDbImpTopicMessages::WriteMessageInformationL( |
|
1655 RWriteStream& aOut, |
|
1656 const TCbsDbMessage& aMessage, |
|
1657 const TStreamId& aContentsId ) |
|
1658 { |
|
1659 // Write the handle. |
|
1660 aOut.WriteInt32L( aMessage.iHandle ); |
|
1661 |
|
1662 // Write the message key. |
|
1663 aOut.WriteInt16L( aMessage.iKey ); |
|
1664 |
|
1665 // Write the language. |
|
1666 aOut.WriteInt16L( aMessage.iLanguage ); |
|
1667 |
|
1668 // Write the date and time. |
|
1669 aOut << aMessage.iDateTime; |
|
1670 |
|
1671 // Write the permanent status. |
|
1672 CbsStreamHelper::WriteBoolL( aOut, aMessage.iPermanent ); |
|
1673 |
|
1674 // Write the read status. |
|
1675 CbsStreamHelper::WriteBoolL( aOut, aMessage.iRead ); |
|
1676 |
|
1677 // Write the stream identifier to the contents. |
|
1678 aOut << aContentsId; |
|
1679 } |
|
1680 |
|
1681 // ----------------------------------------------------------------------------- |
|
1682 // CCbsDbImpTopicMessages::UpdateSoftNotificationL |
|
1683 // Updates the soft notification (dialog) when unread message count changes. |
|
1684 // (other items were commented in a header). |
|
1685 // ----------------------------------------------------------------------------- |
|
1686 // |
|
1687 void CCbsDbImpTopicMessages::UpdateSoftNotificationL( |
|
1688 const TCbsDbMessageHandle& aHandle, |
|
1689 const CCbsRecEtel& aReceiver ) |
|
1690 { |
|
1691 TCbsDbTopic topic; |
|
1692 TCbsDbTopicNumber topicNum( iTopicList.ExtractTopicNumber( aHandle ) ); |
|
1693 iTopicList.FindTopicByNumberL( topicNum, topic ); |
|
1694 |
|
1695 // If topic is hotmarked, update the soft notification (dialog) , |
|
1696 // since number of read messages was changed |
|
1697 if ( topic.iHotmarked ) |
|
1698 { |
|
1699 aReceiver.Interface().LaunchMessageSoftNotificationL( EFalse ); |
|
1700 } |
|
1701 } |
|
1702 |
|
1703 // ----------------------------------------------------------------------------- |
|
1704 // CCbsDbImpTopicMessages::RevertFileOperationL |
|
1705 // Reverts any not commited file operation in data files, |
|
1706 // reloads cache and then leaves with aReason. |
|
1707 // (other items were commented in a header). |
|
1708 // ----------------------------------------------------------------------------- |
|
1709 // |
|
1710 void CCbsDbImpTopicMessages::RevertFileOperationL( |
|
1711 TInt aReason ) |
|
1712 { |
|
1713 iTopicList.RevertFilesL(); |
|
1714 InvalidateCache(); |
|
1715 User::Leave( aReason ); |
|
1716 } |
|
1717 |
|
1718 // ========================== OTHER EXPORTED FUNCTIONS ========================= |
|
1719 |
|
1720 // End of File |