webservices/wsxml/src/senxmlreader.cpp
changeset 0 62f9d29f7211
equal deleted inserted replaced
-1:000000000000 0:62f9d29f7211
       
     1 /*
       
     2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:        
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 // INCLUDE FILES
       
    26 #include <xml/attribute.h> // From syslibs, needed for RAttributeArray
       
    27 
       
    28 #include <SenXmlReader.h>
       
    29 #include <SenXmlConstants.h>
       
    30 #include <SenXmlUtils.h>
       
    31 #include <MSenContentHandlerClient.h>
       
    32 #include "senxmldebug.h"
       
    33 
       
    34 #ifdef EKA2
       
    35     #ifndef __SERIES60_30__
       
    36         // S60 3.1 or newer
       
    37         #include <xml/matchdata.h>
       
    38     #endif
       
    39 #else
       
    40     // Use fss with S60 2nd edition FP3 (2.8) - temp file is needed with expat
       
    41     #include <s32file.h> // filestream
       
    42 #endif
       
    43 
       
    44 // DEBUG:
       
    45 #include "sendebug.h"
       
    46 
       
    47 using namespace Xml;
       
    48 
       
    49 namespace
       
    50     {
       
    51     const TInt KArraySize = 128;
       
    52     
       
    53     typedef struct
       
    54         {
       
    55         CSenXmlReader*  ipReader;
       
    56         TInt            iEnabledFeature;
       
    57         } TReaderData;
       
    58     }
       
    59     
       
    60 _LIT8(KDefaultMimeType, "");  // Expat is made default, so don't have to give mime type
       
    61 
       
    62 EXPORT_C CSenXmlReader* CSenXmlReader::NewL()
       
    63     {
       
    64     CSenXmlReader* pNew = NewLC();
       
    65     CleanupStack::Pop();
       
    66     return pNew;
       
    67     }
       
    68 
       
    69 EXPORT_C CSenXmlReader* CSenXmlReader::NewLC()
       
    70     {
       
    71     
       
    72     CSenXmlReader* pNew = new (ELeave) CSenXmlReader(KSenDefaultParserFeature);
       
    73     CleanupStack::PushL(pNew);
       
    74     
       
    75     pNew->ConstructL(KDefaultMimeType);// KXmlParserMimeType : Defaulted to Expat
       
    76     return pNew;
       
    77     }
       
    78 
       
    79 EXPORT_C CSenXmlReader* CSenXmlReader::NewL(TInt aParserFeature)
       
    80     {
       
    81     CSenXmlReader* pNew = NewLC(aParserFeature);
       
    82     CleanupStack::Pop();
       
    83     return pNew;
       
    84     }
       
    85 
       
    86 EXPORT_C CSenXmlReader* CSenXmlReader::NewLC(TInt aParserFeature)
       
    87     {
       
    88     CSenXmlReader* pNew = new (ELeave) CSenXmlReader(aParserFeature);
       
    89     CleanupStack::PushL(pNew);
       
    90     pNew->ConstructL(KDefaultMimeType);// KXmlParserMimeType : Defaulted to Expat
       
    91     if(aParserFeature<0)
       
    92         {
       
    93         User::Leave(KErrArgument);
       
    94         }
       
    95     return pNew;
       
    96     }
       
    97 
       
    98 EXPORT_C CSenXmlReader* CSenXmlReader::NewL(const TDesC8& aParserMimeType)
       
    99     {
       
   100     CSenXmlReader* pNew = NewLC(aParserMimeType);
       
   101     CleanupStack::Pop();
       
   102     return pNew;
       
   103     }
       
   104 
       
   105 EXPORT_C CSenXmlReader* CSenXmlReader::NewLC(const TDesC8& aParserMimeType)
       
   106     {
       
   107     CSenXmlReader* pNew = new (ELeave) CSenXmlReader(KSenDefaultParserFeature);
       
   108     CleanupStack::PushL(pNew);
       
   109     pNew->ConstructL(aParserMimeType);
       
   110     return pNew;
       
   111     }
       
   112 
       
   113 EXPORT_C CSenXmlReader* CSenXmlReader::NewL(const TDesC8& aParserMimeType,
       
   114                                             TInt aParserFeature)
       
   115     {
       
   116     CSenXmlReader* pNew = NewLC(aParserMimeType, aParserFeature);
       
   117     CleanupStack::Pop();
       
   118     return pNew;
       
   119     }
       
   120 
       
   121 EXPORT_C CSenXmlReader* CSenXmlReader::NewLC(const TDesC8& aParserMimeType,
       
   122                                              TInt aParserFeature)
       
   123     {
       
   124     CSenXmlReader* pNew = new (ELeave) CSenXmlReader(aParserFeature);
       
   125     CleanupStack::PushL(pNew);
       
   126     pNew->ConstructL(aParserMimeType);
       
   127     if(aParserFeature<0)
       
   128         {
       
   129         User::Leave(KErrArgument);
       
   130         }
       
   131     return pNew;
       
   132     }
       
   133 
       
   134 EXPORT_C CSenXmlReader::CSenXmlReader(TInt aEnabledFeature)
       
   135 :
       
   136 iParser(NULL),
       
   137 iContentHandler(NULL),
       
   138 ipNsPrefixes(NULL),
       
   139 ipNsUris(NULL),
       
   140 iEnabledFeature(aEnabledFeature)
       
   141     {
       
   142     }
       
   143 
       
   144 EXPORT_C CSenXmlReader::~CSenXmlReader()
       
   145     {
       
   146     delete iParser;
       
   147     delete ipNsPrefixes;
       
   148     delete ipNsUris;
       
   149     iStringPool.Close();
       
   150     }
       
   151 
       
   152 #if defined( __SERIES60_30__ )
       
   153 void CSenXmlReader::ConstructL(const TDesC8& aParserMimeType)
       
   154     {
       
   155     if(aParserMimeType.Length()==0)
       
   156         {
       
   157         // Use default MIME type
       
   158         iParser = CParser::NewL(KXmlParserMimeType, *this);
       
   159         }
       
   160     else
       
   161         {
       
   162         // Pass aParserMimeType
       
   163         iParser = CParser::NewL(aParserMimeType, *this);
       
   164         }
       
   165     iParser->EnableFeature(iEnabledFeature);
       
   166     iStringPool.OpenL();
       
   167     }
       
   168 #else
       
   169 void CSenXmlReader::ConstructL(const TDesC8& aParserMimeType)
       
   170     {
       
   171     CMatchData* pMatchData = CMatchData::NewL();
       
   172     CleanupStack::PushL(pMatchData);
       
   173     
       
   174     if(aParserMimeType.Length()==0)
       
   175         {
       
   176         // Use default MIME type and variant
       
   177         // for this parser instance (text/xml)
       
   178         pMatchData->SetMimeTypeL(KXmlParserMimeType);
       
   179         }
       
   180     else
       
   181         {
       
   182         // Use specified aParserMimeType:
       
   183         pMatchData->SetMimeTypeL(aParserMimeType);
       
   184 	    
       
   185 	    // Set the default variant type (libxml2)
       
   186 		pMatchData->SetVariantL(KXmlVariant);             
       
   187         }
       
   188     
       
   189     iParser = CParser::NewL(*pMatchData, *this);
       
   190     CleanupStack::PopAndDestroy(pMatchData);
       
   191 
       
   192     iParser->EnableFeature(iEnabledFeature);
       
   193     iStringPool.OpenL();
       
   194     }
       
   195 #endif
       
   196 
       
   197 EXPORT_C void CSenXmlReader::SetContentHandler(
       
   198                                     MSenContentHandlerClient& aContentHandler)
       
   199     {
       
   200     iContentHandler = &aContentHandler;
       
   201     }
       
   202 
       
   203 #ifdef EKA2 
       
   204 // In S60 3rd edition platform there is a fixed version of expat parser which
       
   205 // can parse XML documents which size is 2048 bytes or greater. The previous 
       
   206 // versions crashed with larger documents.
       
   207 EXPORT_C void CSenXmlReader::ParseL(const TDesC8& aBuff)
       
   208     {
       
   209     CleanUp();
       
   210 
       
   211 #if defined(__SERIES60_30__)
       
   212     RecreateParserL();
       
   213 #endif // __SERIES_30__ defined
       
   214 
       
   215     // Note(!): Store the currently enabled feature, since the same member
       
   216     // is used to carry a possible error code from OnErrorL() callback:
       
   217     TInt feature(iEnabledFeature);
       
   218 
       
   219     TReaderData* pData = new (ELeave) TReaderData;
       
   220     pData->ipReader         = this;
       
   221     pData->iEnabledFeature  = iEnabledFeature;
       
   222     CleanupStack::PushL( TCleanupItem( CSenXmlReader::CleanupParser, pData ) );
       
   223     // Parse the XML document:
       
   224     iParser->ParseL(aBuff);
       
   225     CleanupStack::Pop();
       
   226     delete pData;
       
   227 
       
   228     iParser->ParseEndL(); // Enables Symbian XML framework errors to propagete OnErrorL() callback
       
   229 
       
   230     CleanUp();
       
   231 
       
   232     // Check if iEnabledFeature member was used to carry an error from OnErrorL() callback..
       
   233     if (iEnabledFeature < 0)
       
   234         {
       
   235         TInt error(iEnabledFeature);
       
   236         SENDEBUG((_L("CSenXmlReader::ParserL: leaving (%d)"), error));
       
   237         // Switch back the originally enabled feature
       
   238         iEnabledFeature = feature;
       
   239         User::Leave(error);
       
   240         }
       
   241     iContentHandler->EndDocument();
       
   242     }
       
   243 #else 
       
   244 EXPORT_C void CSenXmlReader::ParseL(const TDesC8& aBuff)
       
   245     {
       
   246     // In S60 2nd edition FP3 (2.8) platform a temp file has to be used, since the
       
   247     // underlying expat parser would crash when parsing a document which consists 
       
   248     // of more that 2048 bytes of XML.
       
   249 
       
   250     if (aBuff.Length() > 2048) // there is 2048 bytes limitation in expat parser!
       
   251         {
       
   252         SENDEBUG_L("CSenXmlReader::ParseL(): parsing over 2048 bytes of XML (EKA1)");
       
   253         SENDEBUG((_L("- document size: %d bytes."), aBuff.Length() ));
       
   254 
       
   255         // Parse large XML documents using file server
       
   256         RFs fss;
       
   257         User::LeaveIfError(fss.Connect());
       
   258         CleanupClosePushL(fss);
       
   259 
       
   260         // Now create a new temp file in the specified path using unique 
       
   261         // file name which is generated by the file server. Since file 
       
   262         // server is not responsible to delete this file, it must be done 
       
   263         // after parsing is finished.
       
   264 
       
   265         // Path for temp file
       
   266         _LIT(KFilePath, "c:\\");
       
   267 
       
   268         // Stores the temp file name when fileOutStream.Temp() returns:
       
   269         TFileName tempFilename; 
       
   270     
       
   271         // Try to generate new temporary file, leave if it failes:
       
   272         RFileWriteStream fileOutStream;
       
   273         User::LeaveIfError(fileOutStream.Temp(fss, KFilePath, tempFilename, EFileWrite));
       
   274         CleanupClosePushL(fileOutStream);
       
   275         SENDEBUG((_L("CSenXmlReader::ParseL(): used temp file name: '%S'"), &tempFilename));
       
   276 
       
   277         // Write XML document into the file:
       
   278         fileOutStream.WriteL(aBuff);
       
   279 
       
   280         // fileOutStream.Close(). Must be done prior ParseL()!
       
   281         CleanupStack::PopAndDestroy(); 
       
   282 
       
   283         // Parse the file:
       
   284         ParseL(fss, tempFilename);
       
   285 
       
   286         // Now delete the temporary file (when it is not in locked in parser's use)
       
   287         fss.Delete(tempFilename);
       
   288 
       
   289         // Finally close the file server session
       
   290         CleanupStack::PopAndDestroy(); // fss.Close()
       
   291         SENDEBUG_L("CSenXmlReader::ParseL() successfully parsed > 2048 bytes of XML.");
       
   292         }
       
   293     else
       
   294         {
       
   295         // Smaller documents may be parsed normally, even with older versions
       
   296         // of Symbian XML framework's expat parser.
       
   297         
       
   298         CleanUp();
       
   299         
       
   300 #if defined(__SERIES60_30__)
       
   301     RecreateParserL();
       
   302 #endif // __SERIES_30__ defined
       
   303 
       
   304         TInt feature(iEnabledFeature);
       
   305 
       
   306         TReaderData* pData = new (ELeave) TReaderData;
       
   307         pData->ipReader         = this;
       
   308         pData->iEnabledFeature  = iEnabledFeature;
       
   309         CleanupStack::PushL( TCleanupItem( CSenXmlReader::CleanupParser, pData ) );
       
   310         // Parse the XML document:
       
   311         iParser->ParseL(aBuff);
       
   312         CleanupStack::Pop();
       
   313         delete pData;
       
   314         
       
   315         iParser->ParseEndL(); // Enables Symbian XML framework errors to propagete OnErrorL() callback
       
   316 
       
   317         CleanUp();
       
   318 
       
   319         if (iEnabledFeature < 0) 
       
   320             {
       
   321             TInt error(iEnabledFeature);
       
   322             iEnabledFeature = feature;
       
   323             SENDEBUG((_L("CSenXmlReader::ParserL: leaving (%d)"), iEnabledFeature));
       
   324             User::Leave(error);
       
   325             }
       
   326             
       
   327         iContentHandler->EndDocument();
       
   328         }
       
   329     }
       
   330 #endif // not EKA2 
       
   331 
       
   332 
       
   333 EXPORT_C void CSenXmlReader::ParseL(RFs &aRFs, const TDesC& aFileToParse)
       
   334     {
       
   335     CleanUp();
       
   336 
       
   337 #if defined(__SERIES60_30__)
       
   338     RecreateParserL();
       
   339 #endif // __SERIES_30__ defined
       
   340     
       
   341     TInt feature(iEnabledFeature);
       
   342 
       
   343     TReaderData* pData = new (ELeave) TReaderData;
       
   344     pData->ipReader         = this;
       
   345     pData->iEnabledFeature  = iEnabledFeature;
       
   346     CleanupStack::PushL( TCleanupItem( CSenXmlReader::CleanupParser, pData ) );
       
   347     // Parse the XML document:
       
   348     Xml::ParseL(*iParser, aRFs, aFileToParse); 
       
   349     // Note: Xml::ParseL calls ParseL() and ParseEndL() internally:
       
   350     CleanupStack::Pop();
       
   351     delete pData;
       
   352     
       
   353     CleanUp();
       
   354 
       
   355     if(iEnabledFeature < 0) 
       
   356         {
       
   357         TInt leaveError = iEnabledFeature;
       
   358         iEnabledFeature = feature;
       
   359         User::Leave(leaveError);
       
   360         }
       
   361         
       
   362     iContentHandler->EndDocument();
       
   363     }
       
   364 
       
   365 // protected helper
       
   366 void CSenXmlReader::RecreateParserL()
       
   367     {
       
   368     delete iParser;
       
   369     iParser = NULL;
       
   370 
       
   371     delete ipNsPrefixes;
       
   372     ipNsPrefixes = NULL;
       
   373     delete ipNsUris;
       
   374     ipNsUris = NULL;
       
   375 
       
   376 #if defined(__SERIES60_30__)
       
   377     // Use default MIME type
       
   378     iParser = CParser::NewL(KXmlParserMimeType, *this);
       
   379 #else
       
   380     CMatchData* pMatchData = CMatchData::NewL();
       
   381     CleanupStack::PushL(pMatchData);
       
   382     
       
   383     pMatchData->SetMimeTypeL(KXmlParserMimeType);
       
   384     pMatchData->SetVariantL(KXmlVariant);
       
   385 
       
   386     iParser = CParser::NewL(*pMatchData, *this);
       
   387     CleanupStack::PopAndDestroy(pMatchData);
       
   388 #endif
       
   389 
       
   390     iParser->EnableFeature(iEnabledFeature);
       
   391     }
       
   392 
       
   393 void CSenXmlReader::OnStartDocumentL(
       
   394                                 const RDocumentParameters& /* aDocParam */,
       
   395                                 TInt /* aErrorCode */)
       
   396     {
       
   397     if(!iContentHandler)
       
   398         {
       
   399         SENDEBUG_L("OnStartDocumentL: KErrSenXmlContentHandlerNotSet");
       
   400         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   401         }
       
   402     iContentHandler->StartDocument();
       
   403     }
       
   404 
       
   405 void CSenXmlReader::OnEndDocumentL(TInt /* aErrorCode */)
       
   406     {
       
   407     if(!iContentHandler)
       
   408         {
       
   409         SENDEBUG_L("OnEndDocumentL: KErrSenXmlContentHandlerNotSet");
       
   410         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   411         }
       
   412     iContentHandler->EndDocument();
       
   413     }
       
   414 
       
   415 
       
   416 void CSenXmlReader::OnStartElementL(const RTagInfo& aElement,
       
   417                              const RAttributeArray& aAttributes,
       
   418                              TInt /* aErrorCode */)
       
   419     {
       
   420     if(!iContentHandler)
       
   421         {
       
   422         SENDEBUG_L("OnStartElementL: KErrSenXmlContentHandlerNotSet");
       
   423         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   424         }
       
   425 
       
   426 
       
   427     const TPtrC8 localName = aElement.LocalName().DesC();
       
   428     const TPtrC8 nsUri = aElement.Uri().DesC();
       
   429     const TPtrC8 prefix = aElement.Prefix().DesC();
       
   430 
       
   431     TPtrC8 qualifiedName = localName;
       
   432 
       
   433     if (prefix != KNullDesC8)
       
   434         {
       
   435         HBufC8* pQName = HBufC8::NewLC(prefix.Length()+localName.Length()+
       
   436                                         KSenColon().Length());
       
   437         TPtr8 qName = pQName->Des();
       
   438         qName.Append(prefix);
       
   439         qName.Append(KSenColon);
       
   440         qName.Append(localName);
       
   441         qualifiedName.Set(qName);
       
   442         }
       
   443 
       
   444     if(ipNsPrefixes)
       
   445         {
       
   446         // there are namespaces to declare!
       
   447 
       
   448         // make a new array for all attributes including namespace (to be added)
       
   449         RAttributeArray attributesAndNamespaces;
       
   450 
       
   451         CleanupClosePushL(attributesAndNamespaces);
       
   452         TInt nsDeclarationCount(ipNsPrefixes->Count());
       
   453         for(TInt i=0; i<nsDeclarationCount; i++)
       
   454             {
       
   455             // open and take ownership of RString - xmlnsAttrPrefix
       
   456             RAttribute nsAttribute;
       
   457             //CleanupClosePushL(nsAttribute);
       
   458 
       
   459             TPtrC8 nsPrefix = ipNsPrefixes->MdcaPoint(i);
       
   460             TPtrC8 nsURI =  ipNsUris->MdcaPoint(i);
       
   461 
       
   462             if (nsPrefix != KNullDesC8)
       
   463                 {
       
   464                 nsAttribute.Open(iStringPool.OpenStringL(nsURI), 
       
   465                                 iStringPool.OpenStringL(KSenXmlns()),
       
   466                                 iStringPool.OpenStringL(nsPrefix),
       
   467                                 iStringPool.OpenStringL(nsURI) );
       
   468 
       
   469                 }
       
   470             else
       
   471                 {
       
   472                 nsAttribute.Open(iStringPool.OpenStringL(nsURI),
       
   473                             iStringPool.OpenStringL(KNullDesC8()),
       
   474                             iStringPool.OpenStringL(KSenXmlns()),
       
   475                             iStringPool.OpenStringL(nsURI) );
       
   476 
       
   477                 }   
       
   478 
       
   479 
       
   480             // append the namespace attribute (declaration)
       
   481             CleanupClosePushL(nsAttribute);
       
   482             attributesAndNamespaces.AppendL(nsAttribute);
       
   483             CleanupStack::Pop(); // nsAttribute
       
   484             }
       
   485 
       
   486         // the ns declarations have been done using NON-CANONIZING method
       
   487         delete ipNsPrefixes;
       
   488         ipNsPrefixes = NULL;
       
   489         delete ipNsUris;
       
   490         ipNsUris = NULL;
       
   491 
       
   492 
       
   493 
       
   494         // append all other ("real") attributes
       
   495         TInt count(aAttributes.Count());
       
   496         for(TInt a=0; a<count; a++)
       
   497             {
       
   498             attributesAndNamespaces.AppendL(const_cast <RAttribute&> (aAttributes[a]).Copy());
       
   499             }
       
   500 
       
   501 
       
   502         // now give the stream content forward to the interested handler object.
       
   503         // we have successfully added the namespace declaration as NON-canonized(!)
       
   504         // attribute (if conditions have been met).
       
   505         iContentHandler->StartElement(nsUri, localName, qualifiedName, attributesAndNamespaces);
       
   506 
       
   507         // close the copied attributes previously added into this array as copies
       
   508         count = attributesAndNamespaces.Count();
       
   509         for(TInt j=0; j<count; j++)
       
   510             {
       
   511             attributesAndNamespaces[j].Close();
       
   512             }
       
   513         // close the actual array
       
   514         CleanupStack::PopAndDestroy(); // attributesAndNamespaces.Close();
       
   515         }
       
   516     else
       
   517         {
       
   518         // give the original attributes to content handler (no new namespaces declared in attrs)
       
   519         iContentHandler->StartElement(nsUri, localName, qualifiedName, aAttributes);
       
   520         }
       
   521     
       
   522 
       
   523     // delete qualified element name, if one was allocated
       
   524     if (prefix != KNullDesC8)
       
   525         {
       
   526         CleanupStack::PopAndDestroy(); // pQName
       
   527         }
       
   528 
       
   529 
       
   530     }
       
   531 
       
   532 
       
   533 
       
   534 void CSenXmlReader::OnEndElementL(const RTagInfo& aElement, TInt /* aErrorCode */)
       
   535     {
       
   536     if(!iContentHandler)
       
   537         {
       
   538         SENDEBUG_L("OnEndElementL: KErrSenXmlContentHandlerNotSet");
       
   539         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   540         }
       
   541 
       
   542 
       
   543     const TPtrC8 localName = aElement.LocalName().DesC();
       
   544     const TPtrC8 nsUri = aElement.Uri().DesC();
       
   545     const TPtrC8 prefix = aElement.Prefix().DesC();
       
   546 
       
   547     TPtrC8 qualifiedName = localName;
       
   548 
       
   549     if (prefix != KNullDesC8)
       
   550         {
       
   551         HBufC8* pQName = HBufC8::NewLC(prefix.Length()+localName.Length()+
       
   552                                         KSenColon().Length());
       
   553         TPtr8 qName = pQName->Des();
       
   554         qName.Append(prefix);
       
   555         qName.Append(KSenColon);
       
   556         qName.Append(localName);
       
   557         qualifiedName.Set(qName);
       
   558         }
       
   559 
       
   560 
       
   561     iContentHandler->EndElement(nsUri,
       
   562                                 localName,
       
   563                                 qualifiedName);
       
   564 
       
   565     if (prefix != KNullDesC8)
       
   566         {
       
   567         CleanupStack::PopAndDestroy(); // pQName
       
   568         }
       
   569 
       
   570     }
       
   571 
       
   572 
       
   573 void CSenXmlReader::OnContentL(const TDesC8& aBytes, TInt /* aErrorCode */)
       
   574     {
       
   575     if(!iContentHandler)
       
   576         {
       
   577         SENDEBUG_L("OnContentL: KErrSenXmlContentHandlerNotSet");
       
   578         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   579         }
       
   580     iContentHandler->Characters(aBytes,0,aBytes.Length());
       
   581     }
       
   582 
       
   583 
       
   584 void CSenXmlReader::OnStartPrefixMappingL(
       
   585                                    const RString& aPrefix,
       
   586                                    const RString& aUri,
       
   587                                    TInt /*aErrorCode*/)
       
   588     {
       
   589     if(!iContentHandler)
       
   590         {
       
   591         SENDEBUG_L("OnStartPrefixMappingL: KErrSenXmlContentHandlerNotSet");
       
   592         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   593         }
       
   594 
       
   595     if(!ipNsPrefixes)
       
   596         {
       
   597         ipNsPrefixes = new (ELeave) CDesC8ArrayFlat(KArraySize);
       
   598         }
       
   599 
       
   600     if(!ipNsUris)
       
   601         {
       
   602         ipNsUris = new (ELeave) CDesC8ArrayFlat(KArraySize);
       
   603         }
       
   604 
       
   605     ipNsPrefixes->AppendL(aPrefix.DesC());
       
   606     ipNsUris->AppendL(aUri.DesC());
       
   607 
       
   608     iContentHandler->StartPrefixMappingL(aPrefix.DesC(), aUri.DesC());
       
   609     }
       
   610 
       
   611 
       
   612 
       
   613 void CSenXmlReader::OnEndPrefixMappingL(const RString& aPrefix,
       
   614                                         TInt /*aErrorCode*/)
       
   615     {
       
   616     if(!iContentHandler)
       
   617         {
       
   618         SENDEBUG_L("OnEndPrefixMappingL: KErrSenXmlContentHandlerNotSet");
       
   619         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   620         }
       
   621     iContentHandler->EndPrefixMappingL(aPrefix.DesC());
       
   622     }
       
   623 
       
   624 
       
   625 void CSenXmlReader::OnIgnorableWhiteSpaceL(const TDesC8& aBytes,
       
   626                                            TInt /*aErrorCode*/)
       
   627     {
       
   628     if(!iContentHandler)
       
   629         {
       
   630         SENDEBUG_L("OnIgnorableWhiteSpaceL: KErrSenXmlContentHandlerNotSet");
       
   631         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   632         }
       
   633     iContentHandler->OnIgnorableWhiteSpaceL(aBytes);
       
   634     }
       
   635 
       
   636 
       
   637 void CSenXmlReader::OnSkippedEntityL(const RString& aName, TInt /*aErrorCode*/)
       
   638     {
       
   639     if(!iContentHandler)
       
   640         {
       
   641         SENDEBUG_L("OnSkippedEntityL: KErrSenXmlContentHandlerNotSet");
       
   642         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   643         }
       
   644     iContentHandler->SkippedEntity(aName.DesC());
       
   645 
       
   646     //TInt retVal = iContentHandler->SkippedEntity(aName.DesC());
       
   647     // content handler spesific code returned error
       
   648     //User::LeaveIfError(retVal); 
       
   649     }
       
   650 
       
   651 
       
   652 void CSenXmlReader::OnProcessingInstructionL(
       
   653                                       const TDesC8& aTarget,
       
   654                                       const TDesC8& aData,
       
   655                                       TInt /*aErrorCode */)
       
   656     {
       
   657     if(!iContentHandler)
       
   658         {
       
   659         SENDEBUG_L("OnProcessingInstructionL: KErrSenXmlContentHandlerNotSet");
       
   660         User::Leave(KErrSenXmlContentHandlerNotSet);
       
   661         }
       
   662     iContentHandler->ProcessingInstructions(aTarget, aData);
       
   663     }
       
   664 
       
   665 // Note: Symbian XML framework error codes are listed in XmlFrameworkErrors.h
       
   666 void CSenXmlReader::OnError(TInt aErrorCode)
       
   667     {
       
   668 #ifdef _SENDEBUG
       
   669     // Symbian XML framework signals about some error:
       
   670     SENDEBUG_L("CSenXmlReader::OnError");
       
   671     SENDEBUG_L(" -Symbian XML framework signalled an error: ");
       
   672     TBuf<32> buf;
       
   673     buf.AppendNum(aErrorCode);
       
   674     SENDEBUG((buf));
       
   675 #endif    
       
   676  
       
   677      if(!iContentHandler)
       
   678         {
       
   679         SENDEBUG_L("OnError: KErrSenXmlContentHandlerNotSet");
       
   680         // Cannot report any signalled error to content handler,
       
   681         // since it has not been set. Force ParseL to leave by 
       
   682         // setting spesific error code (KErrSenXmlContentHandlerNotSet)
       
   683         iEnabledFeature = KErrSenXmlContentHandlerNotSet;
       
   684         return;
       
   685         }
       
   686     TInt retVal(iContentHandler->Error(aErrorCode));
       
   687 
       
   688 #ifdef _SENDEBUG
       
   689     // Symbian XML framework signals about some error:
       
   690     SENDEBUG_L(" -Error() callback to content handler returned an error:");
       
   691     TBuf<32> buf2;
       
   692     buf2.AppendNum(retVal);
       
   693     SENDEBUG((buf2));
       
   694 #endif    
       
   695     retVal = 0; // not used in release builds
       
   696 
       
   697     // In 3.0, iEnabledFeature member was used to indicate ParseL
       
   698     // that it should leave(!). 
       
   699     iEnabledFeature = aErrorCode;
       
   700     }
       
   701 
       
   702 
       
   703 TAny* CSenXmlReader::GetExtendedInterface(const TInt32 aUid)
       
   704     {
       
   705     if(!iContentHandler)
       
   706         {
       
   707         SENDEBUG_L("GetExtendedInterface: KErrSenXmlContentHandlerNotSet");
       
   708         return NULL;
       
   709         }
       
   710     return iContentHandler->GetExtendedInterface(aUid);
       
   711     }
       
   712 
       
   713 
       
   714 EXPORT_C TInt CSenXmlReader::EnabledParserFeature()
       
   715     {
       
   716     return iEnabledFeature;
       
   717     }
       
   718 
       
   719 
       
   720 TInt CSenXmlReader::SetParserFeature(TInt aParserFeature)
       
   721     {
       
   722     if(iParser)
       
   723         {
       
   724         iEnabledFeature = aParserFeature;
       
   725         TInt retCode = iParser->EnableFeature(aParserFeature);
       
   726         return retCode;
       
   727         }
       
   728     else
       
   729         {
       
   730         // internal error: iParser should always be available!
       
   731         TInt leaveCode(KErrNone);
       
   732         // try to re-instantiate the parser - once
       
   733         TRAP(leaveCode, RecreateParserL());
       
   734         if(leaveCode!=KErrNone)
       
   735             {
       
   736             return leaveCode;
       
   737             }
       
   738         iEnabledFeature = aParserFeature;
       
   739         TInt retCode2 = iParser->EnableFeature(aParserFeature);
       
   740         return retCode2;
       
   741         }
       
   742     }
       
   743 
       
   744 // DEPRECATED
       
   745 EXPORT_C TInt CSenXmlReader::ParserFeature()
       
   746     {
       
   747     return EnabledParserFeature();
       
   748     }
       
   749     
       
   750 void CSenXmlReader::CleanUp()
       
   751     {
       
   752     delete ipNsPrefixes;
       
   753     ipNsPrefixes = NULL;
       
   754     delete ipNsUris;
       
   755     ipNsUris = NULL;
       
   756 #if defined(__SERIES60_30__)
       
   757     delete iParser;
       
   758     iParser = NULL;
       
   759 #endif // __SERIES_30__ defined
       
   760     }
       
   761 
       
   762 void CSenXmlReader::CleanupParser(TAny* apReaderData)
       
   763 	{
       
   764 	TReaderData* pData = REINTERPRET_CAST(TReaderData*, apReaderData);
       
   765 	pData->ipReader->SetParserFeature(pData->iEnabledFeature);
       
   766 	delete pData;
       
   767 	}
       
   768     
       
   769 // END OF FILE
       
   770 
       
   771