--- 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;
- }
-