|
1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <e32std.h> |
|
17 #include <msvapi.h> |
|
18 #include <msvids.h> |
|
19 #include <msvuids.h> |
|
20 #include <push/unknownmimedefs.h> |
|
21 #include <pushentry.h> |
|
22 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
23 #include "PushEntryPanic.h" |
|
24 #endif//SYMBIAN_ENABLE_SPLIT_HEADERS |
|
25 |
|
26 GLDEF_C TPtrC16 LimitStringSize(const TPtrC16& aString, TInt aMaxSize) |
|
27 { |
|
28 if (aString.Length() < aMaxSize) |
|
29 return aString; |
|
30 else |
|
31 return aString.Left(aMaxSize); |
|
32 } |
|
33 |
|
34 GLDEF_C TPtrC8 LimitStringSize(const TPtrC8& aString, TInt aMaxSize) |
|
35 { |
|
36 if (aString.Length() < aMaxSize) |
|
37 return aString; |
|
38 else |
|
39 return aString.Left(aMaxSize); |
|
40 } |
|
41 |
|
42 |
|
43 /** |
|
44 Destructor. |
|
45 */ |
|
46 EXPORT_C CPushMsgEntryBase::~CPushMsgEntryBase() |
|
47 { |
|
48 delete iMsgDetails; |
|
49 delete iMsgDescription; |
|
50 delete iHeader; |
|
51 delete iFrom; |
|
52 delete iAppIDString; |
|
53 } |
|
54 |
|
55 |
|
56 /** |
|
57 Stores the Push message in the message store. |
|
58 |
|
59 It creates an entry in the message server as a child of the specified parent, |
|
60 sets the relevant index entry fields, and calls ExternalizeL() to save additional |
|
61 data to a message store for the entry. |
|
62 |
|
63 If the operation fails the entry is deleted, along with the data in its message |
|
64 store. |
|
65 |
|
66 @param aSession |
|
67 Message server session. |
|
68 |
|
69 @param aParent |
|
70 ID of the parent for the new entry. It is the caller's responsibility to ensure |
|
71 that the parent ID is correct. |
|
72 |
|
73 @return |
|
74 ID of the new message server entry. |
|
75 */ |
|
76 EXPORT_C TMsvId CPushMsgEntryBase::SaveL(CMsvSession& aSession, TMsvId aParent) |
|
77 { |
|
78 __ASSERT_ALWAYS(aParent != KMsvNullIndexEntryId, |
|
79 User::Panic(KPushPanicMoniker, EPushEntryNullMsgId)); |
|
80 // Ensure that the entry parameters are correctly set. |
|
81 iEntry.iServiceId = KMsvLocalServiceIndexEntryId; //Saving under the local service |
|
82 iEntry.iMtm = KUidMtmWapPush; |
|
83 iEntry.iType = KUidMsvMessageEntry; |
|
84 iEntry.SetInPreparation(ETrue); |
|
85 iEntry.SetReadOnly(EFalse); |
|
86 iEntry.SetUnread(ETrue); |
|
87 SetPushMsgType(); |
|
88 |
|
89 // Create this outside of the TRAP - otherwise the leave would get trapped and |
|
90 // We'd tried to delete an entry that doesn't exist. |
|
91 CMsvEntry* msvEntry = aSession.GetEntryL(aParent); //Get parent entry |
|
92 CleanupStack::PushL(msvEntry); |
|
93 |
|
94 TUid mtmUid = msvEntry->Entry().iMtm; |
|
95 __ASSERT_ALWAYS((mtmUid == KUidMtmWapPush)||(mtmUid == KUidMsvLocalServiceMtm), |
|
96 User::Panic(KPushPanicMoniker,EPushEntryWrongMTMtype)); |
|
97 msvEntry->CreateL(iEntry); |
|
98 |
|
99 // CMsvSession::CleanupEntryPushL() can fail, leaving an partially complete |
|
100 // entry in the store. Use a TRAP and RemoveEntry to do the same job. |
|
101 TRAPD(createErr, DoSaveL(*msvEntry)); |
|
102 |
|
103 if (createErr != KErrNone) |
|
104 { |
|
105 aSession.RemoveEntry(iEntry.Id()); |
|
106 User::Leave(createErr); |
|
107 } |
|
108 |
|
109 iHasServerEntry = ETrue; |
|
110 |
|
111 // CMsvEntry is gone, so ensure iDescription & iDetails point |
|
112 // to persistent copies of the strings, if they exist else set to null |
|
113 if (iMsgDescription) |
|
114 iEntry.iDescription.Set(*iMsgDescription); |
|
115 else |
|
116 iEntry.iDescription.Set(KNullDesC); |
|
117 if (iMsgDetails) |
|
118 iEntry.iDetails.Set(*iMsgDetails); |
|
119 else |
|
120 iEntry.iDescription.Set(KNullDesC); |
|
121 |
|
122 iEntry.SetInPreparation(EFalse); |
|
123 UpdateL(aSession); |
|
124 |
|
125 CleanupStack::PopAndDestroy(); //msvEntry |
|
126 return iEntry.Id(); |
|
127 } |
|
128 |
|
129 |
|
130 /** |
|
131 Helper function that does the actual saving of various data members to the message store |
|
132 attached to the entry. It is done this way so that if any function call leaves, the |
|
133 error can be trapped in SaveL, and the new entry deleted before SaveL leaves. |
|
134 |
|
135 @param aMsvEntry Parent of the new entry. |
|
136 |
|
137 @internalComponent |
|
138 */ |
|
139 void CPushMsgEntryBase::DoSaveL(CMsvEntry& aMsvEntry) |
|
140 { |
|
141 // synchronous create in the Push Msg folder under Local Service |
|
142 aMsvEntry.SetEntryL(iEntry.Id()); |
|
143 __ASSERT_ALWAYS(iEntry.iBioType == PushMsgType(), |
|
144 User::Panic(KPushPanicMoniker,EPushEntryWrongMsgtype)); |
|
145 |
|
146 CMsvStore* store = aMsvEntry.EditStoreL(); |
|
147 CleanupStack::PushL(store); |
|
148 |
|
149 RMsvWriteStream out; |
|
150 TUid streamId; |
|
151 streamId.iUid = PushMsgType(); |
|
152 out.AssignLC(*store, streamId); |
|
153 ExternalizeL(out); //call this polymorphic function to save data |
|
154 out.CommitL(); |
|
155 out.Close(); // make sure we close the file |
|
156 store->CommitL(); |
|
157 CleanupStack::PopAndDestroy(2); //out, store |
|
158 } |
|
159 |
|
160 |
|
161 /** |
|
162 Updates an existing message server entry. |
|
163 |
|
164 The functionality is similiar to SaveL(), except no new entry is created. |
|
165 Before calling this function, the existing entry must be loaded into the object |
|
166 using RetrieveL(). |
|
167 |
|
168 @param aSession |
|
169 Message server session. |
|
170 */ |
|
171 EXPORT_C void CPushMsgEntryBase::UpdateL(CMsvSession& aSession) |
|
172 { |
|
173 if (iHasServerEntry ==EFalse ) |
|
174 User::Leave(KWPushNoMsgIndexEntry); |
|
175 CMsvEntry* msvEntry = aSession.GetEntryL(iEntry.Id()); |
|
176 CleanupStack::PushL(msvEntry); |
|
177 |
|
178 //Can only overwrite a pushmessage of the same type |
|
179 // Mtm & Push Type Uid must be correct |
|
180 __ASSERT_ALWAYS( msvEntry->Entry().iMtm == KUidMtmWapPush, |
|
181 User::Panic(KPushPanicMoniker, EPushEntryWrongMTMtype)); |
|
182 __ASSERT_ALWAYS( msvEntry->Entry().iBioType == PushMsgType(), |
|
183 User::Panic(KPushPanicMoniker, EPushEntryWrongMsgtype)); |
|
184 |
|
185 // Remove existing contents of stream and store new data |
|
186 CMsvStore* store; |
|
187 store = msvEntry->EditStoreL(); |
|
188 CleanupStack::PushL(store); |
|
189 |
|
190 RMsvWriteStream out; |
|
191 TUid streamId; |
|
192 streamId.iUid = PushMsgType(); |
|
193 out.AssignLC(*store, streamId); |
|
194 ExternalizeL(out); |
|
195 |
|
196 // Ensure the defaults are set correctly. Assume others set by user |
|
197 iEntry.iMtm = KUidMtmWapPush; |
|
198 SetPushMsgType(); |
|
199 msvEntry->ChangeL(iEntry); |
|
200 |
|
201 // Done the changes to the TMsvEntry, now commit changes to the stream & store |
|
202 out.CommitL(); |
|
203 out.Close(); // make sure we close the file |
|
204 store->CommitL(); |
|
205 CleanupStack::PopAndDestroy(3); //out, store, msventry |
|
206 iHasServerEntry = ETrue; |
|
207 |
|
208 // CMsvEntry is gone, so ensure iDescription & iDetails point to persistent |
|
209 // copies of the strings, if they exist else point them to Null Descriptors |
|
210 if (iMsgDescription) |
|
211 iEntry.iDescription.Set(*iMsgDescription); |
|
212 else |
|
213 iEntry.iDescription.Set(KNullDesC); |
|
214 |
|
215 if (iMsgDetails) |
|
216 iEntry.iDetails.Set(*iMsgDetails); |
|
217 else |
|
218 iEntry.iDescription.Set(KNullDesC); |
|
219 } |
|
220 |
|
221 |
|
222 /** |
|
223 Retrieves Push message from the message store into the object. |
|
224 |
|
225 The data held in TMsvEntry::iDetails and TMsvEntry::iDescription is copied |
|
226 to member descriptors to ensure that it persists after the local CMsvEntry |
|
227 variable is destroyed. |
|
228 |
|
229 @param aSession |
|
230 Message server session. |
|
231 |
|
232 @param aMsgId |
|
233 ID of the entry to load. |
|
234 |
|
235 @leave KErrNotFound |
|
236 The push message cannot be located in the Message Store. |
|
237 @leave CMsvSession::GetEntryL |
|
238 @leave TDesC::AllocL |
|
239 @leave CMsvEntry::ReadStoreL |
|
240 @leave CPushMsgEntryBase::RestoreL |
|
241 */ |
|
242 EXPORT_C void CPushMsgEntryBase::RetrieveL(CMsvSession& aSession, TMsvId aMsgId) |
|
243 { |
|
244 __ASSERT_ALWAYS(aMsgId!= KMsvNullIndexEntryId, |
|
245 User::Panic(KPushPanicMoniker, EPushEntryNullMsgId)); |
|
246 |
|
247 // Switch to our entry & then get the associated message store. |
|
248 CMsvEntry* msvEntry = aSession.GetEntryL(aMsgId); |
|
249 CleanupStack::PushL(msvEntry); |
|
250 |
|
251 // Set our TMsvEntry member variable |
|
252 iEntry = msvEntry->Entry(); |
|
253 |
|
254 // Make iDetails and iDescription persist as long as this object exists. |
|
255 // Delete any existing buffers |
|
256 delete iMsgDetails; |
|
257 iMsgDetails = NULL; |
|
258 iMsgDetails = iEntry.iDetails.AllocL(); |
|
259 iEntry.iDetails.Set(*iMsgDetails); |
|
260 |
|
261 delete iMsgDescription; |
|
262 iMsgDescription =NULL; |
|
263 iMsgDescription = iEntry.iDescription.AllocL(); |
|
264 iEntry.iDescription.Set(*iMsgDescription); |
|
265 |
|
266 CMsvStore* store = msvEntry->ReadStoreL(); |
|
267 CleanupStack::PushL(store); |
|
268 |
|
269 //Load in the additional data from the message store |
|
270 RestoreL(*store); |
|
271 |
|
272 CleanupStack::PopAndDestroy(2); //store, msvEntry |
|
273 // Obviously has a server entry |
|
274 iHasServerEntry = ETrue; |
|
275 } |
|
276 |
|
277 |
|
278 /** |
|
279 Restores data from the associated message store. |
|
280 |
|
281 The data is loaded by a call to the derived class InternalizeL(). |
|
282 |
|
283 @param aStore |
|
284 Store to load from. |
|
285 */ |
|
286 EXPORT_C void CPushMsgEntryBase::RestoreL(CMsvStore& aStore) |
|
287 { |
|
288 RMsvReadStream in; |
|
289 TUid streamId; |
|
290 streamId.iUid = PushMsgType(); |
|
291 in.OpenLC(aStore, streamId); |
|
292 InternalizeL(in); |
|
293 CleanupStack::PopAndDestroy(); //in |
|
294 } |
|
295 |
|
296 |
|
297 /** |
|
298 Sets directly the TMsvEntry for the message. |
|
299 |
|
300 This resets the context of the Push Entry, and the caller should ensure that all |
|
301 data member variables of the class are up to date. |
|
302 |
|
303 @param aEntry |
|
304 Message server index entry. |
|
305 */ |
|
306 EXPORT_C void CPushMsgEntryBase::SetEntry(const TMsvEntry& aEntry) |
|
307 { |
|
308 iEntry = aEntry; |
|
309 iEntry.iMtm = KUidMtmWapPush; |
|
310 } |
|
311 |
|
312 |
|
313 /** |
|
314 Sets the Status field for the Push Message Entry. |
|
315 |
|
316 The bits of the TMsvEntry::iMtmData1 member holding the Status are reset. |
|
317 |
|
318 @param aStatusFlags |
|
319 Status value for the message entry. |
|
320 */ |
|
321 EXPORT_C void CPushMsgEntryBase::SetStatus(TInt aStatusFlags) |
|
322 { |
|
323 // Get everything except the Status bits from iMtmData1 |
|
324 TInt everythingButStatus = iEntry.MtmData1() & KPushMaskEverythingButStatus; |
|
325 // Remove any extraneous bits from the new status & then set the status + action values |
|
326 iEntry.SetMtmData1( everythingButStatus + (aStatusFlags & KPushMaskOnlyStatus) ); |
|
327 } |
|
328 |
|
329 |
|
330 /** |
|
331 Gets the raw WAP Push message header. |
|
332 |
|
333 @return |
|
334 Message header, or KNullDesC8 if it has not been set with SetHeaderL(). |
|
335 */ |
|
336 EXPORT_C const TDesC8& CPushMsgEntryBase::Header() const |
|
337 { |
|
338 if (iHeader) // check the header exists |
|
339 return *iHeader; |
|
340 else |
|
341 return KNullDesC8; |
|
342 } |
|
343 |
|
344 |
|
345 /** |
|
346 Sets a buffer that specifies the WAP Push message header. |
|
347 |
|
348 Any existing buffer is deleted. |
|
349 |
|
350 @param aHeader |
|
351 Message header |
|
352 */ |
|
353 EXPORT_C void CPushMsgEntryBase::SetHeaderL(const TDesC8& aHeader) |
|
354 { |
|
355 HBufC8* temp = aHeader.AllocL(); |
|
356 delete iHeader; |
|
357 iHeader = temp; |
|
358 } |
|
359 |
|
360 |
|
361 /** |
|
362 Gets a buffer holding the From field. |
|
363 |
|
364 @return |
|
365 From field, or KNullDesC8 if it has not been set with SetFromL(). |
|
366 */ |
|
367 EXPORT_C const TDesC8& CPushMsgEntryBase::From() const |
|
368 { |
|
369 if (iFrom) |
|
370 return *iFrom; |
|
371 else |
|
372 return KNullDesC8; |
|
373 } |
|
374 |
|
375 |
|
376 /** |
|
377 Sets a buffer that specifies the From field. |
|
378 |
|
379 Any existing buffer is deleted. |
|
380 |
|
381 @param aFrom |
|
382 From field |
|
383 */ |
|
384 EXPORT_C void CPushMsgEntryBase::SetFromL(const TDesC8& aFrom) |
|
385 { |
|
386 HBufC8* temp = aFrom.AllocL(); |
|
387 delete iFrom; |
|
388 iFrom = temp; |
|
389 } |
|
390 |
|
391 |
|
392 /** |
|
393 Constructor. |
|
394 |
|
395 This initialises TMsvEntry::iDate. |
|
396 */ |
|
397 EXPORT_C CPushMsgEntryBase::CPushMsgEntryBase() |
|
398 { |
|
399 iEntry.iDate.UniversalTime(); |
|
400 } |
|
401 |
|
402 |
|
403 /** |
|
404 Externalises the object to a message store stream. |
|
405 |
|
406 Derived classes should override this function if required, and call the base |
|
407 class function. |
|
408 |
|
409 @param aStream |
|
410 Message store stream. |
|
411 */ |
|
412 EXPORT_C void CPushMsgEntryBase::ExternalizeL(RMsvWriteStream& aStream) |
|
413 { |
|
414 aStream<< LimitStringSize(Header(), KLongestStringAllowed); |
|
415 aStream<< LimitStringSize(From(), KLongestStringAllowed); |
|
416 |
|
417 if (iAppIDString) |
|
418 aStream<< *iAppIDString; |
|
419 else |
|
420 aStream<< KNullDesC; |
|
421 |
|
422 aStream.WriteInt32L(iAppIdInt); |
|
423 } |
|
424 |
|
425 |
|
426 /** |
|
427 Internalises the object from a message store stream. |
|
428 |
|
429 Derived classes should override this function if required, and call the base |
|
430 class function. |
|
431 |
|
432 @param aStream |
|
433 Message store stream. |
|
434 */ |
|
435 EXPORT_C void CPushMsgEntryBase::InternalizeL(RMsvReadStream& aStream) |
|
436 { |
|
437 delete iHeader; |
|
438 iHeader = NULL; |
|
439 iHeader = HBufC8::NewL(aStream, KLongestStringAllowed); |
|
440 |
|
441 delete iFrom; |
|
442 iFrom = NULL; |
|
443 iFrom = HBufC8::NewL(aStream, KLongestStringAllowed); |
|
444 |
|
445 delete iAppIDString; |
|
446 iAppIDString = NULL; |
|
447 iAppIDString = HBufC8::NewL(aStream, KLongestStringAllowed); |
|
448 |
|
449 iAppIdInt = aStream.ReadUint32L(); |
|
450 } |
|
451 |
|
452 |
|
453 /** |
|
454 Constructor, with the message AppID in string form. |
|
455 |
|
456 It calls SetPushMsgType() to ensure that TMsvEntry::iBioType is set to the |
|
457 correct Push Message Type UID. |
|
458 |
|
459 @param aAppURI |
|
460 AppID in string form. |
|
461 */ |
|
462 EXPORT_C void CPushMsgEntryBase::ConstructL(const TPtrC8& aAppURI) |
|
463 { |
|
464 ConstructL(); |
|
465 iAppIDString = aAppURI.AllocL(); |
|
466 } |
|
467 |
|
468 |
|
469 /** |
|
470 Constructor, with message AppID in numeric form. |
|
471 |
|
472 It calls SetPushMsgType() to ensure that TMsvEntry::iBioType is set to the |
|
473 correct Push Message Type UID. |
|
474 |
|
475 @param aAppID |
|
476 AppID in numeric form. |
|
477 */ |
|
478 EXPORT_C void CPushMsgEntryBase::ConstructL(const TInt& aAppID) |
|
479 { |
|
480 ConstructL(); |
|
481 iAppIdInt=aAppID; |
|
482 } |
|
483 |
|
484 /** |
|
485 Constructor. |
|
486 |
|
487 It calls SetPushMsgType() to ensure that TMsvEntry::iBioType is set to the |
|
488 correct Push Message Type Uid. |
|
489 */ |
|
490 EXPORT_C void CPushMsgEntryBase::ConstructL() |
|
491 { |
|
492 SetStatus(EPushMsgStatusValid); |
|
493 SetPushMsgType(); //Make sure this is set, need it for both StoreL & RestoreL |
|
494 } |
|
495 |
|
496 |
|
497 /** |
|
498 Gets the message description field. |
|
499 |
|
500 @return |
|
501 Message description field, or KNullDesC if not set. |
|
502 */ |
|
503 EXPORT_C const TDesC& CPushMsgEntryBase::MsgDescription() const |
|
504 { |
|
505 if (iMsgDescription) |
|
506 return *iMsgDescription; |
|
507 else |
|
508 return KNullDesC; |
|
509 } |
|
510 |
|
511 |
|
512 /** |
|
513 Sets the message description field. |
|
514 |
|
515 @param aDescription |
|
516 Message description field value to copy. |
|
517 */ |
|
518 EXPORT_C void CPushMsgEntryBase::SetMsgDescriptionL(const TDesC& aDescription) |
|
519 { |
|
520 HBufC* tempBuf = aDescription.AllocL(); |
|
521 |
|
522 delete iMsgDescription; |
|
523 iMsgDescription = tempBuf; |
|
524 iEntry.iDescription.Set(*iMsgDescription); |
|
525 } |
|
526 |
|
527 |
|
528 /** |
|
529 Gets the message details field. |
|
530 |
|
531 @return |
|
532 Message details field, or KNullDesC if not set. |
|
533 */ |
|
534 EXPORT_C const TDesC& CPushMsgEntryBase::MsgDetails() const |
|
535 { |
|
536 if (iMsgDetails) |
|
537 return *iMsgDetails; |
|
538 else |
|
539 return KNullDesC; |
|
540 } |
|
541 |
|
542 |
|
543 /** |
|
544 Sets the message details field. |
|
545 |
|
546 @param aDetails |
|
547 Message details field value to copy. |
|
548 */ |
|
549 EXPORT_C void CPushMsgEntryBase::SetMsgDetailsL(const TDesC& aDetails) |
|
550 { |
|
551 HBufC* tempBuf = aDetails.AllocL(); |
|
552 |
|
553 delete iMsgDetails; |
|
554 iMsgDetails = tempBuf; |
|
555 iEntry.iDetails.Set(*iMsgDetails); |
|
556 } |
|
557 |
|
558 |
|
559 /** |
|
560 Gets the date/time that the push message was received. |
|
561 |
|
562 @return |
|
563 Date/time that the push message was received. |
|
564 */ |
|
565 EXPORT_C const TTime& CPushMsgEntryBase::ReceivedDate() const |
|
566 { |
|
567 return iEntry.iDate; |
|
568 } |
|
569 |
|
570 |
|
571 /** |
|
572 Gets the AppID of the message. |
|
573 |
|
574 The AppID can either be an integer or a string. It is returned in one of the two |
|
575 parameters, while the third parameter indicates what form it takes. |
|
576 |
|
577 @param aAppURI |
|
578 On return, AppId in string form. |
|
579 |
|
580 @param aAppID |
|
581 On return, AppId in numeric form. |
|
582 |
|
583 @param aIsAnInt |
|
584 On return, true if the AppID is an integer value, false if a string. |
|
585 |
|
586 @return |
|
587 KErrNone if successful. |
|
588 KErrNotFound if the appId has not been set. |
|
589 */ |
|
590 EXPORT_C TInt CPushMsgEntryBase::AppID(TPtrC8& aAppURI, TInt& aAppID, TBool& aIsAnInt) const |
|
591 { |
|
592 if (iAppIDString && iAppIDString->Length() > 0) |
|
593 { |
|
594 aAppURI.Set(*iAppIDString); |
|
595 aIsAnInt=EFalse; |
|
596 return KErrNone; |
|
597 } |
|
598 else if (iAppIdInt > 0) |
|
599 { |
|
600 aAppID=iAppIdInt; |
|
601 aIsAnInt=ETrue; |
|
602 return KErrNone; |
|
603 } |
|
604 return KErrNotFound; |
|
605 } |
|
606 |