pushmtm/Plugins/PushContentHandler/CSIContentHandler.cpp
changeset 51 48e827313edd
parent 37 481242ead638
child 53 f427d27b98d8
--- a/pushmtm/Plugins/PushContentHandler/CSIContentHandler.cpp	Tue Feb 02 00:12:41 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1835 +0,0 @@
-/*
-* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:  Implementation of CSIContentHandler.
-*
-*/
-
-
-
-// INCLUDE FILES
-
-#include "CSIContentHandler.h"
-#include "PushMtmUtil.h"
-#include "PushMtmSettings.h"
-#include "PushMtmLog.h"
-#include "PushMtmUiDef.h"
-#include "StringResourceReader.h"
-#include "PushContentHandlerPanic.h"
-#include "si_dict.h"
-#include "PushContentHandlerUtils.h"
-#include <push/CSIPushMsgEntry.h>
-#include <msvids.h>
-#include <PushMtmUi.rsg>
-#include <nw_dom_node.h>
-#include <nw_dom_document.h>
-#include <nw_dom_element.h>
-#include <nw_dom_text.h>
-#include <nw_wbxml_dictionary.h>
-#include <THttpFields.h>
-
-// CONSTANTS
-
-// si attributes / elements
-_LIT8( KSi,          "si" );
-_LIT8( KIndication,  "indication" );
-_LIT8( KHrefAttrib,  "href" );
-_LIT8( KSiIdAttrib,  "si-id" );
-_LIT8( KCreatedAttrib,   "created" );
-_LIT8( KExpiresAttrib,   "si-expires" );
-_LIT8( KActionAttrib,    "action" );
-
-// action attribute literals
-_LIT8( KDeleteAction,    "delete" );
-_LIT8( KSignalNone,      "signal-none" );
-_LIT8( KSignalLow,       "signal-low" );
-_LIT8( KSignalMedium,    "signal-medium" );
-_LIT8( KSignalHigh,      "signal-high" );
-
-_LIT( KSiTextContentType, "text/vnd.wap.si" );
-
-const TInt KValidMaxEncodedDateTimeSize = 7;
-const TInt KValidUTCLength = 20; // YYYY-MM-DDTHH:MM:SSZ
-const TInt KValidUTCNumericals = 14;
-const TInt KValidUTCYearBlockLength = 4;
-const TInt KValidUTCOtherBlockLength = 2;
-const TUint8 KAsciiZeroCharCode = 0x30;
-
-const TInt KValidTTimeMonthStart = 4;
-const TInt KValidTTimeDayStart = 6;
-const TInt KValidTTimeHourStart = 8;
-const TInt KValidTTimeMinuteStart = 10;
-const TInt KValidTTimeSecondStart = 12;
-const TInt KValidTTimeBlockLength = 2;
-
-const TInt KValidTTimeLength = 14; // YYYYMMDDHHMMSS
-
-const TInt KNoOfDictArrays = 1;
-
-_LIT( KCharMinus, "-" );
-_LIT( KCharT, "T" );
-_LIT( KCharColon, ":" );
-_LIT( KCharZ, "Z" );
-
-/// Conversion buffer size.
-LOCAL_D const TInt KPushConversionBufferSize = 256;
-/// Zero width non-breaking space character.
-LOCAL_D const TUint16 KPushZeroWidthNbsp = 0xfeff;
-
-// ================= MEMBER FUNCTIONS =======================
-
-// ---------------------------------------------------------
-// CSIContentHandler::NewL
-// ---------------------------------------------------------
-//
-CSIContentHandler* CSIContentHandler::NewL()
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::NewL")
-
-	CSIContentHandler* self = new (ELeave) CSIContentHandler;
-	CleanupStack::PushL( self );
-	self->ConstructL();
-	CleanupStack::Pop( self );
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::NewL")
-	return self;
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::~CSIContentHandler
-// ---------------------------------------------------------
-//
-CSIContentHandler::~CSIContentHandler()
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::~CSIContentHandler")
-
-    Cancel();
-	delete iHrefBuf;
-	delete iSiIdBuf;
-	delete iData;
-    delete iCharacterSetConverter;
-    iCharacterSetConverter = NULL;
-    delete iCharacterSetsAvailable;
-    iCharacterSetsAvailable = NULL;
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::~CSIContentHandler")
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::CSIContentHandler
-// ---------------------------------------------------------
-//
-CSIContentHandler::CSIContentHandler()
-:   CPushContentHandlerBase(),
-    iSavedMsgId( KMsvNullIndexEntryId ),
-    iPushMsgAction( KErrNotFound ),
-    iExpiresTime( Time::NullTTime() ),
-    iCreatedTime( Time::NullTTime() )
-	{
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::ConstructL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::ConstructL()
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ConstructL")
-
-    CPushContentHandlerBase::ConstructL();
-    // Added to Active Scheduler.
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::ConstructL")
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::CollectGarbageL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::CollectGarbageL()
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::CollectGarbageL")
-
-    DoCollectGarbageL();
-
-    //Ready.
-    iState = EFilteringAndParsing;
-	IdleComplete();
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::CollectGarbageL")
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::ParsePushMsgL
-// Note that cXML parser dosn't do any validation!
-// ---------------------------------------------------------
-//
-void CSIContentHandler::ParsePushMsgL()
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ParsePushMsgL")
-
-    TPtrC8 bodyPtr;
-    iMessage->GetMessageBody( bodyPtr );
-    // If there is no body in the message leave with an error
-    if ( bodyPtr.Size() == 0 )
-        {
-        PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: Empty body")
-        User::Leave( KErrCorrupt );
-        }
-
-    // Get content type. It will tell us wheather the msg body is encoded or
-    // textual.
-    TPtrC contentType;
-	iMessage->GetContentType( contentType );
-    PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: HTTP header - Content type <%S>",&contentType);
-
-    /*
-    TPtrC8 encodingPtr;
-    TBool encodingFound = iMessage->GetHeaderField
-                          ( EHttpContentEncoding, encodingPtr );
-    #ifdef __TEST_LOG__
-    TBuf<64> encodingBuf;
-    encodingBuf.Copy( encodingPtr );
-    PUSHLOG_WRITE_FORMAT(" HTTP header - Content encoding <%S>",&encodingBuf);
-    #endif // __TEST_LOG__
-    */
-
-    // Add SI dictionary.
-    NW_WBXML_Dictionary_t* dictArray[ KNoOfDictArrays ] =
-        { (NW_WBXML_Dictionary_t*)&NW_SI_WBXMLDictionary };
-
-    NW_Status_t stat = NW_STAT_SUCCESS;
-
-    RWbxmlDictionary wbxmlDict;
-    wbxmlDict.InitializeL( KNoOfDictArrays, dictArray );
-    CleanupClosePushL<RWbxmlDictionary>( wbxmlDict );
-
-    NW_TinyDom_Handle_t domHandle;
-    NW_Byte* buffer = (NW_Byte*)bodyPtr.Ptr();
-    NW_Int32 length = (NW_Int32)bodyPtr.Size();
-    // Let's use the content type now.
-    NW_Bool encoded = ( contentType.CompareF( KSiTextContentType ) == 0 ) ?
-                                                         NW_FALSE : NW_TRUE;
-    // SI public identifier.
-    NW_Uint32 publicID = NW_SI_PublicId;
-    NW_Bool extTNotStringTable = NW_FALSE;
-    NW_DOM_NodeType_t type = 0;
-    /**********************************
-    *   Root of DOM
-    ***********************************/
-    CDocumentTreeOwner* docTreeOwner = new (ELeave) CDocumentTreeOwner;
-    CleanupStack::PushL( docTreeOwner );
-    NW_DOM_DocumentNode_t* domNode = NW_DOM_DocumentNode_BuildTree
-        (
-                            &domHandle,
-                            buffer,
-                            length,
-                            encoded,
-                            publicID,
-                            extTNotStringTable
-        );
-	if (!domNode)
-		{
-		PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: domNode is Null")
-		}
-    User::LeaveIfNull( domNode );
-	PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: domNode is not Null") // to be deleted
-    // Let domNode be on the Cleanup Stack.
-    docTreeOwner->SetDocTree( domNode );
-
-    // It must be a document node.
-    type = NW_DOM_Node_getNodeType( domNode );
-    if ( type != NW_DOM_DOCUMENT_NODE )
-        {
-        PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: Not Document node <%d>",type)
-        User::Leave( KErrArgument );
-        }
-
-    // Get character encoding (NW_Uint32)
-    iCharEncoding = NW_DOM_DocumentNode_getCharacterEncoding( domNode );
-    PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: Doc char encoding <%x>",iCharEncoding)
-
-    /**********************************
-    *   ELEMENT si
-    ***********************************/
-    // Get the first element of the document that must be an si.
-	// first make sure if there any children in the dom tree, otherwise we will PANIC(in NW_DOM_DocumentNode_getDocumentElement) and crash WatcherMainThread.
-	TBool domNodeHasChildNodes = EFalse;
-	domNodeHasChildNodes = NW_DOM_Node_hasChildNodes( domNode );
-	PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: check if Dom tree has <SI> node <%d>", domNodeHasChildNodes)
-	if (!domNodeHasChildNodes)
-        {
-        PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: No SI element present in the dom tree. Message corrupted.")
-        User::Leave( KErrCorrupt );
-        }
-
-	PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: before calling getDocumentElement")
-    NW_DOM_ElementNode_t* siElement =
-        NW_DOM_DocumentNode_getDocumentElement( domNode );
-	PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: after calling getDocumentElement")
-	if (!siElement)
-		{
-		PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: siElement is Null")
-		}
-	PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: siElement is not Null, before leaving")
-    User::LeaveIfNull( siElement );
-	PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: siElement is not Null, after leaving if siElement is null")
-
-    type = NW_DOM_Node_getNodeType( siElement );
-
-    CStringOwner* stringOwner = new (ELeave) CStringOwner;
-    CleanupStack::PushL( stringOwner );
-
-    NW_String_t* name = NW_String_new();
-    User::LeaveIfNull( name );
-    // Let name be on the Cleanup Stack.
-    stringOwner->SetString( name );
-    stat = NW_DOM_Node_getNodeName( siElement, name );
-    User::LeaveIfError( NwxStatusToErrCode( stat ) );
-    NW_Byte*  nameBuf = NW_String_getStorage( name );
-    NW_Uint16 nameLen = NW_String_getCharCount( name, iCharEncoding );
-    TPtrC8 namePtr( nameBuf, nameLen );
-
-    // Now comes the validity check.
-    if ( type != NW_DOM_ELEMENT_NODE || namePtr.CompareF( KSi ) != 0 )
-        {
-        PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: Not si element node <%d>",type)
-        User::Leave( KErrArgument );
-        }
-
-    CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
-
-    /**********************************
-    *   ELEMENT indication
-    ***********************************/
-    if ( NW_DOM_Node_hasChildNodes( siElement ) )
-        {
-        NW_DOM_Node_t* node = NW_DOM_Node_getFirstChild( siElement );
-		if (!node)
-			{
-			PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: no si child nodes!")
-			}
-        User::LeaveIfNull( node );
-
-        // Find the indication element.
-        TBool indicationFound = EFalse;
-        do {
-            type = NW_DOM_Node_getNodeType( node );
-
-            CStringOwner* stringOwner = new (ELeave) CStringOwner;
-            CleanupStack::PushL( stringOwner );
-
-            NW_String_t* name = NW_String_new();
-            User::LeaveIfNull( name );
-            stringOwner->SetString( name );
-            stat = NW_DOM_Node_getNodeName( node, name );
-			PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: getNodeName ErrCode: %d", NwxStatusToErrCode( stat ))
-            User::LeaveIfError( NwxStatusToErrCode( stat ) );
-            NW_Byte*  nameBuf = NW_String_getStorage( name );
-            NW_Uint16 nameLen = NW_String_getCharCount( name,
-                                                        iCharEncoding );
-            TPtrC8 namePtr( nameBuf, nameLen );
-
-            if ( type == NW_DOM_ELEMENT_NODE &&
-                 namePtr.CompareF( KIndication ) == 0 )
-                {
-                // We found the indication element. Parse it.
-                PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: indication under si found.")
-                indicationFound = ETrue;
-                NW_DOM_ElementNode_t* indicationElement =
-                    REINTERPRET_CAST( NW_DOM_ElementNode_t*, node );
-                ParseIndicationL( *indicationElement );
-                }
-
-            CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
-
-            if ( !indicationFound )
-                {
-                // Iterate next.
-                node = NW_DOM_Node_getNextSibling( node );
-                if ( !node )
-                    {
-                    PUSHLOG_WRITE("CSIContentHandler::ParsePushMsgL: No more sibling.")
-                    break;
-                    }
-                }
-
-            } while ( !indicationFound );
-        }
-
-    // Cleanup.
-    CleanupStack::PopAndDestroy( 2, &wbxmlDict ); // docTreeOwner, wbxmlDict
-
-    if ( !ActionFlag() )
-        {
-        // default if no action explicitly stated
-        iPushMsgAction = CSIPushMsgEntry::ESIPushMsgSignalMedium;
-        SetActionFlag( ETrue );
-        PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParsePushMsgL: Defaulting to ActionFlag: %d",iPushMsgAction)
-        }
-
-    iState = EProcessing;
-	IdleComplete();
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::ParsePushMsgL")
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::ParseIndicationL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::ParseIndicationL( NW_DOM_ElementNode_t& aIndication )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ParseIndicationL")
-
-    NW_Status_t stat = NW_STAT_SUCCESS;
-    NW_DOM_NodeType_t type = 0;
-
-    if ( NW_DOM_ElementNode_hasAttributes( &aIndication ) )
-        {
-        NW_DOM_AttributeListIterator_t attrIter;
-        stat = NW_DOM_ElementNode_getAttributeListIterator
-                             ( &aIndication, &attrIter );
-		PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParseIndicationL: getAttribListIter ErrCode: %d", NwxStatusToErrCode( stat ))
-        User::LeaveIfError( NwxStatusToErrCode( stat ) );
-
-        NW_DOM_AttributeHandle_t attrHandle;
-        while ( NW_DOM_AttributeListIterator_getNextAttribute
-                ( &attrIter, &attrHandle ) == NW_STAT_WBXML_ITERATE_MORE )
-            {
-            ParseIndAttributeL( attrHandle );
-            }
-        }
-
-    /**********************************
-    *   PCDATA of ELEMENT indication
-    ***********************************/
-    if ( NW_DOM_Node_hasChildNodes( &aIndication ) )
-        {
-        NW_DOM_TextNode_t* textNode =
-            NW_DOM_Node_getFirstChild( &aIndication );
-        User::LeaveIfNull( textNode );
-
-        type = NW_DOM_Node_getNodeType( textNode );
-        if ( type != NW_DOM_TEXT_NODE )
-            {
-            PUSHLOG_WRITE_FORMAT("CSIContentHandler::ParseIndicationL: Not text node <%d>",type)
-            User::Leave( KErrArgument );
-            }
-
-        ParseTextL( *textNode );
-        }
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::ParseIndicationL")
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::ParseIndAttributeL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::ParseIndAttributeL( NW_DOM_AttributeHandle_t&
-                                            aAttrHandle )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ParseIndAttributeL")
-
-    NW_Status_t stat = NW_STAT_SUCCESS;
-
-    CStringOwner* stringOwner = new (ELeave) CStringOwner;
-    CleanupStack::PushL( stringOwner );
-
-    NW_String_t* attrName = NW_String_new();
-    User::LeaveIfNull( attrName );
-    stringOwner->SetString( attrName );
-
-    // Get the name of the attribute.
-    stat = NW_DOM_AttributeHandle_getName( &aAttrHandle, attrName );
-    User::LeaveIfError( NwxStatusToErrCode( stat ) );
-    NW_Byte*  attrNameBuf = NW_String_getStorage( attrName );
-    NW_Uint16 attrNameLen = NW_String_getCharCount( attrName, iCharEncoding );
-    TPtrC8 attrNamePtr( attrNameBuf, attrNameLen );
-
-    if ( attrNamePtr.CompareF( KCreatedAttrib ) == 0 )
-        {
-        if ( CreatedFlag() )
-            {
-            PUSHLOG_WRITE(" created redefinition")
-            User::Leave( KErrCorrupt );
-            }
-        else
-            {
-            TBool gotDate = AttributeToTTimeL( aAttrHandle, iCreatedTime );
-            SetCreatedFlag( gotDate );
-            PUSHLOG_WRITE_FORMAT(" iCreatedTime set %d",gotDate?1:0)
-            }
-        }
-    else if ( attrNamePtr.CompareF( KHrefAttrib ) == 0 )
-        {
-        if ( HrefFlag() )
-            {
-            PUSHLOG_WRITE(" href redefinition")
-            User::Leave( KErrCorrupt );
-            }
-        else
-            {
-            CStringOwner* stringOwner = new (ELeave) CStringOwner;
-            CleanupStack::PushL( stringOwner );
-
-            NW_String_t* val = NW_String_new();
-            User::LeaveIfNull( val );
-            stringOwner->SetString( val );
-            stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
-            if ( stat != NW_STAT_DOM_NO_STRING_RETURNED )
-                {
-                User::LeaveIfError( NwxStatusToErrCode( stat ) );
-                NW_Byte* storage = NW_String_getStorage( val );
-                NW_Uint16 length = NW_String_getCharCount( val,
-                                                           iCharEncoding );
-                if ( length == 0 )
-                    {
-                    // Zero length href attribute is considered as missing.
-                    PUSHLOG_WRITE(" Zero length HrefFlag");
-                    }
-                else
-                    {
-                    TPtrC8 hrefPtr( storage, length );
-                    HBufC* tempHrefBuf = HBufC::NewMaxL( length );
-                    // No leavable after it!!! until...
-                    tempHrefBuf->Des().Copy( hrefPtr );
-                    iHrefBuf = tempHrefBuf; // ...until here.
-                    SetHrefFlag( ETrue );
-                    PUSHLOG_WRITE_FORMAT(" HrefFlag set <%S>",iHrefBuf);
-                    }
-                }
-
-            CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
-            }
-        }
-    else if ( attrNamePtr.CompareF( KExpiresAttrib ) == 0 )
-        {
-        if ( ExpiresFlag() )
-            {
-            PUSHLOG_WRITE(" expires redefinition")
-            User::Leave( KErrCorrupt );
-            }
-        else
-            {
-            TBool gotDate = AttributeToTTimeL( aAttrHandle, iExpiresTime );
-            SetExpiresFlag( gotDate );
-            PUSHLOG_WRITE_FORMAT(" iExpiresTime set %d",gotDate?1:0)
-            }
-        }
-    else if ( attrNamePtr.CompareF( KSiIdAttrib ) == 0 )
-        {
-        if ( SiIdFlag() )
-            {
-            PUSHLOG_WRITE(" si-id redefinition")
-            User::Leave( KErrCorrupt );
-            }
-        else
-            {
-            // It is expected to be String.
-            CStringOwner* stringOwner = new (ELeave) CStringOwner;
-            CleanupStack::PushL( stringOwner );
-
-            NW_String_t* val = NW_String_new();
-            User::LeaveIfNull( val );
-            stringOwner->SetString( val );
-            stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
-            User::LeaveIfError( NwxStatusToErrCode( stat ) );
-            NW_Byte* storage = NW_String_getStorage( val );
-            NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
-            TPtrC8 siidPtr( storage, length );
-
-            iSiIdBuf = HBufC::NewMaxL( siidPtr.Length() );
-            iSiIdBuf->Des().Copy( siidPtr );
-            SetSiIdFlag( ETrue );
-            PUSHLOG_WRITE_FORMAT(" SiIdFlag set <%S>",iSiIdBuf)
-
-            CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
-            }
-        }
-    else if ( attrNamePtr.CompareF( KActionAttrib ) == 0 )
-        {
-        if ( ActionFlag() )
-            {
-            PUSHLOG_WRITE(" action redefinition")
-            User::Leave( KErrCorrupt );
-            }
-        else
-            {
-            // It is expected to be String.
-            CStringOwner* stringOwner = new (ELeave) CStringOwner;
-            CleanupStack::PushL( stringOwner );
-
-            NW_String_t* val = NW_String_new();
-            User::LeaveIfNull( val );
-            stringOwner->SetString( val );
-            stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
-            User::LeaveIfError( NwxStatusToErrCode( stat ) );
-            NW_Byte* storage = NW_String_getStorage( val );
-            NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
-            TPtrC8 actionPtr( storage, length );
-
-            iPushMsgAction = ConvertActionString( actionPtr );
-            SetActionFlag( ETrue );
-            PUSHLOG_WRITE_FORMAT(" ActionFlag: %d",iPushMsgAction)
-
-            CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
-            }
-        }
-    else
-        {
-        __ASSERT_DEBUG( EFalse,
-            ContHandPanic( EPushContHandPanUnexpSiToken ) );
-        }
-
-    CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::ParseIndAttributeL")
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::ParseTextL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::ParseTextL( NW_DOM_TextNode_t& aTextNode )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ParseTextL")
-
-    if ( DataFlag() )
-        {
-        PUSHLOG_WRITE(" Data flag already set.")
-        }
-    else
-        {
-        CStringOwner* stringOwner = new (ELeave) CStringOwner;
-        CleanupStack::PushL( stringOwner );
-
-        NW_String_t* data = NW_String_new();
-        User::LeaveIfNull( data );
-        stringOwner->SetString( data );
-        NW_Status_t stat = NW_STAT_SUCCESS;
-        stat = NW_DOM_TextNode_getData( &aTextNode, data );
-        User::LeaveIfError( NwxStatusToErrCode( stat ) );
-
-        HBufC16* ucs2buffer = ConvertToUnicodeL( *data, iCharEncoding );
-        // Be careful: ucs2buffer is not on the CleanupStack!
-        __ASSERT_DEBUG( ucs2buffer != 0, ContHandPanic( EPushContHandPanNullUcs2Buf ) );
-
-        TPtrC16 ucs2ptrC( *ucs2buffer );
-        if ( ucs2ptrC.Length() == 0 )
-            {
-            // Zero length data is considered as nothing.
-            PUSHLOG_WRITE(" Zero length Data");
-            }
-        else
-            {
-            PUSHLOG_WRITE_FORMAT(" Data: <%S>",&ucs2ptrC);
-
-            #ifdef __TEST_LOG__
-            // Write out each unicode character identifier
-            TInt length = ucs2ptrC.Length();
-            for (TInt logI=0;logI<length;logI++)
-                {
-                TBuf16<1> currChar;
-                currChar.Copy( ucs2ptrC.Mid( logI, /*aLength*/1 ) );
-                PUSHLOG_WRITE_FORMAT2(" 0x%x %S",currChar[0],&currChar);
-                }
-            #endif // __TEST_LOG__
-
-            iData = ucs2buffer; // Ownership transferred.
-            ucs2buffer = NULL;
-            SetDataFlag( ETrue );
-            }
-
-        CleanupStack::PopAndDestroy( stringOwner );
-        }
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::ParseTextL")
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::ConvertToUnicodeL
-// ---------------------------------------------------------
-//
-HBufC16* CSIContentHandler::ConvertToUnicodeL( const TDesC8& aSrc, TUint aCharSetId )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ConvertToUnicodeL");
-
-    __ASSERT_DEBUG( aCharSetId != 0, ContHandPanic( EPushContHandPanNullCharSetId ) );
-
-    InitialiseCharacterSetConverterL();
-
-    HBufC16* ucs2buffer = NULL; // The return value.
-    TBool resultOnStack = EFalse;
-
-    #ifdef __TEST_LOG__
-    // Write out the original 8-bit buffer
-    TInt origiLength = aSrc.Length();
-    for (TInt origiLogI=0;origiLogI<origiLength;origiLogI++)
-        {
-        TBuf16<1> currChar; // Only 16-bit buffer can be written out.
-        currChar.Copy( aSrc.Mid( origiLogI, /*aLength*/1 ) );
-        PUSHLOG_WRITE_FORMAT2(" 0x%x %S",currChar[0],&currChar);
-        }
-    #endif // __TEST_LOG__
-
-    // Result
-    HBufC16* buffer = HBufC16::NewLC( KPushConversionBufferSize );
-    PUSHLOG_WRITE(" buffer allocated");
-    TPtr16 ptr( buffer->Des() );
-
-    // Prepare conversion for the given charset ID.
-    RFs& fs = iMsvSession->FileSession();
-    iCharacterSetConverter->PrepareToConvertToOrFromL
-        ( aCharSetId, *iCharacterSetsAvailable, fs );
-    PUSHLOG_WRITE(" PrepareToConvertToOrFromL OK");
-
-    TInt state = 0;
-    TInt remaining = iCharacterSetConverter->ConvertToUnicode( ptr, aSrc, state );
-    PUSHLOG_WRITE_FORMAT(" remaining: %d",remaining);
-    while ( remaining >= 0 )
-        {
-        if ( ucs2buffer == NULL )
-            {
-            ucs2buffer = HBufC::NewLC( ptr.Length() );
-            resultOnStack = ETrue;
-            }
-        else
-            {
-            __ASSERT_DEBUG( resultOnStack,
-                ContHandPanic( EPushContHandPanSiResNotOnStack ) );
-            // This may change the address of ucs2buffer so we need to put
-            // it on the cleanup stack again!!
-            ucs2buffer = ucs2buffer->ReAllocL
-                ( ucs2buffer->Length() + ptr.Length() );
-            CleanupStack::Pop();    // old ucs2buffer
-            CleanupStack::PushL( ucs2buffer );  // possibly new copy
-            PUSHLOG_WRITE(" ucs2buffer reallocated");
-            }
-        TPtr16 ucs2ptr( ucs2buffer->Des() );
-        ucs2ptr.Append( ptr );
-        if ( remaining > 0 )
-            {
-            // Try to convert all remaining characters.
-            ptr.Zero();
-            remaining = iCharacterSetConverter->ConvertToUnicode
-                ( ptr, aSrc.Right( remaining ), state );
-            PUSHLOG_WRITE_FORMAT(" remaining: %d",remaining);
-            }
-        else
-            {
-            PUSHLOG_WRITE(" break");
-            break;
-            }
-        }
-
-    if ( resultOnStack )
-        {
-        CleanupStack::Pop();    // ucs2buffer
-        resultOnStack = EFalse;
-        }
-
-    // ucs2buffer is not on the CleanupStack!
-
-    CleanupStack::PopAndDestroy( buffer ); // buffer
-
-    if ( ucs2buffer == NULL )
-        {
-        PUSHLOG_WRITE(" NULL ucs2buffer - allocating an empty buf");
-        ucs2buffer = KNullDesC().AllocL();
-        }
-    else
-        {
-        // Check if first character is a Zero-width nbsp.
-        TPtrC16 ucs2ptrC( *ucs2buffer );
-        if ( ucs2ptrC.Length() >= 1 && ucs2ptrC[0] == KPushZeroWidthNbsp )
-            {
-            // First character is a Zero-width NBSP. This character is used as
-            // BOM in some encodings and should not be present at this point.
-            // But we are tolerant and remove it.
-            // (Not expecting big-endianness here.)
-            HBufC16* temp = ucs2buffer;
-            CleanupStack::PushL( temp );
-            ucs2buffer = ucs2ptrC.Mid( 1 ).AllocL();
-            CleanupStack::PopAndDestroy( temp ); // temp
-            PUSHLOG_WRITE(" BOM removed");
-            }
-        else
-            {
-            PUSHLOG_WRITE(" No BOM");
-            }
-        }
-
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::ConvertToUnicodeL");
-    return ucs2buffer;
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::ConvertToUnicodeL
-// ---------------------------------------------------------
-//
-HBufC16* CSIContentHandler::ConvertToUnicodeL
-    ( NW_String_t& aString, NW_Uint32 aCharEncoding )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ConvertToUnicodeL");
-
-    /* As cXmlLibrary does, we support only the following charsets:
-    #define HTTP_iso_10646_ucs_2        0x03E8
-    #define HTTP_iso_8859_1             0x04
-    #define HTTP_us_ascii               0x03
-    #define HTTP_utf_8                  0x6A
-    #define HTTP_utf_16                 1015
-    */
-    TUint id = 0;
-    if ( aCharEncoding == HTTP_iso_10646_ucs_2 )
-        {
-        id = KCharacterSetIdentifierUcs2;
-        PUSHLOG_WRITE(" KCharacterSetIdentifierUcs2")
-        }
-    else if ( aCharEncoding == HTTP_iso_8859_1 )
-        {
-        id = KCharacterSetIdentifierIso88591;
-        PUSHLOG_WRITE(" KCharacterSetIdentifierIso88591")
-        }
-    else if ( aCharEncoding == HTTP_us_ascii )
-        {
-        id = KCharacterSetIdentifierAscii;
-        PUSHLOG_WRITE(" KCharacterSetIdentifierAscii")
-        }
-    else if ( aCharEncoding == HTTP_utf_8 )
-        {
-        id = KCharacterSetIdentifierUtf8;
-        PUSHLOG_WRITE(" KCharacterSetIdentifierUtf8")
-        }
-    else if ( aCharEncoding == HTTP_utf_16 ) // No such in CharConv.h
-        {
-        id = KCharacterSetIdentifierUcs2;
-        PUSHLOG_WRITE(" KCharacterSetIdentifierUcs2")
-        }
-    else
-        {
-        id = KCharacterSetIdentifierUtf8; // Defaulting to UTF-8
-        PUSHLOG_WRITE(" DEFAULTING to KCharacterSetIdentifierUtf8");
-        }
-
-    PUSHLOG_WRITE_FORMAT(" id: 0x%x",id);
-    __ASSERT_DEBUG( id != 0, ContHandPanic( EPushContHandPanNullCharSetId ) );
-
-    // Source
-    PUSHLOG_WRITE_FORMAT(" Storage: 0x%x",NW_String_getStorage(&aString));
-    PUSHLOG_WRITE_FORMAT(" Byte count: %d",NW_String_getByteCount(&aString)-1);
-
-    // We will use NW_String_getByteCount(&aString)-1 as size, because
-    // NW_String_getByteCount(&aString) includes NULL terminator.
-    const TPtrC8 src( NW_String_getStorage(&aString),
-                      NW_String_getByteCount(&aString)-1 );
-    HBufC16* ucs2buffer = ConvertToUnicodeL( src, id );
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::ConvertToUnicodeL");
-    return ucs2buffer;
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::InitialiseCharacterSetConverterL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::InitialiseCharacterSetConverterL()
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::InitialiseCharacterSetConverterL")
-
-    iCharacterSetConverter = CCnvCharacterSetConverter::NewL();
-
-    RFs& fs = iMsvSession->FileSession();
-    iCharacterSetsAvailable =
-        CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL( fs );
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::InitialiseCharacterSetConverterL")
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::ConvertActionString
-// ---------------------------------------------------------
-//
-TUint CSIContentHandler::ConvertActionString
-                         ( const TDesC8& aActionString ) const
-	{
-	const TInt KMatchFound = 0;
-
-	// set to default signal value (to rid ourselves of build warning)
-	TUint actionValue = CSIPushMsgEntry::ESIPushMsgSignalMedium;
-
-	if ( aActionString.Compare( KDeleteAction ) == KMatchFound )
-        {
-		actionValue = CSIPushMsgEntry::ESIPushMsgDelete;
-        }
-	else if ( aActionString.Compare( KSignalNone ) == KMatchFound )
-        {
-		actionValue = CSIPushMsgEntry::ESIPushMsgSignalNone;
-        }
-	else if ( aActionString.Compare( KSignalLow ) == KMatchFound )
-        {
-		actionValue = CSIPushMsgEntry::ESIPushMsgSignalLow;
-        }
-	else if ( aActionString.Compare( KSignalMedium ) == KMatchFound )
-        {
-		actionValue = CSIPushMsgEntry::ESIPushMsgSignalMedium;
-        }
-	else if ( aActionString.Compare( KSignalHigh ) == KMatchFound )
-        {
-		actionValue = CSIPushMsgEntry::ESIPushMsgSignalHigh;
-        }
-
-	return actionValue;
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::SetSIPushMsgEntryFieldsL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::SetSIPushMsgEntryFieldsL( CSIPushMsgEntry&
-                                                  aSIPushMsgEntry )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::SetSIPushMsgEntryFieldsL")
-
-	if ( SiIdFlag() || HrefFlag() )
-		{
-		if ( SiIdFlag() && ( HrefFlag() == EFalse ) )
-			{
-            // Message has only si-id but no href.
-            aSIPushMsgEntry.SetIdL( *iSiIdBuf );
-			}
-		else if ( HrefFlag() && ( SiIdFlag() == EFalse ) )
-			{
-            // If message has no si-id but does have a href, use href as si-id.
-            aSIPushMsgEntry.SetIdL( *iHrefBuf );
-            aSIPushMsgEntry.SetUrlL( *iHrefBuf );
-			}
-		else
-            {
-            // Use si-id and href as is.
-            aSIPushMsgEntry.SetIdL( *iSiIdBuf );
-            aSIPushMsgEntry.SetUrlL( *iHrefBuf );
-            }
-		}
-
-    __ASSERT_DEBUG( ActionFlag(),
-                    ContHandPanic( EPushContHandPanUnspecSiAction ) );
-	if ( ActionFlag() )
-        {
-		aSIPushMsgEntry.SetAction( iPushMsgAction );
-        }
-	else // default if no action explicitly stated
-        {
-		aSIPushMsgEntry.SetAction( CSIPushMsgEntry::ESIPushMsgSignalMedium );
-        }
-
-	// uses default null time value if no explicit date set in message
-	aSIPushMsgEntry.SetCreated( iCreatedTime );
-	aSIPushMsgEntry.SetExpires( iExpiresTime );
-
-	// PCDATA (text) from message
-	if ( DataFlag() )
-        {
-		aSIPushMsgEntry.SetTextL( *iData );
-        }
-
-	TPtrC8 msgHeaderPtr;
-	iMessage->GetHeader( msgHeaderPtr );
-	aSIPushMsgEntry.SetHeaderL( msgHeaderPtr );
-
-    // Get server address.
-    TPtrC8 srvAddress;
-    if ( iMessage->GetServerAddress( srvAddress ) )
-        {
-	    aSIPushMsgEntry.SetFromL( srvAddress );
-        }
-
-    // First line in Inbox: TMsvEntry::iDetails.
-    if ( srvAddress.Length() == 0 )
-        {
-        // Read from resource.
-        HBufC* details =
-            iStrRscReader->AllocReadResourceLC( R_PUSHMISC_UNK_SENDER );
-        aSIPushMsgEntry.SetMsgDetailsL( *details );
-        CleanupStack::PopAndDestroy( details );
-        }
-    else
-        {
-        // Convert the "From" information to the format required by the UI
-        // spec and then decode it.
-        HBufC* details = iWapPushUtils->ConvertDetailsL( srvAddress );
-        CleanupStack::PushL( details );
-        HBufC* convertedFrom =
-            CPushMtmUtil::ConvertUriToDisplayFormL( *details );
-        CleanupStack::PushL( convertedFrom );
-        //
-        aSIPushMsgEntry.SetMsgDetailsL( *convertedFrom );
-        //
-        CleanupStack::PopAndDestroy( 2, details ); // convertedFrom, details
-        }
-
-    // Second line in Inbox: TMsvEntry::iDescription.
-	if ( DataFlag() )
-        {
-        // Display SI message.
-		aSIPushMsgEntry.SetMsgDescriptionL( *iData );
-        }
-    else
-        {
-        // Display URL.
-        __ASSERT_DEBUG( HrefFlag(),
-                        ContHandPanic( EPushContHandPanUnspecSiHref ) );
-        const TPtrC url = aSIPushMsgEntry.Url();
-        HBufC* convertedUrl = CPushMtmUtil::ConvertUriToDisplayFormL( url );
-        CleanupStack::PushL( convertedUrl );
-        //
-        aSIPushMsgEntry.SetMsgDescriptionL( *convertedUrl );
-        //
-        CleanupStack::PopAndDestroy( convertedUrl ); // convertedUrl
-        }
-
-    // ******** Push MTM specific processing *********
-
-    /*
-    * Unfortunately in CPushMsgEntryBase there is no such functionality
-    * with which we can reach TMsvEntry as non-const, but we have to
-    * modify the entry's iMtmData2 member somehow. We can do it
-    * with either casting or with modifying and saving the entry
-    * manually after it has been saved by CSIPushMsgEntry. The latter
-    * solution is more expensive so we choose the first.
-    */
-    TMsvEntry& tEntry = CONST_CAST( TMsvEntry&, aSIPushMsgEntry.Entry() );
-    if ( HrefFlag() )
-        {
-        CPushMtmUtil::SetAttrs( tEntry, EPushMtmAttrHasHref );
-        }
-    else
-        {
-        CPushMtmUtil::ResetAttrs( tEntry, EPushMtmAttrHasHref );
-        }
-
-    // *** Set the entry to unread and new state. ***
-
-    tEntry.SetNew( ETrue );
-    tEntry.SetUnread( ETrue );
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::SetSIPushMsgEntryFieldsL")
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::ProcessingPushMsgEntryL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::ProcessingPushMsgEntryL()
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ProcessingPushMsgEntryL")
-
-	TBool deletePushMsg( EFalse );
-
-    __ASSERT_DEBUG( ActionFlag(),
-                    ContHandPanic( EPushContHandPanUnspecSiAction ) );
-
-    // S60 requirement: if both the href and the message is empty then
-    // delete the msg.
-    if ( HrefFlag() == EFalse && DataFlag() == EFalse )
-        {
-        deletePushMsg = ETrue;
-        }
-
-    // Expiration.
-    if ( !deletePushMsg && ExpiresFlag() )
-        {
-	    TTime today;
-	    today.UniversalTime();
-#ifdef __TEST_LOG__
-        _LIT( KDateFormat, "%E%D%X%N%Y %1 %2 %3" );
-        _LIT( KTimeFormat, "%-B%:0%J%:1%T%:2%S%:3%+B" );
-        TBuf<32> dateHolder;
-        TBuf<32> timeHolder;
-        today.FormatL( dateHolder, KDateFormat );
-        today.FormatL( timeHolder, KTimeFormat );
-        PUSHLOG_WRITE_FORMAT(" now date: <%S>",&dateHolder)
-        PUSHLOG_WRITE_FORMAT(" now time: <%S>",&timeHolder)
-        iExpiresTime.FormatL( dateHolder, KDateFormat );
-        iExpiresTime.FormatL( timeHolder, KTimeFormat );
-        PUSHLOG_WRITE_FORMAT(" exp date: <%S>",&dateHolder)
-        PUSHLOG_WRITE_FORMAT(" exp time: <%S>",&timeHolder)
-#endif // __TEST_LOG__
-	    // check if message has expiry date before today's date
-	    if ( iExpiresTime < today )
-		    {
-            PUSHLOG_WRITE("CSIContentHandler already expired")
-		    deletePushMsg = ETrue;
-		    }
-        }
-
-	// An SI with the action attribute set to “delete” MUST have an
-    // explicitly assigned value for si-id.
-	if ( !deletePushMsg && ActionFlag() )
-		{
-		if ( iPushMsgAction == CSIPushMsgEntry::ESIPushMsgDelete )
-            {
-            if ( !SiIdFlag() || ( SiIdFlag() && iSiIdBuf->Length() == 0 ) )
-                {
-                deletePushMsg = ETrue;
-                }
-            }
-        }
-
-    // Handling out of order delivery & Replacement.
-    TMsvId matchingEntryId = KMsvNullIndexEntryId;
-
-    if ( !deletePushMsg && ( SiIdFlag() || HrefFlag() ) && CreatedFlag() )
-        {
-        deletePushMsg = HandleMsgOrderReceptionL( matchingEntryId );
-        }
-
-    if ( !deletePushMsg && ActionFlag() )
-        {
-        // SI with action=signal-none must not be presented to the end-user.
-        // Note. In S60 signal-none behaves the same as delete: the
-        // message is discarded after processing it!
-        if ( iPushMsgAction == CSIPushMsgEntry::ESIPushMsgSignalNone )
-            {
-            deletePushMsg = ETrue;
-            }
-        // SI with action=delete must also be discarded.
-        else if ( iPushMsgAction == CSIPushMsgEntry::ESIPushMsgDelete )
-            {
-            deletePushMsg = ETrue;
-            }
-        }
-
-	// Store message if not marked for deletion.
-	if ( !deletePushMsg )
-        {
-		StoreSIMessageL( matchingEntryId );
-        }
-    else
-        {
-        // The new entry must be discarded.
-        // Delete the corresponding matching entry, too.
-        if ( matchingEntryId != KMsvNullIndexEntryId )
-            {
-            iWapPushUtils->DeleteEntryL( matchingEntryId );
-            }
-        }
-
-	iState = EDone;
-	IdleComplete();
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::ProcessingPushMsgEntryL")
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::StoreSIMessageL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::StoreSIMessageL( TMsvId aMatchingEntryId )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::StoreSIMessageL")
-
-	CSIPushMsgEntry* siEntry = CSIPushMsgEntry::NewL();
-	CleanupStack::PushL( siEntry );
-
-    if ( aMatchingEntryId != KMsvNullIndexEntryId )
-    {
-       PUSHLOG_WRITE("Matching SI found");
-       //Delete this old entry
-       iWapPushUtils->DeleteEntryL( aMatchingEntryId );
-    }
-
-    SetSIPushMsgEntryFieldsL( *siEntry );
-    iSavedMsgId = siEntry->SaveL( *iMsvSession, KMsvGlobalInBoxIndexEntryId );
-
-#ifdef __TEST_LOG__
-        _LIT( KDateFormat, "%E%D%X%N%Y %1 %2 %3" );
-        _LIT( KTimeFormat, "%-B%:0%J%:1%T%:2%S%:3%+B" );
-        TBuf<32> dateHolder;
-        TBuf<32> timeHolder;
-        TTime recDateTime = siEntry->ReceivedDate();
-        recDateTime.FormatL( dateHolder, KDateFormat );
-        recDateTime.FormatL( timeHolder, KTimeFormat );
-        PUSHLOG_WRITE_FORMAT(" rec date: <%S>",&dateHolder)
-        PUSHLOG_WRITE_FORMAT(" rec time: <%S>",&timeHolder)
-#endif // __TEST_LOG__
-
-	CleanupStack::PopAndDestroy( siEntry ); // siEntry
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::StoreSIMessageL")
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::HandleMsgOrderReceptionL
-// ---------------------------------------------------------
-//
-TBool CSIContentHandler::HandleMsgOrderReceptionL( TMsvId& aMatchingEntryId )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::HandleMsgOrderReceptionL")
-
-    __ASSERT_DEBUG( ( SiIdFlag() || HrefFlag() ),
-            ContHandPanic( EPushContHandPanNoSiIdOrHrefAttr ) );
-    __ASSERT_DEBUG( CreatedFlag(),
-            ContHandPanic( EPushContHandPanNoCreatedAttr ) );
-
-    CMsvEntrySelection* matchingIdList = NULL;
-	TBool discardPushMsg( EFalse );
-
-	// Get list of matching stored SI messages.
-	if ( SiIdFlag() && iSiIdBuf->Length() != 0 )
-        {
-		matchingIdList = iWapPushUtils->FindSiIdLC( *iSiIdBuf );
-        }
-	else // HrefFlag()
-        {
-        // Use href as si-id.
-		matchingIdList = iWapPushUtils->FindSiIdLC( *iHrefBuf );
-        }
-    const TInt matchingListCount( matchingIdList->Count() );
-    // Note that the count can be greater than 1.
-
-    PUSHLOG_WRITE_FORMAT("CSIContentHandler Count: %d",matchingListCount)
-
-	if ( 0 < matchingListCount && CreatedFlag() )
-		{
-		CSIPushMsgEntry* siEntry = CSIPushMsgEntry::NewL();
-		CleanupStack::PushL( siEntry );
-
-		// Delete older stored messages and/or mark current message for
-        // deletion if same date or older than stored messages
-        TBool foundOneToBeReplaced = EFalse;
-		for ( TInt count = 0; count < matchingListCount; ++count )
-			{
-			TMsvId matchingSiMsgEntryId( matchingIdList->At(count) );
-
-            siEntry->RetrieveL( *iMsvSession, matchingSiMsgEntryId );
-
-			// Skip date comparisons if creation date not valid -
-            // SI without created attribute never gets replaced.
-			TTime existingSiCreatedTime( siEntry->Created() );
-
-			if ( existingSiCreatedTime == Time::NullTTime() )
-                {
-				// continue;
-                }
-            else
-                {
-                __ASSERT_DEBUG( !foundOneToBeReplaced,
-                                ContHandPanic( EPushContHandPanTooManySi ) );
-                if ( foundOneToBeReplaced )
-                    {
-                    PUSHLOG_WRITE(" Already found one")
-                    // Only one SI has to be found.
-                    // If the program runs into it, then make a
-                    // garbage collection to ensure consistency and
-                    // remove other messages found.
-                    iWapPushUtils->DeleteEntryL( matchingSiMsgEntryId );
-                    // After the 'for' only one SI is allowed that has created
-                    // attribute.
-                    }
-                else
-                    {
-                    foundOneToBeReplaced = ETrue; // A match was found.
-                    // Check if received SI is newer than existing stored Si
-                    // (out of order).
-                    if ( iCreatedTime > existingSiCreatedTime )
-	                    {
-                        PUSHLOG_WRITE(" Replacing...")
-                        // The new SI replaces the existing.
-                        aMatchingEntryId = matchingSiMsgEntryId;
-                        discardPushMsg = EFalse;
-	                    }
-                    else if ( iCreatedTime <= existingSiCreatedTime )
-                        {
-                        PUSHLOG_WRITE(" Discarding...")
-                        // Received SI is older than existing stored Si.
-                        discardPushMsg = ETrue;
-                        }
-                    }
-                }
-			}
-
-		CleanupStack::PopAndDestroy( siEntry ); // siEntry
-		}
-
-	CleanupStack::PopAndDestroy( matchingIdList ); // matchingIdList
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::HandleMsgOrderReceptionL")
-    return discardPushMsg;
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::ConvertDateTimeL
-// ---------------------------------------------------------
-//
-TBool CSIContentHandler::ConvertDateTimeL( const TDesC& aDateTime,
-                                           TTime& aConvertedDate ) const
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ConvertDateTimeL")
-
-	TTime convertedTime = Time::NullTTime();
-	TBool convertedOK = EFalse;
-
-    // check supplied descriptor is the correct length
-	if ( aDateTime.Length() != KValidUTCLength )
-        {
-        PUSHLOG_WRITE_FORMAT(" invalid UTC length <%d>",aDateTime.Length())
-        User::Leave( KErrCorrupt );
-        }
-    else
-		{
-		TBuf<KValidUTCLength> str = aDateTime;
-        PUSHLOG_WRITE_FORMAT(" datetime str: <%S>",&str)
-		if ( !IsValidUTCTime( str ) )
-            {
-            // The UTC time is invalid.
-            PUSHLOG_WRITE(" invalid UTC time")
-            User::Leave( KErrCorrupt );
-            }
-        else
-			{
-            // Now 'str' is in format YYYYMMDD:HHMMSS
-			// Adjust UTC time to zero offset TTime. Only month and day
-            // is effected.
-			const TInt KFirstMonthChar = KValidTTimeMonthStart;
-			const TInt KSecondMonthChar = KFirstMonthChar + 1;
-			const TInt KFirstDayChar = KValidTTimeDayStart;
-			const TInt KSecondDayChar = KFirstDayChar + 1;
-            // Month.
-			// check for special case of month = 10 which becomes 09
-			if ( str[KFirstMonthChar] == '1' && str[KSecondMonthChar] == '0' )
-				{
-				str[KFirstMonthChar] = '0';
-				str[KSecondMonthChar] = '9';
-				}
-			else
-                {
-				// month value is either 11, 12 or less than 10, ie 1 - 9.
-				// reduce day by one, eg 11 becomes 10, 12 becomes 11, 09 becomes 08
-				str[KSecondMonthChar]--;
-                }
-
-            // Day.
-			// check for special cases 10, 20, 30
-			if ( str[KSecondDayChar] == '0' )
-				{
-				// reduce day by 1, ie 10 becomes 09, 20 becomes 19 ...
-				str[KSecondDayChar] = '9';
-				str[KFirstDayChar]--;
-				}
-			else
-                {
-				// day value is between 1 and 9 so reduce day by one
-				// eg 29 becomes 28, 11 bcomes 10, 31 becomes 30
-				str[KSecondDayChar]--;
-                }
-
-			// string is now syntaxically correct, but Set() will return an
-            // error if it's semantically incorrect.
-            User::LeaveIfError( convertedTime.Set( str ) );
-			convertedOK = ETrue;
-			}
-		}
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::ConvertDateTimeL")
-	aConvertedDate = convertedTime;
-	return convertedOK;
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::ConvertOpaqueToUtcL
-// ---------------------------------------------------------
-//
-HBufC* CSIContentHandler::ConvertOpaqueToUtcL( const TDesC8& aOpaque ) const
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::ConvertOpaqueToUtcL")
-
-    const TInt opaqueSize = aOpaque.Size();
-    if ( KValidMaxEncodedDateTimeSize < opaqueSize )
-        {
-        PUSHLOG_WRITE_FORMAT(" Bad OPAQUE size: <%d>",opaqueSize)
-        User::Leave( KErrCorrupt );
-        }
-
-    HBufC* converted = HBufC::NewMaxLC( KValidUTCLength );
-    TPtr convertedPtr = converted->Des();
-    convertedPtr.SetLength( 0 ); // Reset.
-
-    // Split up each opaque byte to two bytes.
-    TUint8 byte( 0x00 );
-    TUint8 high( 0x00 );
-    TUint8 low( 0x00 );
-    TInt i = 0;
-    for ( i = 0; i < opaqueSize; ++i )
-        {
-        byte = aOpaque[i];
-        high = (TUint8)( (byte & 0xF0) >> 4 );
-        low  = (TUint8)(  byte & 0x0F );
-        // Check high and low if they are in the range [0-9].
-        if ( 9 < high || 9 < low )
-            {
-            PUSHLOG_WRITE_FORMAT2(" Overflow: <%d, %d>",high,low)
-            User::Leave( KErrOverflow );
-            }
-        convertedPtr.Append( TChar(KAsciiZeroCharCode + high) );
-        convertedPtr.Append( TChar(KAsciiZeroCharCode + low) );
-        }
-
-    // A valid UTC %Datetime contains 14 numerical characters and 6
-    // non-numerical: “1999-04-30T06:40:00Z”.
-    // So fill the remaining bytes with zeros.
-    for ( i = convertedPtr.Length(); i < KValidUTCNumericals; ++i )
-        {
-        convertedPtr.Append( TChar('0') );
-        }
-
-    // Insert the necessary non-numerical boundary characters.
-    i = 0;
-    // Skip year and insert '-'. (Don't forget to increase i with 1 each time!)
-    i += KValidUTCYearBlockLength;
-    convertedPtr.Insert( i++, KCharMinus );
-    // Skip month and insert '-'.
-    i += KValidUTCOtherBlockLength;
-    convertedPtr.Insert( i++, KCharMinus );
-    // Skip day and insert 'T'.
-    i += KValidUTCOtherBlockLength;
-    convertedPtr.Insert( i++, KCharT );
-    // Skip hour and insert ':'.
-    i += KValidUTCOtherBlockLength;
-    convertedPtr.Insert( i++, KCharColon );
-    // Skip minute and insert ':'.
-    i += KValidUTCOtherBlockLength;
-    convertedPtr.Insert( i++, KCharColon );
-    // Skip second and insert 'Z'.
-    i += KValidUTCOtherBlockLength;
-    convertedPtr.Insert( i++, KCharZ );
-
-    CleanupStack::Pop( converted ); // converted
-    PUSHLOG_LEAVEFN("CSIContentHandler::ConvertOpaqueToUtcL")
-	return converted;
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::IsValidUTCTime
-// ---------------------------------------------------------
-//
-TBool CSIContentHandler::IsValidUTCTime( TDes& aDateTime ) const
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::IsValidUTCTime")
-
-    TBool isValid( ETrue ); // Return value.
-
-    // Now aDateTime has to be in format YYYY-MM-DDTHH:MM:SSZ
-
-    // check supplied descriptor is the correct length
-	if ( aDateTime.Length() != KValidUTCLength )
-        {
-        PUSHLOG_WRITE_FORMAT(" invalid UTC length <%d>",aDateTime.Length())
-        isValid = EFalse;
-        }
-    else
-        {
-	    // strip out formatting characters
-	    TInt formatCharPos = 4;
-	    aDateTime.Delete( formatCharPos, 1 );
-	    // now move through two characters at a time and remove other chars
-	    // to just leave digits
-	    const TInt KRemainingFormatChars = 5;
-        TInt i( 0 );
-	    for ( i = 0; i < KRemainingFormatChars; ++i )
-		    {
-		    formatCharPos += 2;
-		    aDateTime.Delete( formatCharPos, 1 );
-		    }
-
-        // Now aDateTime has to be in format YYYYMMDDHHMMSS
-
-        __ASSERT_DEBUG( aDateTime.Length() == KValidTTimeLength,
-                        ContHandPanic( EPushContHandPanBadTTimeLength ) );
-
-        // now have UTC string stripped of format characters - check remaining
-        // characters are all digits - YYYYMMDDHHMMSS
-        TChar ch;
-        for ( i = 0; i < KValidTTimeLength; ++i )
-		    {
-		    ch = aDateTime[i];
-		    if ( ch.IsDigit() == EFalse )
-                {
-                PUSHLOG_WRITE_FORMAT(" not digit <%d>",i)
-                isValid = EFalse;
-                }
-		    }
-
-        if ( isValid )
-            {
-            /*
-            In YYYYMMDDHHMMSS
-            YYYY = 4 digit year ("0000" ... "9999")
-            MM = 2 digit month ("01"=January, "02"=February ... "12"=December)
-            DD = 2 digit day ("01", "02" ... "31")
-            HH = 2 digit hour, 24-hour timekeeping system ("00" ... "23")
-            MM = 2 digit minute ("00" ... "59")
-            SS = 2 digit second ("00" ... "59")
-            */
-            TInt err;
-            TUint val;
-            // Do not check year. There are no restrictions.
-            // Check month.
-            TLex parser( aDateTime.Mid( KValidTTimeMonthStart,
-                                        KValidTTimeBlockLength ) );
-            err = parser.Val( val, EDecimal );
-            if ( err )
-                {
-                isValid = EFalse;
-                PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
-                }
-            else
-                {
-                PUSHLOG_WRITE_FORMAT(" month: <%d>",val)
-                if ( val < 1 || 12 < val )
-                    {
-                    isValid = EFalse;
-                    }
-                }
-            // Check day.
-            if ( isValid )
-                {
-                parser = aDateTime.Mid( KValidTTimeDayStart,
-                                        KValidTTimeBlockLength );
-                err = parser.Val( val, EDecimal );
-                if ( err )
-                    {
-                    isValid = EFalse;
-                    PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
-                    }
-                else
-                    {
-                    PUSHLOG_WRITE_FORMAT(" day: <%d>",val)
-                    if ( val < 1 || 31 < val )
-                        {
-                        isValid = EFalse;
-                        }
-                    }
-                }
-            // Check hour.
-            if ( isValid )
-                {
-                parser = aDateTime.Mid( KValidTTimeHourStart,
-                                        KValidTTimeBlockLength );
-                err = parser.Val( val, EDecimal );
-                if ( err )
-                    {
-                    isValid = EFalse;
-                    PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
-                    }
-                else
-                    {
-                    PUSHLOG_WRITE_FORMAT(" hour: <%d>",val)
-                    if ( 23 < val )
-                        {
-                        isValid = EFalse;
-                        }
-                    }
-                }
-            // Check minute.
-            if ( isValid )
-                {
-                parser = aDateTime.Mid( KValidTTimeMinuteStart,
-                                        KValidTTimeBlockLength );
-                err = parser.Val( val, EDecimal );
-                if ( err )
-                    {
-                    isValid = EFalse;
-                    PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
-                    }
-                else
-                    {
-                    PUSHLOG_WRITE_FORMAT(" min: <%d>",val)
-                    if ( 59 < val )
-                        {
-                        isValid = EFalse;
-                        }
-                    }
-                }
-            // Check second.
-            if ( isValid )
-                {
-                parser = aDateTime.Mid( KValidTTimeSecondStart,
-                                        KValidTTimeBlockLength );
-                err = parser.Val( val, EDecimal );
-                if ( err )
-                    {
-                    isValid = EFalse;
-                    PUSHLOG_WRITE_FORMAT(" parser err: <%d>",err)
-                    }
-                else
-                    {
-                    PUSHLOG_WRITE_FORMAT(" sec: <%d>",val)
-                    if ( 59 < val )
-                        {
-                        isValid = EFalse;
-                        }
-                    }
-                }
-
-	        // insert colon seperating date from time
-	        const TInt KColonPosition = 8;
-	        aDateTime.Insert( KColonPosition, KCharColon );
-
-            // Now aDateTime has to be in format YYYYMMDD:HHMMSS
-            }
-        }
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::IsValidUTCTime")
-	return isValid; // aDateTime contains a modified buffer.
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::AttributeToTTimeL
-// ---------------------------------------------------------
-//
-TBool CSIContentHandler::AttributeToTTimeL
-                        ( NW_DOM_AttributeHandle_t& aAttrHandle,
-                          TTime& aConvertedDate ) const
-    {
-    PUSHLOG_ENTERFN("CSIContentHandler::AttributeToTTimeL")
-
-    TBool gotDate = EFalse;
-    NW_Status_t stat = NW_STAT_SUCCESS;
-    NW_DOM_AttrVal_t attrVal;
-
-    // It is expected to be String or Opaque.
-    // It may be Opaque, to which we will need a NW_DOM_AttrVal_t structure.
-    stat = NW_DOM_AttributeHandle_getNextVal( &aAttrHandle, &attrVal );
-
-    if ( stat != NW_STAT_WBXML_ITERATE_MORE )
-        {
-        User::LeaveIfError( NwxStatusToErrCode( stat ) );
-        }
-    else
-        {
-        NW_Uint16 valType = NW_DOM_AttrVal_getType( &attrVal );
-
-        if ( valType == NW_DOM_ATTR_VAL_STRING )
-            {
-            CStringOwner* stringOwner = new (ELeave) CStringOwner;
-            CleanupStack::PushL( stringOwner );
-
-            NW_String_t* val = NW_String_new();
-            User::LeaveIfNull( val );
-            stringOwner->SetString( val );
-            //
-            stat = NW_DOM_AttrVal_toString( &attrVal, val, iCharEncoding );
-            User::LeaveIfError( NwxStatusToErrCode( stat ) );
-            NW_Byte* storage = NW_String_getStorage( val );
-            NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
-            TPtrC8 dataPtr( storage, length );
-            HBufC* dataBuf = HBufC::NewMaxLC( dataPtr.Length() );
-            dataBuf->Des().Copy( dataPtr );
-            gotDate = ConvertDateTimeL( *dataBuf, aConvertedDate );
-
-            CleanupStack::PopAndDestroy( 2, stringOwner ); // dataBuf,
-                                                           // stringOwner
-            }
-        else if ( valType == NW_DOM_ATTR_VAL_OPAQUE )
-            {
-            NW_Uint32 len = 0;
-            NW_Byte* data = NW_DOM_AttrVal_getOpaque( &attrVal, &len );
-            User::LeaveIfNull( data );
-            TPtrC8 dataPtr( data, len );
-
-            HBufC* dateTime = ConvertOpaqueToUtcL( dataPtr );
-            CleanupStack::PushL( dateTime );
-            gotDate = ConvertDateTimeL( *dateTime, aConvertedDate );
-            CleanupStack::PopAndDestroy( dateTime ); // dateTime
-            }
-        else
-            {
-            User::Leave( KErrNotSupported );
-            }
-        }
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::AttributeToTTimeL")
-    return gotDate; // aConvertedDate contains the result.
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::HandleMessageL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::HandleMessageL( CPushMessage* aPushMsg,
-                                        TRequestStatus& aStatus )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::HandleMessageL")
-
-    __ASSERT_DEBUG( aPushMsg != NULL,
-                    ContHandPanic( EPushContHandPanMsgNull ) );
-
-#ifdef __TEST_LOG__
-    TPtrC8 bodyPtr;
-    aPushMsg->GetMessageBody( bodyPtr );
-    PUSHLOG_HEXDUMP( bodyPtr )
-#endif // __TEST_LOG__
-
-	iMessage = aPushMsg;
-	iAcknowledge = ETrue;
-	SetConfirmationStatus( aStatus );
-
-	iState = EGarbageCollecting;
-	IdleComplete();
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::HandleMessageL")
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::HandleMessageL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::HandleMessageL( CPushMessage* aPushMsg )
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::HandleMessageL")
-
-    __ASSERT_DEBUG( aPushMsg != NULL,
-                    ContHandPanic( EPushContHandPanMsgNull ) );
-
-#ifdef __TEST_LOG__
-    TPtrC8 bodyPtr;
-    aPushMsg->GetMessageBody( bodyPtr );
-    PUSHLOG_HEXDUMP( bodyPtr )
-#endif // __TEST_LOG__
-
-    iAcknowledge = EFalse;
-	iMessage = aPushMsg;
-
-	iState = EGarbageCollecting;
-	IdleComplete();
-
-    PUSHLOG_LEAVEFN("CSIContentHandler::HandleMessageL")
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::CancelHandleMessage
-// ---------------------------------------------------------
-//
-void CSIContentHandler::CancelHandleMessage()
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::CancelHandleMessage")
-    Cancel();
-    PUSHLOG_LEAVEFN("CSIContentHandler::CancelHandleMessage")
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::CPushHandlerBase_Reserved1
-// ---------------------------------------------------------
-//
-void CSIContentHandler::CPushHandlerBase_Reserved1()
-    {
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::CPushHandlerBase_Reserved2
-// ---------------------------------------------------------
-//
-void CSIContentHandler::CPushHandlerBase_Reserved2()
-    {
-    }
-
-// ---------------------------------------------------------
-// CSIContentHandler::DoCancel
-// ---------------------------------------------------------
-//
-void CSIContentHandler::DoCancel()
-	{
-    PUSHLOG_ENTERFN("CSIContentHandler::DoCancel")
-	Complete( KErrCancel );
-    PUSHLOG_LEAVEFN("CSIContentHandler::DoCancel")
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::RunL
-// ---------------------------------------------------------
-//
-void CSIContentHandler::RunL()
-	{
-    // Handle errors in RunError().
-    PUSHLOG_WRITE_FORMAT("iStatus.Int(): %d",iStatus.Int())
-    User::LeaveIfError( iStatus.Int() );
-
-	// use active state machine routine to manage activites:
-	switch ( iState )
-		{
-	    case EGarbageCollecting:
-            {
-		    CollectGarbageL();
-		    break;
-            }
-	    case EFilteringAndParsing:
-            {
-            if ( !FilterPushMsgL() )
-                {
-                // It did not pass the filter. Done.
-	            iState = EDone;
-	            IdleComplete();
-                }
-            else
-                {
-                // Continue.
-		        TInt ret = KErrNone;
-				PUSHLOG_WRITE("CSIContentHandler::RunL : before trapping parsing.")
-				TRAP(ret, ParsePushMsgL());
-				PUSHLOG_WRITE_FORMAT("CSIContentHandler::RunL : after trapping parsing. ret = %d", ret)
-				if ( ret != KErrNone)
-					{
-					PUSHLOG_WRITE("CSIContentHandler::RunL : Parsing failed. discarding message.")
-					iState = EDone;
-					IdleComplete();
-					}
-                }
-		    break;
-            }
-	    case EProcessing:
-            {
-		    ProcessingPushMsgEntryL();
-		    break;
-            }
-	    case EDone:
-            {
-            PUSHLOG_WRITE("CSIContentHandler EDone")
-		    Complete( KErrNone );
-		    break;
-            }
-	    default:
-            {
-            // JIC.
-            PUSHLOG_WRITE("CSIContentHandler default Done")
-		    Complete( KErrNone );
-		    break;
-            }
-		}
-	}
-
-// ---------------------------------------------------------
-// CSIContentHandler::RunError
-// ---------------------------------------------------------
-//
-TInt CSIContentHandler::RunError( TInt aError )
-	{
-    PUSHLOG_WRITE_FORMAT("CSIContentHandler::RunError: %d",aError)
-
-	iState = EDone;
-	Complete( aError );
-	return KErrNone;
-	}
-