diff options
Diffstat (limited to 'sax')
-rw-r--r-- | sax/source/fastparser/fastparser.cxx | 236 | ||||
-rw-r--r-- | sax/source/fastparser/fastparser.hxx | 29 |
2 files changed, 141 insertions, 124 deletions
diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index 623638a1a9dd..c67658adda93 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -23,7 +23,6 @@ #include <rtl/ustrbuf.hxx> #include <com/sun/star/lang/DisposedException.hpp> -#include <com/sun/star/xml/sax/XFastContextHandler.hpp> #include <com/sun/star/xml/sax/SAXParseException.hpp> #include <com/sun/star/xml/sax/FastToken.hpp> @@ -41,18 +40,15 @@ using namespace ::com::sun::star::io; namespace sax_fastparser { -// -------------------------------------------------------------------- - -struct SaxContextImpl +SaxContext::SaxContext( sal_Int32 nElementToken, const OUString& aNamespace, const OUString& aElementName ): + mnElementToken(nElementToken) { - Reference< XFastContextHandler > mxContext; - sal_Int32 mnElementToken; - OUString maNamespace; - OUString maElementName; - - SaxContextImpl() { mnElementToken = 0; } - SaxContextImpl( const SaxContextImplPtr& p ) { mnElementToken = p->mnElementToken; maNamespace = p->maNamespace; } -}; + if (nElementToken == FastToken::DONTKNOW) + { + maNamespace = aNamespace; + maElementName = aElementName; + } +} // -------------------------------------------------------------------- @@ -193,52 +189,105 @@ Entity::~Entity() { } -// -------------------------------------------------------------------- -// FastSaxParser implementation -// -------------------------------------------------------------------- - -FastSaxParser::FastSaxParser() +void Entity::startElement( sal_Int32 nElementToken, const OUString& aNamespace, + const OUString& aElementName, FastAttributeList *pAttributes ) { - mxDocumentLocator.set( new FastLocatorImpl( this ) ); - maUtf8Buffer.realloc( mnUtf8BufferSize ); -} + Reference< XFastContextHandler > xParentContext; + if( !maContextStack.empty() ) + { + xParentContext = maContextStack.top().mxContext; + if (!xParentContext.is()) + { + maContextStack.push( SaxContext(nElementToken, aNamespace, aElementName) ); + return; + } + } -// -------------------------------------------------------------------- + maContextStack.push( SaxContext(nElementToken, aNamespace, aElementName) ); -FastSaxParser::~FastSaxParser() -{ - if( mxDocumentLocator.is() ) - mxDocumentLocator->dispose(); + try + { + Reference< XFastAttributeList > xAttr( pAttributes ); + Reference< XFastContextHandler > xContext; + if( nElementToken == FastToken::DONTKNOW ) + { + if( xParentContext.is() ) + xContext = xParentContext->createUnknownChildContext( aNamespace, aElementName, xAttr ); + else if( mxDocumentHandler.is() ) + xContext = mxDocumentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr ); + + if( xContext.is() ) + { + xContext->startUnknownElement( aNamespace, aElementName, xAttr ); + } + } + else + { + if( xParentContext.is() ) + xContext = xParentContext->createFastChildContext( nElementToken, xAttr ); + else if( mxDocumentHandler.is() ) + xContext = mxDocumentHandler->createFastChildContext( nElementToken, xAttr ); + + if( xContext.is() ) + { + xContext->startFastElement( nElementToken, xAttr ); + } + } + maContextStack.top().mxContext = xContext; + } + catch (const Exception& e) + { + maSavedException <<= e; + } } -// -------------------------------------------------------------------- +void Entity::characters( const OUString& sChars ) +{ + const Reference< XFastContextHandler >& xContext( maContextStack.top().mxContext ); + if( xContext.is() ) try + { + xContext->characters( sChars ); + } + catch (const Exception& e) + { + maSavedException <<= e; + } +} -void FastSaxParser::pushContext() +void Entity::endElement() { - Entity& rEntity = getEntity(); - if( rEntity.maContextStack.empty() ) + const SaxContext& aContext = maContextStack.top(); + const Reference< XFastContextHandler >& xContext( aContext.mxContext ); + if( xContext.is() ) try { - rEntity.maContextStack.push( SaxContextImplPtr( new SaxContextImpl ) ); - rEntity.maNamespaceCount.push(0); - DefineNamespace( OString("xml"), "http://www.w3.org/XML/1998/namespace"); + sal_Int32 nElementToken = aContext.mnElementToken; + if( nElementToken != FastToken::DONTKNOW ) + xContext->endFastElement( nElementToken ); + else + xContext->endUnknownElement( aContext.maNamespace.get(), aContext.maElementName.get() ); } - else + catch (const Exception& e) { - rEntity.maContextStack.push( SaxContextImplPtr( new SaxContextImpl( rEntity.maContextStack.top() ) ) ); - rEntity.maNamespaceCount.push( rEntity.maNamespaceCount.top() ); + maSavedException <<= e; } + maContextStack.pop(); +} +// -------------------------------------------------------------------- +// FastSaxParser implementation +// -------------------------------------------------------------------- + +FastSaxParser::FastSaxParser() +{ + mxDocumentLocator.set( new FastLocatorImpl( this ) ); + maUtf8Buffer.realloc( mnUtf8BufferSize ); } // -------------------------------------------------------------------- -void FastSaxParser::popContext() +FastSaxParser::~FastSaxParser() { - Entity& rEntity = getEntity(); - assert(!rEntity.maContextStack.empty()); // pop without push? - if( !rEntity.maContextStack.empty() ) - rEntity.maContextStack.pop(); - if( !rEntity.maNamespaceCount.empty() ) - rEntity.maNamespaceCount.pop(); + if( mxDocumentLocator.is() ) + mxDocumentLocator->dispose(); } // -------------------------------------------------------------------- @@ -727,20 +776,16 @@ struct AttributeData void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char** awAttributes ) { - Reference< XFastContextHandler > xParentContext; Entity& rEntity = getEntity(); - if( !rEntity.maContextStack.empty() ) + if( rEntity.maNamespaceCount.empty() ) { - xParentContext = rEntity.maContextStack.top()->mxContext; - if( !xParentContext.is() ) - { - // we ignore current elements, so no processing needed - pushContext(); - return; - } + rEntity.maNamespaceCount.push(0); + DefineNamespace( OString("xml"), "http://www.w3.org/XML/1998/namespace"); + } + else + { + rEntity.maNamespaceCount.push( rEntity.maNamespaceCount.top() ); } - - pushContext(); rEntity.mxAttributes->clear(); @@ -749,6 +794,9 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char sal_Int32 nNameLen, nPrefixLen; const XML_Char *pName; const XML_Char *pPrefix; + OUString aNamespace; + if (!rEntity.maNamespaceStack.empty()) + aNamespace = rEntity.maNamespaceStack.top(); try { @@ -783,7 +831,7 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char if( (nNameLen == 5) && (strcmp( pName, "xmlns" ) == 0) ) { // namespace of the element found - rEntity.maContextStack.top()->maNamespace = OUString( awAttributes[i+1], strlen( awAttributes[i+1] ), RTL_TEXTENCODING_UTF8 ); + aNamespace = OUString( awAttributes[i+1], strlen( awAttributes[i+1] ), RTL_TEXTENCODING_UTF8 ); } else { @@ -819,48 +867,18 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char splitName( pwName, pPrefix, nPrefixLen, pName, nNameLen ); if( nPrefixLen > 0 ) nElementToken = GetTokenWithPrefix( pPrefix, nPrefixLen, pName, nNameLen ); - else if( !rEntity.maContextStack.top()->maNamespace.isEmpty() ) - nElementToken = GetTokenWithNamespaceURL( rEntity.maContextStack.top()->maNamespace, pName, nNameLen ); + else if( !aNamespace.isEmpty() ) + nElementToken = GetTokenWithNamespaceURL( aNamespace, pName, nNameLen ); else nElementToken = GetToken( pName ); - rEntity.maContextStack.top()->mnElementToken = nElementToken; - Reference< XFastAttributeList > xAttr( rEntity.mxAttributes.get() ); - Reference< XFastContextHandler > xContext; if( nElementToken == FastToken::DONTKNOW ) - { if( nPrefixLen > 0 ) - rEntity.maContextStack.top()->maNamespace = GetNamespaceURL( pPrefix, nPrefixLen ); - - const OUString aNamespace( rEntity.maContextStack.top()->maNamespace ); - const OUString aElementName( pName, nNameLen, RTL_TEXTENCODING_UTF8 ); - rEntity.maContextStack.top()->maElementName = aElementName; - - if( xParentContext.is() ) - xContext = xParentContext->createUnknownChildContext( aNamespace, aElementName, xAttr ); - else if( rEntity.mxDocumentHandler.is() ) - xContext = rEntity.mxDocumentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr ); + aNamespace = GetNamespaceURL( pPrefix, nPrefixLen ); - if( xContext.is() ) - { - rEntity.maContextStack.top()->mxContext = xContext; - xContext->startUnknownElement( aNamespace, aElementName, xAttr ); - } - } - else - { - if( xParentContext.is() ) - xContext = xParentContext->createFastChildContext( nElementToken, xAttr ); - else if( rEntity.mxDocumentHandler.is() ) - xContext = rEntity.mxDocumentHandler->createFastChildContext( nElementToken, xAttr ); - - - if( xContext.is() ) - { - rEntity.maContextStack.top()->mxContext = xContext; - xContext->startFastElement( nElementToken, xAttr ); - } - } + rEntity.maNamespaceStack.push(aNamespace); + rEntity.startElement( nElementToken, aNamespace, + OUString(pName, nNameLen, RTL_TEXTENCODING_UTF8), rEntity.mxAttributes.get() ); } catch (const Exception& e) { @@ -871,41 +889,21 @@ void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char void FastSaxParser::callbackEndElement( SAL_UNUSED_PARAMETER const XML_Char* ) { Entity& rEntity = getEntity(); - assert(!rEntity.maContextStack.empty()); // no context? - if( !rEntity.maContextStack.empty() ) - { - SaxContextImplPtr pContext = rEntity.maContextStack.top(); - const Reference< XFastContextHandler >& xContext( pContext->mxContext ); - if( xContext.is() ) try - { - sal_Int32 nElementToken = pContext->mnElementToken; - if( nElementToken != FastToken::DONTKNOW ) - xContext->endFastElement( nElementToken ); - else - xContext->endUnknownElement( pContext->maNamespace, pContext->maElementName ); - } - catch (const Exception& e) - { - rEntity.maSavedException <<= e; - } + assert( !rEntity.maNamespaceCount.empty() ); + if( !rEntity.maNamespaceCount.empty() ) + rEntity.maNamespaceCount.pop(); - popContext(); - } + assert( !rEntity.maNamespaceStack.empty() ); + if( !rEntity.maNamespaceStack.empty() ) + rEntity.maNamespaceStack.pop(); + + rEntity.endElement(); } void FastSaxParser::callbackCharacters( const XML_Char* s, int nLen ) { - Entity& rEntity = getEntity(); - const Reference< XFastContextHandler >& xContext( rEntity.maContextStack.top()->mxContext ); - if( xContext.is() ) try - { - xContext->characters( OUString( s, nLen, RTL_TEXTENCODING_UTF8 ) ); - } - catch (const Exception& e) - { - rEntity.maSavedException <<= e; - } + getEntity().characters( OUString( s, nLen, RTL_TEXTENCODING_UTF8 ) ); } void FastSaxParser::callbackEntityDecl( diff --git a/sax/source/fastparser/fastparser.hxx b/sax/source/fastparser/fastparser.hxx index aa71fb0ad4d9..51086965a8b4 100644 --- a/sax/source/fastparser/fastparser.hxx +++ b/sax/source/fastparser/fastparser.hxx @@ -22,12 +22,14 @@ #include <vector> #include <stack> -#include <boost/unordered_map.hpp> +#include <boost/optional.hpp> #include <boost/shared_ptr.hpp> +#include <boost/unordered_map.hpp> #include <rtl/ref.hxx> +#include <com/sun/star/xml/sax/XFastContextHandler.hpp> +#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/xml/sax/XFastTokenHandler.hpp> -#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <cppuhelper/implbase2.hxx> @@ -43,9 +45,7 @@ namespace sax_fastparser { class FastLocatorImpl; struct NamespaceDefine; -struct SaxContextImpl; -typedef ::boost::shared_ptr< SaxContextImpl > SaxContextImplPtr; typedef ::boost::shared_ptr< NamespaceDefine > NamespaceDefineRef; typedef ::boost::unordered_map< OUString, sal_Int32, @@ -53,6 +53,17 @@ typedef ::boost::unordered_map< OUString, sal_Int32, // -------------------------------------------------------------------- +struct SaxContext +{ + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > mxContext; + sal_Int32 mnElementToken; + boost::optional< OUString > maNamespace; + boost::optional< OUString > maElementName; + SaxContext( sal_Int32 nElementToken, const OUString& aNamespace, const OUString& aElementName ); +}; + +// -------------------------------------------------------------------- + struct ParserData { ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastDocumentHandler > mxDocumentHandler; @@ -79,13 +90,21 @@ struct Entity : public ParserData // therefore the exception must be saved somewhere. ::com::sun::star::uno::Any maSavedException; - ::std::stack< SaxContextImplPtr > maContextStack; + ::std::stack< OUString > maNamespaceStack; + /* Context for main thread consuming events. + * startElement() stores the data, which characters() and endElement() uses + */ + ::std::stack< SaxContext> maContextStack; // Determines which elements of maNamespaceDefines are valid in current context ::std::stack< sal_uInt32 > maNamespaceCount; ::std::vector< NamespaceDefineRef > maNamespaceDefines; explicit Entity( const ParserData& rData ); ~Entity(); + void startElement( sal_Int32 nElementToken, const OUString& aNamespace, + const OUString& aElementName, FastAttributeList *pAttributes ); + void characters( const OUString& sChars ); + void endElement(); }; // -------------------------------------------------------------------- |