email/emailnotificationhandler/src/EMNXMLContentHandler.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Extracts needed attributes from received EMN message.
       
    15 *		
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "EMNXMLContentHandler.h"
       
    21 #include "EMNLogging.h"
       
    22 
       
    23 // Used in compares
       
    24 _LIT8( KEmnElement, "emn" );
       
    25 _LIT8( KMailboxAttribute, "mailbox");
       
    26 _LIT8( KTimestampAttribute, "timestamp");
       
    27 
       
    28 // Used for parsing timestamp attribute's value from ASCII message.
       
    29 _LIT( KColonChar, ":" );
       
    30 _LIT( KDashChar, "-" );
       
    31 _LIT( KDateTimeSeparator, "T" );
       
    32 _LIT( KTimezoneSeparator, "Z" );
       
    33 
       
    34 // Received timestamp string length
       
    35 const TInt KEMNLengthOfRecvTimeStamp = 20;
       
    36 
       
    37 // Index of hour or minute in timestamp string
       
    38 const TInt KEMNTimestampIncHour = 5;
       
    39 const TInt KEMNTimestampIncHourMinute = 6;
       
    40 
       
    41 // Constants for getting first or last four bits from byte
       
    42 const TInt KEMNUpperBits = 4;
       
    43 const TInt KEMNLowerBits = 0xf;
       
    44 
       
    45 // Constants for date handling
       
    46 const TInt KEMNAtLeastDate = 4;
       
    47 const TInt KEMNIndexOfMilleniumAndCentury = 0;
       
    48 const TInt KEMNIndexOfDecadeAndYear = 1;
       
    49 const TInt KEMNIndexOfMonth = 2;
       
    50 const TInt KEMNIndexOfDay = 3;
       
    51 
       
    52 // Constants for time handling
       
    53 const TInt KEMNIndexOfHour = 4;
       
    54 const TInt KEMNIndexOfMinute = 5;
       
    55 
       
    56 using namespace Xml;
       
    57 
       
    58 //-----------------------------------------------------------------------------
       
    59 // CEMNXMLContentHandler::CEMNXMLContentHandler
       
    60 //-----------------------------------------------------------------------------
       
    61 CEMNXMLContentHandler::CEMNXMLContentHandler(
       
    62     TEMNElement& aElement, TBool aIsAscii ) :
       
    63     iElement( aElement ), 
       
    64     iIsAscii( aIsAscii ), 
       
    65     iFoundMailboxAttribute( EFalse )
       
    66 	{
       
    67 	KEMNLOGGER_WRITE("CEMNXMLContentHandler::CEMNXMLContentHandler()");
       
    68 	}
       
    69 
       
    70 //-----------------------------------------------------------------------------
       
    71 // CEMNXMLContentHandler::NewL
       
    72 //-----------------------------------------------------------------------------
       
    73 CEMNXMLContentHandler* CEMNXMLContentHandler::NewL( 
       
    74     TEMNElement& aElement, 
       
    75     TBool aIsAscii )
       
    76 	{
       
    77 	CEMNXMLContentHandler* self = NewLC( aElement, aIsAscii );
       
    78 	CleanupStack::Pop( self );
       
    79 	return self;
       
    80 	}
       
    81 
       
    82 //-----------------------------------------------------------------------------
       
    83 // CEMNXMLContentHandler::NewLC
       
    84 //-----------------------------------------------------------------------------
       
    85 CEMNXMLContentHandler* CEMNXMLContentHandler::NewLC(
       
    86     TEMNElement& aElement, 
       
    87     TBool aIsAscii )
       
    88 	{
       
    89 	CEMNXMLContentHandler* self = 
       
    90 	    new (ELeave) CEMNXMLContentHandler( aElement, aIsAscii );
       
    91 	CleanupStack::PushL( self );
       
    92 	self->ConstructL();
       
    93 	return self;
       
    94 	}
       
    95 
       
    96 //-----------------------------------------------------------------------------
       
    97 // CEMNXMLContentHandler::ConstructL
       
    98 //-----------------------------------------------------------------------------
       
    99 void CEMNXMLContentHandler::ConstructL()
       
   100     {
       
   101     }
       
   102 
       
   103 //-----------------------------------------------------------------------------
       
   104 // CEMNXMLContentHandler::~CEMNXMLContentHandler
       
   105 //-----------------------------------------------------------------------------
       
   106 CEMNXMLContentHandler::~CEMNXMLContentHandler()
       
   107 	{
       
   108 	KEMNLOGGER_WRITE("CEMNXMLContentHandler::~CEMNXMLContentHandler()");
       
   109 	}
       
   110 
       
   111 //-----------------------------------------------------------------------------
       
   112 // CEMNXMLContentHandler::OnStartDocumentL
       
   113 //-----------------------------------------------------------------------------
       
   114 void CEMNXMLContentHandler::OnStartDocumentL(
       
   115     const RDocumentParameters& /*aDocParam*/, 
       
   116     TInt /*aErrorCode*/ )
       
   117 	{
       
   118 	KEMNLOGGER_WRITE("CEMNXMLContentHandler::OnStartDocumentL()");
       
   119 	}
       
   120 
       
   121 //-----------------------------------------------------------------------------
       
   122 // CEMNXMLContentHandler::OnEndDocumentL
       
   123 //-----------------------------------------------------------------------------
       
   124 void CEMNXMLContentHandler::OnEndDocumentL( TInt /*aErrorCode*/ )
       
   125 	{
       
   126 	KEMNLOGGER_WRITE("<- EMN message data");
       
   127 	
       
   128 	// This EMN message will be discarded if no mailbox attribute found.
       
   129 	if ( !iFoundMailboxAttribute ) 
       
   130 	    {
       
   131 	    KEMNLOGGER_WRITE("CEMNXMLContentHandler::OnEndDocumentL(): No mailbox attribute found, leaving.");
       
   132 	    User::Leave( EEMNMissingMailboxAttribute );
       
   133 	    }
       
   134 	}
       
   135 	
       
   136 //-----------------------------------------------------------------------------
       
   137 // CEMNXMLContentHandler::OnStartElementL
       
   138 //-----------------------------------------------------------------------------
       
   139 void CEMNXMLContentHandler::OnStartElementL(
       
   140     const RTagInfo& aElement, 
       
   141     const RAttributeArray& aAttributes, 
       
   142     TInt aErrorCode )
       
   143 	{
       
   144 	KEMNLOGGER_WRITE("CEMNXMLContentHandler::OnStartElementL()");
       
   145 	KEMNLOGGER_WRITE("EMN message data ->");
       
   146 	
       
   147 	// Element name
       
   148 	const TDesC8& localPart8 = aElement.LocalName().DesC();
       
   149     KEMNLOGGER_WRITE_FORMAT8("<%s>", localPart8.Ptr() );
       
   150     
       
   151     // Attribute(s) of emn element
       
   152     if ( localPart8.Compare( KEmnElement ) == 0 )   // Is emn element
       
   153         {
       
   154         TInt attributeCount = aAttributes.Count();
       
   155         
       
   156         for ( TInt n = 0; n < attributeCount; n++ )
       
   157             {
       
   158             const RAttribute& attribute = aAttributes[n];
       
   159             const RTagInfo& nameInfo = attribute.Attribute();
       
   160             
       
   161             const TDesC8& localPart8 = nameInfo.LocalName().DesC();
       
   162     		const TDesC8& prefix8 = nameInfo.Prefix().DesC();
       
   163     		const TDesC8& value8 = attribute.Value().DesC();
       
   164     		
       
   165     		// Mailbox attribute is similar to both ascii and binary
       
   166     		if ( localPart8.Compare( KMailboxAttribute ) == 0)
       
   167     		    {
       
   168     		    KEMNLOGGER_WRITE_FORMAT8("mailbox=%s", value8.Ptr() );
       
   169     		    // Read the whole value of mailbox attribute and copy that
       
   170                 // to iElement. Conversion happens from 8-bit to 16 bit
       
   171                 // unicode.
       
   172                 iElement.mailbox.Copy( value8.Left( KAOMailboxAttributeLength ) );
       
   173                 iFoundMailboxAttribute = ETrue;
       
   174     		    }
       
   175     		// Timestamp attribute is in different form in ascii than in binary
       
   176     		// so we need to extract it with different methods.
       
   177     		else if ( localPart8.Compare( KTimestampAttribute ) == 0 )
       
   178     		    {
       
   179     		    KEMNLOGGER_WRITE_FORMAT8("timestamp=%s", value8.Ptr() );
       
   180       		    // NOTE: Currently timestamp attribute is omitted. 
       
   181                 /* This code branch will be commented out when there is some nice
       
   182     	        use case for timestamp.
       
   183     		    if ( iIsAscii )
       
   184     		        {
       
   185     		        HandleXMLAttributesL( localPart8, value8 );
       
   186     		        }
       
   187                 else
       
   188                     {
       
   189                     HandleWBXMLAttributesL( localPart8, value8 );
       
   190                     }
       
   191     	        */
       
   192     		    }
       
   193     		// Something else than mailbox or timestamp attribute
       
   194         	else
       
   195     		    {
       
   196     		    KEMNLOGGER_WRITE_FORMAT28("Unknown attribute: %s=%s", localPart8.Ptr(), value8.Ptr() );
       
   197     		    }  
       
   198             }
       
   199         }
       
   200     else    // No emn element found
       
   201         {
       
   202         KEMNLOGGER_WRITE_FORMAT8("%s\">", localPart8.Ptr() );
       
   203         User::Leave( EEMNMissingEMNElement );
       
   204         }
       
   205     
       
   206 	User::LeaveIfError( aErrorCode );
       
   207 	}
       
   208 	
       
   209 //-----------------------------------------------------------------------------
       
   210 // CEMNXMLContentHandler::HandleXMLAttributes
       
   211 //-----------------------------------------------------------------------------
       
   212 void CEMNXMLContentHandler::HandleXMLAttributesL(
       
   213     const TDesC8& aAttributeName8, 
       
   214     const TDesC8& aAttributeValue8 )
       
   215     {
       
   216     // Currently only timestamp attribute is handled here. Mailbox attribute
       
   217     // is same for both XML and WBXML.
       
   218     if ( aAttributeName8.Compare( KTimestampAttribute ) == 0 )
       
   219 	    {
       
   220 	    iElement.timestamp = NULL;
       
   221 	    
       
   222 	    TPtrC8 p8( aAttributeValue8.Ptr(), aAttributeValue8.Length() );
       
   223 	    HBufC* tmpBuf = HBufC::NewLC( aAttributeValue8.Length() );
       
   224 	    // Copies 8 bit to 16 bit and makes a new copy from heap
       
   225         tmpBuf->Des().Copy( p8 );
       
   226         TPtr ptr = tmpBuf->Des();
       
   227         
       
   228         if ( ptr.Length() == KEMNLengthOfRecvTimeStamp )
       
   229             {
       
   230             // Parse received timestamp to be in a form, which can be set to TTime 
       
   231             // "2010-12-31T00:01:00Z" != YYYYMMDD:HHMMSS
       
   232             TInt pos = ptr.Find( KColonChar );
       
   233             while ( pos != KErrNotFound )
       
   234                 {
       
   235                 ptr.Delete( pos, 1 );
       
   236                 pos = ptr.Find( KColonChar );
       
   237                 }
       
   238                 
       
   239             // "2010-12-31T000100Z" != YYYYMMDD:HHMMSS
       
   240             pos = ptr.Find( KDashChar );
       
   241             while ( pos != KErrNotFound )
       
   242                 {
       
   243                 ptr.Delete( pos, 1 );
       
   244                 pos = ptr.Find( KDashChar );
       
   245                 }
       
   246             
       
   247             // "20101231T000100Z" != YYYYMMDD:HHMMSS
       
   248             pos = ptr.Find( KDateTimeSeparator );
       
   249             while ( pos != KErrNotFound )
       
   250                 {
       
   251                 ptr.Replace( pos, 1, KColonChar );
       
   252                 pos = ptr.Find( KDateTimeSeparator );
       
   253                 }
       
   254             
       
   255             // "20101231:000100Z" != YYYYMMDD:HHMMSS
       
   256             pos = ptr.Find( KTimezoneSeparator );
       
   257             while ( pos != KErrNotFound )
       
   258                 {
       
   259                 ptr.Delete( pos, 1 );
       
   260                 pos = ptr.Find( KTimezoneSeparator );
       
   261                 }
       
   262             
       
   263             // "20101231:000100" == YYYYMMDD:HHMMSS, but day and month must be 
       
   264             // decreased by one, because those are offset from zero and we 
       
   265             // received them in offset from one.
       
   266             
       
   267             /*
       
   268             * if MM == 09 -> MM = 08
       
   269             * if MM == 10 -> MM = 09
       
   270             * if MM == 11 -> MM = 10
       
   271             */
       
   272             if ( ( ptr[4] == '1' ) && (  ptr[5] == '0' ) )  // CSI: 47 # see comments
       
   273                 {
       
   274                 ptr[4] = ( ptr[4] - 0x1 );  // 1 -> 0
       
   275                 ptr[5] = ( ptr[5] + 0x9 );  // 0 -> 9
       
   276                 }
       
   277             else
       
   278                 {
       
   279                 ptr[5] = ( ptr[5] - 0x1 );  // n -> n-1
       
   280                 }
       
   281 
       
   282             /*
       
   283             * if DD == 09 -> DD = 08
       
   284             * if DD == 13 -> DD = 12
       
   285             * if DD == 28 -> DD = 27
       
   286             * if DD == 31 -> DD = 30
       
   287             * if DD == 10 -> DD = 09
       
   288             * if DD == 20 -> DD = 19
       
   289             * if DD == 30 -> DD = 29
       
   290             */
       
   291             if ( ( ( ptr[6] == '1' ) ||                          // CSI: 47 # see comments
       
   292                    ( ptr[6] == '2' ) ||                          // CSI: 47 # see comments
       
   293                    ( ptr[6] == '3' ) ) && ( ptr[7] ) == '0' )    // CSI: 47 # see comments
       
   294                 {
       
   295                 ptr[6] = ( ptr[6] - 0x1 );  // n -> n-1
       
   296                 ptr[7] = ( ptr[7] + 0x9 );  // 0 -> 9
       
   297                 }
       
   298             else
       
   299                 {
       
   300                 ptr[7] = ( ptr[7] - 0x1 );  // n -> n-1
       
   301                 }
       
   302             
       
   303             // Now the "20101231:000100" should be "20101130:000100"
       
   304             // Make a TTime object from it.
       
   305             TTime time;
       
   306             TInt err = time.Set( ptr );
       
   307             if ( err == KErrNone )
       
   308                 {
       
   309                 iElement.timestamp = time;
       
   310                 }
       
   311             else
       
   312                 {
       
   313                 iElement.timestamp = NULL;
       
   314                 }
       
   315             }
       
   316             
       
   317         CleanupStack::PopAndDestroy( tmpBuf );
       
   318 	    }
       
   319     }
       
   320 
       
   321 //-----------------------------------------------------------------------------
       
   322 // CEMNXMLContentHandler::HandleWBXMLAttributes
       
   323 //-----------------------------------------------------------------------------
       
   324 void CEMNXMLContentHandler::HandleWBXMLAttributesL(
       
   325     const TDesC8& aAttributeName8, 
       
   326     const TDesC8& aAttributeValue8 )
       
   327     {
       
   328     // Currently only timestamp attribute is handled here. Mailbox attribute
       
   329     // is same for both XML and WBXML.
       
   330     if ( aAttributeName8.Compare( KTimestampAttribute ) == 0 )
       
   331 	    {
       
   332 	    iElement.timestamp = NULL;
       
   333 	    
       
   334 	    // Here is an example of received timestamp string: 20 05 11 12 13 14 01
       
   335 	    // It is 12th of November 2005, 01:14:01 PM
       
   336 	    
       
   337 	    // Timestamp length must be atleast 4. It means that at least year, month
       
   338 	    // and day must be given, because those can't be zeros. Hour, minute and 
       
   339 	    // second can be zeros. But not all the Push Content GWs doesn't send those,
       
   340 	    // so we must handle both situations.
       
   341 	    TInt timestampLength = aAttributeValue8.Length();
       
   342 	    if ( timestampLength >= KEMNAtLeastDate )
       
   343 	        {
       
   344 	        TDateTime datetime;
       
   345             TInt err;
       
   346             TInt temp1;
       
   347             TInt temp2;
       
   348             
       
   349             temp1 = aAttributeValue8[ KEMNIndexOfMilleniumAndCentury ];
       
   350             temp2 = aAttributeValue8[ KEMNIndexOfDecadeAndYear ];
       
   351             
       
   352             // Separately parse millenium, century, decade and year
       
   353             TInt year = 
       
   354                 ( ( temp1 >> KEMNUpperBits ) * 1000 ) +      // CSI: 47 # see comments
       
   355                 ( ( temp1 & KEMNLowerBits ) * 100 ) +        // CSI: 47 # see comments
       
   356                 ( ( temp2 >> KEMNUpperBits ) * 10 ) +        // CSI: 47 # see comments
       
   357                 ( temp2 & KEMNLowerBits );
       
   358 
       
   359             temp1 = aAttributeValue8[ KEMNIndexOfMonth ];
       
   360             TInt month = 
       
   361                 ( ( temp1 >> KEMNUpperBits ) * 10 ) +        // CSI: 47 # see comments
       
   362                 ( temp1 & KEMNLowerBits );
       
   363 
       
   364             temp1 = aAttributeValue8[ KEMNIndexOfDay ];
       
   365             TInt day = 
       
   366                 ( ( temp1 >> KEMNUpperBits ) * 10 ) +        // CSI: 47 # see comments
       
   367                 ( temp1 & KEMNLowerBits );
       
   368 
       
   369             err = datetime.SetYear( year );
       
   370             if ( err != KErrNone )
       
   371                 {
       
   372                 User::Leave( EEMNInvalidYear );
       
   373                 }
       
   374                 
       
   375             err = datetime.SetMonth( static_cast<TMonth>( month - 1  ) );
       
   376             if ( err != KErrNone )
       
   377                 {
       
   378                 User::Leave( EEMNInvalidMonth );
       
   379                 }
       
   380                 
       
   381             err = datetime.SetDay( day - 1 );
       
   382             if ( err != KErrNone )
       
   383                 {
       
   384                 User::Leave( EEMNInvalidDay );
       
   385                 }
       
   386                 
       
   387             // There might not be hour, minute and second in EMN message
       
   388             if ( timestampLength > KEMNAtLeastDate )
       
   389                 {
       
   390                 // At least hour                
       
   391                 if ( timestampLength >= KEMNTimestampIncHour )
       
   392                     {
       
   393                     temp1 = aAttributeValue8[ KEMNIndexOfHour ];
       
   394                     TInt hour = ( ( temp1 >> KEMNUpperBits ) * 10 ) +    // CSI: 47 # see comments
       
   395                         ( temp1 & KEMNLowerBits );
       
   396 
       
   397                     err = datetime.SetHour( hour );
       
   398                     if ( err != KErrNone )
       
   399                         {
       
   400                         User::Leave( EEMNInvalidHour );
       
   401                         }
       
   402                     }
       
   403                 
       
   404                 // At least hour and minute
       
   405                 if ( timestampLength >= KEMNTimestampIncHourMinute )
       
   406                     {
       
   407                     temp1 = aAttributeValue8[ KEMNIndexOfMinute ];
       
   408                     TInt minute = 
       
   409                         ( ( temp1 >> KEMNUpperBits ) * 10 ) +    // CSI: 47 # see comments
       
   410                         ( temp1 & KEMNLowerBits );
       
   411                             
       
   412                     err = datetime.SetMinute( minute );
       
   413                     if ( err != KErrNone )
       
   414                         {
       
   415                         User::Leave( EEMNInvalidMinute );
       
   416                         }
       
   417                     }
       
   418                 }
       
   419             else
       
   420                 {
       
   421                 datetime.SetHour( 0 );
       
   422                 datetime.SetMinute( 0 );
       
   423                 }
       
   424                 
       
   425             // At this point, datetime should be well formed, so no need to do extra
       
   426             // checks.
       
   427             TTime time( datetime );
       
   428             
       
   429             iElement.timestamp = time;
       
   430             KEMNLOGGER_WRITE_DATETIME("timestamp=", time );
       
   431 	        }
       
   432 	    else
       
   433 	        {
       
   434 	        KEMNLOGGER_WRITE("Timestamp provided, but not valid ==> EMN discarded!" );
       
   435 	        KEMNLOGGER_WRITE_FORMAT("Timestamp length was %d", aAttributeValue8.Length() );
       
   436 	        
       
   437 	        // Timestamp attribute was found, but its format was not valid.
       
   438 	        User::Leave( EEMNInvalidTimestampAttribute );
       
   439 	        }
       
   440 	    }
       
   441     }
       
   442 
       
   443 //-----------------------------------------------------------------------------
       
   444 // CEMNXMLContentHandler::CEMNXMLContentHandler
       
   445 //-----------------------------------------------------------------------------
       
   446 void CEMNXMLContentHandler::OnEndElementL(
       
   447     const RTagInfo& aElement, 
       
   448     TInt /*aErrorCode*/ )
       
   449 	{
       
   450 	const TDesC8& localPart8 = aElement.LocalName().DesC();
       
   451 	KEMNLOGGER_WRITE_FORMAT8("</%s>", localPart8.Ptr() );
       
   452 	}
       
   453 
       
   454 //-----------------------------------------------------------------------------
       
   455 // CEMNXMLContentHandler::OnContentL
       
   456 //-----------------------------------------------------------------------------
       
   457 void CEMNXMLContentHandler::OnContentL(
       
   458     const TDesC8& /*aData8*/, 
       
   459     TInt /*aErrorCode*/ )
       
   460 	{
       
   461 	// Content of an EMN message should always be empty.
       
   462 	}
       
   463 
       
   464 //-----------------------------------------------------------------------------
       
   465 // CEMNXMLContentHandler::OnStartPrefixMappingL
       
   466 //-----------------------------------------------------------------------------
       
   467 void CEMNXMLContentHandler::OnStartPrefixMappingL(
       
   468     const RString& /*aPrefix*/,
       
   469     const RString& /*aUri*/,
       
   470     TInt /*aErrorCode*/ )
       
   471 	{
       
   472 	}
       
   473 
       
   474 //-----------------------------------------------------------------------------
       
   475 // CEMNXMLContentHandler::OnEndPrefixMappingL
       
   476 //-----------------------------------------------------------------------------
       
   477 void CEMNXMLContentHandler::OnEndPrefixMappingL(
       
   478     const RString& /*aPrefix*/,
       
   479     TInt /*aErrorCode*/ )
       
   480 	{
       
   481 	}
       
   482 
       
   483 //-----------------------------------------------------------------------------
       
   484 // CEMNXMLContentHandler::OnIgnorableWhiteSpaceL
       
   485 //-----------------------------------------------------------------------------
       
   486 void CEMNXMLContentHandler::OnIgnorableWhiteSpaceL(
       
   487     const TDesC8& /*aBytes*/, 
       
   488     TInt /*aErrorCode*/ )
       
   489 	{
       
   490 	}
       
   491 
       
   492 //-----------------------------------------------------------------------------
       
   493 // CEMNXMLContentHandler::OnSkippedEntityL
       
   494 //-----------------------------------------------------------------------------
       
   495 void CEMNXMLContentHandler::OnSkippedEntityL(
       
   496     const RString& /*aName*/, 
       
   497     TInt /*aErrorCode*/ )
       
   498 	{
       
   499 	}
       
   500 
       
   501 //-----------------------------------------------------------------------------
       
   502 // CEMNXMLContentHandler::OnProcessingInstructionL
       
   503 //-----------------------------------------------------------------------------
       
   504 void CEMNXMLContentHandler::OnProcessingInstructionL(
       
   505     const TDesC8& /* aTarget8*/,
       
   506     const TDesC8& /*aData8*/,
       
   507     TInt /*aErrorCode*/ )
       
   508 	{
       
   509 	}
       
   510 
       
   511 //-----------------------------------------------------------------------------
       
   512 // CEMNXMLContentHandler::OnExtensionL
       
   513 //-----------------------------------------------------------------------------
       
   514 void CEMNXMLContentHandler::OnExtensionL(
       
   515     const RString& /*aData*/, 
       
   516     TInt /*aToken*/,
       
   517     TInt /*aErrorCode*/ )
       
   518 	{
       
   519 	}
       
   520 
       
   521 //-----------------------------------------------------------------------------
       
   522 // CEMNXMLContentHandler::OnError
       
   523 //-----------------------------------------------------------------------------
       
   524 void CEMNXMLContentHandler::OnError( TInt __DEBUG_ONLY( aError ) )
       
   525 	{
       
   526 	KEMNLOGGER_WRITE_FORMAT("CEMNXMLContentHandler::OnError() aError = %d", aError );
       
   527 	
       
   528 #ifdef _DEBUG
       
   529 	// No actions taken, if there is something wrong with elements or attributes
       
   530 	// in received EMN message. This is because OMA EMN spesification says that
       
   531 	// received message can be discarded if it is not valid or well-formed. This
       
   532 	// error handling is just for debugging purposes.
       
   533 	switch ( aError )
       
   534 	    {
       
   535   	    case EEMNMissingEMNElement:
       
   536   	        KEMNLOGGER_WRITE("No EMN element found.");
       
   537   	        break;
       
   538   	        
       
   539 	    case EEMNMissingMailboxAttribute:
       
   540 	        KEMNLOGGER_WRITE("Mailbox attribute not found.");
       
   541 	        break;
       
   542 	        
       
   543 	    case EEMNMissingTimestampAttribute:
       
   544 	        KEMNLOGGER_WRITE("Timestamp attribute not found.");
       
   545 	        break;
       
   546 	    
       
   547 	    // Received timestamp attribute did not contain proper date and time.
       
   548 	    case EEMNInvalidTimestampAttribute:
       
   549 
       
   550 	    // Following errors indicates that values were not in acceptable ranges
       
   551 	    case EEMNInvalidYear:
       
   552 	    case EEMNInvalidMonth:
       
   553 	    case EEMNInvalidDay:
       
   554 	    case EEMNInvalidMinute:
       
   555 	    case EEMNInvalidHour:
       
   556             KEMNLOGGER_WRITE("Timestamp attribute found, but with invalid value.");
       
   557 	        break;
       
   558 	    default:
       
   559 	        KEMNLOGGER_WRITE("Invalid error code, where we got it?.");
       
   560 	    }
       
   561 #endif
       
   562 	}
       
   563 
       
   564 //-----------------------------------------------------------------------------
       
   565 // CEMNXMLContentHandler::GetExtendedInterface
       
   566 //-----------------------------------------------------------------------------
       
   567 TAny* CEMNXMLContentHandler::GetExtendedInterface( const TInt32 )
       
   568 	{
       
   569 	KEMNLOGGER_WRITE("CEMNXMLContentHandler::GetExtendedInterface()");
       
   570 	return NULL;
       
   571 	}
       
   572