--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsxml/src/senxmlreader.cpp Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,771 @@
+/*
+* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+
+
+
+
+
+// INCLUDE FILES
+#include <xml/attribute.h> // From syslibs, needed for RAttributeArray
+
+#include <SenXmlReader.h>
+#include <SenXmlConstants.h>
+#include <SenXmlUtils.h>
+#include <MSenContentHandlerClient.h>
+#include "senxmldebug.h"
+
+#ifdef EKA2
+ #ifndef __SERIES60_30__
+ // S60 3.1 or newer
+ #include <xml/matchdata.h>
+ #endif
+#else
+ // Use fss with S60 2nd edition FP3 (2.8) - temp file is needed with expat
+ #include <s32file.h> // filestream
+#endif
+
+// DEBUG:
+#include "sendebug.h"
+
+using namespace Xml;
+
+namespace
+ {
+ const TInt KArraySize = 128;
+
+ typedef struct
+ {
+ CSenXmlReader* ipReader;
+ TInt iEnabledFeature;
+ } TReaderData;
+ }
+
+_LIT8(KDefaultMimeType, ""); // Expat is made default, so don't have to give mime type
+
+EXPORT_C CSenXmlReader* CSenXmlReader::NewL()
+ {
+ CSenXmlReader* pNew = NewLC();
+ CleanupStack::Pop();
+ return pNew;
+ }
+
+EXPORT_C CSenXmlReader* CSenXmlReader::NewLC()
+ {
+
+ CSenXmlReader* pNew = new (ELeave) CSenXmlReader(KSenDefaultParserFeature);
+ CleanupStack::PushL(pNew);
+
+ pNew->ConstructL(KDefaultMimeType);// KXmlParserMimeType : Defaulted to Expat
+ return pNew;
+ }
+
+EXPORT_C CSenXmlReader* CSenXmlReader::NewL(TInt aParserFeature)
+ {
+ CSenXmlReader* pNew = NewLC(aParserFeature);
+ CleanupStack::Pop();
+ return pNew;
+ }
+
+EXPORT_C CSenXmlReader* CSenXmlReader::NewLC(TInt aParserFeature)
+ {
+ CSenXmlReader* pNew = new (ELeave) CSenXmlReader(aParserFeature);
+ CleanupStack::PushL(pNew);
+ pNew->ConstructL(KDefaultMimeType);// KXmlParserMimeType : Defaulted to Expat
+ if(aParserFeature<0)
+ {
+ User::Leave(KErrArgument);
+ }
+ return pNew;
+ }
+
+EXPORT_C CSenXmlReader* CSenXmlReader::NewL(const TDesC8& aParserMimeType)
+ {
+ CSenXmlReader* pNew = NewLC(aParserMimeType);
+ CleanupStack::Pop();
+ return pNew;
+ }
+
+EXPORT_C CSenXmlReader* CSenXmlReader::NewLC(const TDesC8& aParserMimeType)
+ {
+ CSenXmlReader* pNew = new (ELeave) CSenXmlReader(KSenDefaultParserFeature);
+ CleanupStack::PushL(pNew);
+ pNew->ConstructL(aParserMimeType);
+ return pNew;
+ }
+
+EXPORT_C CSenXmlReader* CSenXmlReader::NewL(const TDesC8& aParserMimeType,
+ TInt aParserFeature)
+ {
+ CSenXmlReader* pNew = NewLC(aParserMimeType, aParserFeature);
+ CleanupStack::Pop();
+ return pNew;
+ }
+
+EXPORT_C CSenXmlReader* CSenXmlReader::NewLC(const TDesC8& aParserMimeType,
+ TInt aParserFeature)
+ {
+ CSenXmlReader* pNew = new (ELeave) CSenXmlReader(aParserFeature);
+ CleanupStack::PushL(pNew);
+ pNew->ConstructL(aParserMimeType);
+ if(aParserFeature<0)
+ {
+ User::Leave(KErrArgument);
+ }
+ return pNew;
+ }
+
+EXPORT_C CSenXmlReader::CSenXmlReader(TInt aEnabledFeature)
+:
+iParser(NULL),
+iContentHandler(NULL),
+ipNsPrefixes(NULL),
+ipNsUris(NULL),
+iEnabledFeature(aEnabledFeature)
+ {
+ }
+
+EXPORT_C CSenXmlReader::~CSenXmlReader()
+ {
+ delete iParser;
+ delete ipNsPrefixes;
+ delete ipNsUris;
+ iStringPool.Close();
+ }
+
+#if defined( __SERIES60_30__ )
+void CSenXmlReader::ConstructL(const TDesC8& aParserMimeType)
+ {
+ if(aParserMimeType.Length()==0)
+ {
+ // Use default MIME type
+ iParser = CParser::NewL(KXmlParserMimeType, *this);
+ }
+ else
+ {
+ // Pass aParserMimeType
+ iParser = CParser::NewL(aParserMimeType, *this);
+ }
+ iParser->EnableFeature(iEnabledFeature);
+ iStringPool.OpenL();
+ }
+#else
+void CSenXmlReader::ConstructL(const TDesC8& aParserMimeType)
+ {
+ CMatchData* pMatchData = CMatchData::NewL();
+ CleanupStack::PushL(pMatchData);
+
+ if(aParserMimeType.Length()==0)
+ {
+ // Use default MIME type and variant
+ // for this parser instance (text/xml)
+ pMatchData->SetMimeTypeL(KXmlParserMimeType);
+ }
+ else
+ {
+ // Use specified aParserMimeType:
+ pMatchData->SetMimeTypeL(aParserMimeType);
+
+ // Set the default variant type (libxml2)
+ pMatchData->SetVariantL(KXmlVariant);
+ }
+
+ iParser = CParser::NewL(*pMatchData, *this);
+ CleanupStack::PopAndDestroy(pMatchData);
+
+ iParser->EnableFeature(iEnabledFeature);
+ iStringPool.OpenL();
+ }
+#endif
+
+EXPORT_C void CSenXmlReader::SetContentHandler(
+ MSenContentHandlerClient& aContentHandler)
+ {
+ iContentHandler = &aContentHandler;
+ }
+
+#ifdef EKA2
+// In S60 3rd edition platform there is a fixed version of expat parser which
+// can parse XML documents which size is 2048 bytes or greater. The previous
+// versions crashed with larger documents.
+EXPORT_C void CSenXmlReader::ParseL(const TDesC8& aBuff)
+ {
+ CleanUp();
+
+#if defined(__SERIES60_30__)
+ RecreateParserL();
+#endif // __SERIES_30__ defined
+
+ // Note(!): Store the currently enabled feature, since the same member
+ // is used to carry a possible error code from OnErrorL() callback:
+ TInt feature(iEnabledFeature);
+
+ TReaderData* pData = new (ELeave) TReaderData;
+ pData->ipReader = this;
+ pData->iEnabledFeature = iEnabledFeature;
+ CleanupStack::PushL( TCleanupItem( CSenXmlReader::CleanupParser, pData ) );
+ // Parse the XML document:
+ iParser->ParseL(aBuff);
+ CleanupStack::Pop();
+ delete pData;
+
+ iParser->ParseEndL(); // Enables Symbian XML framework errors to propagete OnErrorL() callback
+
+ CleanUp();
+
+ // Check if iEnabledFeature member was used to carry an error from OnErrorL() callback..
+ if (iEnabledFeature < 0)
+ {
+ TInt error(iEnabledFeature);
+ SENDEBUG((_L("CSenXmlReader::ParserL: leaving (%d)"), error));
+ // Switch back the originally enabled feature
+ iEnabledFeature = feature;
+ User::Leave(error);
+ }
+ iContentHandler->EndDocument();
+ }
+#else
+EXPORT_C void CSenXmlReader::ParseL(const TDesC8& aBuff)
+ {
+ // In S60 2nd edition FP3 (2.8) platform a temp file has to be used, since the
+ // underlying expat parser would crash when parsing a document which consists
+ // of more that 2048 bytes of XML.
+
+ if (aBuff.Length() > 2048) // there is 2048 bytes limitation in expat parser!
+ {
+ SENDEBUG_L("CSenXmlReader::ParseL(): parsing over 2048 bytes of XML (EKA1)");
+ SENDEBUG((_L("- document size: %d bytes."), aBuff.Length() ));
+
+ // Parse large XML documents using file server
+ RFs fss;
+ User::LeaveIfError(fss.Connect());
+ CleanupClosePushL(fss);
+
+ // Now create a new temp file in the specified path using unique
+ // file name which is generated by the file server. Since file
+ // server is not responsible to delete this file, it must be done
+ // after parsing is finished.
+
+ // Path for temp file
+ _LIT(KFilePath, "c:\\");
+
+ // Stores the temp file name when fileOutStream.Temp() returns:
+ TFileName tempFilename;
+
+ // Try to generate new temporary file, leave if it failes:
+ RFileWriteStream fileOutStream;
+ User::LeaveIfError(fileOutStream.Temp(fss, KFilePath, tempFilename, EFileWrite));
+ CleanupClosePushL(fileOutStream);
+ SENDEBUG((_L("CSenXmlReader::ParseL(): used temp file name: '%S'"), &tempFilename));
+
+ // Write XML document into the file:
+ fileOutStream.WriteL(aBuff);
+
+ // fileOutStream.Close(). Must be done prior ParseL()!
+ CleanupStack::PopAndDestroy();
+
+ // Parse the file:
+ ParseL(fss, tempFilename);
+
+ // Now delete the temporary file (when it is not in locked in parser's use)
+ fss.Delete(tempFilename);
+
+ // Finally close the file server session
+ CleanupStack::PopAndDestroy(); // fss.Close()
+ SENDEBUG_L("CSenXmlReader::ParseL() successfully parsed > 2048 bytes of XML.");
+ }
+ else
+ {
+ // Smaller documents may be parsed normally, even with older versions
+ // of Symbian XML framework's expat parser.
+
+ CleanUp();
+
+#if defined(__SERIES60_30__)
+ RecreateParserL();
+#endif // __SERIES_30__ defined
+
+ TInt feature(iEnabledFeature);
+
+ TReaderData* pData = new (ELeave) TReaderData;
+ pData->ipReader = this;
+ pData->iEnabledFeature = iEnabledFeature;
+ CleanupStack::PushL( TCleanupItem( CSenXmlReader::CleanupParser, pData ) );
+ // Parse the XML document:
+ iParser->ParseL(aBuff);
+ CleanupStack::Pop();
+ delete pData;
+
+ iParser->ParseEndL(); // Enables Symbian XML framework errors to propagete OnErrorL() callback
+
+ CleanUp();
+
+ if (iEnabledFeature < 0)
+ {
+ TInt error(iEnabledFeature);
+ iEnabledFeature = feature;
+ SENDEBUG((_L("CSenXmlReader::ParserL: leaving (%d)"), iEnabledFeature));
+ User::Leave(error);
+ }
+
+ iContentHandler->EndDocument();
+ }
+ }
+#endif // not EKA2
+
+
+EXPORT_C void CSenXmlReader::ParseL(RFs &aRFs, const TDesC& aFileToParse)
+ {
+ CleanUp();
+
+#if defined(__SERIES60_30__)
+ RecreateParserL();
+#endif // __SERIES_30__ defined
+
+ TInt feature(iEnabledFeature);
+
+ TReaderData* pData = new (ELeave) TReaderData;
+ pData->ipReader = this;
+ pData->iEnabledFeature = iEnabledFeature;
+ CleanupStack::PushL( TCleanupItem( CSenXmlReader::CleanupParser, pData ) );
+ // Parse the XML document:
+ Xml::ParseL(*iParser, aRFs, aFileToParse);
+ // Note: Xml::ParseL calls ParseL() and ParseEndL() internally:
+ CleanupStack::Pop();
+ delete pData;
+
+ CleanUp();
+
+ if(iEnabledFeature < 0)
+ {
+ TInt leaveError = iEnabledFeature;
+ iEnabledFeature = feature;
+ User::Leave(leaveError);
+ }
+
+ iContentHandler->EndDocument();
+ }
+
+// protected helper
+void CSenXmlReader::RecreateParserL()
+ {
+ delete iParser;
+ iParser = NULL;
+
+ delete ipNsPrefixes;
+ ipNsPrefixes = NULL;
+ delete ipNsUris;
+ ipNsUris = NULL;
+
+#if defined(__SERIES60_30__)
+ // Use default MIME type
+ iParser = CParser::NewL(KXmlParserMimeType, *this);
+#else
+ CMatchData* pMatchData = CMatchData::NewL();
+ CleanupStack::PushL(pMatchData);
+
+ pMatchData->SetMimeTypeL(KXmlParserMimeType);
+ pMatchData->SetVariantL(KXmlVariant);
+
+ iParser = CParser::NewL(*pMatchData, *this);
+ CleanupStack::PopAndDestroy(pMatchData);
+#endif
+
+ iParser->EnableFeature(iEnabledFeature);
+ }
+
+void CSenXmlReader::OnStartDocumentL(
+ const RDocumentParameters& /* aDocParam */,
+ TInt /* aErrorCode */)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnStartDocumentL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+ iContentHandler->StartDocument();
+ }
+
+void CSenXmlReader::OnEndDocumentL(TInt /* aErrorCode */)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnEndDocumentL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+ iContentHandler->EndDocument();
+ }
+
+
+void CSenXmlReader::OnStartElementL(const RTagInfo& aElement,
+ const RAttributeArray& aAttributes,
+ TInt /* aErrorCode */)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnStartElementL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+
+
+ const TPtrC8 localName = aElement.LocalName().DesC();
+ const TPtrC8 nsUri = aElement.Uri().DesC();
+ const TPtrC8 prefix = aElement.Prefix().DesC();
+
+ TPtrC8 qualifiedName = localName;
+
+ if (prefix != KNullDesC8)
+ {
+ HBufC8* pQName = HBufC8::NewLC(prefix.Length()+localName.Length()+
+ KSenColon().Length());
+ TPtr8 qName = pQName->Des();
+ qName.Append(prefix);
+ qName.Append(KSenColon);
+ qName.Append(localName);
+ qualifiedName.Set(qName);
+ }
+
+ if(ipNsPrefixes)
+ {
+ // there are namespaces to declare!
+
+ // make a new array for all attributes including namespace (to be added)
+ RAttributeArray attributesAndNamespaces;
+
+ CleanupClosePushL(attributesAndNamespaces);
+ TInt nsDeclarationCount(ipNsPrefixes->Count());
+ for(TInt i=0; i<nsDeclarationCount; i++)
+ {
+ // open and take ownership of RString - xmlnsAttrPrefix
+ RAttribute nsAttribute;
+ //CleanupClosePushL(nsAttribute);
+
+ TPtrC8 nsPrefix = ipNsPrefixes->MdcaPoint(i);
+ TPtrC8 nsURI = ipNsUris->MdcaPoint(i);
+
+ if (nsPrefix != KNullDesC8)
+ {
+ nsAttribute.Open(iStringPool.OpenStringL(nsURI),
+ iStringPool.OpenStringL(KSenXmlns()),
+ iStringPool.OpenStringL(nsPrefix),
+ iStringPool.OpenStringL(nsURI) );
+
+ }
+ else
+ {
+ nsAttribute.Open(iStringPool.OpenStringL(nsURI),
+ iStringPool.OpenStringL(KNullDesC8()),
+ iStringPool.OpenStringL(KSenXmlns()),
+ iStringPool.OpenStringL(nsURI) );
+
+ }
+
+
+ // append the namespace attribute (declaration)
+ CleanupClosePushL(nsAttribute);
+ attributesAndNamespaces.AppendL(nsAttribute);
+ CleanupStack::Pop(); // nsAttribute
+ }
+
+ // the ns declarations have been done using NON-CANONIZING method
+ delete ipNsPrefixes;
+ ipNsPrefixes = NULL;
+ delete ipNsUris;
+ ipNsUris = NULL;
+
+
+
+ // append all other ("real") attributes
+ TInt count(aAttributes.Count());
+ for(TInt a=0; a<count; a++)
+ {
+ attributesAndNamespaces.AppendL(const_cast <RAttribute&> (aAttributes[a]).Copy());
+ }
+
+
+ // now give the stream content forward to the interested handler object.
+ // we have successfully added the namespace declaration as NON-canonized(!)
+ // attribute (if conditions have been met).
+ iContentHandler->StartElement(nsUri, localName, qualifiedName, attributesAndNamespaces);
+
+ // close the copied attributes previously added into this array as copies
+ count = attributesAndNamespaces.Count();
+ for(TInt j=0; j<count; j++)
+ {
+ attributesAndNamespaces[j].Close();
+ }
+ // close the actual array
+ CleanupStack::PopAndDestroy(); // attributesAndNamespaces.Close();
+ }
+ else
+ {
+ // give the original attributes to content handler (no new namespaces declared in attrs)
+ iContentHandler->StartElement(nsUri, localName, qualifiedName, aAttributes);
+ }
+
+
+ // delete qualified element name, if one was allocated
+ if (prefix != KNullDesC8)
+ {
+ CleanupStack::PopAndDestroy(); // pQName
+ }
+
+
+ }
+
+
+
+void CSenXmlReader::OnEndElementL(const RTagInfo& aElement, TInt /* aErrorCode */)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnEndElementL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+
+
+ const TPtrC8 localName = aElement.LocalName().DesC();
+ const TPtrC8 nsUri = aElement.Uri().DesC();
+ const TPtrC8 prefix = aElement.Prefix().DesC();
+
+ TPtrC8 qualifiedName = localName;
+
+ if (prefix != KNullDesC8)
+ {
+ HBufC8* pQName = HBufC8::NewLC(prefix.Length()+localName.Length()+
+ KSenColon().Length());
+ TPtr8 qName = pQName->Des();
+ qName.Append(prefix);
+ qName.Append(KSenColon);
+ qName.Append(localName);
+ qualifiedName.Set(qName);
+ }
+
+
+ iContentHandler->EndElement(nsUri,
+ localName,
+ qualifiedName);
+
+ if (prefix != KNullDesC8)
+ {
+ CleanupStack::PopAndDestroy(); // pQName
+ }
+
+ }
+
+
+void CSenXmlReader::OnContentL(const TDesC8& aBytes, TInt /* aErrorCode */)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnContentL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+ iContentHandler->Characters(aBytes,0,aBytes.Length());
+ }
+
+
+void CSenXmlReader::OnStartPrefixMappingL(
+ const RString& aPrefix,
+ const RString& aUri,
+ TInt /*aErrorCode*/)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnStartPrefixMappingL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+
+ if(!ipNsPrefixes)
+ {
+ ipNsPrefixes = new (ELeave) CDesC8ArrayFlat(KArraySize);
+ }
+
+ if(!ipNsUris)
+ {
+ ipNsUris = new (ELeave) CDesC8ArrayFlat(KArraySize);
+ }
+
+ ipNsPrefixes->AppendL(aPrefix.DesC());
+ ipNsUris->AppendL(aUri.DesC());
+
+ iContentHandler->StartPrefixMappingL(aPrefix.DesC(), aUri.DesC());
+ }
+
+
+
+void CSenXmlReader::OnEndPrefixMappingL(const RString& aPrefix,
+ TInt /*aErrorCode*/)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnEndPrefixMappingL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+ iContentHandler->EndPrefixMappingL(aPrefix.DesC());
+ }
+
+
+void CSenXmlReader::OnIgnorableWhiteSpaceL(const TDesC8& aBytes,
+ TInt /*aErrorCode*/)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnIgnorableWhiteSpaceL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+ iContentHandler->OnIgnorableWhiteSpaceL(aBytes);
+ }
+
+
+void CSenXmlReader::OnSkippedEntityL(const RString& aName, TInt /*aErrorCode*/)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnSkippedEntityL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+ iContentHandler->SkippedEntity(aName.DesC());
+
+ //TInt retVal = iContentHandler->SkippedEntity(aName.DesC());
+ // content handler spesific code returned error
+ //User::LeaveIfError(retVal);
+ }
+
+
+void CSenXmlReader::OnProcessingInstructionL(
+ const TDesC8& aTarget,
+ const TDesC8& aData,
+ TInt /*aErrorCode */)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnProcessingInstructionL: KErrSenXmlContentHandlerNotSet");
+ User::Leave(KErrSenXmlContentHandlerNotSet);
+ }
+ iContentHandler->ProcessingInstructions(aTarget, aData);
+ }
+
+// Note: Symbian XML framework error codes are listed in XmlFrameworkErrors.h
+void CSenXmlReader::OnError(TInt aErrorCode)
+ {
+#ifdef _SENDEBUG
+ // Symbian XML framework signals about some error:
+ SENDEBUG_L("CSenXmlReader::OnError");
+ SENDEBUG_L(" -Symbian XML framework signalled an error: ");
+ TBuf<32> buf;
+ buf.AppendNum(aErrorCode);
+ SENDEBUG((buf));
+#endif
+
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("OnError: KErrSenXmlContentHandlerNotSet");
+ // Cannot report any signalled error to content handler,
+ // since it has not been set. Force ParseL to leave by
+ // setting spesific error code (KErrSenXmlContentHandlerNotSet)
+ iEnabledFeature = KErrSenXmlContentHandlerNotSet;
+ return;
+ }
+ TInt retVal(iContentHandler->Error(aErrorCode));
+
+#ifdef _SENDEBUG
+ // Symbian XML framework signals about some error:
+ SENDEBUG_L(" -Error() callback to content handler returned an error:");
+ TBuf<32> buf2;
+ buf2.AppendNum(retVal);
+ SENDEBUG((buf2));
+#endif
+ retVal = 0; // not used in release builds
+
+ // In 3.0, iEnabledFeature member was used to indicate ParseL
+ // that it should leave(!).
+ iEnabledFeature = aErrorCode;
+ }
+
+
+TAny* CSenXmlReader::GetExtendedInterface(const TInt32 aUid)
+ {
+ if(!iContentHandler)
+ {
+ SENDEBUG_L("GetExtendedInterface: KErrSenXmlContentHandlerNotSet");
+ return NULL;
+ }
+ return iContentHandler->GetExtendedInterface(aUid);
+ }
+
+
+EXPORT_C TInt CSenXmlReader::EnabledParserFeature()
+ {
+ return iEnabledFeature;
+ }
+
+
+TInt CSenXmlReader::SetParserFeature(TInt aParserFeature)
+ {
+ if(iParser)
+ {
+ iEnabledFeature = aParserFeature;
+ TInt retCode = iParser->EnableFeature(aParserFeature);
+ return retCode;
+ }
+ else
+ {
+ // internal error: iParser should always be available!
+ TInt leaveCode(KErrNone);
+ // try to re-instantiate the parser - once
+ TRAP(leaveCode, RecreateParserL());
+ if(leaveCode!=KErrNone)
+ {
+ return leaveCode;
+ }
+ iEnabledFeature = aParserFeature;
+ TInt retCode2 = iParser->EnableFeature(aParserFeature);
+ return retCode2;
+ }
+ }
+
+// DEPRECATED
+EXPORT_C TInt CSenXmlReader::ParserFeature()
+ {
+ return EnabledParserFeature();
+ }
+
+void CSenXmlReader::CleanUp()
+ {
+ delete ipNsPrefixes;
+ ipNsPrefixes = NULL;
+ delete ipNsUris;
+ ipNsUris = NULL;
+#if defined(__SERIES60_30__)
+ delete iParser;
+ iParser = NULL;
+#endif // __SERIES_30__ defined
+ }
+
+void CSenXmlReader::CleanupParser(TAny* apReaderData)
+ {
+ TReaderData* pData = REINTERPRET_CAST(TReaderData*, apReaderData);
+ pData->ipReader->SetParserFeature(pData->iEnabledFeature);
+ delete pData;
+ }
+
+// END OF FILE
+
+