vpnengine/utlxml/src/XmlPullParser.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2003 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: Implementation of CXmlPullParser.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <eikenv.h>
       
    21 #include <e32std.h>
       
    22 #include <e32des8.h>
       
    23 #include "XppImpl.h"
       
    24 
       
    25 const TInt KExtraPunctuation = 5;
       
    26 const TInt KBufSizeIncrement = 1024;
       
    27 const TInt KBufInitSize = 2048;
       
    28 
       
    29 //
       
    30 // Common literal text
       
    31 //
       
    32 _LIT8(KOpenBracket, "<");
       
    33 _LIT8(KCloseBracket, ">");
       
    34 //_LIT8(KStartEndTag, "</");
       
    35 //_LIT8(KCloseTag, "/>");
       
    36 _LIT8(KSpace, " ");
       
    37 _LIT8(KEquals, "=");
       
    38 _LIT8(KSlash, "/");
       
    39 _LIT8(KSingleQuote, "\'");
       
    40 _LIT8(KDoubleQuote, "\"");
       
    41 //_LIT8(KQuestionMark, "?");
       
    42 //_LIT8(KExclamationMark, "!");
       
    43 //_LIT8(KOpenCurlyBracket, "{");
       
    44 //_LIT8(KCloseCurlyBracket, "}");
       
    45 //_LIT8(KHyphen, "-");
       
    46 _LIT8(KOpenAngleBracket , "[");
       
    47 _LIT8(KCloseAngleBracket, "]");
       
    48 
       
    49 _LIT8(KAmpersand, "&");
       
    50 _LIT8(KAmpersandHash, "&#");
       
    51 _LIT8(KSemicolon, ";");
       
    52 
       
    53 // XML special marks
       
    54 //_LIT8(KStartXmlProlog, "<?xml");
       
    55 //_LIT8(KStartComment, "<!--");
       
    56 _LIT8(KEndComment, "-->");
       
    57 //_LIT8(KStartProcessingInstructions, "<?");
       
    58 _LIT8(KEndPIAndProlog, "?>");
       
    59 _LIT8(KStartCData, "<![CDATA[");
       
    60 _LIT8(KEndCData, "]]>");
       
    61 //_LIT8(KStartDocType, "<!DOCTYPE");
       
    62 //_LIT8(KStartElement, "<!ELEMENT");
       
    63 //_LIT8(KStartAttList, "<!ATTLIST");
       
    64 //_LIT8(KStartEntity, "<!ENTITY");
       
    65 //_LIT8(KStartNotation, "<!NOTATION");
       
    66 //_LIT8(KEndCdata, "]]>");
       
    67 
       
    68 _LIT8(KEntityLowerThan, "&lt;");           // <
       
    69 _LIT8(KEntityGreaterThan, "&gt;");         // >
       
    70 _LIT8(KEntityAmpersand, "&amp;");          // &
       
    71 _LIT8(KEntityApostrophe, "&apos;");        // '
       
    72 _LIT8(KEntityQuotation, "&quot;");         // "
       
    73 
       
    74 
       
    75 ////////////////////////////////////////////////////////////////////////////////////////
       
    76 // 
       
    77 ////////////////////////////////////////////////////////////////////////////////////////
       
    78 CXmlPullParser::CXmlPullParser()
       
    79 : iState(EStateStartDocument), iCurrentElementPos(0), iPathBufPtr(NULL, 0), iDepth(0), 
       
    80 iIsEmptyElement(EFalse), iCdataStartFound(EFalse), iCdataSectionText(EFalse),
       
    81 iStringValuePtr(NULL, 0), iStringValueArray(NULL)
       
    82     {
       
    83     }
       
    84 
       
    85 ////////////////////////////////////////////////////////////////////////////////////////
       
    86 // 
       
    87 ////////////////////////////////////////////////////////////////////////////////////////
       
    88 // NewLC with two stage construction 
       
    89 EXPORT_C CXmlPullParser* CXmlPullParser::NewLC(CDesC8ArrayFlat& aStringValueArray)
       
    90     {
       
    91     // get new, leave if can't
       
    92     CXmlPullParser* self = new (ELeave) CXmlPullParser();
       
    93     // push onto cleanup stack in case self->ConstructL leaves 
       
    94     CleanupStack::PushL(self);
       
    95     // complete construction with second phase constructor 
       
    96     self->ConstructL(aStringValueArray);
       
    97     return self;
       
    98     }
       
    99 
       
   100 ////////////////////////////////////////////////////////////////////////////////////////
       
   101 // 
       
   102 ////////////////////////////////////////////////////////////////////////////////////////
       
   103 EXPORT_C CXmlPullParser* CXmlPullParser::NewL(CDesC8ArrayFlat& aStringValueArray) 
       
   104     {
       
   105     CXmlPullParser* self=NewLC(aStringValueArray);
       
   106     CleanupStack::Pop();
       
   107     return self;
       
   108     }
       
   109 
       
   110 ////////////////////////////////////////////////////////////////////////////////////////
       
   111 // 
       
   112 ////////////////////////////////////////////////////////////////////////////////////////
       
   113 void CXmlPullParser::ConstructL(CDesC8ArrayFlat& aStringValueArray)
       
   114     {
       
   115     iPathBuf = HBufC8::NewMaxL(KBufInitSize);
       
   116     iPathBufPtr.Set(iPathBuf->Des());
       
   117     iPathBufPtr.SetLength(0);  // Otherwise the Length is set to KBufInitSize
       
   118     iCAttrDataArray = new (ELeave) CArrayFixFlat<TAttrData>(1);
       
   119     iStringValue = HBufC8::NewMaxL(KBufInitSize);
       
   120     iStringValuePtr.Set(iStringValue->Des());
       
   121     iStringValuePtr.SetLength(0);  // Otherwise the Length is set to KBufInitSize
       
   122     //iStringValueArray = new (ELeave) CDesC8ArrayFlat(1);
       
   123     iStringValueArray = &aStringValueArray;
       
   124     }
       
   125 
       
   126 ////////////////////////////////////////////////////////////////////////////////////////
       
   127 // 
       
   128 ////////////////////////////////////////////////////////////////////////////////////////
       
   129 CXmlPullParser::~CXmlPullParser()
       
   130     {
       
   131     delete (iPathBuf);
       
   132     delete iCAttrDataArray;
       
   133     delete (iStringValue);
       
   134     //delete iStringValueArray;
       
   135     }
       
   136 
       
   137 
       
   138 ////////////////////////////////////////////////////////////////////////////////////////
       
   139 // 
       
   140 ////////////////////////////////////////////////////////////////////////////////////////
       
   141 void CXmlPullParser::CheckSpaceL(const TDesC8& aText)
       
   142     {
       
   143     TInt spaceLeft = iPathBufPtr.MaxLength() - iPathBufPtr.Length() - KExtraPunctuation;
       
   144     if (aText.Length() > spaceLeft)
       
   145         {
       
   146         TInt newMaxLength = iPathBufPtr.MaxLength() + aText.Length() + KBufSizeIncrement;
       
   147         iPathBuf = iPathBuf->ReAllocL(newMaxLength);
       
   148         iPathBufPtr.Set(iPathBuf->Des());
       
   149         }
       
   150     }
       
   151 
       
   152 
       
   153 ////////////////////////////////////////////////////////////////////////////////////////
       
   154 // 
       
   155 ////////////////////////////////////////////////////////////////////////////////////////
       
   156 EXPORT_C void CXmlPullParser::SetInput(const TDesC8& aInput)
       
   157     {
       
   158     iState = EStateStartDocument;
       
   159     iText.Set(KNullDesC8);
       
   160     iCAttrDataArray->Delete(0, iCAttrDataArray->Count());
       
   161     iDocument.Set(aInput);
       
   162     iDocPart.Set(KNullDesC8);
       
   163     iLexer.Assign(aInput);  // Assigns a string to this object from a descriptor
       
   164     iCurrentElementPos = 0;
       
   165     iPathBufPtr.Zero();
       
   166     iElement.Set(KNullDesC8);
       
   167     iDepth = 0;
       
   168     iIsEmptyElement = EFalse;
       
   169     iCdataStartFound = EFalse;
       
   170     iCdataSectionText = EFalse;
       
   171     }
       
   172 
       
   173 ////////////////////////////////////////////////////////////////////////////////////////
       
   174 // 
       
   175 ////////////////////////////////////////////////////////////////////////////////////////
       
   176 EXPORT_C TInt CXmlPullParser::NextL()
       
   177     {
       
   178     TInt rv;
       
   179     
       
   180     switch (iState)
       
   181         {
       
   182         case EStateStartDocument:
       
   183             // skip
       
   184             if ((rv = SkipLeadingNonRelevantElements()) == ERcDocumentError)
       
   185                 {
       
   186                 return rv;
       
   187                 }
       
   188             else
       
   189                 {
       
   190                 iCurrentElementPos = iLexer.Offset();
       
   191                 rv = GetElementStartTagL();
       
   192                 return rv;
       
   193                 }
       
   194             //break;
       
   195             
       
   196         case EStateStartTag:
       
   197             // skip
       
   198             if ((rv = SkipNonRelevantElements()) == ERcDocumentError)
       
   199                 {
       
   200                 return rv;
       
   201                 }
       
   202             else
       
   203                 {
       
   204                 iCurrentElementPos = iLexer.Offset();
       
   205                 if (iIsEmptyElement)
       
   206                     {
       
   207                     // delete /end tag from the iPathBuf
       
   208                     // this is done by subtracting the length of the buffer
       
   209                     iPathBufPtr.SetLength(iPathBufPtr.LocateReverse('/'));
       
   210                     
       
   211                     // decrement iDepth
       
   212                     iDepth--;
       
   213 
       
   214                     // if we have an XML-document that is only one empty-element
       
   215                     // then we must check if we are already in the end of the document
       
   216                     if (CheckIfEndOfFile())
       
   217                         {
       
   218                         return KErrNone;
       
   219                         }
       
   220                     }
       
   221                 if (CheckIfNextEndTag())  // Check iState!!
       
   222                     {
       
   223                     if (iState == EStateError)
       
   224                         {
       
   225                         return ERcDocumentError;
       
   226                         }
       
   227                     else
       
   228                         {
       
   229                         rv = GetElementEndTag();
       
   230                         return rv;
       
   231                         }
       
   232                     }
       
   233                 else if (CheckIfNextStartTag())  // Check iState!!
       
   234                     {
       
   235                     if (iState == EStateError)
       
   236                         {
       
   237                         return ERcDocumentError;
       
   238                         }
       
   239                     else
       
   240                         {
       
   241                         rv = GetElementStartTagL();
       
   242                         return rv;
       
   243                         }
       
   244                     }
       
   245                 else // etext
       
   246                     {
       
   247                     rv = GetElementText();
       
   248                     return rv;
       
   249                     }
       
   250                 }
       
   251             //break;
       
   252 
       
   253         case EStateText:
       
   254             // skip
       
   255             if ((rv = SkipNonRelevantElements()) == ERcDocumentError)
       
   256                 {
       
   257                 return rv;
       
   258                 }
       
   259             else
       
   260                 {
       
   261                 iCurrentElementPos = iLexer.Offset();
       
   262                 if (iState == EStateEndDocument)
       
   263                     {
       
   264                     // in EStateText we can not be in the end of the xml-document
       
   265                     iState = EStateError;
       
   266                     return ERcDocumentError;
       
   267                     }
       
   268 
       
   269                 if (iCdataStartFound)
       
   270                     {
       
   271                     rv = GetElementText();
       
   272                     return rv;
       
   273                     }
       
   274                 else
       
   275                     {
       
   276                     if (CheckIfNextEndTag())  // Check iState!!
       
   277                         {
       
   278                         if (iState == EStateError)
       
   279                             {
       
   280                             return ERcDocumentError;
       
   281                             }
       
   282                         else
       
   283                             {
       
   284                             // get end tag
       
   285                             rv = GetElementEndTag();
       
   286                             return rv;
       
   287                             }
       
   288                         }
       
   289                     else if (CheckIfNextStartTag())  // Check iState!!
       
   290                         {
       
   291                         if (iState == EStateError)
       
   292                             {
       
   293                             return ERcDocumentError;
       
   294                             }
       
   295                         else
       
   296                             {
       
   297                             // get start tag
       
   298                             rv = GetElementStartTagL();
       
   299                             return rv;
       
   300                             }
       
   301                         }
       
   302                     else // etext
       
   303                         {
       
   304                         // get text
       
   305                         rv = GetElementText();
       
   306                         return rv;
       
   307                         }
       
   308                     }
       
   309                 }
       
   310             //break;
       
   311 
       
   312         case EStateEndTag:
       
   313             // after end tag can be end of file, new start tag, new end tag or etext
       
   314             // skip
       
   315             if ((rv = SkipNonRelevantElements()) == ERcDocumentError)
       
   316                 {
       
   317                 return rv;
       
   318                 }
       
   319             else
       
   320                 {
       
   321                 iCurrentElementPos = iLexer.Offset();
       
   322                 if (CheckIfEndOfFile())
       
   323                     {
       
   324                     return KErrNone;
       
   325                     }
       
   326                 else
       
   327                     {
       
   328                     if (CheckIfNextStartTag())  // Check iState
       
   329                         {
       
   330                         if (iState == EStateError)
       
   331                             {
       
   332                             return ERcDocumentError;
       
   333                             }
       
   334                         else
       
   335                             {
       
   336                             rv = GetElementStartTagL();
       
   337                             return rv;
       
   338                             }
       
   339                         }
       
   340                     else if (CheckIfNextEndTag())  // Check iState!!
       
   341                         {
       
   342                         if (iState == EStateError)
       
   343                             {
       
   344                             return ERcDocumentError;
       
   345                             }
       
   346                         else
       
   347                             {
       
   348                             rv = GetElementEndTag();
       
   349                             return rv;
       
   350                             }
       
   351                         }
       
   352                     else // etext
       
   353                         {
       
   354                         // get text
       
   355                         rv = GetElementText();
       
   356                         return rv;
       
   357                         }
       
   358                     }
       
   359                 }
       
   360 
       
   361             //break;
       
   362         case EStateEndDocument:
       
   363             return ERcWrongParserState;
       
   364             //break;
       
   365         case EStateError:
       
   366             return ERcWrongParserState;
       
   367             //break;
       
   368         default:
       
   369             return ERcUnknown;  // all the States are handled above
       
   370             //break;
       
   371         }
       
   372     }
       
   373 
       
   374 ////////////////////////////////////////////////////////////////////////////////////////
       
   375 // 
       
   376 ////////////////////////////////////////////////////////////////////////////////////////
       
   377 EXPORT_C CXmlPullParser::TParserState CXmlPullParser::State()
       
   378     {
       
   379     return iState;
       
   380     }
       
   381 
       
   382 ////////////////////////////////////////////////////////////////////////////////////////
       
   383 // 
       
   384 ////////////////////////////////////////////////////////////////////////////////////////
       
   385 EXPORT_C TInt CXmlPullParser::Name(TPtrC8& aName)
       
   386     {
       
   387     if ((iState == EStateStartTag) || 
       
   388         (iState == EStateText) || 
       
   389         (iState == EStateEndTag) ||
       
   390         (iState == EStateEndDocument))
       
   391         {
       
   392         aName.Set(iElement);
       
   393         return KErrNone;
       
   394         }
       
   395     else
       
   396         {
       
   397         return ERcWrongParserState;
       
   398         }
       
   399     }
       
   400 
       
   401 ////////////////////////////////////////////////////////////////////////////////////////
       
   402 // 
       
   403 ////////////////////////////////////////////////////////////////////////////////////////
       
   404 EXPORT_C TInt CXmlPullParser::PathL(TPtrC8& aPath)
       
   405     {
       
   406     if ((iState == EStateStartTag) || 
       
   407         (iState == EStateText) || 
       
   408         (iState == EStateEndTag))
       
   409         {
       
   410         aPath.Set(iPathBufPtr);
       
   411         return KErrNone;
       
   412         }
       
   413     else
       
   414         {
       
   415         return ERcWrongParserState;
       
   416         }
       
   417     }
       
   418 
       
   419 ////////////////////////////////////////////////////////////////////////////////////////
       
   420 // 
       
   421 ////////////////////////////////////////////////////////////////////////////////////////
       
   422 EXPORT_C TInt CXmlPullParser::Depth(TInt& aDepth)
       
   423     {
       
   424     if ((iState == EStateStartTag) || 
       
   425         (iState == EStateText) || 
       
   426         (iState == EStateEndTag))
       
   427         {
       
   428         aDepth = iDepth;
       
   429         return KErrNone;
       
   430         }
       
   431     else
       
   432         {
       
   433         return ERcWrongParserState;
       
   434         }
       
   435     }
       
   436 
       
   437 ////////////////////////////////////////////////////////////////////////////////////////
       
   438 // 
       
   439 ////////////////////////////////////////////////////////////////////////////////////////
       
   440 EXPORT_C TInt CXmlPullParser::AttributeCount(TInt& aCount)
       
   441     {
       
   442     if (iState == EStateStartTag)
       
   443         {
       
   444         aCount = iCAttrDataArray->Count();
       
   445         return KErrNone;
       
   446         }
       
   447     else
       
   448         {
       
   449         return ERcWrongParserState;
       
   450         }
       
   451     }
       
   452 
       
   453 ////////////////////////////////////////////////////////////////////////////////////////
       
   454 // 
       
   455 ////////////////////////////////////////////////////////////////////////////////////////
       
   456 EXPORT_C TInt CXmlPullParser::AttributeName(TInt aIndex, TPtrC8& aName)
       
   457     {
       
   458     if (iState == EStateStartTag)
       
   459         {
       
   460         if ((aIndex < iCAttrDataArray->Count()) && (aIndex >= 0))
       
   461             {
       
   462             aName.Set(iCAttrDataArray->At(aIndex).iName);
       
   463             return KErrNone;
       
   464             }
       
   465         else
       
   466             {
       
   467             return KErrNotFound;
       
   468             }
       
   469         }
       
   470     else
       
   471         {
       
   472         return ERcWrongParserState;
       
   473         }
       
   474     }
       
   475 
       
   476 ////////////////////////////////////////////////////////////////////////////////////////
       
   477 // 
       
   478 ////////////////////////////////////////////////////////////////////////////////////////
       
   479 EXPORT_C TInt CXmlPullParser::AttributeValuePredefEntitiesNotEscaped(TInt aIndex, TPtrC8& aValue)
       
   480     {
       
   481     if (iState == EStateStartTag)
       
   482         {
       
   483         if ((aIndex < iCAttrDataArray->Count()) && (aIndex >= 0))
       
   484             {
       
   485             aValue.Set(iCAttrDataArray->At(aIndex).iValue);
       
   486             return KErrNone;
       
   487             }
       
   488         else
       
   489             {
       
   490             return KErrNotFound;
       
   491             }
       
   492         }
       
   493     else
       
   494         {
       
   495         return ERcWrongParserState;
       
   496         }
       
   497     }
       
   498 
       
   499 ////////////////////////////////////////////////////////////////////////////////////////
       
   500 // 
       
   501 ////////////////////////////////////////////////////////////////////////////////////////
       
   502 EXPORT_C TInt CXmlPullParser::AttributeValuePredefEntitiesNotEscaped(const TDesC8& aName, TPtrC8& aValue)
       
   503     {
       
   504     TInt count;
       
   505     TInt index = 0;
       
   506     if (iState == EStateStartTag)
       
   507         {
       
   508         count = iCAttrDataArray->Count();
       
   509         while (index < count)
       
   510             {
       
   511             if (iCAttrDataArray->At(index).iName == aName)
       
   512                 {
       
   513                 aValue.Set(iCAttrDataArray->At(index).iValue);
       
   514                 return KErrNone;
       
   515                 }
       
   516             else
       
   517                 {
       
   518                 index ++;
       
   519                 }
       
   520             }
       
   521         return KErrNotFound;
       
   522         }
       
   523     else
       
   524         {
       
   525         return ERcWrongParserState;
       
   526         }
       
   527     }
       
   528 
       
   529 
       
   530 ////////////////////////////////////////////////////////////////////////////////////////
       
   531 // 
       
   532 ////////////////////////////////////////////////////////////////////////////////////////
       
   533 EXPORT_C TInt CXmlPullParser::AttributeValueL(TInt aIndex, TPtrC8& aValue)
       
   534     {
       
   535     TInt ret;
       
   536     ret = AttributeValuePredefEntitiesNotEscaped(aIndex, aValue);
       
   537     
       
   538     if (ret == KErrNone)
       
   539         {
       
   540         CheckStringValueBufferSpaceL(aValue);
       
   541         
       
   542         iStringValuePtr = aValue;
       
   543         
       
   544         if ( (ret = EscapeCharRefAndPreDefEntities()) != KErrNone )
       
   545             {
       
   546             return ret;
       
   547             }
       
   548         else
       
   549             {
       
   550             iStringValueArray->AppendL(iStringValuePtr);
       
   551             aValue.Set(iStringValueArray->MdcaPoint(iStringValueArray->MdcaCount()-1));
       
   552             return KErrNone;
       
   553             }
       
   554         }
       
   555     else
       
   556         {
       
   557         return ret;
       
   558         }
       
   559     }
       
   560 
       
   561 
       
   562 ////////////////////////////////////////////////////////////////////////////////////////
       
   563 // 
       
   564 ////////////////////////////////////////////////////////////////////////////////////////
       
   565 EXPORT_C TInt CXmlPullParser::AttributeValueL(const TDesC8& aName, TPtrC8& aValue)
       
   566     {
       
   567     TInt ret;
       
   568     ret = AttributeValuePredefEntitiesNotEscaped(aName, aValue);
       
   569 
       
   570     if (ret == KErrNone)
       
   571         {
       
   572         CheckStringValueBufferSpaceL(aValue);
       
   573 
       
   574         iStringValuePtr = aValue;
       
   575 
       
   576         if ( (ret = EscapeCharRefAndPreDefEntities()) != KErrNone )
       
   577             {
       
   578             return ret;
       
   579             }
       
   580         else
       
   581             {
       
   582             iStringValueArray->AppendL(iStringValuePtr);
       
   583             aValue.Set(iStringValueArray->MdcaPoint(iStringValueArray->MdcaCount()-1));
       
   584             return KErrNone;
       
   585             }
       
   586         }
       
   587     else
       
   588         {
       
   589         return ret;
       
   590         }
       
   591     }
       
   592 
       
   593 ////////////////////////////////////////////////////////////////////////////////////////
       
   594 // 
       
   595 ////////////////////////////////////////////////////////////////////////////////////////
       
   596 void CXmlPullParser::CheckStringValueBufferSpaceL(const TDesC8& aValue)
       
   597     {
       
   598     TInt newLength = aValue.Length();
       
   599     if ( newLength > (iStringValuePtr.MaxLength()) )
       
   600         {
       
   601         iStringValue = iStringValue->ReAllocL(newLength);
       
   602         iStringValuePtr.Set(iStringValue->Des());
       
   603         }
       
   604     }
       
   605 
       
   606 ////////////////////////////////////////////////////////////////////////////////////////
       
   607 // 
       
   608 ////////////////////////////////////////////////////////////////////////////////////////
       
   609 EXPORT_C TInt CXmlPullParser::IsEmptyElement(TBool& aIsEmptyElement)
       
   610     {
       
   611     if (iState == EStateStartTag)
       
   612         {
       
   613         aIsEmptyElement = iIsEmptyElement;
       
   614         return KErrNone;
       
   615         }
       
   616     else
       
   617         {
       
   618         return ERcWrongParserState;
       
   619         }
       
   620     }
       
   621 
       
   622 ////////////////////////////////////////////////////////////////////////////////////////
       
   623 // 
       
   624 ////////////////////////////////////////////////////////////////////////////////////////
       
   625 EXPORT_C TInt CXmlPullParser::TextPredefEntitiesNotEscaped(TPtrC8& aText)
       
   626     {
       
   627     if (iState == EStateText)
       
   628         {
       
   629         aText.Set(iText);
       
   630         return KErrNone;
       
   631         }
       
   632     else
       
   633         {
       
   634         return ERcWrongParserState;
       
   635         }
       
   636     }
       
   637 
       
   638 ////////////////////////////////////////////////////////////////////////////////////////
       
   639 // 
       
   640 ////////////////////////////////////////////////////////////////////////////////////////
       
   641 EXPORT_C TInt CXmlPullParser::TextL(TPtrC8& aText)
       
   642     {
       
   643     TInt ret;
       
   644     ret = TextPredefEntitiesNotEscaped(aText);
       
   645 
       
   646     if (ret == KErrNone)
       
   647         {
       
   648         CheckStringValueBufferSpaceL(aText);
       
   649 
       
   650         iStringValuePtr = aText;
       
   651 
       
   652         if ( !(iCdataSectionText) )
       
   653             {
       
   654             if ( (ret = EscapeCharRefAndPreDefEntities()) != KErrNone )
       
   655                 {
       
   656                 return ret;
       
   657                 }
       
   658             else
       
   659                 {
       
   660                 iStringValueArray->AppendL(iStringValuePtr);
       
   661                 aText.Set(iStringValueArray->MdcaPoint(iStringValueArray->MdcaCount()-1));
       
   662                 }
       
   663             }
       
   664         return KErrNone;
       
   665         }
       
   666     else
       
   667         {
       
   668         return ret;
       
   669         }
       
   670     }
       
   671 
       
   672 
       
   673 ////////////////////////////////////////////////////////////////////////////////////////
       
   674 // 
       
   675 ////////////////////////////////////////////////////////////////////////////////////////
       
   676 EXPORT_C TInt CXmlPullParser::Pos()
       
   677     {
       
   678     return iLexer.Offset();
       
   679     }
       
   680 
       
   681 ////////////////////////////////////////////////////////////////////////////////////////
       
   682 // 
       
   683 ////////////////////////////////////////////////////////////////////////////////////////
       
   684 EXPORT_C TInt CXmlPullParser::CurrentElementPos()
       
   685     {
       
   686     return iCurrentElementPos;
       
   687     }
       
   688 
       
   689 ////////////////////////////////////////////////////////////////////////////////////////
       
   690 // 
       
   691 ////////////////////////////////////////////////////////////////////////////////////////
       
   692 EXPORT_C TInt CXmlPullParser::Length()
       
   693     {
       
   694     return iDocument.Length();
       
   695     }
       
   696 
       
   697 ////////////////////////////////////////////////////////////////////////////////////////
       
   698 // 
       
   699 ////////////////////////////////////////////////////////////////////////////////////////
       
   700 EXPORT_C TPtrC8 CXmlPullParser::DocPart(TInt aStartPos, TInt aEndPos)
       
   701     {
       
   702     iDocPart.Set(iDocument.Mid(aStartPos, (aEndPos - aStartPos + 1)));
       
   703     return iDocPart;
       
   704     }
       
   705 
       
   706 ////////////////////////////////////////////////////////////////////////////////////////
       
   707 // 
       
   708 ////////////////////////////////////////////////////////////////////////////////////////
       
   709 TInt CXmlPullParser::SkipLeadingNonRelevantElements()
       
   710     {
       
   711     TPtrC8 token;
       
   712     TInt endStringOffset;
       
   713     TBool prologFound = ETrue;
       
   714     TBool commentFound = ETrue;
       
   715     TBool piFound = ETrue;
       
   716     TBool dtdFound = ETrue;
       
   717 
       
   718     iLexer.SkipSpaceAndMark(iMarkPosition);  // Remember where we are
       
   719     
       
   720     if (iLexer.Eos())
       
   721         {
       
   722         iState = EStateEndDocument;
       
   723         return KErrNone;
       
   724         }
       
   725     else
       
   726         {
       
   727         token.Set(iLexer.Remainder());  // pointer to the rest of the xml document
       
   728         
       
   729         while (prologFound || commentFound || piFound || dtdFound)
       
   730             {
       
   731             // check for prolog: if prolog found skip it
       
   732             if (iLexer.Get() == '<' && iLexer.Get() == '?' &&
       
   733                 iLexer.Get() == 'x' && iLexer.Get() == 'm' && iLexer.Get() == 'l')
       
   734                 {
       
   735                 token.Set(iLexer.Remainder());  // pointer to the rest of the xml document
       
   736                 if (token.Find(KEndPIAndProlog) != KErrNotFound)
       
   737                     {
       
   738                     endStringOffset = token.Find(KEndPIAndProlog) + KEndPIAndProlog().Length();
       
   739                     iLexer.Inc(endStringOffset);
       
   740                     iLexer.SkipSpaceAndMark(iMarkPosition);  // Remember where we are
       
   741                     prologFound = ETrue;
       
   742                     }
       
   743                 else
       
   744                     {
       
   745                     iState = EStateError;
       
   746                     return ERcDocumentError; // no end string found
       
   747                     }
       
   748                 }
       
   749             else
       
   750                 {
       
   751                 iLexer.UnGetToMark(iMarkPosition);
       
   752                 prologFound = EFalse;
       
   753                 }
       
   754             
       
   755             // check for comment: if found skip it
       
   756             if (iLexer.Get() == '<' && iLexer.Get() == '!' &&
       
   757                 iLexer.Get() == '-' && iLexer.Get() == '-')
       
   758                 {
       
   759                 token.Set(iLexer.Remainder());  // pointer to the rest of the xml document
       
   760                 if (token.Find(KEndComment) != KErrNotFound)
       
   761                     {
       
   762                     endStringOffset = token.Find(KEndComment) + KEndComment().Length();
       
   763                     iLexer.Inc(endStringOffset);
       
   764                     iLexer.SkipSpaceAndMark(iMarkPosition);  // Remember where we are
       
   765                     commentFound = ETrue;
       
   766                     }
       
   767                 else
       
   768                     {
       
   769                     iState = EStateError;
       
   770                     return ERcDocumentError; // no end string found
       
   771                     }
       
   772                 }
       
   773             else
       
   774                 {
       
   775                 iLexer.UnGetToMark(iMarkPosition);
       
   776                 commentFound = EFalse;
       
   777                 }
       
   778             
       
   779             // check for processing instructions: if found skip it
       
   780             if (iLexer.Get() == '<' && iLexer.Get() == '?')
       
   781                 {
       
   782                 token.Set(iLexer.Remainder());  // pointer to the rest of the xml document
       
   783                 if (token.Find(KEndPIAndProlog) != KErrNotFound)
       
   784                     {
       
   785                     endStringOffset = token.Find(KEndPIAndProlog) + KEndPIAndProlog().Length();
       
   786                     iLexer.Inc(endStringOffset);
       
   787                     iLexer.SkipSpaceAndMark(iMarkPosition);  // Remember where we are
       
   788                     piFound = ETrue;
       
   789                     }
       
   790                 else
       
   791                     {
       
   792                     iState = EStateError;
       
   793                     return ERcDocumentError; // no end string found
       
   794                     }
       
   795                 }
       
   796             else
       
   797                 {
       
   798                 iLexer.UnGetToMark(iMarkPosition);
       
   799                 piFound = EFalse;
       
   800                 }
       
   801             
       
   802             // check for document type declaration: if found skip it
       
   803             if (iLexer.Get() == '<' && iLexer.Get() == '!' &&
       
   804                 iLexer.Get() == 'D' && iLexer.Get() == 'O' &&
       
   805                 iLexer.Get() == 'C' && iLexer.Get() == 'T' &&
       
   806                 iLexer.Get() == 'Y' && iLexer.Get() == 'P' &&
       
   807                 iLexer.Get() == 'E')
       
   808                 {
       
   809                 token.Set(iLexer.Remainder());  // pointer to the rest of the xml document
       
   810                 // if '[' found skip to ']' and then search for '>' (= end of doctype)
       
   811                 if (token.Find(KOpenAngleBracket) != KErrNotFound)
       
   812                     {
       
   813                     iLexer.Inc(token.Find(KOpenAngleBracket)
       
   814                                           + KOpenAngleBracket().Length());
       
   815                     token.Set(iLexer.Remainder());
       
   816                     // Search for ']'
       
   817                     if (token.Find(KCloseAngleBracket) != KErrNotFound)
       
   818                         {
       
   819                         iLexer.Inc(token.Find(KCloseAngleBracket) + KCloseAngleBracket().Length());
       
   820                         token.Set(iLexer.Remainder());
       
   821                         }
       
   822                     else
       
   823                         {
       
   824                         iState = EStateError;
       
   825                         return ERcDocumentError; // no end string found
       
   826                         }
       
   827                     }
       
   828                 if (token.Find(KCloseBracket) != KErrNotFound)
       
   829                     {
       
   830                     endStringOffset = token.Find(KCloseBracket) + KCloseBracket().Length();
       
   831                     iLexer.Inc(endStringOffset);
       
   832                     iLexer.SkipSpaceAndMark(iMarkPosition);  // Remember where we are
       
   833                     dtdFound = ETrue;
       
   834                     }
       
   835                 else
       
   836                     {
       
   837                     iState = EStateError;
       
   838                     return ERcDocumentError; // no end string found
       
   839                     }
       
   840                 }
       
   841             else
       
   842                 {
       
   843                 iLexer.UnGetToMark(iMarkPosition);
       
   844                 dtdFound = EFalse;
       
   845                 }
       
   846             }
       
   847         }
       
   848         return KErrNone;
       
   849     }
       
   850 
       
   851 ////////////////////////////////////////////////////////////////////////////////////////
       
   852 // 
       
   853 ////////////////////////////////////////////////////////////////////////////////////////
       
   854 TInt CXmlPullParser::SkipNonRelevantElements()
       
   855     {
       
   856     TPtrC8 token;
       
   857     TInt endStringOffset;
       
   858     TBool prologFound = ETrue;
       
   859     TBool commentFound = ETrue;
       
   860     TBool piFound = ETrue;
       
   861     TBool dtdFound = ETrue;
       
   862 
       
   863     iLexer.Mark(iMarkPosition);  // Remember where we are
       
   864     
       
   865     if (iLexer.Eos())
       
   866         {
       
   867         iState = EStateEndDocument;
       
   868         return KErrNone;
       
   869         }
       
   870     else
       
   871         {
       
   872         token.Set(iLexer.Remainder());  // pointer to the rest of the xml document
       
   873         
       
   874         while (prologFound || commentFound || piFound || dtdFound)
       
   875             {
       
   876             // check for prolog: if prolog found -> error
       
   877             // Spec says: "The document type declaration must appear before 
       
   878             // the first element in the document."
       
   879             if (iLexer.Get() == '<' && iLexer.Get() == '?' &&
       
   880                 iLexer.Get() == 'x' && iLexer.Get() == 'm' && iLexer.Get() == 'l')
       
   881                 {
       
   882                 prologFound = ETrue;
       
   883                 iState = EStateError;
       
   884                 return ERcDocumentError;
       
   885                 }
       
   886             else
       
   887                 {
       
   888                 iLexer.UnGetToMark(iMarkPosition);
       
   889                 prologFound = EFalse;
       
   890                 }
       
   891             
       
   892             // check for comment: if found skip it
       
   893             if (iLexer.Get() == '<' && iLexer.Get() == '!' &&
       
   894                 iLexer.Get() == '-' && iLexer.Get() == '-')
       
   895                 {
       
   896                 token.Set(iLexer.Remainder());  // pointer to the rest of the xml document
       
   897                 if (token.Find(KEndComment) != KErrNotFound)
       
   898                     {
       
   899                     endStringOffset = token.Find(KEndComment) + KEndComment().Length();
       
   900                     iLexer.Inc(endStringOffset);
       
   901                     iLexer.Mark(iMarkPosition);  // Remember where we are
       
   902                     commentFound = ETrue;
       
   903                     }
       
   904                 else
       
   905                     {
       
   906                     iState = EStateError;
       
   907                     return ERcDocumentError; // no end string found
       
   908                     }
       
   909                 }
       
   910             else
       
   911                 {
       
   912                 iLexer.UnGetToMark(iMarkPosition);
       
   913                 commentFound = EFalse;
       
   914                 }
       
   915             
       
   916             // check for processing instructions: if found skip it
       
   917             if (iLexer.Get() == '<' && iLexer.Get() == '?')
       
   918                 {
       
   919                 token.Set(iLexer.Remainder());  // pointer to the rest of the xml document
       
   920                 if (token.Find(KEndPIAndProlog) != KErrNotFound)
       
   921                     {
       
   922                     endStringOffset = token.Find(KEndPIAndProlog) + KEndPIAndProlog().Length();
       
   923                     iLexer.Inc(endStringOffset);
       
   924                     iLexer.Mark(iMarkPosition);  // Remember where we are
       
   925                     piFound = ETrue;
       
   926                     }
       
   927                 else
       
   928                     {
       
   929                     iState = EStateError;
       
   930                     return ERcDocumentError; // no end string found
       
   931                     }
       
   932                 }
       
   933             else
       
   934                 {
       
   935                 iLexer.UnGetToMark(iMarkPosition);
       
   936                 piFound = EFalse;
       
   937                 }
       
   938             
       
   939             // check for document type declaration: if found skip it
       
   940             if (iLexer.Get() == '<' && iLexer.Get() == '!' &&
       
   941                 iLexer.Get() == 'D' && iLexer.Get() == 'O' &&
       
   942                 iLexer.Get() == 'C' && iLexer.Get() == 'T' &&
       
   943                 iLexer.Get() == 'Y' && iLexer.Get() == 'P' &&
       
   944                 iLexer.Get() == 'E')
       
   945                 {
       
   946                 token.Set(iLexer.Remainder());  // pointer to the rest of the xml document
       
   947                 // if '[' found skip to ']' and then search for '>' (= end of doctype)
       
   948                 if (token.Find(KOpenAngleBracket) != KErrNotFound)
       
   949                     {
       
   950                     iLexer.Inc(token.Find(KOpenAngleBracket)
       
   951                                           + KOpenAngleBracket().Length());
       
   952                     token.Set(iLexer.Remainder());
       
   953                     // Search for ']'
       
   954                     if (token.Find(KCloseAngleBracket) != KErrNotFound)
       
   955                         {
       
   956                         iLexer.Inc(token.Find(KCloseAngleBracket) + KCloseAngleBracket().Length());
       
   957                         token.Set(iLexer.Remainder());
       
   958                         }
       
   959                     else
       
   960                         {
       
   961                         iState = EStateError;
       
   962                         return ERcDocumentError; // no end string found
       
   963                         }
       
   964                     }
       
   965                 if (token.Find(KCloseBracket) != KErrNotFound)
       
   966                     {
       
   967                     endStringOffset = token.Find(KCloseBracket) + KCloseBracket().Length();
       
   968                     iLexer.Inc(endStringOffset);
       
   969                     iLexer.SkipSpaceAndMark(iMarkPosition);  // Remember where we are
       
   970                     dtdFound = ETrue;
       
   971                     }
       
   972                 else
       
   973                     {
       
   974                     iState = EStateError;
       
   975                     return ERcDocumentError; // no end string found
       
   976                     }
       
   977                 
       
   978                 }                   
       
   979             else
       
   980                 {
       
   981                 iLexer.UnGetToMark(iMarkPosition);
       
   982                 dtdFound = EFalse;
       
   983                 }
       
   984             }
       
   985         }
       
   986         return KErrNone;
       
   987     }
       
   988 
       
   989 ////////////////////////////////////////////////////////////////////////////////////////
       
   990 //
       
   991 ////////////////////////////////////////////////////////////////////////////////////////
       
   992 TInt CXmlPullParser::GetElementStartTagL()
       
   993     {
       
   994     TPtrC8 token;
       
   995     TPtrC8 startTag;
       
   996     TInt offset;
       
   997     TInt eqpos;
       
   998     TInt spacepos;
       
   999     TInt attrValueLen;
       
  1000     TLex8 tokenLexer;
       
  1001     TChar ch;
       
  1002 
       
  1003 
       
  1004     iLexer.Mark(iMarkPosition);  // Remember where we are
       
  1005 
       
  1006     if (iLexer.Eos())
       
  1007         {
       
  1008         iState = EStateError;   // we can not be in the end of the doc when 
       
  1009                                 // we should have Start Tag 
       
  1010         return ERcDocumentError;
       
  1011         }
       
  1012     else
       
  1013         {
       
  1014 
       
  1015         // Delete attributes from iCAttrDataArray
       
  1016         iCAttrDataArray->Delete(0, iCAttrDataArray->Count());
       
  1017 
       
  1018 
       
  1019         if (iLexer.Get() == '<' && iLexer.Peek().IsAlpha())
       
  1020             {
       
  1021             iLexer.Mark(iMarkPosition);  // start of the element
       
  1022             token.Set(iLexer.Remainder());
       
  1023             offset = token.Find(KCloseBracket);
       
  1024             
       
  1025             // start tag and possible attribute(s)
       
  1026             startTag.Set(token.Left(offset));
       
  1027             tokenLexer.Assign(startTag);
       
  1028 
       
  1029             // Start tag format: '<' Name (S Attribute)* S?'>'
       
  1030             // tag name -> iElement
       
  1031             if (startTag.Find(KSpace) == KErrNotFound)
       
  1032                 {
       
  1033                 // case: no attributes/space in the start tag
       
  1034                 iElement.Set(startTag.Left(offset));
       
  1035                 if (iElement[iElement.Length() - 1] == '/')
       
  1036                     {
       
  1037                     iElement.Set(iElement.Left(iElement.Length() - 1));
       
  1038                     }
       
  1039                 }
       
  1040             else
       
  1041                 {
       
  1042                 // case: space after tag name or
       
  1043                 // case: at least one attribute in the start tag
       
  1044                 iElement.Set(startTag.Left(startTag.Find(KSpace)));
       
  1045                 }
       
  1046             
       
  1047             // set state
       
  1048             iState = EStateStartTag;
       
  1049 
       
  1050             // Add /tag name to iPathBuf
       
  1051             CheckSpaceL(iElement);  // Check that there is enough space in iPathBuf
       
  1052 
       
  1053             iPathBufPtr.Append(KSlash);  // '/'
       
  1054             iPathBufPtr.Append(iElement);  // tag name
       
  1055 
       
  1056             // increment iDepth
       
  1057             iDepth++;
       
  1058 
       
  1059             while ((eqpos = startTag.Find(KEquals)) != KErrNotFound)
       
  1060                 {
       
  1061                 TAttrData startTagAttr;
       
  1062                 // get attribute(s)
       
  1063                 spacepos = startTag.Find(KSpace);
       
  1064                 tokenLexer.Inc(spacepos);
       
  1065                 startTagAttr.iName.Set(startTag.Mid(spacepos + KSpace().Length(), 
       
  1066                                         eqpos - spacepos - KEquals().Length()));
       
  1067                 // rest of the start tag and attributes
       
  1068                 startTag.Set(startTag.Right(startTag.Length() - eqpos - KEquals().Length()));
       
  1069                 tokenLexer.Inc(eqpos - spacepos + KEquals().Length());
       
  1070                 ch = tokenLexer.Get();
       
  1071                 if (ch == '\'' || ch == '\"')  // this should be ' or "
       
  1072                     {
       
  1073                     startTag.Set(startTag.Right(startTag.Length() - 1));
       
  1074                     // if attribute ending ' or " not found return error
       
  1075                     if ((attrValueLen = startTag.Locate(ch)) != KErrNotFound)
       
  1076                         {
       
  1077                         startTagAttr.iValue.Set(startTag.Left(attrValueLen));
       
  1078                         iCAttrDataArray->AppendL(startTagAttr);
       
  1079                         startTag.Set(startTag.Right(startTag.Length() - attrValueLen));
       
  1080                         tokenLexer.Inc(attrValueLen);
       
  1081                         }
       
  1082                     else
       
  1083                         {
       
  1084                         iState = EStateError;
       
  1085                         return ERcDocumentError;
       
  1086                         }
       
  1087                     }
       
  1088                 else
       
  1089                     {
       
  1090                     iState = EStateError;
       
  1091                     return ERcDocumentError;
       
  1092                     }
       
  1093                 }
       
  1094 
       
  1095             // check if tag is empty element
       
  1096             iLexer.Inc(offset - KCloseBracket().Length());  // iLexer into the end of the tag - 1 position
       
  1097             iLexer.Mark(iMarkPosition);
       
  1098 
       
  1099             if (iLexer.Get() == '/')  // next char is '>' for sure
       
  1100                 {
       
  1101                 iLexer.Inc(KCloseBracket().Length());
       
  1102                 iIsEmptyElement = ETrue;
       
  1103                 iLexer.Mark(iMarkPosition);
       
  1104                 }
       
  1105             else if (iLexer.Get() == '>')
       
  1106                 {
       
  1107                 iIsEmptyElement = EFalse;
       
  1108                 iLexer.Mark(iMarkPosition);
       
  1109                 }
       
  1110             else
       
  1111                 {
       
  1112                 iState = EStateError;
       
  1113                 return ERcDocumentError;
       
  1114                 }
       
  1115             }
       
  1116         else
       
  1117             {
       
  1118             iState = EStateError;
       
  1119             return ERcDocumentError;
       
  1120             }
       
  1121         }
       
  1122     return KErrNone;
       
  1123     }
       
  1124 
       
  1125 ////////////////////////////////////////////////////////////////////////////////////////
       
  1126 //
       
  1127 ////////////////////////////////////////////////////////////////////////////////////////
       
  1128 TInt CXmlPullParser::GetElementText()
       
  1129     {
       
  1130     TPtrC8 elementText;
       
  1131     TInt offset;
       
  1132     TInt cdataStartOffset;
       
  1133     TInt cdataEndOffset;
       
  1134 
       
  1135     iLexer.Mark(iMarkPosition);  // Remember where we are
       
  1136 
       
  1137     if (iLexer.Eos())
       
  1138         {
       
  1139         iState = EStateError;   // we can not be in the end of the doc when 
       
  1140                                 // we should have Start Tag 
       
  1141         return ERcDocumentError;
       
  1142         }
       
  1143     else
       
  1144         {
       
  1145         elementText.Set(iLexer.Remainder());
       
  1146 
       
  1147         if (iCdataStartFound)
       
  1148             {
       
  1149             if ((cdataEndOffset = elementText.Find(KEndCData)) != KErrNotFound)
       
  1150                 {
       
  1151                 iCdataStartFound = EFalse;
       
  1152                 iCdataSectionText = ETrue;  // text inside CDATA section
       
  1153                 iText.Set(elementText.Left(cdataEndOffset));
       
  1154                 if (iText.Find(KStartCData) != KErrNotFound)
       
  1155                     {
       
  1156                     // Nested CDATA sections are not allowed
       
  1157                     iState = EStateError;
       
  1158                     return ERcDocumentError;
       
  1159                     }
       
  1160                 iLexer.Inc(cdataEndOffset + KEndCData().Length());
       
  1161                 }
       
  1162             else
       
  1163                 {
       
  1164                 // CDATA end not found -> error
       
  1165                 iState = EStateError;
       
  1166                 return ERcDocumentError;
       
  1167                 }
       
  1168             }
       
  1169         else
       
  1170             {
       
  1171             // Start of CDATA section '<![CDATA['
       
  1172             if ((cdataStartOffset = elementText.Find(KStartCData)) == 0)
       
  1173                 {
       
  1174                 if ((cdataEndOffset = elementText.Find(KEndCData)) != KErrNotFound)
       
  1175                     {
       
  1176                     iCdataStartFound = EFalse;
       
  1177                     iCdataSectionText = ETrue;  // text inside CDATA section
       
  1178                     iText.Set(elementText.Mid(KStartCData().Length(), cdataEndOffset - KStartCData().Length()));
       
  1179                     if (iText.Find(KStartCData) != KErrNotFound)
       
  1180                         {
       
  1181                         // Nested CDATA sections are not allowed
       
  1182                         iState = EStateError;
       
  1183                         return ERcDocumentError;
       
  1184                         }
       
  1185                     iLexer.Inc(cdataEndOffset + KEndCData().Length());
       
  1186                     }
       
  1187                 else
       
  1188                     {
       
  1189                     // CDATA end not found -> error
       
  1190                     iState = EStateError;
       
  1191                     return ERcDocumentError;
       
  1192                     }
       
  1193                 }
       
  1194             else
       
  1195                 {
       
  1196                 offset = elementText.Find(KOpenBracket);  // any '<'
       
  1197                 
       
  1198                 if ((cdataStartOffset != KErrNotFound) && !(offset < cdataStartOffset))
       
  1199                     {
       
  1200                     iCdataStartFound = ETrue;
       
  1201                     iCdataSectionText = EFalse;  // text before CDATA section
       
  1202                     iText.Set(elementText.Left(cdataStartOffset)); 
       
  1203                     iLexer.Inc(cdataStartOffset + KStartCData().Length());
       
  1204                     }
       
  1205                 else
       
  1206                     {
       
  1207                     // No CDATA section found
       
  1208                     // iCdataStartFound = EFalse; // this is EFalse any way
       
  1209                     iCdataSectionText = EFalse;
       
  1210                     if (offset != KErrNotFound)
       
  1211                         {
       
  1212                         iText.Set(elementText.Left(offset));
       
  1213                         iLexer.Inc(offset);
       
  1214                         }
       
  1215                     else
       
  1216                         {
       
  1217                         iState = EStateError;
       
  1218                         return ERcDocumentError;
       
  1219                         }
       
  1220                     }
       
  1221                 }
       
  1222             }
       
  1223         iState = EStateText;
       
  1224         return KErrNone;
       
  1225         }
       
  1226     }
       
  1227 
       
  1228 ////////////////////////////////////////////////////////////////////////////////////////
       
  1229 //
       
  1230 ////////////////////////////////////////////////////////////////////////////////////////
       
  1231 TBool CXmlPullParser::CheckIfNextEndTag()
       
  1232     {
       
  1233     iLexer.Mark(iMarkPosition);
       
  1234 
       
  1235     if (iLexer.Eos())
       
  1236         {
       
  1237         iState = EStateError;   // we can not be in the end of the doc when 
       
  1238                                 // we should have Start/End Tag 
       
  1239         return ETrue;  // the caller must check the iState!!
       
  1240         }
       
  1241     else
       
  1242         {
       
  1243         if (iLexer.Get() == '<' && iLexer.Get() == '/')
       
  1244             {
       
  1245             iLexer.UnGetToMark(iMarkPosition);
       
  1246             return ETrue;
       
  1247             }
       
  1248         else
       
  1249             {
       
  1250             iLexer.UnGetToMark(iMarkPosition);
       
  1251             return EFalse;
       
  1252             }
       
  1253         }
       
  1254     }
       
  1255 
       
  1256 ////////////////////////////////////////////////////////////////////////////////////////
       
  1257 //
       
  1258 ////////////////////////////////////////////////////////////////////////////////////////
       
  1259 TBool CXmlPullParser::CheckIfNextStartTag()
       
  1260     {
       
  1261     iLexer.Mark(iMarkPosition);
       
  1262 
       
  1263     if (iLexer.Eos())
       
  1264         {
       
  1265         iState = EStateError;   // we can not be in the end of the doc when 
       
  1266                                 // we should have Start/End Tag 
       
  1267         return ETrue;  // the caller must check the iState!!
       
  1268         }
       
  1269     else
       
  1270         {
       
  1271         if (iLexer.Get() == '<' && iLexer.Get().IsAlpha())
       
  1272             {
       
  1273             iLexer.UnGetToMark(iMarkPosition);
       
  1274             return ETrue;
       
  1275             }
       
  1276         else
       
  1277             {
       
  1278             iLexer.UnGetToMark(iMarkPosition);
       
  1279             return EFalse;
       
  1280             }
       
  1281         }
       
  1282     }
       
  1283 
       
  1284 
       
  1285 ////////////////////////////////////////////////////////////////////////////////////////
       
  1286 //
       
  1287 ////////////////////////////////////////////////////////////////////////////////////////
       
  1288 TInt CXmlPullParser::GetElementEndTag()
       
  1289     {
       
  1290     TPtrC8 elementText;
       
  1291     TInt offset;
       
  1292 
       
  1293     iLexer.Mark(iMarkPosition);  // Remember where we are
       
  1294 
       
  1295     if (iLexer.Eos())
       
  1296         {
       
  1297         iState = EStateError;   // we can not be in the end of the doc when 
       
  1298                                 // we should have End Tag 
       
  1299         return ERcDocumentError;
       
  1300         }
       
  1301     else
       
  1302         {
       
  1303         if (iLexer.Get() == '<' && iLexer.Get() == '/')
       
  1304             {
       
  1305             elementText.Set(iLexer.Remainder());
       
  1306             if ((offset = elementText.Find(KCloseBracket)) != KErrNotFound)
       
  1307                 {
       
  1308                 // End tag format: '</' Name S? '>'
       
  1309                 iElement.Set(elementText.Left(offset));
       
  1310                 if (iElement[iElement.Length() - 1] == ' ')
       
  1311                     {
       
  1312                     iElement.Set(iElement.Left(iElement.Length() - 1));
       
  1313                     }
       
  1314 
       
  1315                 // delete /end tag from the iPathBuf
       
  1316                 // this is done by subtracting the length of the buffer
       
  1317                 iPathBufPtr.SetLength(iPathBufPtr.LocateReverse('/'));
       
  1318 
       
  1319                 // decrement iDepth
       
  1320                 iDepth--;
       
  1321 
       
  1322                 iLexer.Inc(offset + KCloseBracket().Length());
       
  1323                 iState = EStateEndTag;
       
  1324                 return KErrNone;
       
  1325                 }
       
  1326             else
       
  1327                 {
       
  1328                 iState = EStateError;
       
  1329                 return ERcDocumentError;
       
  1330                 }
       
  1331             }
       
  1332         else
       
  1333             {
       
  1334             iState = EStateError;
       
  1335             return ERcDocumentError;
       
  1336             }
       
  1337         }
       
  1338     }
       
  1339 
       
  1340 ////////////////////////////////////////////////////////////////////////////////////////
       
  1341 //
       
  1342 ////////////////////////////////////////////////////////////////////////////////////////
       
  1343 TBool CXmlPullParser::CheckIfEndOfFile()
       
  1344     {
       
  1345     iLexer.Mark(iMarkPosition);
       
  1346 
       
  1347     if ( (iDepth == 0) && (iPathBufPtr.Length() == 0) )
       
  1348         {
       
  1349         iState = EStateEndDocument;
       
  1350         return ETrue;
       
  1351         }
       
  1352     else
       
  1353         {
       
  1354         return EFalse;
       
  1355         }
       
  1356     }
       
  1357 
       
  1358 ////////////////////////////////////////////////////////////////////////////////////////
       
  1359 // 
       
  1360 ////////////////////////////////////////////////////////////////////////////////////////
       
  1361 TInt CXmlPullParser::EscapeCharRefAndPreDefEntities()
       
  1362     {
       
  1363     TInt retVal;
       
  1364 
       
  1365     if (iStringValuePtr.Find(KAmpersandHash) != KErrNotFound)
       
  1366         {
       
  1367         retVal = CharacterReferencesEscaped();  // handle &#xaa; and &#aa;
       
  1368         if ( retVal != KErrNone )
       
  1369             {
       
  1370             return retVal;
       
  1371             }
       
  1372         }
       
  1373     
       
  1374     if (iStringValuePtr.Find(KAmpersand) != KErrNotFound)
       
  1375         {
       
  1376         retVal = PredefinedEntitiesEscaped();  // handle &lt; &gt; &amp; &apos; and &quot;
       
  1377         if ( retVal != KErrNone )
       
  1378             {
       
  1379             return retVal;
       
  1380             }
       
  1381         }
       
  1382 
       
  1383     return KErrNone;
       
  1384     }
       
  1385 
       
  1386 ////////////////////////////////////////////////////////////////////////////////////////
       
  1387 //
       
  1388 ////////////////////////////////////////////////////////////////////////////////////////
       
  1389 TInt CXmlPullParser::CharacterReferencesEscaped()
       
  1390     {
       
  1391     TInt startPos, length;
       
  1392     TInt retVal;
       
  1393     TInt i = 0;
       
  1394     TRadix radix = EDecimal;
       
  1395     
       
  1396     TLex8 tempLexer;
       
  1397     TLexMark8 mark;
       
  1398     TUint number;
       
  1399 
       
  1400     TPtrC8 tempPtr;
       
  1401    
       
  1402     while ( (startPos = iStringValuePtr.Find(KAmpersandHash)) != KErrNotFound)
       
  1403         {
       
  1404         tempPtr.Set(iStringValuePtr.Right(iStringValuePtr.Length() - startPos));
       
  1405         length = tempPtr.Find(KSemicolon) - KAmpersandHash().Length();
       
  1406         tempPtr.Set(iStringValuePtr.Mid(startPos + KAmpersandHash().Length(), length));
       
  1407         tempLexer.Assign(tempPtr);
       
  1408         if ( tempLexer.Peek() == 'x' )
       
  1409             {
       
  1410             tempLexer.Inc();  //increment to next character position
       
  1411             tempLexer.Mark(mark);
       
  1412             for ( i = 0; i < (length - 1); i++ )  // check that whole input is hexadecimal
       
  1413                 {
       
  1414                 if ( !(tempLexer.Get()).IsHexDigit() )
       
  1415                     {
       
  1416                     return ERcDocumentError;  // after &#x there must be hexadecimal digits (0-9, a-f, A-F).
       
  1417                     }
       
  1418                 }
       
  1419             tempLexer.UnGetToMark(mark);
       
  1420             radix = EHex;
       
  1421             }
       
  1422         else 
       
  1423             {
       
  1424             tempLexer.Mark(mark);
       
  1425             for ( i = 0; i < length; i++ )
       
  1426                 {
       
  1427                 if ( !(tempLexer.Get()).IsDigit() )
       
  1428                     {
       
  1429                     return ERcDocumentError; // after &# there must be standard decimal digits (0-9).
       
  1430                     }
       
  1431                 }
       
  1432             tempLexer.UnGetToMark(mark);
       
  1433             radix = EDecimal;
       
  1434             }
       
  1435 
       
  1436         if ( (retVal = tempLexer.Val(number, radix)) == KErrNone)
       
  1437             {
       
  1438             TChar ch(number);
       
  1439             TBuf8<12> buf;
       
  1440             buf.Append(ch);
       
  1441             iStringValuePtr.Replace(startPos, length + KAmpersandHash().Length() + 
       
  1442                 KSemicolon().Length(), buf);
       
  1443             }
       
  1444         else
       
  1445             {
       
  1446             return retVal;
       
  1447             }
       
  1448         }
       
  1449     return KErrNone;
       
  1450     }
       
  1451 
       
  1452 ////////////////////////////////////////////////////////////////////////////////////////
       
  1453 //
       
  1454 ////////////////////////////////////////////////////////////////////////////////////////
       
  1455 TInt CXmlPullParser::PredefinedEntitiesEscaped()
       
  1456     {
       
  1457     TInt pos;
       
  1458    
       
  1459     while (iStringValuePtr.Find(KAmpersand) != KErrNotFound)
       
  1460         {
       
  1461         if ((pos = iStringValuePtr.Find(KEntityLowerThan)) != KErrNotFound)
       
  1462             {
       
  1463             iStringValuePtr.Replace(pos, KEntityLowerThan().Length(), KOpenBracket);
       
  1464             }
       
  1465         else if ((pos = iStringValuePtr.Find(KEntityGreaterThan)) != KErrNotFound)
       
  1466             {
       
  1467             iStringValuePtr.Replace(pos, KEntityGreaterThan().Length(), KCloseBracket);
       
  1468             }
       
  1469         else if ((pos = iStringValuePtr.Find(KEntityAmpersand)) != KErrNotFound)
       
  1470             {
       
  1471             iStringValuePtr.Replace(pos, KEntityAmpersand().Length(), KAmpersand);
       
  1472             }
       
  1473         else if ((pos = iStringValuePtr.Find(KEntityApostrophe)) != KErrNotFound)
       
  1474             {
       
  1475             iStringValuePtr.Replace(pos, KEntityApostrophe().Length(), KSingleQuote);
       
  1476             }
       
  1477         else if ((pos = iStringValuePtr.Find(KEntityQuotation)) != KErrNotFound)
       
  1478             {
       
  1479             iStringValuePtr.Replace(pos, KEntityQuotation().Length(), KDoubleQuote);
       
  1480             }
       
  1481         else
       
  1482             {
       
  1483             return KErrNone;
       
  1484             }
       
  1485         }
       
  1486     return KErrNone;
       
  1487     }