48
|
1 |
/*
|
|
2 |
* Copyright (c) 2002 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 the License "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: Implementation of CSIContentHandler.
|
|
15 |
*
|
|
16 |
*/
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
// INCLUDE FILES
|
|
21 |
|
|
22 |
#include "CSIContentHandler.h"
|
|
23 |
#include "PushMtmUtil.h"
|
|
24 |
#include "PushMtmSettings.h"
|
|
25 |
#include "PushMtmLog.h"
|
|
26 |
#include "PushMtmUiDef.h"
|
|
27 |
#include "StringResourceReader.h"
|
|
28 |
#include "PushContentHandlerPanic.h"
|
|
29 |
#include "si_dict.h"
|
|
30 |
#include "PushContentHandlerUtils.h"
|
|
31 |
#include <push/CSIPushMsgEntry.h>
|
|
32 |
#include <msvids.h>
|
|
33 |
#include <PushMtmUi.rsg>
|
|
34 |
#include <nw_dom_node.h>
|
|
35 |
#include <nw_dom_document.h>
|
|
36 |
#include <nw_dom_element.h>
|
|
37 |
#include <nw_dom_text.h>
|
|
38 |
#include <nw_wbxml_dictionary.h>
|
|
39 |
#include <THttpFields.h>
|
|
40 |
|
|
41 |
// CONSTANTS
|
|
42 |
|
|
43 |
// si attributes / elements
|
|
44 |
_LIT8( KSi, "si" );
|
|
45 |
_LIT8( KIndication, "indication" );
|
|
46 |
_LIT8( KHrefAttrib, "href" );
|
|
47 |
_LIT8( KSiIdAttrib, "si-id" );
|
|
48 |
_LIT8( KCreatedAttrib, "created" );
|
|
49 |
_LIT8( KExpiresAttrib, "si-expires" );
|
|
50 |
_LIT8( KActionAttrib, "action" );
|
|
51 |
|
|
52 |
// action attribute literals
|
|
53 |
_LIT8( KDeleteAction, "delete" );
|
|
54 |
_LIT8( KSignalNone, "signal-none" );
|
|
55 |
_LIT8( KSignalLow, "signal-low" );
|
|
56 |
_LIT8( KSignalMedium, "signal-medium" );
|
|
57 |
_LIT8( KSignalHigh, "signal-high" );
|
|
58 |
|
|
59 |
_LIT( KSiTextContentType, "text/vnd.wap.si" );
|
|
60 |
|
|
61 |
const TInt KValidMaxEncodedDateTimeSize = 7;
|
|
62 |
const TInt KValidUTCLength = 20; // YYYY-MM-DDTHH:MM:SSZ
|
|
63 |
const TInt KValidUTCNumericals = 14;
|
|
64 |
const TInt KValidUTCYearBlockLength = 4;
|
|
65 |
const TInt KValidUTCOtherBlockLength = 2;
|
|
66 |
const TUint8 KAsciiZeroCharCode = 0x30;
|
|
67 |
|
|
68 |
const TInt KValidTTimeMonthStart = 4;
|
|
69 |
const TInt KValidTTimeDayStart = 6;
|
|
70 |
const TInt KValidTTimeHourStart = 8;
|
|
71 |
const TInt KValidTTimeMinuteStart = 10;
|
|
72 |
const TInt KValidTTimeSecondStart = 12;
|
|
73 |
const TInt KValidTTimeBlockLength = 2;
|
|
74 |
|
|
75 |
const TInt KValidTTimeLength = 14; // YYYYMMDDHHMMSS
|
|
76 |
|
|
77 |
const TInt KNoOfDictArrays = 1;
|
|
78 |
|
|
79 |
_LIT( KCharMinus, "-" );
|
|
80 |
_LIT( KCharT, "T" );
|
|
81 |
_LIT( KCharColon, ":" );
|
|
82 |
_LIT( KCharZ, "Z" );
|
|
83 |
|
|
84 |
/// Conversion buffer size.
|
|
85 |
LOCAL_D const TInt KPushConversionBufferSize = 256;
|
|
86 |
/// Zero width non-breaking space character.
|
|
87 |
LOCAL_D const TUint16 KPushZeroWidthNbsp = 0xfeff;
|
|
88 |
|
|
89 |
// ================= MEMBER FUNCTIONS =======================
|
|
90 |
|
|
91 |
// ---------------------------------------------------------
|
|
92 |
// CSIContentHandler::NewL
|
|
93 |
// ---------------------------------------------------------
|
|
94 |
//
|
|
95 |
CSIContentHandler* CSIContentHandler::NewL()
|
|
96 |
{
|
|
97 |
PUSHLOG_ENTERFN("CSIContentHandler::NewL")
|
|
98 |
|
|
99 |
CSIContentHandler* self = new (ELeave) CSIContentHandler;
|
|
100 |
CleanupStack::PushL( self );
|
|
101 |
self->ConstructL();
|
|
102 |
CleanupStack::Pop( self );
|
|
103 |
|
|
104 |
PUSHLOG_LEAVEFN("CSIContentHandler::NewL")
|
|
105 |
return self;
|
|
106 |
}
|
|
107 |
|
|
108 |
// ---------------------------------------------------------
|
|
109 |
// CSIContentHandler::~CSIContentHandler
|
|
110 |
// ---------------------------------------------------------
|
|
111 |
//
|
|
112 |
CSIContentHandler::~CSIContentHandler()
|
|
113 |
{
|
|
114 |
PUSHLOG_ENTERFN("CSIContentHandler::~CSIContentHandler")
|
|
115 |
|
|
116 |
Cancel();
|
|
117 |
delete iHrefBuf;
|
|
118 |
delete iSiIdBuf;
|
|
119 |
delete iData;
|
|
120 |
delete iCharacterSetConverter;
|
|
121 |
iCharacterSetConverter = NULL;
|
|
122 |
delete iCharacterSetsAvailable;
|
|
123 |
iCharacterSetsAvailable = NULL;
|
|
124 |
|
|
125 |
PUSHLOG_LEAVEFN("CSIContentHandler::~CSIContentHandler")
|
|
126 |
}
|
|
127 |
|
|
128 |
// ---------------------------------------------------------
|
|
129 |
// CSIContentHandler::CSIContentHandler
|
|
130 |
// ---------------------------------------------------------
|
|
131 |
//
|
|
132 |
CSIContentHandler::CSIContentHandler()
|
|
133 |
: CPushContentHandlerBase(),
|
|
134 |
iSavedMsgId( KMsvNullIndexEntryId ),
|
|
135 |
iPushMsgAction( KErrNotFound ),
|
|
136 |
iExpiresTime( Time::NullTTime() ),
|
|
137 |
iCreatedTime( Time::NullTTime() )
|
|
138 |
{
|
|
139 |
}
|
|
140 |
|
|
141 |
// ---------------------------------------------------------
|
|
142 |
// CSIContentHandler::ConstructL
|
|
143 |
// ---------------------------------------------------------
|
|
144 |
//
|
|
145 |
void CSIContentHandler::ConstructL()
|
|
146 |
{
|
|
147 |
PUSHLOG_ENTERFN("CSIContentHandler::ConstructL")
|
|
148 |
|
|
149 |
CPushContentHandlerBase::ConstructL();
|
|
150 |
// Added to Active Scheduler.
|
|
151 |
|
|
152 |
PUSHLOG_LEAVEFN("CSIContentHandler::ConstructL")
|
|
153 |
}
|
|
154 |
|
|
155 |
// ---------------------------------------------------------
|
|
156 |
// CSIContentHandler::CollectGarbageL
|
|
157 |
// ---------------------------------------------------------
|
|
158 |
//
|
|
159 |
void CSIContentHandler::CollectGarbageL()
|
|
160 |
{
|
|
161 |
PUSHLOG_ENTERFN("CSIContentHandler::CollectGarbageL")
|
|
162 |
|
|
163 |
DoCollectGarbageL();
|
|
164 |
|
|
165 |
//Ready.
|
|
166 |
iState = EFilteringAndParsing;
|
|
167 |
IdleComplete();
|
|
168 |
|
|
169 |
PUSHLOG_LEAVEFN("CSIContentHandler::CollectGarbageL")
|
|
170 |
}
|
|
171 |
|
|
172 |
// ---------------------------------------------------------
|
|
173 |
// CSIContentHandler::ParsePushMsgL
|
|
174 |
// Note that cXML parser dosn't do any validation!
|
|
175 |
// ---------------------------------------------------------
|
|
176 |
//
|
|
177 |
void CSIContentHandler::ParsePushMsgL()
|
|
178 |
{
|
|
179 |
PUSHLOG_ENTERFN("CSIContentHandler::ParsePushMsgL")
|
|
180 |
|
|
181 |
TPtrC8 bodyPtr;
|
|
182 |
iMessage->GetMessageBody( bodyPtr );
|
|
183 |
// If there is no body in the message leave with an error
|
|
184 |
if ( bodyPtr.Size() == 0 )
|
|
185 |
{
|
|
186 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: Empty body")
|
|
187 |
User::Leave( KErrCorrupt );
|
|
188 |
}
|
|
189 |
|
|
190 |
// Get content type. It will tell us wheather the msg body is encoded or
|
|
191 |
// textual.
|
|
192 |
TPtrC contentType;
|
|
193 |
iMessage->GetContentType( contentType );
|
|
194 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: HTTP header - Content type <%S>",&contentType);
|
|
195 |
|
|
196 |
/*
|
|
197 |
TPtrC8 encodingPtr;
|
|
198 |
TBool encodingFound = iMessage->GetHeaderField
|
|
199 |
( EHttpContentEncoding, encodingPtr );
|
|
200 |
#ifdef __TEST_LOG__
|
|
201 |
TBuf<64> encodingBuf;
|
|
202 |
encodingBuf.Copy( encodingPtr );
|
|
203 |
PUSHLOG_WRITE_FORMAT(" HTTP header - Content encoding <%S>",&encodingBuf);
|
|
204 |
#endif // __TEST_LOG__
|
|
205 |
*/
|
|
206 |
|
|
207 |
// Add SI dictionary.
|
|
208 |
NW_WBXML_Dictionary_t* dictArray[ KNoOfDictArrays ] =
|
|
209 |
{ (NW_WBXML_Dictionary_t*)&NW_SI_WBXMLDictionary };
|
|
210 |
|
|
211 |
NW_Status_t stat = NW_STAT_SUCCESS;
|
|
212 |
|
|
213 |
RWbxmlDictionary wbxmlDict;
|
|
214 |
wbxmlDict.InitializeL( KNoOfDictArrays, dictArray );
|
|
215 |
CleanupClosePushL<RWbxmlDictionary>( wbxmlDict );
|
|
216 |
|
|
217 |
NW_TinyDom_Handle_t domHandle;
|
|
218 |
NW_Byte* buffer = (NW_Byte*)bodyPtr.Ptr();
|
|
219 |
NW_Int32 length = (NW_Int32)bodyPtr.Size();
|
|
220 |
// Let's use the content type now.
|
|
221 |
NW_Bool encoded = ( contentType.CompareF( KSiTextContentType ) == 0 ) ?
|
|
222 |
NW_FALSE : NW_TRUE;
|
|
223 |
// SI public identifier.
|
|
224 |
NW_Uint32 publicID = NW_SI_PublicId;
|
|
225 |
NW_Bool extTNotStringTable = NW_FALSE;
|
|
226 |
NW_DOM_NodeType_t type = 0;
|
|
227 |
/**********************************
|
|
228 |
* Root of DOM
|
|
229 |
***********************************/
|
|
230 |
CDocumentTreeOwner* docTreeOwner = new (ELeave) CDocumentTreeOwner;
|
|
231 |
CleanupStack::PushL( docTreeOwner );
|
|
232 |
NW_DOM_DocumentNode_t* domNode = NW_DOM_DocumentNode_BuildTree
|
|
233 |
(
|
|
234 |
&domHandle,
|
|
235 |
buffer,
|
|
236 |
length,
|
|
237 |
encoded,
|
|
238 |
publicID,
|
|
239 |
extTNotStringTable
|
|
240 |
);
|
|
241 |
if (!domNode)
|
|
242 |
{
|
|
243 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: domNode is Null")
|
|
244 |
}
|
|
245 |
User::LeaveIfNull( domNode );
|
|
246 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: domNode is not Null") // to be deleted
|
|
247 |
// Let domNode be on the Cleanup Stack.
|
|
248 |
docTreeOwner->SetDocTree( domNode );
|
|
249 |
|
|
250 |
// It must be a document node.
|
|
251 |
type = NW_DOM_Node_getNodeType( domNode );
|
|
252 |
if ( type != NW_DOM_DOCUMENT_NODE )
|
|
253 |
{
|
|
254 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: Not Document node <%d>",type)
|
|
255 |
User::Leave( KErrArgument );
|
|
256 |
}
|
|
257 |
|
|
258 |
// Get character encoding (NW_Uint32)
|
|
259 |
iCharEncoding = NW_DOM_DocumentNode_getCharacterEncoding( domNode );
|
|
260 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: Doc char encoding <%x>",iCharEncoding)
|
|
261 |
|
|
262 |
/**********************************
|
|
263 |
* ELEMENT si
|
|
264 |
***********************************/
|
|
265 |
// Get the first element of the document that must be an si.
|
|
266 |
// first make sure if there any children in the dom tree, otherwise we will PANIC(in NW_DOM_DocumentNode_getDocumentElement) and crash WatcherMainThread.
|
|
267 |
TBool domNodeHasChildNodes = EFalse;
|
|
268 |
domNodeHasChildNodes = NW_DOM_Node_hasChildNodes( domNode );
|
|
269 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: check if Dom tree has <SI> node <%d>", domNodeHasChildNodes)
|
|
270 |
if (!domNodeHasChildNodes)
|
|
271 |
{
|
|
272 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: No SI element present in the dom tree. Message corrupted.")
|
|
273 |
User::Leave( KErrCorrupt );
|
|
274 |
}
|
|
275 |
|
|
276 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: before calling getDocumentElement")
|
|
277 |
NW_DOM_ElementNode_t* siElement =
|
|
278 |
NW_DOM_DocumentNode_getDocumentElement( domNode );
|
|
279 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: after calling getDocumentElement")
|
|
280 |
if (!siElement)
|
|
281 |
{
|
|
282 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: siElement is Null")
|
|
283 |
}
|
|
284 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: siElement is not Null, before leaving")
|
|
285 |
User::LeaveIfNull( siElement );
|
|
286 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: siElement is not Null, after leaving if siElement is null")
|
|
287 |
|
|
288 |
type = NW_DOM_Node_getNodeType( siElement );
|
|
289 |
|
|
290 |
CStringOwner* stringOwner = new (ELeave) CStringOwner;
|
|
291 |
CleanupStack::PushL( stringOwner );
|
|
292 |
|
|
293 |
NW_String_t* name = NW_String_new();
|
|
294 |
User::LeaveIfNull( name );
|
|
295 |
// Let name be on the Cleanup Stack.
|
|
296 |
stringOwner->SetString( name );
|
|
297 |
stat = NW_DOM_Node_getNodeName( siElement, name );
|
|
298 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
299 |
NW_Byte* nameBuf = NW_String_getStorage( name );
|
|
300 |
NW_Uint16 nameLen = NW_String_getCharCount( name, iCharEncoding );
|
|
301 |
TPtrC8 namePtr( nameBuf, nameLen );
|
|
302 |
|
|
303 |
// Now comes the validity check.
|
|
304 |
if ( type != NW_DOM_ELEMENT_NODE || namePtr.CompareF( KSi ) != 0 )
|
|
305 |
{
|
|
306 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: Not si element node <%d>",type)
|
|
307 |
User::Leave( KErrArgument );
|
|
308 |
}
|
|
309 |
|
|
310 |
CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
|
|
311 |
|
|
312 |
/**********************************
|
|
313 |
* ELEMENT indication
|
|
314 |
***********************************/
|
|
315 |
if ( NW_DOM_Node_hasChildNodes( siElement ) )
|
|
316 |
{
|
|
317 |
NW_DOM_Node_t* node = NW_DOM_Node_getFirstChild( siElement );
|
|
318 |
if (!node)
|
|
319 |
{
|
|
320 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: no si child nodes!")
|
|
321 |
}
|
|
322 |
User::LeaveIfNull( node );
|
|
323 |
|
|
324 |
// Find the indication element.
|
|
325 |
TBool indicationFound = EFalse;
|
|
326 |
do {
|
|
327 |
type = NW_DOM_Node_getNodeType( node );
|
|
328 |
|
|
329 |
CStringOwner* stringOwner = new (ELeave) CStringOwner;
|
|
330 |
CleanupStack::PushL( stringOwner );
|
|
331 |
|
|
332 |
NW_String_t* name = NW_String_new();
|
|
333 |
User::LeaveIfNull( name );
|
|
334 |
stringOwner->SetString( name );
|
|
335 |
stat = NW_DOM_Node_getNodeName( node, name );
|
|
336 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: getNodeName ErrCode: %d", NwxStatusToErrCode( stat ))
|
|
337 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
338 |
NW_Byte* nameBuf = NW_String_getStorage( name );
|
|
339 |
NW_Uint16 nameLen = NW_String_getCharCount( name,
|
|
340 |
iCharEncoding );
|
|
341 |
TPtrC8 namePtr( nameBuf, nameLen );
|
|
342 |
|
|
343 |
if ( type == NW_DOM_ELEMENT_NODE &&
|
|
344 |
namePtr.CompareF( KIndication ) == 0 )
|
|
345 |
{
|
|
346 |
// We found the indication element. Parse it.
|
|
347 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: indication under si found.")
|
|
348 |
indicationFound = ETrue;
|
|
349 |
NW_DOM_ElementNode_t* indicationElement =
|
|
350 |
REINTERPRET_CAST( NW_DOM_ElementNode_t*, node );
|
|
351 |
ParseIndicationL( *indicationElement );
|
|
352 |
}
|
|
353 |
|
|
354 |
CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
|
|
355 |
|
|
356 |
if ( !indicationFound )
|
|
357 |
{
|
|
358 |
// Iterate next.
|
|
359 |
node = NW_DOM_Node_getNextSibling( node );
|
|
360 |
if ( !node )
|
|
361 |
{
|
|
362 |
PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: No more sibling.")
|
|
363 |
break;
|
|
364 |
}
|
|
365 |
}
|
|
366 |
|
|
367 |
} while ( !indicationFound );
|
|
368 |
}
|
|
369 |
|
|
370 |
// Cleanup.
|
|
371 |
CleanupStack::PopAndDestroy( 2, &wbxmlDict ); // docTreeOwner, wbxmlDict
|
|
372 |
|
|
373 |
if ( !ActionFlag() )
|
|
374 |
{
|
|
375 |
// default if no action explicitly stated
|
|
376 |
iPushMsgAction = CSIPushMsgEntry::ESIPushMsgSignalMedium;
|
|
377 |
SetActionFlag( ETrue );
|
|
378 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: Defaulting to ActionFlag: %d",iPushMsgAction)
|
|
379 |
}
|
|
380 |
|
|
381 |
iState = EProcessing;
|
|
382 |
IdleComplete();
|
|
383 |
|
|
384 |
PUSHLOG_LEAVEFN("CSIContentHandler::ParsePushMsgL")
|
|
385 |
}
|
|
386 |
|
|
387 |
// ---------------------------------------------------------
|
|
388 |
// CSIContentHandler::ParseIndicationL
|
|
389 |
// ---------------------------------------------------------
|
|
390 |
//
|
|
391 |
void CSIContentHandler::ParseIndicationL( NW_DOM_ElementNode_t& aIndication )
|
|
392 |
{
|
|
393 |
PUSHLOG_ENTERFN("CSIContentHandler::ParseIndicationL")
|
|
394 |
|
|
395 |
NW_Status_t stat = NW_STAT_SUCCESS;
|
|
396 |
NW_DOM_NodeType_t type = 0;
|
|
397 |
|
|
398 |
if ( NW_DOM_ElementNode_hasAttributes( &aIndication ) )
|
|
399 |
{
|
|
400 |
NW_DOM_AttributeListIterator_t attrIter;
|
|
401 |
stat = NW_DOM_ElementNode_getAttributeListIterator
|
|
402 |
( &aIndication, &attrIter );
|
|
403 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParseIndicationL: getAttribListIter ErrCode: %d", NwxStatusToErrCode( stat ))
|
|
404 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
405 |
|
|
406 |
NW_DOM_AttributeHandle_t attrHandle;
|
|
407 |
while ( NW_DOM_AttributeListIterator_getNextAttribute
|
|
408 |
( &attrIter, &attrHandle ) == NW_STAT_WBXML_ITERATE_MORE )
|
|
409 |
{
|
|
410 |
ParseIndAttributeL( attrHandle );
|
|
411 |
}
|
|
412 |
}
|
|
413 |
|
|
414 |
/**********************************
|
|
415 |
* PCDATA of ELEMENT indication
|
|
416 |
***********************************/
|
|
417 |
if ( NW_DOM_Node_hasChildNodes( &aIndication ) )
|
|
418 |
{
|
|
419 |
NW_DOM_TextNode_t* textNode =
|
|
420 |
NW_DOM_Node_getFirstChild( &aIndication );
|
|
421 |
User::LeaveIfNull( textNode );
|
|
422 |
|
|
423 |
type = NW_DOM_Node_getNodeType( textNode );
|
|
424 |
if ( type != NW_DOM_TEXT_NODE )
|
|
425 |
{
|
|
426 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParseIndicationL: Not text node <%d>",type)
|
|
427 |
User::Leave( KErrArgument );
|
|
428 |
}
|
|
429 |
|
|
430 |
ParseTextL( *textNode );
|
|
431 |
}
|
|
432 |
|
|
433 |
PUSHLOG_LEAVEFN("CSIContentHandler::ParseIndicationL")
|
|
434 |
}
|
|
435 |
|
|
436 |
// ---------------------------------------------------------
|
|
437 |
// CSIContentHandler::ParseIndAttributeL
|
|
438 |
// ---------------------------------------------------------
|
|
439 |
//
|
|
440 |
void CSIContentHandler::ParseIndAttributeL( NW_DOM_AttributeHandle_t&
|
|
441 |
aAttrHandle )
|
|
442 |
{
|
|
443 |
PUSHLOG_ENTERFN("CSIContentHandler::ParseIndAttributeL")
|
|
444 |
|
|
445 |
NW_Status_t stat = NW_STAT_SUCCESS;
|
|
446 |
|
|
447 |
CStringOwner* stringOwner = new (ELeave) CStringOwner;
|
|
448 |
CleanupStack::PushL( stringOwner );
|
|
449 |
|
|
450 |
NW_String_t* attrName = NW_String_new();
|
|
451 |
User::LeaveIfNull( attrName );
|
|
452 |
stringOwner->SetString( attrName );
|
|
453 |
|
|
454 |
// Get the name of the attribute.
|
|
455 |
stat = NW_DOM_AttributeHandle_getName( &aAttrHandle, attrName );
|
|
456 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
457 |
NW_Byte* attrNameBuf = NW_String_getStorage( attrName );
|
|
458 |
NW_Uint16 attrNameLen = NW_String_getCharCount( attrName, iCharEncoding );
|
|
459 |
TPtrC8 attrNamePtr( attrNameBuf, attrNameLen );
|
|
460 |
|
|
461 |
if ( attrNamePtr.CompareF( KCreatedAttrib ) == 0 )
|
|
462 |
{
|
|
463 |
if ( CreatedFlag() )
|
|
464 |
{
|
|
465 |
PUSHLOG_WRITE(" created redefinition")
|
|
466 |
User::Leave( KErrCorrupt );
|
|
467 |
}
|
|
468 |
else
|
|
469 |
{
|
|
470 |
TBool gotDate = AttributeToTTimeL( aAttrHandle, iCreatedTime );
|
|
471 |
SetCreatedFlag( gotDate );
|
|
472 |
PUSHLOG_WRITE_FORMAT(" iCreatedTime set %d",gotDate?1:0)
|
|
473 |
}
|
|
474 |
}
|
|
475 |
else if ( attrNamePtr.CompareF( KHrefAttrib ) == 0 )
|
|
476 |
{
|
|
477 |
if ( HrefFlag() )
|
|
478 |
{
|
|
479 |
PUSHLOG_WRITE(" href redefinition")
|
|
480 |
User::Leave( KErrCorrupt );
|
|
481 |
}
|
|
482 |
else
|
|
483 |
{
|
|
484 |
CStringOwner* stringOwner = new (ELeave) CStringOwner;
|
|
485 |
CleanupStack::PushL( stringOwner );
|
|
486 |
|
|
487 |
NW_String_t* val = NW_String_new();
|
|
488 |
User::LeaveIfNull( val );
|
|
489 |
stringOwner->SetString( val );
|
|
490 |
stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
|
|
491 |
if ( stat != NW_STAT_DOM_NO_STRING_RETURNED )
|
|
492 |
{
|
|
493 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
494 |
NW_Byte* storage = NW_String_getStorage( val );
|
|
495 |
NW_Uint16 length = NW_String_getCharCount( val,
|
|
496 |
iCharEncoding );
|
|
497 |
if ( length == 0 )
|
|
498 |
{
|
|
499 |
// Zero length href attribute is considered as missing.
|
|
500 |
PUSHLOG_WRITE(" Zero length HrefFlag");
|
|
501 |
}
|
|
502 |
else
|
|
503 |
{
|
|
504 |
TPtrC8 hrefPtr( storage, length );
|
|
505 |
HBufC* tempHrefBuf = HBufC::NewMaxL( length );
|
|
506 |
// No leavable after it!!! until...
|
|
507 |
tempHrefBuf->Des().Copy( hrefPtr );
|
|
508 |
iHrefBuf = tempHrefBuf; // ...until here.
|
|
509 |
SetHrefFlag( ETrue );
|
|
510 |
PUSHLOG_WRITE_FORMAT(" HrefFlag set <%S>",iHrefBuf);
|
|
511 |
}
|
|
512 |
}
|
|
513 |
|
|
514 |
CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
|
|
515 |
}
|
|
516 |
}
|
|
517 |
else if ( attrNamePtr.CompareF( KExpiresAttrib ) == 0 )
|
|
518 |
{
|
|
519 |
if ( ExpiresFlag() )
|
|
520 |
{
|
|
521 |
PUSHLOG_WRITE(" expires redefinition")
|
|
522 |
User::Leave( KErrCorrupt );
|
|
523 |
}
|
|
524 |
else
|
|
525 |
{
|
|
526 |
TBool gotDate = AttributeToTTimeL( aAttrHandle, iExpiresTime );
|
|
527 |
SetExpiresFlag( gotDate );
|
|
528 |
PUSHLOG_WRITE_FORMAT(" iExpiresTime set %d",gotDate?1:0)
|
|
529 |
}
|
|
530 |
}
|
|
531 |
else if ( attrNamePtr.CompareF( KSiIdAttrib ) == 0 )
|
|
532 |
{
|
|
533 |
if ( SiIdFlag() )
|
|
534 |
{
|
|
535 |
PUSHLOG_WRITE(" si-id redefinition")
|
|
536 |
User::Leave( KErrCorrupt );
|
|
537 |
}
|
|
538 |
else
|
|
539 |
{
|
|
540 |
// It is expected to be String.
|
|
541 |
CStringOwner* stringOwner = new (ELeave) CStringOwner;
|
|
542 |
CleanupStack::PushL( stringOwner );
|
|
543 |
|
|
544 |
NW_String_t* val = NW_String_new();
|
|
545 |
User::LeaveIfNull( val );
|
|
546 |
stringOwner->SetString( val );
|
|
547 |
stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
|
|
548 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
549 |
NW_Byte* storage = NW_String_getStorage( val );
|
|
550 |
NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
|
|
551 |
TPtrC8 siidPtr( storage, length );
|
|
552 |
|
|
553 |
iSiIdBuf = HBufC::NewMaxL( siidPtr.Length() );
|
|
554 |
iSiIdBuf->Des().Copy( siidPtr );
|
|
555 |
SetSiIdFlag( ETrue );
|
|
556 |
PUSHLOG_WRITE_FORMAT(" SiIdFlag set <%S>",iSiIdBuf)
|
|
557 |
|
|
558 |
CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
|
|
559 |
}
|
|
560 |
}
|
|
561 |
else if ( attrNamePtr.CompareF( KActionAttrib ) == 0 )
|
|
562 |
{
|
|
563 |
if ( ActionFlag() )
|
|
564 |
{
|
|
565 |
PUSHLOG_WRITE(" action redefinition")
|
|
566 |
User::Leave( KErrCorrupt );
|
|
567 |
}
|
|
568 |
else
|
|
569 |
{
|
|
570 |
// It is expected to be String.
|
|
571 |
CStringOwner* stringOwner = new (ELeave) CStringOwner;
|
|
572 |
CleanupStack::PushL( stringOwner );
|
|
573 |
|
|
574 |
NW_String_t* val = NW_String_new();
|
|
575 |
User::LeaveIfNull( val );
|
|
576 |
stringOwner->SetString( val );
|
|
577 |
stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
|
|
578 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
579 |
NW_Byte* storage = NW_String_getStorage( val );
|
|
580 |
NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
|
|
581 |
TPtrC8 actionPtr( storage, length );
|
|
582 |
|
|
583 |
iPushMsgAction = ConvertActionString( actionPtr );
|
|
584 |
SetActionFlag( ETrue );
|
|
585 |
PUSHLOG_WRITE_FORMAT(" ActionFlag: %d",iPushMsgAction)
|
|
586 |
|
|
587 |
CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
|
|
588 |
}
|
|
589 |
}
|
|
590 |
else
|
|
591 |
{
|
|
592 |
__ASSERT_DEBUG( EFalse,
|
|
593 |
ContHandPanic( EPushContHandPanUnexpSiToken ) );
|
|
594 |
}
|
|
595 |
|
|
596 |
CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
|
|
597 |
|
|
598 |
PUSHLOG_LEAVEFN("CSIContentHandler::ParseIndAttributeL")
|
|
599 |
}
|
|
600 |
|
|
601 |
// ---------------------------------------------------------
|
|
602 |
// CSIContentHandler::ParseTextL
|
|
603 |
// ---------------------------------------------------------
|
|
604 |
//
|
|
605 |
void CSIContentHandler::ParseTextL( NW_DOM_TextNode_t& aTextNode )
|
|
606 |
{
|
|
607 |
PUSHLOG_ENTERFN("CSIContentHandler::ParseTextL")
|
|
608 |
|
|
609 |
if ( DataFlag() )
|
|
610 |
{
|
|
611 |
PUSHLOG_WRITE(" Data flag already set.")
|
|
612 |
}
|
|
613 |
else
|
|
614 |
{
|
|
615 |
CStringOwner* stringOwner = new (ELeave) CStringOwner;
|
|
616 |
CleanupStack::PushL( stringOwner );
|
|
617 |
|
|
618 |
NW_String_t* data = NW_String_new();
|
|
619 |
User::LeaveIfNull( data );
|
|
620 |
stringOwner->SetString( data );
|
|
621 |
NW_Status_t stat = NW_STAT_SUCCESS;
|
|
622 |
stat = NW_DOM_TextNode_getData( &aTextNode, data );
|
|
623 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
624 |
|
|
625 |
HBufC16* ucs2buffer = ConvertToUnicodeL( *data, iCharEncoding );
|
|
626 |
// Be careful: ucs2buffer is not on the CleanupStack!
|
|
627 |
__ASSERT_DEBUG( ucs2buffer != 0, ContHandPanic( EPushContHandPanNullUcs2Buf ) );
|
|
628 |
|
|
629 |
TPtrC16 ucs2ptrC( *ucs2buffer );
|
|
630 |
if ( ucs2ptrC.Length() == 0 )
|
|
631 |
{
|
|
632 |
// Zero length data is considered as nothing.
|
|
633 |
PUSHLOG_WRITE(" Zero length Data");
|
|
634 |
}
|
|
635 |
else
|
|
636 |
{
|
|
637 |
PUSHLOG_WRITE_FORMAT(" Data: <%S>",&ucs2ptrC);
|
|
638 |
|
|
639 |
#ifdef __TEST_LOG__
|
|
640 |
// Write out each unicode character identifier
|
|
641 |
TInt length = ucs2ptrC.Length();
|
|
642 |
for (TInt logI=0;logI<length;logI++)
|
|
643 |
{
|
|
644 |
TBuf16<1> currChar;
|
|
645 |
currChar.Copy( ucs2ptrC.Mid( logI, /*aLength*/1 ) );
|
|
646 |
PUSHLOG_WRITE_FORMAT2(" 0x%x %S",currChar[0],&currChar);
|
|
647 |
}
|
|
648 |
#endif // __TEST_LOG__
|
|
649 |
|
|
650 |
iData = ucs2buffer; // Ownership transferred.
|
|
651 |
ucs2buffer = NULL;
|
|
652 |
SetDataFlag( ETrue );
|
|
653 |
}
|
|
654 |
|
|
655 |
CleanupStack::PopAndDestroy( stringOwner );
|
|
656 |
}
|
|
657 |
|
|
658 |
PUSHLOG_LEAVEFN("CSIContentHandler::ParseTextL")
|
|
659 |
}
|
|
660 |
|
|
661 |
// ---------------------------------------------------------
|
|
662 |
// CSIContentHandler::ConvertToUnicodeL
|
|
663 |
// ---------------------------------------------------------
|
|
664 |
//
|
|
665 |
HBufC16* CSIContentHandler::ConvertToUnicodeL( const TDesC8& aSrc, TUint aCharSetId )
|
|
666 |
{
|
|
667 |
PUSHLOG_ENTERFN("CSIContentHandler::ConvertToUnicodeL");
|
|
668 |
|
|
669 |
__ASSERT_DEBUG( aCharSetId != 0, ContHandPanic( EPushContHandPanNullCharSetId ) );
|
|
670 |
|
|
671 |
InitialiseCharacterSetConverterL();
|
|
672 |
|
|
673 |
HBufC16* ucs2buffer = NULL; // The return value.
|
|
674 |
TBool resultOnStack = EFalse;
|
|
675 |
|
|
676 |
#ifdef __TEST_LOG__
|
|
677 |
// Write out the original 8-bit buffer
|
|
678 |
TInt origiLength = aSrc.Length();
|
|
679 |
for (TInt origiLogI=0;origiLogI<origiLength;origiLogI++)
|
|
680 |
{
|
|
681 |
TBuf16<1> currChar; // Only 16-bit buffer can be written out.
|
|
682 |
currChar.Copy( aSrc.Mid( origiLogI, /*aLength*/1 ) );
|
|
683 |
PUSHLOG_WRITE_FORMAT2(" 0x%x %S",currChar[0],&currChar);
|
|
684 |
}
|
|
685 |
#endif // __TEST_LOG__
|
|
686 |
|
|
687 |
// Result
|
|
688 |
HBufC16* buffer = HBufC16::NewLC( KPushConversionBufferSize );
|
|
689 |
PUSHLOG_WRITE(" buffer allocated");
|
|
690 |
TPtr16 ptr( buffer->Des() );
|
|
691 |
|
|
692 |
// Prepare conversion for the given charset ID.
|
|
693 |
RFs& fs = iMsvSession->FileSession();
|
|
694 |
iCharacterSetConverter->PrepareToConvertToOrFromL
|
|
695 |
( aCharSetId, *iCharacterSetsAvailable, fs );
|
|
696 |
PUSHLOG_WRITE(" PrepareToConvertToOrFromL OK");
|
|
697 |
|
|
698 |
TInt state = 0;
|
|
699 |
TInt remaining = iCharacterSetConverter->ConvertToUnicode( ptr, aSrc, state );
|
|
700 |
PUSHLOG_WRITE_FORMAT(" remaining: %d",remaining);
|
|
701 |
while ( remaining >= 0 )
|
|
702 |
{
|
|
703 |
if ( ucs2buffer == NULL )
|
|
704 |
{
|
|
705 |
ucs2buffer = HBufC::NewLC( ptr.Length() );
|
|
706 |
resultOnStack = ETrue;
|
|
707 |
}
|
|
708 |
else
|
|
709 |
{
|
|
710 |
__ASSERT_DEBUG( resultOnStack,
|
|
711 |
ContHandPanic( EPushContHandPanSiResNotOnStack ) );
|
|
712 |
// This may change the address of ucs2buffer so we need to put
|
|
713 |
// it on the cleanup stack again!!
|
|
714 |
ucs2buffer = ucs2buffer->ReAllocL
|
|
715 |
( ucs2buffer->Length() + ptr.Length() );
|
|
716 |
CleanupStack::Pop(); // old ucs2buffer
|
|
717 |
CleanupStack::PushL( ucs2buffer ); // possibly new copy
|
|
718 |
PUSHLOG_WRITE(" ucs2buffer reallocated");
|
|
719 |
}
|
|
720 |
TPtr16 ucs2ptr( ucs2buffer->Des() );
|
|
721 |
ucs2ptr.Append( ptr );
|
|
722 |
if ( remaining > 0 )
|
|
723 |
{
|
|
724 |
// Try to convert all remaining characters.
|
|
725 |
ptr.Zero();
|
|
726 |
remaining = iCharacterSetConverter->ConvertToUnicode
|
|
727 |
( ptr, aSrc.Right( remaining ), state );
|
|
728 |
PUSHLOG_WRITE_FORMAT(" remaining: %d",remaining);
|
|
729 |
}
|
|
730 |
else
|
|
731 |
{
|
|
732 |
PUSHLOG_WRITE(" break");
|
|
733 |
break;
|
|
734 |
}
|
|
735 |
}
|
|
736 |
|
|
737 |
if ( resultOnStack )
|
|
738 |
{
|
|
739 |
CleanupStack::Pop(); // ucs2buffer
|
|
740 |
resultOnStack = EFalse;
|
|
741 |
}
|
|
742 |
|
|
743 |
// ucs2buffer is not on the CleanupStack!
|
|
744 |
|
|
745 |
CleanupStack::PopAndDestroy( buffer ); // buffer
|
|
746 |
|
|
747 |
if ( ucs2buffer == NULL )
|
|
748 |
{
|
|
749 |
PUSHLOG_WRITE(" NULL ucs2buffer - allocating an empty buf");
|
|
750 |
ucs2buffer = KNullDesC().AllocL();
|
|
751 |
}
|
|
752 |
else
|
|
753 |
{
|
|
754 |
// Check if first character is a Zero-width nbsp.
|
|
755 |
TPtrC16 ucs2ptrC( *ucs2buffer );
|
|
756 |
if ( ucs2ptrC.Length() >= 1 && ucs2ptrC[0] == KPushZeroWidthNbsp )
|
|
757 |
{
|
|
758 |
// First character is a Zero-width NBSP. This character is used as
|
|
759 |
// BOM in some encodings and should not be present at this point.
|
|
760 |
// But we are tolerant and remove it.
|
|
761 |
// (Not expecting big-endianness here.)
|
|
762 |
HBufC16* temp = ucs2buffer;
|
|
763 |
CleanupStack::PushL( temp );
|
|
764 |
ucs2buffer = ucs2ptrC.Mid( 1 ).AllocL();
|
|
765 |
CleanupStack::PopAndDestroy( temp ); // temp
|
|
766 |
PUSHLOG_WRITE(" BOM removed");
|
|
767 |
}
|
|
768 |
else
|
|
769 |
{
|
|
770 |
PUSHLOG_WRITE(" No BOM");
|
|
771 |
}
|
|
772 |
}
|
|
773 |
|
|
774 |
|
|
775 |
PUSHLOG_LEAVEFN("CSIContentHandler::ConvertToUnicodeL");
|
|
776 |
return ucs2buffer;
|
|
777 |
}
|
|
778 |
|
|
779 |
// ---------------------------------------------------------
|
|
780 |
// CSIContentHandler::ConvertToUnicodeL
|
|
781 |
// ---------------------------------------------------------
|
|
782 |
//
|
|
783 |
HBufC16* CSIContentHandler::ConvertToUnicodeL
|
|
784 |
( NW_String_t& aString, NW_Uint32 aCharEncoding )
|
|
785 |
{
|
|
786 |
PUSHLOG_ENTERFN("CSIContentHandler::ConvertToUnicodeL");
|
|
787 |
|
|
788 |
/* As cXmlLibrary does, we support only the following charsets:
|
|
789 |
#define HTTP_iso_10646_ucs_2 0x03E8
|
|
790 |
#define HTTP_iso_8859_1 0x04
|
|
791 |
#define HTTP_us_ascii 0x03
|
|
792 |
#define HTTP_utf_8 0x6A
|
|
793 |
#define HTTP_utf_16 1015
|
|
794 |
*/
|
|
795 |
TUint id = 0;
|
|
796 |
if ( aCharEncoding == HTTP_iso_10646_ucs_2 )
|
|
797 |
{
|
|
798 |
id = KCharacterSetIdentifierUcs2;
|
|
799 |
PUSHLOG_WRITE(" KCharacterSetIdentifierUcs2")
|
|
800 |
}
|
|
801 |
else if ( aCharEncoding == HTTP_iso_8859_1 )
|
|
802 |
{
|
|
803 |
id = KCharacterSetIdentifierIso88591;
|
|
804 |
PUSHLOG_WRITE(" KCharacterSetIdentifierIso88591")
|
|
805 |
}
|
|
806 |
else if ( aCharEncoding == HTTP_us_ascii )
|
|
807 |
{
|
|
808 |
id = KCharacterSetIdentifierAscii;
|
|
809 |
PUSHLOG_WRITE(" KCharacterSetIdentifierAscii")
|
|
810 |
}
|
|
811 |
else if ( aCharEncoding == HTTP_utf_8 )
|
|
812 |
{
|
|
813 |
id = KCharacterSetIdentifierUtf8;
|
|
814 |
PUSHLOG_WRITE(" KCharacterSetIdentifierUtf8")
|
|
815 |
}
|
|
816 |
else if ( aCharEncoding == HTTP_utf_16 ) // No such in CharConv.h
|
|
817 |
{
|
|
818 |
id = KCharacterSetIdentifierUcs2;
|
|
819 |
PUSHLOG_WRITE(" KCharacterSetIdentifierUcs2")
|
|
820 |
}
|
|
821 |
else
|
|
822 |
{
|
|
823 |
id = KCharacterSetIdentifierUtf8; // Defaulting to UTF-8
|
|
824 |
PUSHLOG_WRITE(" DEFAULTING to KCharacterSetIdentifierUtf8");
|
|
825 |
}
|
|
826 |
|
|
827 |
PUSHLOG_WRITE_FORMAT(" id: 0x%x",id);
|
|
828 |
__ASSERT_DEBUG( id != 0, ContHandPanic( EPushContHandPanNullCharSetId ) );
|
|
829 |
|
|
830 |
// Source
|
|
831 |
PUSHLOG_WRITE_FORMAT(" Storage: 0x%x",NW_String_getStorage(&aString));
|
|
832 |
PUSHLOG_WRITE_FORMAT(" Byte count: %d",NW_String_getByteCount(&aString)-1);
|
|
833 |
|
|
834 |
// We will use NW_String_getByteCount(&aString)-1 as size, because
|
|
835 |
// NW_String_getByteCount(&aString) includes NULL terminator.
|
|
836 |
const TPtrC8 src( NW_String_getStorage(&aString),
|
|
837 |
NW_String_getByteCount(&aString)-1 );
|
|
838 |
HBufC16* ucs2buffer = ConvertToUnicodeL( src, id );
|
|
839 |
|
|
840 |
PUSHLOG_LEAVEFN("CSIContentHandler::ConvertToUnicodeL");
|
|
841 |
return ucs2buffer;
|
|
842 |
}
|
|
843 |
|
|
844 |
// ---------------------------------------------------------
|
|
845 |
// CSIContentHandler::InitialiseCharacterSetConverterL
|
|
846 |
// ---------------------------------------------------------
|
|
847 |
//
|
|
848 |
void CSIContentHandler::InitialiseCharacterSetConverterL()
|
|
849 |
{
|
|
850 |
PUSHLOG_ENTERFN("CSIContentHandler::InitialiseCharacterSetConverterL")
|
|
851 |
|
|
852 |
iCharacterSetConverter = CCnvCharacterSetConverter::NewL();
|
|
853 |
|
|
854 |
RFs& fs = iMsvSession->FileSession();
|
|
855 |
iCharacterSetsAvailable =
|
|
856 |
CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL( fs );
|
|
857 |
|
|
858 |
PUSHLOG_LEAVEFN("CSIContentHandler::InitialiseCharacterSetConverterL")
|
|
859 |
}
|
|
860 |
|
|
861 |
// ---------------------------------------------------------
|
|
862 |
// CSIContentHandler::ConvertActionString
|
|
863 |
// ---------------------------------------------------------
|
|
864 |
//
|
|
865 |
TUint CSIContentHandler::ConvertActionString
|
|
866 |
( const TDesC8& aActionString ) const
|
|
867 |
{
|
|
868 |
const TInt KMatchFound = 0;
|
|
869 |
|
|
870 |
// set to default signal value (to rid ourselves of build warning)
|
|
871 |
TUint actionValue = CSIPushMsgEntry::ESIPushMsgSignalMedium;
|
|
872 |
|
|
873 |
if ( aActionString.Compare( KDeleteAction ) == KMatchFound )
|
|
874 |
{
|
|
875 |
actionValue = CSIPushMsgEntry::ESIPushMsgDelete;
|
|
876 |
}
|
|
877 |
else if ( aActionString.Compare( KSignalNone ) == KMatchFound )
|
|
878 |
{
|
|
879 |
actionValue = CSIPushMsgEntry::ESIPushMsgSignalNone;
|
|
880 |
}
|
|
881 |
else if ( aActionString.Compare( KSignalLow ) == KMatchFound )
|
|
882 |
{
|
|
883 |
actionValue = CSIPushMsgEntry::ESIPushMsgSignalLow;
|
|
884 |
}
|
|
885 |
else if ( aActionString.Compare( KSignalMedium ) == KMatchFound )
|
|
886 |
{
|
|
887 |
actionValue = CSIPushMsgEntry::ESIPushMsgSignalMedium;
|
|
888 |
}
|
|
889 |
else if ( aActionString.Compare( KSignalHigh ) == KMatchFound )
|
|
890 |
{
|
|
891 |
actionValue = CSIPushMsgEntry::ESIPushMsgSignalHigh;
|
|
892 |
}
|
|
893 |
|
|
894 |
return actionValue;
|
|
895 |
}
|
|
896 |
|
|
897 |
// ---------------------------------------------------------
|
|
898 |
// CSIContentHandler::SetSIPushMsgEntryFieldsL
|
|
899 |
// ---------------------------------------------------------
|
|
900 |
//
|
|
901 |
void CSIContentHandler::SetSIPushMsgEntryFieldsL( CSIPushMsgEntry&
|
|
902 |
aSIPushMsgEntry )
|
|
903 |
{
|
|
904 |
PUSHLOG_ENTERFN("CSIContentHandler::SetSIPushMsgEntryFieldsL")
|
|
905 |
|
|
906 |
if ( SiIdFlag() || HrefFlag() )
|
|
907 |
{
|
|
908 |
if ( SiIdFlag() && ( HrefFlag() == EFalse ) )
|
|
909 |
{
|
|
910 |
// Message has only si-id but no href.
|
|
911 |
aSIPushMsgEntry.SetIdL( *iSiIdBuf );
|
|
912 |
}
|
|
913 |
else if ( HrefFlag() && ( SiIdFlag() == EFalse ) )
|
|
914 |
{
|
|
915 |
// If message has no si-id but does have a href, use href as si-id.
|
|
916 |
aSIPushMsgEntry.SetIdL( *iHrefBuf );
|
|
917 |
aSIPushMsgEntry.SetUrlL( *iHrefBuf );
|
|
918 |
}
|
|
919 |
else
|
|
920 |
{
|
|
921 |
// Use si-id and href as is.
|
|
922 |
aSIPushMsgEntry.SetIdL( *iSiIdBuf );
|
|
923 |
aSIPushMsgEntry.SetUrlL( *iHrefBuf );
|
|
924 |
}
|
|
925 |
}
|
|
926 |
|
|
927 |
__ASSERT_DEBUG( ActionFlag(),
|
|
928 |
ContHandPanic( EPushContHandPanUnspecSiAction ) );
|
|
929 |
if ( ActionFlag() )
|
|
930 |
{
|
|
931 |
aSIPushMsgEntry.SetAction( iPushMsgAction );
|
|
932 |
}
|
|
933 |
else // default if no action explicitly stated
|
|
934 |
{
|
|
935 |
aSIPushMsgEntry.SetAction( CSIPushMsgEntry::ESIPushMsgSignalMedium );
|
|
936 |
}
|
|
937 |
|
|
938 |
// uses default null time value if no explicit date set in message
|
|
939 |
aSIPushMsgEntry.SetCreated( iCreatedTime );
|
|
940 |
aSIPushMsgEntry.SetExpires( iExpiresTime );
|
|
941 |
|
|
942 |
// PCDATA (text) from message
|
|
943 |
if ( DataFlag() )
|
|
944 |
{
|
|
945 |
aSIPushMsgEntry.SetTextL( *iData );
|
|
946 |
}
|
|
947 |
|
|
948 |
TPtrC8 msgHeaderPtr;
|
|
949 |
iMessage->GetHeader( msgHeaderPtr );
|
|
950 |
aSIPushMsgEntry.SetHeaderL( msgHeaderPtr );
|
|
951 |
|
|
952 |
// Get server address.
|
|
953 |
TPtrC8 srvAddress;
|
|
954 |
if ( iMessage->GetServerAddress( srvAddress ) )
|
|
955 |
{
|
|
956 |
aSIPushMsgEntry.SetFromL( srvAddress );
|
|
957 |
}
|
|
958 |
|
|
959 |
// First line in Inbox: TMsvEntry::iDetails.
|
|
960 |
if ( srvAddress.Length() == 0 )
|
|
961 |
{
|
|
962 |
// Read from resource.
|
|
963 |
HBufC* details =
|
|
964 |
iStrRscReader->AllocReadResourceLC( R_PUSHMISC_UNK_SENDER );
|
|
965 |
aSIPushMsgEntry.SetMsgDetailsL( *details );
|
|
966 |
CleanupStack::PopAndDestroy( details );
|
|
967 |
}
|
|
968 |
else
|
|
969 |
{
|
|
970 |
// Convert the "From" information to the format required by the UI
|
|
971 |
// spec and then decode it.
|
|
972 |
HBufC* details = iWapPushUtils->ConvertDetailsL( srvAddress );
|
|
973 |
CleanupStack::PushL( details );
|
|
974 |
HBufC* convertedFrom =
|
|
975 |
CPushMtmUtil::ConvertUriToDisplayFormL( *details );
|
|
976 |
CleanupStack::PushL( convertedFrom );
|
|
977 |
//
|
|
978 |
aSIPushMsgEntry.SetMsgDetailsL( *convertedFrom );
|
|
979 |
//
|
|
980 |
CleanupStack::PopAndDestroy( 2, details ); // convertedFrom, details
|
|
981 |
}
|
|
982 |
|
|
983 |
// Second line in Inbox: TMsvEntry::iDescription.
|
|
984 |
if ( DataFlag() )
|
|
985 |
{
|
|
986 |
// Display SI message.
|
|
987 |
aSIPushMsgEntry.SetMsgDescriptionL( *iData );
|
|
988 |
}
|
|
989 |
else
|
|
990 |
{
|
|
991 |
// Display URL.
|
|
992 |
__ASSERT_DEBUG( HrefFlag(),
|
|
993 |
ContHandPanic( EPushContHandPanUnspecSiHref ) );
|
|
994 |
const TPtrC url = aSIPushMsgEntry.Url();
|
|
995 |
HBufC* convertedUrl = CPushMtmUtil::ConvertUriToDisplayFormL( url );
|
|
996 |
CleanupStack::PushL( convertedUrl );
|
|
997 |
//
|
|
998 |
aSIPushMsgEntry.SetMsgDescriptionL( *convertedUrl );
|
|
999 |
//
|
|
1000 |
CleanupStack::PopAndDestroy( convertedUrl ); // convertedUrl
|
|
1001 |
}
|
|
1002 |
|
|
1003 |
// ******** Push MTM specific processing *********
|
|
1004 |
|
|
1005 |
/*
|
|
1006 |
* Unfortunately in CPushMsgEntryBase there is no such functionality
|
|
1007 |
* with which we can reach TMsvEntry as non-const, but we have to
|
|
1008 |
* modify the entry's iMtmData2 member somehow. We can do it
|
|
1009 |
* with either casting or with modifying and saving the entry
|
|
1010 |
* manually after it has been saved by CSIPushMsgEntry. The latter
|
|
1011 |
* solution is more expensive so we choose the first.
|
|
1012 |
*/
|
|
1013 |
TMsvEntry& tEntry = CONST_CAST( TMsvEntry&, aSIPushMsgEntry.Entry() );
|
|
1014 |
if ( HrefFlag() )
|
|
1015 |
{
|
|
1016 |
CPushMtmUtil::SetAttrs( tEntry, EPushMtmAttrHasHref );
|
|
1017 |
}
|
|
1018 |
else
|
|
1019 |
{
|
|
1020 |
CPushMtmUtil::ResetAttrs( tEntry, EPushMtmAttrHasHref );
|
|
1021 |
}
|
|
1022 |
|
|
1023 |
// *** Set the entry to unread and new state. ***
|
|
1024 |
|
|
1025 |
tEntry.SetNew( ETrue );
|
|
1026 |
tEntry.SetUnread( ETrue );
|
|
1027 |
|
|
1028 |
PUSHLOG_LEAVEFN("CSIContentHandler::SetSIPushMsgEntryFieldsL")
|
|
1029 |
}
|
|
1030 |
|
|
1031 |
// ---------------------------------------------------------
|
|
1032 |
// CSIContentHandler::ProcessingPushMsgEntryL
|
|
1033 |
// ---------------------------------------------------------
|
|
1034 |
//
|
|
1035 |
void CSIContentHandler::ProcessingPushMsgEntryL()
|
|
1036 |
{
|
|
1037 |
PUSHLOG_ENTERFN("CSIContentHandler::ProcessingPushMsgEntryL")
|
|
1038 |
|
|
1039 |
TBool deletePushMsg( EFalse );
|
|
1040 |
|
|
1041 |
__ASSERT_DEBUG( ActionFlag(),
|
|
1042 |
ContHandPanic( EPushContHandPanUnspecSiAction ) );
|
|
1043 |
|
|
1044 |
// S60 requirement: if both the href and the message is empty then
|
|
1045 |
// delete the msg.
|
|
1046 |
if ( HrefFlag() == EFalse && DataFlag() == EFalse )
|
|
1047 |
{
|
|
1048 |
deletePushMsg = ETrue;
|
|
1049 |
}
|
|
1050 |
|
|
1051 |
// Expiration.
|
|
1052 |
if ( !deletePushMsg && ExpiresFlag() )
|
|
1053 |
{
|
|
1054 |
TTime today;
|
|
1055 |
today.UniversalTime();
|
|
1056 |
#ifdef __TEST_LOG__
|
|
1057 |
_LIT( KDateFormat, "%E%D%X%N%Y %1 %2 %3" );
|
|
1058 |
_LIT( KTimeFormat, "%-B%:0%J%:1%T%:2%S%:3%+B" );
|
|
1059 |
TBuf<32> dateHolder;
|
|
1060 |
TBuf<32> timeHolder;
|
|
1061 |
today.FormatL( dateHolder, KDateFormat );
|
|
1062 |
today.FormatL( timeHolder, KTimeFormat );
|
|
1063 |
PUSHLOG_WRITE_FORMAT(" now date: <%S>",&dateHolder)
|
|
1064 |
PUSHLOG_WRITE_FORMAT(" now time: <%S>",&timeHolder)
|
|
1065 |
iExpiresTime.FormatL( dateHolder, KDateFormat );
|
|
1066 |
iExpiresTime.FormatL( timeHolder, KTimeFormat );
|
|
1067 |
PUSHLOG_WRITE_FORMAT(" exp date: <%S>",&dateHolder)
|
|
1068 |
PUSHLOG_WRITE_FORMAT(" exp time: <%S>",&timeHolder)
|
|
1069 |
#endif // __TEST_LOG__
|
|
1070 |
// check if message has expiry date before today's date
|
|
1071 |
if ( iExpiresTime < today )
|
|
1072 |
{
|
|
1073 |
PUSHLOG_WRITE("CSIContentHandler already expired")
|
|
1074 |
deletePushMsg = ETrue;
|
|
1075 |
}
|
|
1076 |
}
|
|
1077 |
|
|
1078 |
// An SI with the action attribute set to “delete” MUST have an
|
|
1079 |
// explicitly assigned value for si-id.
|
|
1080 |
if ( !deletePushMsg && ActionFlag() )
|
|
1081 |
{
|
|
1082 |
if ( iPushMsgAction == CSIPushMsgEntry::ESIPushMsgDelete )
|
|
1083 |
{
|
|
1084 |
if ( !SiIdFlag() || ( SiIdFlag() && iSiIdBuf->Length() == 0 ) )
|
|
1085 |
{
|
|
1086 |
deletePushMsg = ETrue;
|
|
1087 |
}
|
|
1088 |
}
|
|
1089 |
}
|
|
1090 |
|
|
1091 |
// Handling out of order delivery & Replacement.
|
|
1092 |
TMsvId matchingEntryId = KMsvNullIndexEntryId;
|
|
1093 |
|
|
1094 |
if ( !deletePushMsg && ( SiIdFlag() || HrefFlag() ) && CreatedFlag() )
|
|
1095 |
{
|
|
1096 |
deletePushMsg = HandleMsgOrderReceptionL( matchingEntryId );
|
|
1097 |
}
|
|
1098 |
|
|
1099 |
if ( !deletePushMsg && ActionFlag() )
|
|
1100 |
{
|
|
1101 |
// SI with action=signal-none must not be presented to the end-user.
|
|
1102 |
// Note. In S60 signal-none behaves the same as delete: the
|
|
1103 |
// message is discarded after processing it!
|
|
1104 |
if ( iPushMsgAction == CSIPushMsgEntry::ESIPushMsgSignalNone )
|
|
1105 |
{
|
|
1106 |
deletePushMsg = ETrue;
|
|
1107 |
}
|
|
1108 |
// SI with action=delete must also be discarded.
|
|
1109 |
else if ( iPushMsgAction == CSIPushMsgEntry::ESIPushMsgDelete )
|
|
1110 |
{
|
|
1111 |
deletePushMsg = ETrue;
|
|
1112 |
}
|
|
1113 |
}
|
|
1114 |
|
|
1115 |
// Store message if not marked for deletion.
|
|
1116 |
if ( !deletePushMsg )
|
|
1117 |
{
|
|
1118 |
StoreSIMessageL( matchingEntryId );
|
|
1119 |
}
|
|
1120 |
else
|
|
1121 |
{
|
|
1122 |
// The new entry must be discarded.
|
|
1123 |
// Delete the corresponding matching entry, too.
|
|
1124 |
if ( matchingEntryId != KMsvNullIndexEntryId )
|
|
1125 |
{
|
|
1126 |
iWapPushUtils->DeleteEntryL( matchingEntryId );
|
|
1127 |
}
|
|
1128 |
}
|
|
1129 |
|
|
1130 |
iState = EDone;
|
|
1131 |
IdleComplete();
|
|
1132 |
|
|
1133 |
PUSHLOG_LEAVEFN("CSIContentHandler::ProcessingPushMsgEntryL")
|
|
1134 |
}
|
|
1135 |
|
|
1136 |
// ---------------------------------------------------------
|
|
1137 |
// CSIContentHandler::StoreSIMessageL
|
|
1138 |
// ---------------------------------------------------------
|
|
1139 |
//
|
|
1140 |
void CSIContentHandler::StoreSIMessageL( TMsvId aMatchingEntryId )
|
|
1141 |
{
|
|
1142 |
PUSHLOG_ENTERFN("CSIContentHandler::StoreSIMessageL")
|
|
1143 |
|
|
1144 |
CSIPushMsgEntry* siEntry = CSIPushMsgEntry::NewL();
|
|
1145 |
CleanupStack::PushL( siEntry );
|
|
1146 |
|
|
1147 |
if ( aMatchingEntryId != KMsvNullIndexEntryId )
|
|
1148 |
{
|
|
1149 |
PUSHLOG_WRITE("Matching SI found");
|
|
1150 |
//Delete this old entry
|
|
1151 |
iWapPushUtils->DeleteEntryL( aMatchingEntryId );
|
|
1152 |
}
|
|
1153 |
|
|
1154 |
SetSIPushMsgEntryFieldsL( *siEntry );
|
|
1155 |
iSavedMsgId = siEntry->SaveL( *iMsvSession, KMsvGlobalInBoxIndexEntryId );
|
|
1156 |
|
|
1157 |
#ifdef __TEST_LOG__
|
|
1158 |
_LIT( KDateFormat, "%E%D%X%N%Y %1 %2 %3" );
|
|
1159 |
_LIT( KTimeFormat, "%-B%:0%J%:1%T%:2%S%:3%+B" );
|
|
1160 |
TBuf<32> dateHolder;
|
|
1161 |
TBuf<32> timeHolder;
|
|
1162 |
TTime recDateTime = siEntry->ReceivedDate();
|
|
1163 |
recDateTime.FormatL( dateHolder, KDateFormat );
|
|
1164 |
recDateTime.FormatL( timeHolder, KTimeFormat );
|
|
1165 |
PUSHLOG_WRITE_FORMAT(" rec date: <%S>",&dateHolder)
|
|
1166 |
PUSHLOG_WRITE_FORMAT(" rec time: <%S>",&timeHolder)
|
|
1167 |
#endif // __TEST_LOG__
|
|
1168 |
|
|
1169 |
CleanupStack::PopAndDestroy( siEntry ); // siEntry
|
|
1170 |
|
|
1171 |
PUSHLOG_LEAVEFN("CSIContentHandler::StoreSIMessageL")
|
|
1172 |
}
|
|
1173 |
|
|
1174 |
// ---------------------------------------------------------
|
|
1175 |
// CSIContentHandler::HandleMsgOrderReceptionL
|
|
1176 |
// ---------------------------------------------------------
|
|
1177 |
//
|
|
1178 |
TBool CSIContentHandler::HandleMsgOrderReceptionL( TMsvId& aMatchingEntryId )
|
|
1179 |
{
|
|
1180 |
PUSHLOG_ENTERFN("CSIContentHandler::HandleMsgOrderReceptionL")
|
|
1181 |
|
|
1182 |
__ASSERT_DEBUG( ( SiIdFlag() || HrefFlag() ),
|
|
1183 |
ContHandPanic( EPushContHandPanNoSiIdOrHrefAttr ) );
|
|
1184 |
__ASSERT_DEBUG( CreatedFlag(),
|
|
1185 |
ContHandPanic( EPushContHandPanNoCreatedAttr ) );
|
|
1186 |
|
|
1187 |
CMsvEntrySelection* matchingIdList = NULL;
|
|
1188 |
TBool discardPushMsg( EFalse );
|
|
1189 |
|
|
1190 |
// Get list of matching stored SI messages.
|
|
1191 |
if ( SiIdFlag() && iSiIdBuf->Length() != 0 )
|
|
1192 |
{
|
|
1193 |
matchingIdList = iWapPushUtils->FindSiIdLC( *iSiIdBuf );
|
|
1194 |
}
|
|
1195 |
else // HrefFlag()
|
|
1196 |
{
|
|
1197 |
// Use href as si-id.
|
|
1198 |
matchingIdList = iWapPushUtils->FindSiIdLC( *iHrefBuf );
|
|
1199 |
}
|
|
1200 |
const TInt matchingListCount( matchingIdList->Count() );
|
|
1201 |
// Note that the count can be greater than 1.
|
|
1202 |
|
|
1203 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler Count: %d",matchingListCount)
|
|
1204 |
|
|
1205 |
if ( 0 < matchingListCount && CreatedFlag() )
|
|
1206 |
{
|
|
1207 |
CSIPushMsgEntry* siEntry = CSIPushMsgEntry::NewL();
|
|
1208 |
CleanupStack::PushL( siEntry );
|
|
1209 |
|
|
1210 |
// Delete older stored messages and/or mark current message for
|
|
1211 |
// deletion if same date or older than stored messages
|
|
1212 |
TBool foundOneToBeReplaced = EFalse;
|
|
1213 |
for ( TInt count = 0; count < matchingListCount; ++count )
|
|
1214 |
{
|
|
1215 |
TMsvId matchingSiMsgEntryId( matchingIdList->At(count) );
|
|
1216 |
|
|
1217 |
siEntry->RetrieveL( *iMsvSession, matchingSiMsgEntryId );
|
|
1218 |
|
|
1219 |
// Skip date comparisons if creation date not valid -
|
|
1220 |
// SI without created attribute never gets replaced.
|
|
1221 |
TTime existingSiCreatedTime( siEntry->Created() );
|
|
1222 |
|
|
1223 |
if ( existingSiCreatedTime == Time::NullTTime() )
|
|
1224 |
{
|
|
1225 |
// continue;
|
|
1226 |
}
|
|
1227 |
else
|
|
1228 |
{
|
|
1229 |
__ASSERT_DEBUG( !foundOneToBeReplaced,
|
|
1230 |
ContHandPanic( EPushContHandPanTooManySi ) );
|
|
1231 |
if ( foundOneToBeReplaced )
|
|
1232 |
{
|
|
1233 |
PUSHLOG_WRITE(" Already found one")
|
|
1234 |
// Only one SI has to be found.
|
|
1235 |
// If the program runs into it, then make a
|
|
1236 |
// garbage collection to ensure consistency and
|
|
1237 |
// remove other messages found.
|
|
1238 |
iWapPushUtils->DeleteEntryL( matchingSiMsgEntryId );
|
|
1239 |
// After the 'for' only one SI is allowed that has created
|
|
1240 |
// attribute.
|
|
1241 |
}
|
|
1242 |
else
|
|
1243 |
{
|
|
1244 |
foundOneToBeReplaced = ETrue; // A match was found.
|
|
1245 |
// Check if received SI is newer than existing stored Si
|
|
1246 |
// (out of order).
|
|
1247 |
if ( iCreatedTime > existingSiCreatedTime )
|
|
1248 |
{
|
|
1249 |
PUSHLOG_WRITE(" Replacing...")
|
|
1250 |
// The new SI replaces the existing.
|
|
1251 |
aMatchingEntryId = matchingSiMsgEntryId;
|
|
1252 |
discardPushMsg = EFalse;
|
|
1253 |
}
|
|
1254 |
else if ( iCreatedTime <= existingSiCreatedTime )
|
|
1255 |
{
|
|
1256 |
PUSHLOG_WRITE(" Discarding...")
|
|
1257 |
// Received SI is older than existing stored Si.
|
|
1258 |
discardPushMsg = ETrue;
|
|
1259 |
}
|
|
1260 |
}
|
|
1261 |
}
|
|
1262 |
}
|
|
1263 |
|
|
1264 |
CleanupStack::PopAndDestroy( siEntry ); // siEntry
|
|
1265 |
}
|
|
1266 |
|
|
1267 |
CleanupStack::PopAndDestroy( matchingIdList ); // matchingIdList
|
|
1268 |
|
|
1269 |
PUSHLOG_LEAVEFN("CSIContentHandler::HandleMsgOrderReceptionL")
|
|
1270 |
return discardPushMsg;
|
|
1271 |
}
|
|
1272 |
|
|
1273 |
// ---------------------------------------------------------
|
|
1274 |
// CSIContentHandler::ConvertDateTimeL
|
|
1275 |
// ---------------------------------------------------------
|
|
1276 |
//
|
|
1277 |
TBool CSIContentHandler::ConvertDateTimeL( const TDesC& aDateTime,
|
|
1278 |
TTime& aConvertedDate ) const
|
|
1279 |
{
|
|
1280 |
PUSHLOG_ENTERFN("CSIContentHandler::ConvertDateTimeL")
|
|
1281 |
|
|
1282 |
TTime convertedTime = Time::NullTTime();
|
|
1283 |
TBool convertedOK = EFalse;
|
|
1284 |
|
|
1285 |
// check supplied descriptor is the correct length
|
|
1286 |
if ( aDateTime.Length() != KValidUTCLength )
|
|
1287 |
{
|
|
1288 |
PUSHLOG_WRITE_FORMAT(" invalid UTC length <%d>",aDateTime.Length())
|
|
1289 |
User::Leave( KErrCorrupt );
|
|
1290 |
}
|
|
1291 |
else
|
|
1292 |
{
|
|
1293 |
TBuf<KValidUTCLength> str = aDateTime;
|
|
1294 |
PUSHLOG_WRITE_FORMAT(" datetime str: <%S>",&str)
|
|
1295 |
if ( !IsValidUTCTime( str ) )
|
|
1296 |
{
|
|
1297 |
// The UTC time is invalid.
|
|
1298 |
PUSHLOG_WRITE(" invalid UTC time")
|
|
1299 |
User::Leave( KErrCorrupt );
|
|
1300 |
}
|
|
1301 |
else
|
|
1302 |
{
|
|
1303 |
// Now 'str' is in format YYYYMMDD:HHMMSS
|
|
1304 |
// Adjust UTC time to zero offset TTime. Only month and day
|
|
1305 |
// is effected.
|
|
1306 |
const TInt KFirstMonthChar = KValidTTimeMonthStart;
|
|
1307 |
const TInt KSecondMonthChar = KFirstMonthChar + 1;
|
|
1308 |
const TInt KFirstDayChar = KValidTTimeDayStart;
|
|
1309 |
const TInt KSecondDayChar = KFirstDayChar + 1;
|
|
1310 |
// Month.
|
|
1311 |
// check for special case of month = 10 which becomes 09
|
|
1312 |
if ( str[KFirstMonthChar] == '1' && str[KSecondMonthChar] == '0' )
|
|
1313 |
{
|
|
1314 |
str[KFirstMonthChar] = '0';
|
|
1315 |
str[KSecondMonthChar] = '9';
|
|
1316 |
}
|
|
1317 |
else
|
|
1318 |
{
|
|
1319 |
// month value is either 11, 12 or less than 10, ie 1 - 9.
|
|
1320 |
// reduce day by one, eg 11 becomes 10, 12 becomes 11, 09 becomes 08
|
|
1321 |
str[KSecondMonthChar]--;
|
|
1322 |
}
|
|
1323 |
|
|
1324 |
// Day.
|
|
1325 |
// check for special cases 10, 20, 30
|
|
1326 |
if ( str[KSecondDayChar] == '0' )
|
|
1327 |
{
|
|
1328 |
// reduce day by 1, ie 10 becomes 09, 20 becomes 19 ...
|
|
1329 |
str[KSecondDayChar] = '9';
|
|
1330 |
str[KFirstDayChar]--;
|
|
1331 |
}
|
|
1332 |
else
|
|
1333 |
{
|
|
1334 |
// day value is between 1 and 9 so reduce day by one
|
|
1335 |
// eg 29 becomes 28, 11 bcomes 10, 31 becomes 30
|
|
1336 |
str[KSecondDayChar]--;
|
|
1337 |
}
|
|
1338 |
|
|
1339 |
// string is now syntaxically correct, but Set() will return an
|
|
1340 |
// error if it's semantically incorrect.
|
|
1341 |
User::LeaveIfError( convertedTime.Set( str ) );
|
|
1342 |
convertedOK = ETrue;
|
|
1343 |
}
|
|
1344 |
}
|
|
1345 |
|
|
1346 |
PUSHLOG_LEAVEFN("CSIContentHandler::ConvertDateTimeL")
|
|
1347 |
aConvertedDate = convertedTime;
|
|
1348 |
return convertedOK;
|
|
1349 |
}
|
|
1350 |
|
|
1351 |
// ---------------------------------------------------------
|
|
1352 |
// CSIContentHandler::ConvertOpaqueToUtcL
|
|
1353 |
// ---------------------------------------------------------
|
|
1354 |
//
|
|
1355 |
HBufC* CSIContentHandler::ConvertOpaqueToUtcL( const TDesC8& aOpaque ) const
|
|
1356 |
{
|
|
1357 |
PUSHLOG_ENTERFN("CSIContentHandler::ConvertOpaqueToUtcL")
|
|
1358 |
|
|
1359 |
const TInt opaqueSize = aOpaque.Size();
|
|
1360 |
if ( KValidMaxEncodedDateTimeSize < opaqueSize )
|
|
1361 |
{
|
|
1362 |
PUSHLOG_WRITE_FORMAT(" Bad OPAQUE size: <%d>",opaqueSize)
|
|
1363 |
User::Leave( KErrCorrupt );
|
|
1364 |
}
|
|
1365 |
|
|
1366 |
HBufC* converted = HBufC::NewMaxLC( KValidUTCLength );
|
|
1367 |
TPtr convertedPtr = converted->Des();
|
|
1368 |
convertedPtr.SetLength( 0 ); // Reset.
|
|
1369 |
|
|
1370 |
// Split up each opaque byte to two bytes.
|
|
1371 |
TUint8 byte( 0x00 );
|
|
1372 |
TUint8 high( 0x00 );
|
|
1373 |
TUint8 low( 0x00 );
|
|
1374 |
TInt i = 0;
|
|
1375 |
for ( i = 0; i < opaqueSize; ++i )
|
|
1376 |
{
|
|
1377 |
byte = aOpaque[i];
|
|
1378 |
high = (TUint8)( (byte & 0xF0) >> 4 );
|
|
1379 |
low = (TUint8)( byte & 0x0F );
|
|
1380 |
// Check high and low if they are in the range [0-9].
|
|
1381 |
if ( 9 < high || 9 < low )
|
|
1382 |
{
|
|
1383 |
PUSHLOG_WRITE_FORMAT2(" Overflow: <%d, %d>",high,low)
|
|
1384 |
User::Leave( KErrOverflow );
|
|
1385 |
}
|
|
1386 |
convertedPtr.Append( TChar(KAsciiZeroCharCode + high) );
|
|
1387 |
convertedPtr.Append( TChar(KAsciiZeroCharCode + low) );
|
|
1388 |
}
|
|
1389 |
|
|
1390 |
// A valid UTC %Datetime contains 14 numerical characters and 6
|
|
1391 |
// non-numerical: “1999-04-30T06:40:00Z”.
|
|
1392 |
// So fill the remaining bytes with zeros.
|
|
1393 |
for ( i = convertedPtr.Length(); i < KValidUTCNumericals; ++i )
|
|
1394 |
{
|
|
1395 |
convertedPtr.Append( TChar('0') );
|
|
1396 |
}
|
|
1397 |
|
|
1398 |
// Insert the necessary non-numerical boundary characters.
|
|
1399 |
i = 0;
|
|
1400 |
// Skip year and insert '-'. (Don't forget to increase i with 1 each time!)
|
|
1401 |
i += KValidUTCYearBlockLength;
|
|
1402 |
convertedPtr.Insert( i++, KCharMinus );
|
|
1403 |
// Skip month and insert '-'.
|
|
1404 |
i += KValidUTCOtherBlockLength;
|
|
1405 |
convertedPtr.Insert( i++, KCharMinus );
|
|
1406 |
// Skip day and insert 'T'.
|
|
1407 |
i += KValidUTCOtherBlockLength;
|
|
1408 |
convertedPtr.Insert( i++, KCharT );
|
|
1409 |
// Skip hour and insert ':'.
|
|
1410 |
i += KValidUTCOtherBlockLength;
|
|
1411 |
convertedPtr.Insert( i++, KCharColon );
|
|
1412 |
// Skip minute and insert ':'.
|
|
1413 |
i += KValidUTCOtherBlockLength;
|
|
1414 |
convertedPtr.Insert( i++, KCharColon );
|
|
1415 |
// Skip second and insert 'Z'.
|
|
1416 |
i += KValidUTCOtherBlockLength;
|
|
1417 |
convertedPtr.Insert( i++, KCharZ );
|
|
1418 |
|
|
1419 |
CleanupStack::Pop( converted ); // converted
|
|
1420 |
PUSHLOG_LEAVEFN("CSIContentHandler::ConvertOpaqueToUtcL")
|
|
1421 |
return converted;
|
|
1422 |
}
|
|
1423 |
|
|
1424 |
// ---------------------------------------------------------
|
|
1425 |
// CSIContentHandler::IsValidUTCTime
|
|
1426 |
// ---------------------------------------------------------
|
|
1427 |
//
|
|
1428 |
TBool CSIContentHandler::IsValidUTCTime( TDes& aDateTime ) const
|
|
1429 |
{
|
|
1430 |
PUSHLOG_ENTERFN("CSIContentHandler::IsValidUTCTime")
|
|
1431 |
|
|
1432 |
TBool isValid( ETrue ); // Return value.
|
|
1433 |
|
|
1434 |
// Now aDateTime has to be in format YYYY-MM-DDTHH:MM:SSZ
|
|
1435 |
|
|
1436 |
// check supplied descriptor is the correct length
|
|
1437 |
if ( aDateTime.Length() != KValidUTCLength )
|
|
1438 |
{
|
|
1439 |
PUSHLOG_WRITE_FORMAT(" invalid UTC length <%d>",aDateTime.Length())
|
|
1440 |
isValid = EFalse;
|
|
1441 |
}
|
|
1442 |
else
|
|
1443 |
{
|
|
1444 |
// strip out formatting characters
|
|
1445 |
TInt formatCharPos = 4;
|
|
1446 |
aDateTime.Delete( formatCharPos, 1 );
|
|
1447 |
// now move through two characters at a time and remove other chars
|
|
1448 |
// to just leave digits
|
|
1449 |
const TInt KRemainingFormatChars = 5;
|
|
1450 |
TInt i( 0 );
|
|
1451 |
for ( i = 0; i < KRemainingFormatChars; ++i )
|
|
1452 |
{
|
|
1453 |
formatCharPos += 2;
|
|
1454 |
aDateTime.Delete( formatCharPos, 1 );
|
|
1455 |
}
|
|
1456 |
|
|
1457 |
// Now aDateTime has to be in format YYYYMMDDHHMMSS
|
|
1458 |
|
|
1459 |
__ASSERT_DEBUG( aDateTime.Length() == KValidTTimeLength,
|
|
1460 |
ContHandPanic( EPushContHandPanBadTTimeLength ) );
|
|
1461 |
|
|
1462 |
// now have UTC string stripped of format characters - check remaining
|
|
1463 |
// characters are all digits - YYYYMMDDHHMMSS
|
|
1464 |
TChar ch;
|
|
1465 |
for ( i = 0; i < KValidTTimeLength; ++i )
|
|
1466 |
{
|
|
1467 |
ch = aDateTime[i];
|
|
1468 |
if ( ch.IsDigit() == EFalse )
|
|
1469 |
{
|
|
1470 |
PUSHLOG_WRITE_FORMAT(" not digit <%d>",i)
|
|
1471 |
isValid = EFalse;
|
|
1472 |
}
|
|
1473 |
}
|
|
1474 |
|
|
1475 |
if ( isValid )
|
|
1476 |
{
|
|
1477 |
/*
|
|
1478 |
In YYYYMMDDHHMMSS
|
|
1479 |
YYYY = 4 digit year ("0000" ... "9999")
|
|
1480 |
MM = 2 digit month ("01"=January, "02"=February ... "12"=December)
|
|
1481 |
DD = 2 digit day ("01", "02" ... "31")
|
|
1482 |
HH = 2 digit hour, 24-hour timekeeping system ("00" ... "23")
|
|
1483 |
MM = 2 digit minute ("00" ... "59")
|
|
1484 |
SS = 2 digit second ("00" ... "59")
|
|
1485 |
*/
|
|
1486 |
TInt err;
|
|
1487 |
TUint val;
|
|
1488 |
// Do not check year. There are no restrictions.
|
|
1489 |
// Check month.
|
|
1490 |
TLex parser( aDateTime.Mid( KValidTTimeMonthStart,
|
|
1491 |
KValidTTimeBlockLength ) );
|
|
1492 |
err = parser.Val( val, EDecimal );
|
|
1493 |
if ( err )
|
|
1494 |
{
|
|
1495 |
isValid = EFalse;
|
|
1496 |
PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
|
|
1497 |
}
|
|
1498 |
else
|
|
1499 |
{
|
|
1500 |
PUSHLOG_WRITE_FORMAT(" month: <%d>",val)
|
|
1501 |
if ( val < 1 || 12 < val )
|
|
1502 |
{
|
|
1503 |
isValid = EFalse;
|
|
1504 |
}
|
|
1505 |
}
|
|
1506 |
// Check day.
|
|
1507 |
if ( isValid )
|
|
1508 |
{
|
|
1509 |
parser = aDateTime.Mid( KValidTTimeDayStart,
|
|
1510 |
KValidTTimeBlockLength );
|
|
1511 |
err = parser.Val( val, EDecimal );
|
|
1512 |
if ( err )
|
|
1513 |
{
|
|
1514 |
isValid = EFalse;
|
|
1515 |
PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
|
|
1516 |
}
|
|
1517 |
else
|
|
1518 |
{
|
|
1519 |
PUSHLOG_WRITE_FORMAT(" day: <%d>",val)
|
|
1520 |
if ( val < 1 || 31 < val )
|
|
1521 |
{
|
|
1522 |
isValid = EFalse;
|
|
1523 |
}
|
|
1524 |
}
|
|
1525 |
}
|
|
1526 |
// Check hour.
|
|
1527 |
if ( isValid )
|
|
1528 |
{
|
|
1529 |
parser = aDateTime.Mid( KValidTTimeHourStart,
|
|
1530 |
KValidTTimeBlockLength );
|
|
1531 |
err = parser.Val( val, EDecimal );
|
|
1532 |
if ( err )
|
|
1533 |
{
|
|
1534 |
isValid = EFalse;
|
|
1535 |
PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
|
|
1536 |
}
|
|
1537 |
else
|
|
1538 |
{
|
|
1539 |
PUSHLOG_WRITE_FORMAT(" hour: <%d>",val)
|
|
1540 |
if ( 23 < val )
|
|
1541 |
{
|
|
1542 |
isValid = EFalse;
|
|
1543 |
}
|
|
1544 |
}
|
|
1545 |
}
|
|
1546 |
// Check minute.
|
|
1547 |
if ( isValid )
|
|
1548 |
{
|
|
1549 |
parser = aDateTime.Mid( KValidTTimeMinuteStart,
|
|
1550 |
KValidTTimeBlockLength );
|
|
1551 |
err = parser.Val( val, EDecimal );
|
|
1552 |
if ( err )
|
|
1553 |
{
|
|
1554 |
isValid = EFalse;
|
|
1555 |
PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
|
|
1556 |
}
|
|
1557 |
else
|
|
1558 |
{
|
|
1559 |
PUSHLOG_WRITE_FORMAT(" min: <%d>",val)
|
|
1560 |
if ( 59 < val )
|
|
1561 |
{
|
|
1562 |
isValid = EFalse;
|
|
1563 |
}
|
|
1564 |
}
|
|
1565 |
}
|
|
1566 |
// Check second.
|
|
1567 |
if ( isValid )
|
|
1568 |
{
|
|
1569 |
parser = aDateTime.Mid( KValidTTimeSecondStart,
|
|
1570 |
KValidTTimeBlockLength );
|
|
1571 |
err = parser.Val( val, EDecimal );
|
|
1572 |
if ( err )
|
|
1573 |
{
|
|
1574 |
isValid = EFalse;
|
|
1575 |
PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
|
|
1576 |
}
|
|
1577 |
else
|
|
1578 |
{
|
|
1579 |
PUSHLOG_WRITE_FORMAT(" sec: <%d>",val)
|
|
1580 |
if ( 59 < val )
|
|
1581 |
{
|
|
1582 |
isValid = EFalse;
|
|
1583 |
}
|
|
1584 |
}
|
|
1585 |
}
|
|
1586 |
|
|
1587 |
// insert colon seperating date from time
|
|
1588 |
const TInt KColonPosition = 8;
|
|
1589 |
aDateTime.Insert( KColonPosition, KCharColon );
|
|
1590 |
|
|
1591 |
// Now aDateTime has to be in format YYYYMMDD:HHMMSS
|
|
1592 |
}
|
|
1593 |
}
|
|
1594 |
|
|
1595 |
PUSHLOG_LEAVEFN("CSIContentHandler::IsValidUTCTime")
|
|
1596 |
return isValid; // aDateTime contains a modified buffer.
|
|
1597 |
}
|
|
1598 |
|
|
1599 |
// ---------------------------------------------------------
|
|
1600 |
// CSIContentHandler::AttributeToTTimeL
|
|
1601 |
// ---------------------------------------------------------
|
|
1602 |
//
|
|
1603 |
TBool CSIContentHandler::AttributeToTTimeL
|
|
1604 |
( NW_DOM_AttributeHandle_t& aAttrHandle,
|
|
1605 |
TTime& aConvertedDate ) const
|
|
1606 |
{
|
|
1607 |
PUSHLOG_ENTERFN("CSIContentHandler::AttributeToTTimeL")
|
|
1608 |
|
|
1609 |
TBool gotDate = EFalse;
|
|
1610 |
NW_Status_t stat = NW_STAT_SUCCESS;
|
|
1611 |
NW_DOM_AttrVal_t attrVal;
|
|
1612 |
|
|
1613 |
// It is expected to be String or Opaque.
|
|
1614 |
// It may be Opaque, to which we will need a NW_DOM_AttrVal_t structure.
|
|
1615 |
stat = NW_DOM_AttributeHandle_getNextVal( &aAttrHandle, &attrVal );
|
|
1616 |
|
|
1617 |
if ( stat != NW_STAT_WBXML_ITERATE_MORE )
|
|
1618 |
{
|
|
1619 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
1620 |
}
|
|
1621 |
else
|
|
1622 |
{
|
|
1623 |
NW_Uint16 valType = NW_DOM_AttrVal_getType( &attrVal );
|
|
1624 |
|
|
1625 |
if ( valType == NW_DOM_ATTR_VAL_STRING )
|
|
1626 |
{
|
|
1627 |
CStringOwner* stringOwner = new (ELeave) CStringOwner;
|
|
1628 |
CleanupStack::PushL( stringOwner );
|
|
1629 |
|
|
1630 |
NW_String_t* val = NW_String_new();
|
|
1631 |
User::LeaveIfNull( val );
|
|
1632 |
stringOwner->SetString( val );
|
|
1633 |
//
|
|
1634 |
stat = NW_DOM_AttrVal_toString( &attrVal, val, iCharEncoding );
|
|
1635 |
User::LeaveIfError( NwxStatusToErrCode( stat ) );
|
|
1636 |
NW_Byte* storage = NW_String_getStorage( val );
|
|
1637 |
NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
|
|
1638 |
TPtrC8 dataPtr( storage, length );
|
|
1639 |
HBufC* dataBuf = HBufC::NewMaxLC( dataPtr.Length() );
|
|
1640 |
dataBuf->Des().Copy( dataPtr );
|
|
1641 |
gotDate = ConvertDateTimeL( *dataBuf, aConvertedDate );
|
|
1642 |
|
|
1643 |
CleanupStack::PopAndDestroy( 2, stringOwner ); // dataBuf,
|
|
1644 |
// stringOwner
|
|
1645 |
}
|
|
1646 |
else if ( valType == NW_DOM_ATTR_VAL_OPAQUE )
|
|
1647 |
{
|
|
1648 |
NW_Uint32 len = 0;
|
|
1649 |
NW_Byte* data = NW_DOM_AttrVal_getOpaque( &attrVal, &len );
|
|
1650 |
User::LeaveIfNull( data );
|
|
1651 |
TPtrC8 dataPtr( data, len );
|
|
1652 |
|
|
1653 |
HBufC* dateTime = ConvertOpaqueToUtcL( dataPtr );
|
|
1654 |
CleanupStack::PushL( dateTime );
|
|
1655 |
gotDate = ConvertDateTimeL( *dateTime, aConvertedDate );
|
|
1656 |
CleanupStack::PopAndDestroy( dateTime ); // dateTime
|
|
1657 |
}
|
|
1658 |
else
|
|
1659 |
{
|
|
1660 |
User::Leave( KErrNotSupported );
|
|
1661 |
}
|
|
1662 |
}
|
|
1663 |
|
|
1664 |
PUSHLOG_LEAVEFN("CSIContentHandler::AttributeToTTimeL")
|
|
1665 |
return gotDate; // aConvertedDate contains the result.
|
|
1666 |
}
|
|
1667 |
|
|
1668 |
// ---------------------------------------------------------
|
|
1669 |
// CSIContentHandler::HandleMessageL
|
|
1670 |
// ---------------------------------------------------------
|
|
1671 |
//
|
|
1672 |
void CSIContentHandler::HandleMessageL( CPushMessage* aPushMsg,
|
|
1673 |
TRequestStatus& aStatus )
|
|
1674 |
{
|
|
1675 |
PUSHLOG_ENTERFN("CSIContentHandler::HandleMessageL")
|
|
1676 |
|
|
1677 |
__ASSERT_DEBUG( aPushMsg != NULL,
|
|
1678 |
ContHandPanic( EPushContHandPanMsgNull ) );
|
|
1679 |
|
|
1680 |
#ifdef __TEST_LOG__
|
|
1681 |
TPtrC8 bodyPtr;
|
|
1682 |
aPushMsg->GetMessageBody( bodyPtr );
|
|
1683 |
PUSHLOG_HEXDUMP( bodyPtr )
|
|
1684 |
#endif // __TEST_LOG__
|
|
1685 |
|
|
1686 |
iMessage = aPushMsg;
|
|
1687 |
iAcknowledge = ETrue;
|
|
1688 |
SetConfirmationStatus( aStatus );
|
|
1689 |
|
|
1690 |
iState = EGarbageCollecting;
|
|
1691 |
IdleComplete();
|
|
1692 |
|
|
1693 |
PUSHLOG_LEAVEFN("CSIContentHandler::HandleMessageL")
|
|
1694 |
}
|
|
1695 |
|
|
1696 |
// ---------------------------------------------------------
|
|
1697 |
// CSIContentHandler::HandleMessageL
|
|
1698 |
// ---------------------------------------------------------
|
|
1699 |
//
|
|
1700 |
void CSIContentHandler::HandleMessageL( CPushMessage* aPushMsg )
|
|
1701 |
{
|
|
1702 |
PUSHLOG_ENTERFN("CSIContentHandler::HandleMessageL")
|
|
1703 |
|
|
1704 |
__ASSERT_DEBUG( aPushMsg != NULL,
|
|
1705 |
ContHandPanic( EPushContHandPanMsgNull ) );
|
|
1706 |
|
|
1707 |
#ifdef __TEST_LOG__
|
|
1708 |
TPtrC8 bodyPtr;
|
|
1709 |
aPushMsg->GetMessageBody( bodyPtr );
|
|
1710 |
PUSHLOG_HEXDUMP( bodyPtr )
|
|
1711 |
#endif // __TEST_LOG__
|
|
1712 |
|
|
1713 |
iAcknowledge = EFalse;
|
|
1714 |
iMessage = aPushMsg;
|
|
1715 |
|
|
1716 |
iState = EGarbageCollecting;
|
|
1717 |
IdleComplete();
|
|
1718 |
|
|
1719 |
PUSHLOG_LEAVEFN("CSIContentHandler::HandleMessageL")
|
|
1720 |
}
|
|
1721 |
|
|
1722 |
// ---------------------------------------------------------
|
|
1723 |
// CSIContentHandler::CancelHandleMessage
|
|
1724 |
// ---------------------------------------------------------
|
|
1725 |
//
|
|
1726 |
void CSIContentHandler::CancelHandleMessage()
|
|
1727 |
{
|
|
1728 |
PUSHLOG_ENTERFN("CSIContentHandler::CancelHandleMessage")
|
|
1729 |
Cancel();
|
|
1730 |
PUSHLOG_LEAVEFN("CSIContentHandler::CancelHandleMessage")
|
|
1731 |
}
|
|
1732 |
|
|
1733 |
// ---------------------------------------------------------
|
|
1734 |
// CSIContentHandler::CPushHandlerBase_Reserved1
|
|
1735 |
// ---------------------------------------------------------
|
|
1736 |
//
|
|
1737 |
void CSIContentHandler::CPushHandlerBase_Reserved1()
|
|
1738 |
{
|
|
1739 |
}
|
|
1740 |
|
|
1741 |
// ---------------------------------------------------------
|
|
1742 |
// CSIContentHandler::CPushHandlerBase_Reserved2
|
|
1743 |
// ---------------------------------------------------------
|
|
1744 |
//
|
|
1745 |
void CSIContentHandler::CPushHandlerBase_Reserved2()
|
|
1746 |
{
|
|
1747 |
}
|
|
1748 |
|
|
1749 |
// ---------------------------------------------------------
|
|
1750 |
// CSIContentHandler::DoCancel
|
|
1751 |
// ---------------------------------------------------------
|
|
1752 |
//
|
|
1753 |
void CSIContentHandler::DoCancel()
|
|
1754 |
{
|
|
1755 |
PUSHLOG_ENTERFN("CSIContentHandler::DoCancel")
|
|
1756 |
Complete( KErrCancel );
|
|
1757 |
PUSHLOG_LEAVEFN("CSIContentHandler::DoCancel")
|
|
1758 |
}
|
|
1759 |
|
|
1760 |
// ---------------------------------------------------------
|
|
1761 |
// CSIContentHandler::RunL
|
|
1762 |
// ---------------------------------------------------------
|
|
1763 |
//
|
|
1764 |
void CSIContentHandler::RunL()
|
|
1765 |
{
|
|
1766 |
// Handle errors in RunError().
|
|
1767 |
PUSHLOG_WRITE_FORMAT("iStatus.Int(): %d",iStatus.Int())
|
|
1768 |
User::LeaveIfError( iStatus.Int() );
|
|
1769 |
|
|
1770 |
// use active state machine routine to manage activites:
|
|
1771 |
switch ( iState )
|
|
1772 |
{
|
|
1773 |
case EGarbageCollecting:
|
|
1774 |
{
|
|
1775 |
CollectGarbageL();
|
|
1776 |
break;
|
|
1777 |
}
|
|
1778 |
case EFilteringAndParsing:
|
|
1779 |
{
|
|
1780 |
if ( !FilterPushMsgL() )
|
|
1781 |
{
|
|
1782 |
// It did not pass the filter. Done.
|
|
1783 |
iState = EDone;
|
|
1784 |
IdleComplete();
|
|
1785 |
}
|
|
1786 |
else
|
|
1787 |
{
|
|
1788 |
// Continue.
|
|
1789 |
TInt ret = KErrNone;
|
|
1790 |
PUSHLOG_WRITE("CSIContentHandler::RunL : before trapping parsing.")
|
|
1791 |
TRAP(ret, ParsePushMsgL());
|
|
1792 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::RunL : after trapping parsing. ret = %d", ret)
|
|
1793 |
if ( ret != KErrNone)
|
|
1794 |
{
|
|
1795 |
PUSHLOG_WRITE("CSIContentHandler::RunL : Parsing failed. discarding message.")
|
|
1796 |
iState = EDone;
|
|
1797 |
IdleComplete();
|
|
1798 |
}
|
|
1799 |
}
|
|
1800 |
break;
|
|
1801 |
}
|
|
1802 |
case EProcessing:
|
|
1803 |
{
|
|
1804 |
ProcessingPushMsgEntryL();
|
|
1805 |
break;
|
|
1806 |
}
|
|
1807 |
case EDone:
|
|
1808 |
{
|
|
1809 |
PUSHLOG_WRITE("CSIContentHandler EDone")
|
|
1810 |
Complete( KErrNone );
|
|
1811 |
break;
|
|
1812 |
}
|
|
1813 |
default:
|
|
1814 |
{
|
|
1815 |
// JIC.
|
|
1816 |
PUSHLOG_WRITE("CSIContentHandler default Done")
|
|
1817 |
Complete( KErrNone );
|
|
1818 |
break;
|
|
1819 |
}
|
|
1820 |
}
|
|
1821 |
}
|
|
1822 |
|
|
1823 |
// ---------------------------------------------------------
|
|
1824 |
// CSIContentHandler::RunError
|
|
1825 |
// ---------------------------------------------------------
|
|
1826 |
//
|
|
1827 |
TInt CSIContentHandler::RunError( TInt aError )
|
|
1828 |
{
|
|
1829 |
PUSHLOG_WRITE_FORMAT("CSIContentHandler::RunError: %d",aError)
|
|
1830 |
|
|
1831 |
iState = EDone;
|
|
1832 |
Complete( aError );
|
|
1833 |
return KErrNone;
|
|
1834 |
}
|
|
1835 |
|