dr76: #i111404# remaining problems with the FastSaxParser

This commit is contained in:
Daniel Rentz 2010-05-14 19:33:04 +02:00
parent 47d8eeed3f
commit 5025e2acbb
2 changed files with 71 additions and 41 deletions

View file

@ -175,6 +175,30 @@ OUString SAL_CALL FastLocatorImpl::getSystemId(void) throw (RuntimeException)
return mpParser->getEntity().maStructSource.sSystemId;
}
// --------------------------------------------------------------------
ParserData::ParserData()
{
}
ParserData::~ParserData()
{
}
// --------------------------------------------------------------------
Entity::Entity( const ParserData& rData ) :
ParserData( rData )
{
// performance-Improvment. Reference is needed when calling the startTag callback.
// Handing out the same object with every call is allowed (see sax-specification)
mxAttributes.set( new FastAttributeList( mxTokenHandler ) );
}
Entity::~Entity()
{
}
// --------------------------------------------------------------------
// FastSaxParser implementation
// --------------------------------------------------------------------
@ -182,10 +206,6 @@ OUString SAL_CALL FastLocatorImpl::getSystemId(void) throw (RuntimeException)
FastSaxParser::FastSaxParser()
{
mxDocumentLocator.set( new FastLocatorImpl( this ) );
// performance-Improvment. Reference is needed when calling the startTag callback.
// Handing out the same object with every call is allowed (see sax-specification)
mxAttributes.set( new FastAttributeList( mxTokenHandler ) );
}
// --------------------------------------------------------------------
@ -246,7 +266,7 @@ sal_Int32 FastSaxParser::GetToken( const OString& rToken )
{
Sequence< sal_Int8 > aSeq( (sal_Int8*)rToken.getStr(), rToken.getLength() );
return mxTokenHandler->getTokenFromUTF8( aSeq );
return getEntity().mxTokenHandler->getTokenFromUTF8( aSeq );
}
sal_Int32 FastSaxParser::GetToken( const sal_Char* pToken, sal_Int32 nLen /* = 0 */ )
@ -256,7 +276,7 @@ sal_Int32 FastSaxParser::GetToken( const sal_Char* pToken, sal_Int32 nLen /* = 0
Sequence< sal_Int8 > aSeq( (sal_Int8*)pToken, nLen );
return mxTokenHandler->getTokenFromUTF8( aSeq );
return getEntity().mxTokenHandler->getTokenFromUTF8( aSeq );
}
// --------------------------------------------------------------------
@ -422,7 +442,7 @@ void FastSaxParser::parseStream( const InputSource& maStructSource) throw (SAXEx
// Only one text at one time
MutexGuard guard( maMutex );
Entity entity;
Entity entity( maData );
entity.maStructSource = maStructSource;
if( !entity.maStructSource.aInputStream.is() )
@ -447,19 +467,19 @@ void FastSaxParser::parseStream( const InputSource& maStructSource) throw (SAXEx
try
{
// start the document
if( mxDocumentHandler.is() )
if( entity.mxDocumentHandler.is() )
{
Reference< XLocator > xLoc( mxDocumentLocator.get() );
mxDocumentHandler->setDocumentLocator( xLoc );
mxDocumentHandler->startDocument();
entity.mxDocumentHandler->setDocumentLocator( xLoc );
entity.mxDocumentHandler->startDocument();
}
parse();
// finish document
if( mxDocumentHandler.is() )
if( entity.mxDocumentHandler.is() )
{
mxDocumentHandler->endDocument();
entity.mxDocumentHandler->endDocument();
}
}
catch( SAXException & )
@ -487,13 +507,12 @@ void FastSaxParser::parseStream( const InputSource& maStructSource) throw (SAXEx
void FastSaxParser::setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler ) throw (RuntimeException)
{
mxDocumentHandler = Handler;
maData.mxDocumentHandler = Handler;
}
void SAL_CALL FastSaxParser::setTokenHandler( const Reference< XFastTokenHandler >& Handler ) throw (RuntimeException)
{
mxTokenHandler = Handler;
mxAttributes.set( new FastAttributeList( mxTokenHandler ) );
maData.mxTokenHandler = Handler;
}
void SAL_CALL FastSaxParser::registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken ) throw (IllegalArgumentException, RuntimeException)
@ -511,17 +530,17 @@ void SAL_CALL FastSaxParser::registerNamespace( const OUString& NamespaceURL, sa
void FastSaxParser::setErrorHandler(const Reference< XErrorHandler > & Handler) throw (RuntimeException)
{
mxErrorHandler = Handler;
maData.mxErrorHandler = Handler;
}
void FastSaxParser::setEntityResolver(const Reference < XEntityResolver > & Resolver) throw (RuntimeException)
{
mxEntityResolver = Resolver;
maData.mxEntityResolver = Resolver;
}
void FastSaxParser::setLocale( const Locale & Locale ) throw (RuntimeException)
{
maLocale = Locale;
maData.maLocale = Locale;
}
Sequence< OUString > FastSaxParser::getSupportedServiceNames_Static(void)
@ -648,8 +667,8 @@ void FastSaxParser::parse()
);
// error handler is set, it may throw the exception
if( mxErrorHandler.is() )
mxErrorHandler->fatalError( Any( aExcept ) );
if( rEntity.mxErrorHandler.is() )
rEntity.mxErrorHandler->fatalError( Any( aExcept ) );
// error handler has not thrown, but parsing cannot go on, the
// exception MUST be thrown
@ -693,7 +712,7 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char
pushContext();
mxAttributes->clear();
rEntity.mxAttributes->clear();
// create attribute map and process namespace instructions
int i = 0;
@ -752,17 +771,17 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char
{
sal_Int32 nAttributeToken = GetTokenWithPrefix( aIt->maPrefix, aIt->maName );
if( nAttributeToken != FastToken::DONTKNOW )
mxAttributes->add( nAttributeToken, aIt->maValue );
rEntity.mxAttributes->add( nAttributeToken, aIt->maValue );
else
mxAttributes->addUnknown( GetNamespaceURL( aIt->maPrefix ), aIt->maName, aIt->maValue );
rEntity.mxAttributes->addUnknown( GetNamespaceURL( aIt->maPrefix ), aIt->maName, aIt->maValue );
}
else
{
sal_Int32 nAttributeToken = GetToken( aIt->maName );
if( nAttributeToken != FastToken::DONTKNOW )
mxAttributes->add( nAttributeToken, aIt->maValue );
rEntity.mxAttributes->add( nAttributeToken, aIt->maValue );
else
mxAttributes->addUnknown( aIt->maName, aIt->maValue );
rEntity.mxAttributes->addUnknown( aIt->maName, aIt->maValue );
}
}
@ -776,7 +795,7 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char
nElementToken = GetToken( pName );
rEntity.maContextStack.top()->mnElementToken = nElementToken;
Reference< XFastAttributeList > xAttr( mxAttributes.get() );
Reference< XFastAttributeList > xAttr( rEntity.mxAttributes.get() );
Reference< XFastContextHandler > xContext;
if( nElementToken == FastToken::DONTKNOW )
{
@ -790,7 +809,7 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char
if( xParentContext.is() )
xContext = xParentContext->createUnknownChildContext( aNamespace, aElementName, xAttr );
else
xContext = mxDocumentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );
xContext = rEntity.mxDocumentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );
if( xContext.is() )
{
@ -803,7 +822,7 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char
if( xParentContext.is() )
xContext = xParentContext->createFastChildContext( nElementToken, xAttr );
else
xContext = mxDocumentHandler->createFastChildContext( nElementToken, xAttr );
xContext = rEntity.mxDocumentHandler->createFastChildContext( nElementToken, xAttr );
if( xContext.is() )
@ -866,11 +885,11 @@ int FastSaxParser::callbackExternalEntityRef( XML_Parser parser,
InputSource source;
Entity& rCurrEntity = getEntity();
Entity aNewEntity;
Entity aNewEntity( rCurrEntity );
if( mxEntityResolver.is() ) try
if( rCurrEntity.mxEntityResolver.is() ) try
{
aNewEntity.maStructSource = mxEntityResolver->resolveEntity(
aNewEntity.maStructSource = rCurrEntity.mxEntityResolver->resolveEntity(
OUString( publicId, strlen( publicId ), RTL_TEXTENCODING_UTF8 ) ,
OUString( systemId, strlen( systemId ), RTL_TEXTENCODING_UTF8 ) );
}

View file

@ -61,12 +61,27 @@ typedef ::std::hash_map< ::rtl::OUString, sal_Int32,
// --------------------------------------------------------------------
struct ParserData
{
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastDocumentHandler > mxDocumentHandler;
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxTokenHandler;
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XErrorHandler > mxErrorHandler;
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XEntityResolver > mxEntityResolver;
::com::sun::star::lang::Locale maLocale;
ParserData();
~ParserData();
};
// --------------------------------------------------------------------
// Entity binds all information needed for a single file
struct Entity
struct Entity : public ParserData
{
::com::sun::star::xml::sax::InputSource maStructSource;
XML_Parser mpParser;
::sax_expatwrap::XMLFile2UTFConverter maConverter;
::rtl::Reference< FastAttributeList > mxAttributes;
// Exceptions cannot be thrown through the C-XmlParser (possible resource leaks),
// therefore the exception must be saved somewhere.
@ -74,6 +89,9 @@ struct Entity
::std::stack< SaxContextImplPtr > maContextStack;
::std::vector< NamespaceDefineRef > maNamespaceDefines;
explicit Entity( const ParserData& rData );
~Entity();
};
// --------------------------------------------------------------------
@ -134,18 +152,11 @@ private:
private:
::osl::Mutex maMutex;
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastDocumentHandler > mxDocumentHandler;
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxTokenHandler;
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XErrorHandler > mxErrorHandler;
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XEntityResolver > mxEntityResolver;
::rtl::Reference< FastLocatorImpl > mxDocumentLocator;
::rtl::Reference< FastAttributeList > mxAttributes;
::com::sun::star::lang::Locale maLocale;
NamespaceMap maNamespaceMap;
// External entity stack
::std::stack< Entity > maEntities;
ParserData maData; /// Cached parser configuration for next call of parseStream().
::std::stack< Entity > maEntities; /// Entity stack for each call of parseStream().
};
}