PECengine/Parser2/SrcXmlSerializer/CPEngXmlSerializer.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2004 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:  XML Serializer implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include "CPEngXmlSerializer.h"
       
    20 #include "PEngXmlDefs.h"
       
    21 #include "PresenceDebugPrint.h"
       
    22 
       
    23 
       
    24 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
    25 #include "CPEngTagAssertionStack.h"
       
    26 #endif
       
    27 
       
    28 #include <E32Std.h>
       
    29 #include <utf.h>
       
    30 #include <imcvcodc.h>
       
    31 
       
    32 
       
    33 
       
    34 //CONSTANTS
       
    35 /**
       
    36  * State stack granularity.
       
    37  * State stack has great size
       
    38  * variety depending from use case.
       
    39  * 5 should be quite optimal.
       
    40  */
       
    41 const TInt KStackGranurality = 5;
       
    42 
       
    43 /**
       
    44  * WV schema prefix & length.
       
    45  */
       
    46 _LIT( KWVSchemaPrefix, "wv:" );
       
    47 const TInt KWVSchemaPrefixLength = 3;
       
    48 
       
    49 // ================= LOCAL FUNCTIONS =======================
       
    50 /**
       
    51  * Serializer panic implementation.
       
    52  */
       
    53 #if defined(_DEBUG)
       
    54 GLREF_C void PanicSerializer( TPEngSerializerPanics aReason )
       
    55     {
       
    56     User::Panic( KXmlSerializer, aReason );
       
    57     }
       
    58 #else
       
    59 GLREF_C void PanicSerializer( TPEngSerializerPanics /*aReason*/ )
       
    60     {
       
    61     }
       
    62 #endif
       
    63 
       
    64 
       
    65 
       
    66 
       
    67 // ================= MEMBER FUNCTIONS =======================
       
    68 // Two-phased constructor.
       
    69 CPEngXmlSerializer* CPEngXmlSerializer::NewL( TDes8& aBuffer )
       
    70     {
       
    71     CPEngXmlSerializer* self = CPEngXmlSerializer::NewLC( aBuffer );
       
    72     CleanupStack::Pop( self );
       
    73     return self;
       
    74     }
       
    75 
       
    76 
       
    77 
       
    78 CPEngXmlSerializer* CPEngXmlSerializer::NewLC( TDes8& aBuffer )
       
    79     {
       
    80     CPEngXmlSerializer* self = new ( ELeave ) CPEngXmlSerializer( aBuffer );
       
    81 
       
    82     CleanupStack::PushL( self );
       
    83     self->ConstructL();
       
    84 
       
    85     return self;
       
    86     }
       
    87 
       
    88 // Destructor
       
    89 CPEngXmlSerializer::~CPEngXmlSerializer()
       
    90     {
       
    91     iStateStack.Reset();
       
    92 
       
    93 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
    94     delete iAssertionStack;
       
    95 #endif //   __SERIALIZER_TAG_NAME_ASSERT
       
    96 
       
    97 
       
    98 #if _BullseyeCoverage
       
    99     cov_write();
       
   100 #endif
       
   101     }
       
   102 
       
   103 
       
   104 // C++ default constructor can NOT contain any code, that
       
   105 // might leave.
       
   106 //
       
   107 CPEngXmlSerializer::CPEngXmlSerializer( TDes8& aBuffer )
       
   108         : iState( EPEngInRoot ),
       
   109         iWriter( aBuffer ),
       
   110         iStartTagCount( 0 ),
       
   111         iStateStack( KStackGranurality )
       
   112     {
       
   113     }
       
   114 
       
   115 
       
   116 // Symbian OS default constructor can leave.
       
   117 void CPEngXmlSerializer::ConstructL()
       
   118     {
       
   119 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   120     iAssertionStack = CPEngTagAssertionStack::NewL( KStackGranurality );
       
   121 #endif //   __SERIALIZER_TAG_NAME_ASSERT
       
   122     }
       
   123 
       
   124 
       
   125 
       
   126 // -----------------------------------------------------------------------------
       
   127 // CPEngXmlSerializer::Close()
       
   128 // -----------------------------------------------------------------------------
       
   129 //
       
   130 void CPEngXmlSerializer::Close()
       
   131     {
       
   132     delete this;
       
   133     }
       
   134 
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // CPEngXmlSerializer::StartTagL()
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 MPEngXMLSerializer& CPEngXmlSerializer::StartTagL( const TDesC8& aName )
       
   141     {
       
   142     //tag name may not be empty
       
   143     __AssertNotEmptyL( aName );
       
   144 
       
   145 
       
   146 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   147     //make sure that if we can write the start tag,
       
   148     //we get it surely to element stack also
       
   149     iAssertionStack->ReserveOneL();
       
   150 #endif //   __SERIALIZER_TAG_NAME_ASSERT
       
   151 
       
   152 
       
   153     CheckAndCloseOpenStartTagL(); //goes to EElementOpen state
       
   154     iWriter.WriteL( KXmlTagStart );
       
   155 
       
   156 
       
   157 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   158     TPtrC8 writtenTag( iWriter.WriteL( aName ) );
       
   159     iAssertionStack->PushL( writtenTag ); //won't fail, see previous ReserveOneL()
       
   160 #else
       
   161     iWriter.WriteL( aName );
       
   162 #endif //   __SERIALIZER_TAG_NAME_ASSERT
       
   163 
       
   164     iStartTagCount++;
       
   165     iState = EPEngInStartTag;
       
   166 
       
   167     return *this;
       
   168     }
       
   169 
       
   170 
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CPEngXmlSerializer::AttributeL()
       
   174 // -----------------------------------------------------------------------------
       
   175 //
       
   176 MPEngXMLSerializer& CPEngXmlSerializer::AttributeL( const TDesC8& aName,
       
   177                                                     const TDesC8& aValue )
       
   178     {
       
   179     //attribute can be written only just after the start tag.
       
   180     __AssertSerializerStateL( ( iState == EPEngInStartTag ),
       
   181                               EPEngSrlzr_AttributeNotAllowed );
       
   182 
       
   183     //attribute name may not be empty
       
   184     __AssertNotEmptyL( aName );
       
   185 
       
   186 
       
   187     iWriter.WriteL( KXmlWhiteSpace );
       
   188     iWriter.WriteL( aName );
       
   189     iWriter.WriteL( KXmlEqualSign );
       
   190 
       
   191     TBuf8< 1 > quote; //quote is one character, either ' or "
       
   192     quote = KXmlApostrophe;
       
   193     if ( aValue.Find( KXmlDoubleQuote ) == KErrNotFound )
       
   194         {
       
   195         quote = KXmlDoubleQuote;
       
   196         }
       
   197 
       
   198     iWriter.WriteL( quote );
       
   199     WriteXmlEscapedL( aValue, ETrue );
       
   200     iWriter.WriteL( quote );
       
   201 
       
   202 
       
   203     return *this;
       
   204     }
       
   205 
       
   206 
       
   207 
       
   208 // -----------------------------------------------------------------------------
       
   209 // CPEngXmlSerializer::EndTagL()
       
   210 // -----------------------------------------------------------------------------
       
   211 //
       
   212 MPEngXMLSerializer& CPEngXmlSerializer::EndTagL( const TDesC8& aName )
       
   213     {
       
   214     //Check there is start tag to close
       
   215     __AssertSerializerStateL( ( ( iState == EPEngInStartTag ) || ( iState == EPEngInElement ) ),
       
   216                               EPEngSrlzr_EndTagNotAllowed );
       
   217 
       
   218     //tag name may not be empty
       
   219     __AssertNotEmptyL( aName );
       
   220 
       
   221 
       
   222 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   223     //Check end tag name match corresponding start tag name
       
   224     __AssertEndTagName( aName );
       
   225 #endif //   __SERIALIZER_TAG_NAME_ASSERT
       
   226 
       
   227 
       
   228 
       
   229     if ( iState == EPEngInStartTag )
       
   230         {
       
   231         //still in start tag ==> empty element ==> close the tag directly
       
   232         iWriter.WriteL( KXmlEmptyTagEnd );
       
   233         }
       
   234 
       
   235 
       
   236     else
       
   237         {
       
   238         //non empty element ==> write complete end tag
       
   239         iWriter.WriteL( KXmlEndTagStart );
       
   240         iWriter.WriteL( aName );
       
   241         iWriter.WriteL( KXmlTagEnd );
       
   242         }
       
   243 
       
   244 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   245     iAssertionStack->Pop();
       
   246 #endif //   __SERIALIZER_TAG_NAME_ASSERT
       
   247 
       
   248 
       
   249     iStartTagCount--;
       
   250     if ( iStartTagCount == 0 )
       
   251         {
       
   252         //closed the last open element ==> now in root
       
   253         iState = EPEngInRoot;
       
   254         }
       
   255     else
       
   256         {
       
   257         //there is still not closed start tags ==> open elements
       
   258         iState = EPEngInElement;
       
   259         }
       
   260 
       
   261 
       
   262     return *this;
       
   263     }
       
   264 
       
   265 
       
   266 // -----------------------------------------------------------------------------
       
   267 // CPEngXmlSerializer::RawValueL()
       
   268 // -----------------------------------------------------------------------------
       
   269 //
       
   270 MPEngXMLSerializer& CPEngXmlSerializer::RawValueL( const TDesC8& aValue )
       
   271     {
       
   272     //Write raw data
       
   273 
       
   274     CheckAndCloseOpenStartTagL();   //goes to EElementOpen state
       
   275 
       
   276     __AssertNoXmlEscapedCharsL( aValue );
       
   277 
       
   278     iWriter.WriteL( aValue );
       
   279 
       
   280     return *this;
       
   281     }
       
   282 
       
   283 
       
   284 // -----------------------------------------------------------------------------
       
   285 // CPEngXmlSerializer::NarrowTextL()
       
   286 // -----------------------------------------------------------------------------
       
   287 //
       
   288 MPEngXMLSerializer& CPEngXmlSerializer::NarrowTextL( const TDesC8& aText )
       
   289     {
       
   290     // Performed steps:
       
   291     // 1. Escapes XML entities.
       
   292 
       
   293 
       
   294     CheckAndCloseOpenStartTagL();   //goes to EElementOpen state
       
   295 
       
   296     WriteXmlEscapedL( aText, EFalse );
       
   297     return *this;
       
   298     }
       
   299 
       
   300 
       
   301 
       
   302 // -----------------------------------------------------------------------------
       
   303 // CPEngXmlSerializer::UnicodeTextL()
       
   304 // -----------------------------------------------------------------------------
       
   305 //
       
   306 MPEngXMLSerializer& CPEngXmlSerializer::UnicodeTextL( const TDesC16& aText )
       
   307     {
       
   308     // Performed steps:
       
   309     // 1. Converts text from Unicode to Utf8
       
   310     // 2. Escapes XML entities
       
   311 
       
   312     TBuf8<20> outputBuffer;
       
   313     TPtrC16 remainderOfUnicodeText( aText );
       
   314     TInt returnValue;
       
   315 
       
   316     CheckAndCloseOpenStartTagL();   //goes to EElementOpen state
       
   317 
       
   318 
       
   319     FOREVER // conversion loop
       
   320         {
       
   321         returnValue = CnvUtfConverter::ConvertFromUnicodeToUtf8( outputBuffer,
       
   322         remainderOfUnicodeText );
       
   323 
       
   324         // check to see that the descriptor isn’t corrupt
       
   325         if ( returnValue == CnvUtfConverter::EErrorIllFormedInput )
       
   326             {
       
   327             User::Leave( KErrCorrupt );
       
   328             }
       
   329 
       
   330         else if ( returnValue < KErrNone ) // future-proof against "TError" expanding
       
   331             // See SDK help for more information.
       
   332             {
       
   333             User::Leave( KErrGeneral );
       
   334             }
       
   335 
       
   336         //write the Utf8 fragment produced by this round
       
   337         WriteXmlEscapedL( outputBuffer, EFalse );
       
   338 
       
   339         if ( returnValue == 0 )
       
   340             {
       
   341             //no more text left -> break the loop
       
   342             break;
       
   343             }
       
   344 
       
   345         remainderOfUnicodeText.Set( remainderOfUnicodeText.Right( returnValue ) );
       
   346         }
       
   347 
       
   348     return *this;
       
   349     }
       
   350 
       
   351 
       
   352 
       
   353 // -----------------------------------------------------------------------------
       
   354 // CPEngXmlSerializer::WvAddressL()
       
   355 // -----------------------------------------------------------------------------
       
   356 //
       
   357 MPEngXMLSerializer& CPEngXmlSerializer::WvAddressL( const TDesC16& aAddress )
       
   358     {
       
   359     // Performed steps:
       
   360     // 1. Escapes WV Address characters
       
   361     // 2. Converts text from Unicode to Utf8
       
   362     // 3. Escape XML entities
       
   363 
       
   364 
       
   365     TBuf16<20> outputBuffer;
       
   366     TPtrC16 remainderOfAddress( aAddress );
       
   367     TInt returnValue;
       
   368 
       
   369     CheckAndCloseOpenStartTagL();   //goes to EElementOpen state
       
   370 
       
   371 
       
   372     // Skip the possible "wv:" prefix from address
       
   373     // And write it as it is
       
   374     if ( aAddress.Left( KWVSchemaPrefixLength ).CompareF( KWVSchemaPrefix ) == 0 )
       
   375         {
       
   376         remainderOfAddress.Set( aAddress.Mid( KWVSchemaPrefixLength ) );
       
   377         UnicodeTextL( aAddress.Left( KWVSchemaPrefixLength ) );
       
   378         }
       
   379 
       
   380     FOREVER // conversion loop
       
   381         {
       
   382         returnValue = EncodeWvAddressChars( outputBuffer,
       
   383         remainderOfAddress );
       
   384 
       
   385         // Handle possible errors
       
   386         if ( returnValue < KErrNone )
       
   387             {
       
   388             User::Leave( KErrGeneral );
       
   389             }
       
   390 
       
   391 
       
   392         //write the WVAddress part produced by this round
       
   393         UnicodeTextL( outputBuffer );
       
   394 
       
   395 
       
   396         if ( returnValue == 0 )
       
   397             {
       
   398             //no more text left -> break the loop
       
   399             break;
       
   400             }
       
   401 
       
   402         remainderOfAddress.Set( remainderOfAddress.Right( returnValue ) );
       
   403         }
       
   404 
       
   405     return *this;
       
   406     }
       
   407 
       
   408 
       
   409 
       
   410 // -----------------------------------------------------------------------------
       
   411 // CPEngXmlSerializer::Base64DataL()
       
   412 // -----------------------------------------------------------------------------
       
   413 //
       
   414 MPEngXMLSerializer& CPEngXmlSerializer::Base64DataL( const TDesC8& aRawData )
       
   415     {
       
   416     // Performed steps:
       
   417     // 1. Coverts data to BASE64 format
       
   418 
       
   419 
       
   420     CheckAndCloseOpenStartTagL();   //goes to EElementOpen state
       
   421 
       
   422     if ( aRawData.Length() != 0 )
       
   423         {
       
   424         TImCodecB64 base64Encoder;
       
   425         base64Encoder.Initialise();
       
   426 
       
   427         //Encoder doesn't itself cope with buffer overflows,
       
   428         //so allocate twice big buffer to be sure that there is enough
       
   429         //space for B64 data
       
   430         HBufC8* base64Buffer = HBufC8::NewLC( aRawData.Size() * 2 );
       
   431         TPtr8 base64Data( base64Buffer->Des() );
       
   432         base64Encoder.Encode( aRawData, base64Data );
       
   433 
       
   434 
       
   435         //for performance reasons, write
       
   436         //whole base64 data directly to the
       
   437         //xml buffer (no need to do any XML escaping)
       
   438         iWriter.WriteL( base64Data );
       
   439         CleanupStack::PopAndDestroy(); //base64Buffer
       
   440         }
       
   441 
       
   442     return *this;
       
   443     }
       
   444 
       
   445 
       
   446 // -----------------------------------------------------------------------------
       
   447 // CPEngXmlSerializer::PushSerializerStateL()
       
   448 // -----------------------------------------------------------------------------
       
   449 //
       
   450 void CPEngXmlSerializer::PushSerializerStateL()
       
   451     {
       
   452     TPEngSerializerStateData state;
       
   453     state.iWriterLength = iWriter.CurrentLength();
       
   454     state.iState =  iState;
       
   455 
       
   456 
       
   457 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   458     state.iAssertionStackCount = iAssertionStack->Count();
       
   459 #endif //   __SERIALIZER_TAG_NAME_ASSERT
       
   460 
       
   461 
       
   462     User::LeaveIfError( iStateStack.Append( state ) ); //push new state to state stack
       
   463     }
       
   464 
       
   465 
       
   466 // -----------------------------------------------------------------------------
       
   467 // CPEngXmlSerializer::CommitState()
       
   468 // -----------------------------------------------------------------------------
       
   469 //
       
   470 void CPEngXmlSerializer::CommitState()
       
   471     {
       
   472     //check that there is a states to commit
       
   473     __ASSERT_DEBUG( ( iStateStack.Count() > 0 ),
       
   474                     PanicSerializer( EPEngSrlzr_StateStackUnderflow ) );
       
   475 
       
   476     TInt stateCount( iStateStack.Count() );
       
   477     if ( stateCount > 0 )
       
   478         {
       
   479         iStateStack.Remove( stateCount - 1 ); //pop the last state away from state stack (thus -1)
       
   480         }
       
   481     }
       
   482 
       
   483 
       
   484 // -----------------------------------------------------------------------------
       
   485 // CPEngXmlSerializer::RollbackState()
       
   486 // -----------------------------------------------------------------------------
       
   487 //
       
   488 void CPEngXmlSerializer::RollbackState()
       
   489     {
       
   490     //Check that there is a states to rollback
       
   491     __ASSERT_DEBUG( ( iStateStack.Count() > 0 ),
       
   492                     PanicSerializer( EPEngSrlzr_StateStackUnderflow ) );
       
   493 
       
   494     TInt stateCount( iStateStack.Count() );
       
   495     if ( stateCount > 0 )
       
   496         {
       
   497         TPEngSerializerStateData oldState;
       
   498         oldState = iStateStack[ stateCount - 1 ];
       
   499         iStateStack.Remove( stateCount - 1 ); //pop the last state away from state stack (thus -1)
       
   500 
       
   501         //rollback writer
       
   502         iWriter.ReverseTo( oldState.iWriterLength );
       
   503 
       
   504 
       
   505 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   506         //rollback assertion stack
       
   507         iAssertionStack->PopTo( oldState.iAssertionStackCount );
       
   508 #endif //   __SERIALIZER_TAG_NAME_ASSERT
       
   509 
       
   510 
       
   511         //return to old state
       
   512         iState = oldState.iState;
       
   513         }
       
   514     }
       
   515 
       
   516 
       
   517 // -----------------------------------------------------------------------------
       
   518 // CPEngXmlSerializer::PushedStateCount()
       
   519 // -----------------------------------------------------------------------------
       
   520 //
       
   521 TInt CPEngXmlSerializer::PushedStateCount()
       
   522     {
       
   523     return iStateStack.Count();
       
   524     }
       
   525 
       
   526 
       
   527 
       
   528 // -----------------------------------------------------------------------------
       
   529 // CPEngXmlSerializer::CheckAndCloseOpenStartTagL()
       
   530 // -----------------------------------------------------------------------------
       
   531 //
       
   532 void CPEngXmlSerializer::CheckAndCloseOpenStartTagL()
       
   533     {
       
   534     if ( iState == EPEngInStartTag )
       
   535         {
       
   536         iWriter.WriteL( KXmlTagEnd );
       
   537         iState = EPEngInElement;
       
   538         }
       
   539     }
       
   540 
       
   541 
       
   542 
       
   543 
       
   544 // -----------------------------------------------------------------------------
       
   545 // CPEngXmlSerializer::EncodeWvAddressChars()
       
   546 // Return the number of unconverted characters left at the end of the input
       
   547 // descriptor, or the error value
       
   548 // -----------------------------------------------------------------------------
       
   549 //
       
   550 TInt CPEngXmlSerializer::EncodeWvAddressChars( TDes16& aEncodedAddress,
       
   551                                                const TDesC16& aUnicodeAddress )
       
   552     {
       
   553     if ( aUnicodeAddress.Length() == 0 )
       
   554         {
       
   555         aEncodedAddress.SetLength( 0 );
       
   556         return 0;
       
   557         }
       
   558 
       
   559 
       
   560     if ( aEncodedAddress.MaxLength() == 0 )
       
   561         {
       
   562         return aUnicodeAddress.Length();
       
   563         }
       
   564 
       
   565     aEncodedAddress.Zero();
       
   566 
       
   567     TInt addLen( aUnicodeAddress.Length() );
       
   568     for ( TInt ii( 0 ); ii < addLen; ii++ )
       
   569         {
       
   570         TUint16 characterValue = aUnicodeAddress[ ii ];
       
   571 
       
   572         switch ( characterValue )
       
   573             {
       
   574             case ':':
       
   575             case ';':
       
   576             case '?':
       
   577             case '&':
       
   578             case '=':
       
   579             case '+':
       
   580             case '$':
       
   581             case ',':
       
   582                 {
       
   583                 TInt spaceLeft = aEncodedAddress.MaxLength() - aEncodedAddress.Length();
       
   584 
       
   585                 //Encoding special characters produces 3 characters e.g. "%yy"
       
   586                 //(only three produced because encoded characters list is
       
   587                 //limited above)
       
   588                 if ( spaceLeft < 3 )
       
   589                     {
       
   590                     return addLen - ii;
       
   591                     }
       
   592 
       
   593                 aEncodedAddress.Append( KPercentSign16 );
       
   594                 aEncodedAddress.AppendNumUC( characterValue, EHex );
       
   595                 break;
       
   596                 }
       
   597 
       
   598             default:
       
   599                 {
       
   600                 TInt spaceLeft = aEncodedAddress.MaxLength() - aEncodedAddress.Length();
       
   601 
       
   602                 //Adding one non-encoded character requires space one character
       
   603                 if ( spaceLeft < 1 )
       
   604                     {
       
   605                     return addLen - ii;
       
   606                     }
       
   607 
       
   608                 aEncodedAddress.Append( characterValue );
       
   609                 break;
       
   610                 }
       
   611             }
       
   612         }
       
   613 
       
   614 
       
   615     return KErrNone;
       
   616     }
       
   617 
       
   618 
       
   619 
       
   620 
       
   621 
       
   622 // -----------------------------------------------------------------------------
       
   623 // CPEngXmlSerializer::WriteXmlEscapedL()
       
   624 // -----------------------------------------------------------------------------
       
   625 //
       
   626 void CPEngXmlSerializer::WriteXmlEscapedL( const TDesC8& aString,
       
   627                                            TBool aEscapeQuotes )
       
   628     {
       
   629     const TInt length( aString.Length() );
       
   630     TUint8 character;
       
   631 
       
   632     //loop trough the all characters and escape them to writer one by one
       
   633     for ( TInt ii( 0 ); ii < length; ii++ )
       
   634         {
       
   635         character = aString[ ii ];
       
   636         WriteXmlEscapedL( character, aEscapeQuotes );
       
   637         }
       
   638     }
       
   639 
       
   640 
       
   641 // -----------------------------------------------------------------------------
       
   642 // CPEngXmlSerializer::WriteXmlEscapedL()
       
   643 // -----------------------------------------------------------------------------
       
   644 //
       
   645 void CPEngXmlSerializer::WriteXmlEscapedL( TUint8 aCharacter,
       
   646                                            TBool aEscapeQuotes )
       
   647     {
       
   648     switch ( aCharacter )
       
   649         {
       
   650         case '&':
       
   651             {
       
   652             iWriter.WriteL( KEntityAmpersand );
       
   653             break;
       
   654             }
       
   655 
       
   656         case '>':
       
   657             {
       
   658             iWriter.WriteL( KEntityGreaterThan );
       
   659             break;
       
   660             }
       
   661 
       
   662         case '<':
       
   663             {
       
   664             iWriter.WriteL( KEntityLowerThan );
       
   665             break;
       
   666             }
       
   667 
       
   668         case '"':       ///<If character is a double
       
   669         case '\'':      ///<or single quote, escape it only if required
       
   670             {
       
   671             if ( aEscapeQuotes )
       
   672                 {
       
   673                 if ( aCharacter == '"' )
       
   674                     {
       
   675                     iWriter.WriteL( KEntityDoubleQuote );
       
   676                     }
       
   677                 else
       
   678                     {
       
   679                     iWriter.WriteL( KEntityApostrophe );
       
   680                     }
       
   681 
       
   682                 break;
       
   683                 }
       
   684 
       
   685             //else no need to escape quotes ==>
       
   686             //write them as normal characters
       
   687             //FLOW TROUGH
       
   688             }
       
   689 
       
   690         default:
       
   691             {
       
   692             iWriter.WriteL( aCharacter );
       
   693             }
       
   694         }
       
   695     }
       
   696 
       
   697 
       
   698 
       
   699 
       
   700 
       
   701 // -----------------------------------------------------------------------------
       
   702 // CPEngXmlSerializer::__AssertNoXmlEscapedCharsL()
       
   703 // -----------------------------------------------------------------------------
       
   704 //
       
   705 void CPEngXmlSerializer::__AssertNoXmlEscapedCharsL( const TDesC8& aString )
       
   706     {
       
   707     const TInt length( aString.Length() );
       
   708     TUint8 character;
       
   709 
       
   710     //loop trough the all characters and check them
       
   711     for ( TInt ii( 0 ); ii < length; ii++ )
       
   712         {
       
   713         character = aString[ ii ];
       
   714         switch ( character )
       
   715             {
       
   716             case '&':
       
   717             case '>':
       
   718             case '<':
       
   719             case '"':
       
   720             case '\'':
       
   721                 {
       
   722 #if defined(_DEBUG)
       
   723                 PanicSerializer( EPEngSrlzr_XmlMarkupCharNotAllowed );
       
   724 #else
       
   725                 User::Leave( KErrArgument );
       
   726 #endif
       
   727 
       
   728                 break;
       
   729                 }
       
   730 
       
   731             default:
       
   732                 {
       
   733                 break;
       
   734                 }
       
   735             }
       
   736         }
       
   737     }
       
   738 
       
   739 
       
   740 
       
   741 
       
   742 
       
   743 // -----------------------------------------------------------------------------
       
   744 // CPEngXmlSerializer::__AssertSerializerStateL()
       
   745 // -----------------------------------------------------------------------------
       
   746 //
       
   747 #if defined(_DEBUG)
       
   748 void CPEngXmlSerializer::__AssertSerializerStateL( TBool aInCorrectState,
       
   749                                                    TPEngSerializerPanics aPanicReason )
       
   750 #else
       
   751 void CPEngXmlSerializer::__AssertSerializerStateL( TBool aInCorrectState,
       
   752                                                    TPEngSerializerPanics /*aPanicReason*/ )
       
   753 #endif
       
   754     {
       
   755     if ( !aInCorrectState )
       
   756         {
       
   757 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   758         TBuf<150> buffer16; //restrict tag names shown in debug output to 150 characters.
       
   759         //150 characters should be enough for debug purposes.
       
   760 
       
   761         TPtrC8 startTagName = iAssertionStack->Top();
       
   762         buffer16.Copy( startTagName.Left( buffer16.MaxLength() ) );
       
   763 
       
   764         PENG_DP( D_PENG_LIT( "CPEngXmlSerializer: Wrong state. In tag <%S> at nesting level %i" ),
       
   765                  &buffer16, iAssertionStack->Count() );
       
   766 #endif // __SERIALIZER_TAG_NAME_ASSERT
       
   767 
       
   768 
       
   769 #if defined(_DEBUG)
       
   770         PanicSerializer( aPanicReason );
       
   771 #else
       
   772         User::Leave( KErrNotSupported );
       
   773 #endif
       
   774         }
       
   775     }
       
   776 
       
   777 
       
   778 // -----------------------------------------------------------------------------
       
   779 // CPEngXmlSerializer::__AssertNotEmptyL()
       
   780 // -----------------------------------------------------------------------------
       
   781 //
       
   782 void CPEngXmlSerializer::__AssertNotEmptyL( const TDesC8& aString )
       
   783     {
       
   784     if ( aString.Length() == 0 )
       
   785         {
       
   786 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   787         TBuf<150> buffer16; //restrict tag names shown in debug output to 150 characters.
       
   788         //150 characters should be enough for debug purposes.
       
   789 
       
   790         TPtrC8 startTagName = iAssertionStack->Top();
       
   791         buffer16.Copy( startTagName.Left( buffer16.MaxLength() ) );
       
   792 
       
   793         PENG_DP( D_PENG_LIT( "CPEngXmlSerializer: Writing empty tag or attribute. In tag <%S> at nesting level %i" ),
       
   794                  &buffer16, iAssertionStack->Count() );
       
   795 #endif // __SERIALIZER_TAG_NAME_ASSERT
       
   796 
       
   797 
       
   798 #if defined(_DEBUG)
       
   799         PanicSerializer( EPEngSrlzr_EmptyInputString );
       
   800 #else
       
   801         User::Leave( KErrArgument );
       
   802 #endif
       
   803         }
       
   804     }
       
   805 
       
   806 
       
   807 #ifdef __SERIALIZER_TAG_NAME_ASSERT
       
   808 // -----------------------------------------------------------------------------
       
   809 // CPEngXmlSerializer::__AssertEndTagName()
       
   810 // -----------------------------------------------------------------------------
       
   811 //
       
   812 void CPEngXmlSerializer::__AssertEndTagName( const TDesC8& aEndTagName )
       
   813     {
       
   814     if ( aEndTagName != iAssertionStack->Top() )
       
   815         {
       
   816         TBuf<150> buffer16; //restrict tag names shown in debug output to 150 characters.
       
   817         //150 characters should be enough for debug purposes.
       
   818 
       
   819         buffer16.Copy( aEndTagName.Left( buffer16.MaxLength() ) );
       
   820         PENG_DP( D_PENG_LIT( "CPEngXmlSerializer: End tag mismatch. Ending with <%S> at level %i" ),
       
   821                  &buffer16, iAssertionStack->Count() );
       
   822 
       
   823         buffer16.Zero();
       
   824         TPtrC8 startTagName = iAssertionStack->Top();
       
   825         buffer16.Copy( startTagName.Left( buffer16.MaxLength() ) );
       
   826         PENG_DP( D_PENG_LIT( "CPEngXmlSerializer: Required start tag <%S>" ),
       
   827                  &buffer16 );
       
   828 
       
   829         PanicSerializer( EPEngSrlzr_EndTagNameMismatch );
       
   830         }
       
   831     }
       
   832 #endif // __SERIALIZER_TAG_NAME_ASSERT
       
   833 
       
   834 
       
   835 //  End of File
       
   836 
       
   837 
       
   838 
       
   839