diff options
Diffstat (limited to 'sax/source')
-rw-r--r-- | sax/source/fastparser/fastparser.cxx | 38 | ||||
-rw-r--r-- | sax/source/fastparser/legacyfastparser.cxx | 88 |
2 files changed, 113 insertions, 13 deletions
diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index ecc26269beb6..32d66242f805 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -119,6 +119,7 @@ struct ParserData FastTokenHandlerBase* mpTokenHandler; css::uno::Reference< css::xml::sax::XErrorHandler > mxErrorHandler; css::uno::Reference< css::xml::sax::XEntityResolver > mxEntityResolver; + css::uno::Reference< css::xml::sax::XFastNamespaceHandler >mxNamespaceHandler; css::lang::Locale maLocale; ParserData(); @@ -210,6 +211,7 @@ public: OUString getNamespaceURL( const OUString& rPrefix ) throw(css::lang::IllegalArgumentException, css::uno::RuntimeException); void setErrorHandler( const css::uno::Reference< css::xml::sax::XErrorHandler >& Handler ) throw (css::uno::RuntimeException); void setEntityResolver( const css::uno::Reference< css::xml::sax::XEntityResolver >& Resolver ) throw (css::uno::RuntimeException); + void setNamespaceHandler( const css::uno::Reference< css::xml::sax::XFastNamespaceHandler >& Handler) throw (css::uno::RuntimeException); void setLocale( const css::lang::Locale& rLocale ) throw (css::uno::RuntimeException); // called by the C callbacks of the expat parser @@ -863,6 +865,11 @@ void FastSaxParserImpl::setLocale( const lang::Locale & Locale ) throw (RuntimeE maData.maLocale = Locale; } +void FastSaxParserImpl::setNamespaceHandler( const Reference< XFastNamespaceHandler >& Handler ) throw (RuntimeException) +{ + maData.mxNamespaceHandler = Handler; +} + void FastSaxParserImpl::deleteUsedEvents() { Entity& rEntity = getEntity(); @@ -1033,10 +1040,11 @@ void FastSaxParserImpl::callbackStartElement(const xmlChar *localName , const xm new FastAttributeList( rEntity.mxTokenHandler, rEntity.mpTokenHandler ) ); + OUString sNamespace; sal_Int32 nNamespaceToken = FastToken::DONTKNOW; if (!rEntity.maNamespaceStack.empty()) { - rEvent.msNamespace = rEntity.maNamespaceStack.top().msName; + sNamespace = rEntity.maNamespaceStack.top().msName; nNamespaceToken = rEntity.maNamespaceStack.top().mnToken; } @@ -1054,12 +1062,17 @@ void FastSaxParserImpl::callbackStartElement(const xmlChar *localName , const xm { DefineNamespace( OString( XML_CAST( namespaces[ i ] )), OUString( XML_CAST( namespaces[ i + 1 ] ), strlen( XML_CAST( namespaces[ i + 1 ] )), RTL_TEXTENCODING_UTF8 )); + if( rEntity.mxNamespaceHandler.is() ) + rEntity.mxNamespaceHandler->registerNamespace( OUString( XML_CAST( namespaces[ i ] ),strlen( XML_CAST( namespaces[ i ] )), RTL_TEXTENCODING_UTF8 ), + OUString( XML_CAST( namespaces[ i + 1 ] ), strlen( XML_CAST( namespaces[ i + 1 ] )), RTL_TEXTENCODING_UTF8 )); } else { // default namespace - rEvent.msNamespace = OUString( XML_CAST( namespaces[ i + 1 ] ), strlen( XML_CAST( namespaces[ i + 1 ] )), RTL_TEXTENCODING_UTF8 ); - nNamespaceToken = GetNamespaceToken( rEvent.msNamespace ); + sNamespace = OUString( XML_CAST( namespaces[ i + 1 ] ), strlen( XML_CAST( namespaces[ i + 1 ] )), RTL_TEXTENCODING_UTF8 ); + nNamespaceToken = GetNamespaceToken( sNamespace ); + if( rEntity.mxNamespaceHandler.is() ) + rEntity.mxNamespaceHandler->registerNamespace("", OUString( XML_CAST( namespaces[ i + 1 ] ), strlen( XML_CAST( namespaces[ i + 1 ] )), RTL_TEXTENCODING_UTF8 ) ); } } @@ -1072,7 +1085,7 @@ void FastSaxParserImpl::callbackStartElement(const xmlChar *localName , const xm if( nAttributeToken != FastToken::DONTKNOW ) rEvent.mxAttributes->add( nAttributeToken, XML_CAST( attributes[ i + 3 ] ), attributes[ i + 4 ] - attributes[ i + 3 ] ); else - rEvent.mxAttributes->addUnknown( OUString( XML_CAST( attributes[ i + 2 ] ), strlen( XML_CAST( attributes[ i + 2 ] )), RTL_TEXTENCODING_UTF8 ), + rEvent.mxAttributes->addUnknown( OUString( XML_CAST( attributes[ i + 1 ] ), strlen( XML_CAST( attributes[ i + 1 ] )), RTL_TEXTENCODING_UTF8 ), OString( XML_CAST( attributes[ i ] )), OString( XML_CAST( attributes[ i + 3 ] ), attributes[ i + 4 ] - attributes[ i + 3 ] )); } else @@ -1088,7 +1101,7 @@ void FastSaxParserImpl::callbackStartElement(const xmlChar *localName , const xm if( prefix != nullptr ) rEvent.mnElementToken = GetTokenWithPrefix( prefix, strlen( XML_CAST( prefix )), localName, strlen( XML_CAST( localName ))); - else if( !rEvent.msNamespace.isEmpty() ) + else if( !sNamespace.isEmpty() ) rEvent.mnElementToken = GetTokenWithContextNamespace( nNamespaceToken, localName, strlen( XML_CAST( localName ))); else rEvent.mnElementToken = GetToken( localName, strlen( XML_CAST( localName ))); @@ -1097,15 +1110,18 @@ void FastSaxParserImpl::callbackStartElement(const xmlChar *localName , const xm { if( prefix != nullptr ) { - rEvent.msNamespace = OUString( XML_CAST( URI ), strlen( XML_CAST( URI )), RTL_TEXTENCODING_UTF8 ); - nNamespaceToken = GetNamespaceToken( rEvent.msNamespace ); + sNamespace = OUString( XML_CAST( URI ), strlen( XML_CAST( URI )), RTL_TEXTENCODING_UTF8 ); + nNamespaceToken = GetNamespaceToken( sNamespace ); + rEvent.msNamespace = OUString( XML_CAST( prefix ), strlen( XML_CAST( prefix )), RTL_TEXTENCODING_UTF8 ); } + else + rEvent.msNamespace.clear(); rEvent.msElementName = OUString( XML_CAST( localName ), strlen( XML_CAST( localName )), RTL_TEXTENCODING_UTF8 ); } else // token is always preferred. rEvent.msElementName.clear(); - rEntity.maNamespaceStack.push( NameWithToken(rEvent.msNamespace, nNamespaceToken) ); + rEntity.maNamespaceStack.push( NameWithToken(sNamespace, nNamespaceToken) ); if (rEntity.mbEnableThreads) produce(); else @@ -1314,6 +1330,12 @@ void FastSaxParser::setLocale( const lang::Locale& rLocale ) mpImpl->setLocale(rLocale); } +void FastSaxParser::setNamespaceHandler( const uno::Reference< css::xml::sax::XFastNamespaceHandler >& Handler) + throw (uno::RuntimeException, std::exception) +{ + mpImpl->setNamespaceHandler(Handler); +} + OUString FastSaxParser::getImplementationName() throw (uno::RuntimeException, std::exception) { diff --git a/sax/source/fastparser/legacyfastparser.cxx b/sax/source/fastparser/legacyfastparser.cxx index 94929a67d344..ab673441f914 100644 --- a/sax/source/fastparser/legacyfastparser.cxx +++ b/sax/source/fastparser/legacyfastparser.cxx @@ -21,11 +21,14 @@ #include <com/sun/star/xml/sax/XParser.hpp> #include <com/sun/star/xml/sax/FastParser.hpp> #include <com/sun/star/xml/sax/FastToken.hpp> +#include <com/sun/star/lang/XInitialization.hpp> #include <comphelper/attributelist.hxx> #include <cppuhelper/supportsservice.hxx> #include <comphelper/processfactory.hxx> #include <rtl/ref.hxx> #include <sax/fastparser.hxx> +#include <vector> +#include <o3tl/make_unique.hxx> using namespace std; using namespace ::cppu; @@ -37,11 +40,73 @@ using namespace io; namespace { +class NamespaceHandler : public WeakImplHelper< XFastNamespaceHandler > +{ +private: + struct NamespaceDefine + { + OUString m_aPrefix; + OUString m_aNamespaceURI; + + NamespaceDefine( const OUString& rPrefix, const OUString& rNamespaceURI ) : m_aPrefix( rPrefix ), m_aNamespaceURI( rNamespaceURI ) {} + }; + vector< unique_ptr< NamespaceDefine > > m_aNamespaceDefines; + +public: + NamespaceHandler(); + void addNSDeclAttributes( rtl::Reference < comphelper::AttributeList >& rAttrList ); + + //XFastNamespaceHandler + virtual void SAL_CALL registerNamespace( const OUString& rNamespacePrefix, const OUString& rNamespaceURI ) + throw (RuntimeException, exception) override; + virtual OUString SAL_CALL getNamespaceURI( const OUString& rNamespacePrefix ) + throw (RuntimeException, exception) override; +}; + +NamespaceHandler::NamespaceHandler() +{ +} + +void NamespaceHandler::addNSDeclAttributes( rtl::Reference < comphelper::AttributeList >& rAttrList ) +{ + for(const auto& aNamespaceDefine : m_aNamespaceDefines) + { + OUString& rPrefix = aNamespaceDefine.get()->m_aPrefix; + OUString& rNamespaceURI = aNamespaceDefine.get()->m_aNamespaceURI; + OUString sDecl; + if ( rPrefix.isEmpty() ) + sDecl = "xmlns"; + else + sDecl = "xmlns:" + rPrefix; + rAttrList->AddAttribute( sDecl, "CDATA", rNamespaceURI ); + } + m_aNamespaceDefines.clear(); +} -class SaxLegacyFastParser : public WeakImplHelper< XServiceInfo, XParser > +void NamespaceHandler::registerNamespace( const OUString& rNamespacePrefix, const OUString& rNamespaceURI ) + throw (RuntimeException, exception) { + m_aNamespaceDefines.push_back( o3tl::make_unique<NamespaceDefine>( + rNamespacePrefix, rNamespaceURI) ); +} + +OUString NamespaceHandler::getNamespaceURI( const OUString&/* rNamespacePrefix */ ) + throw (RuntimeException, exception) +{ + return OUString(); +} + +class SaxLegacyFastParser : public WeakImplHelper< XInitialization, XServiceInfo, XParser > +{ +private: + rtl::Reference< NamespaceHandler > m_aNamespaceHandler; public: SaxLegacyFastParser(); + +// css::lang::XInitialization: + virtual void SAL_CALL initialize(css::uno::Sequence<css::uno::Any> const& rArguments) + throw (RuntimeException, Exception, exception) override; + // The SAX-Parser-Interface virtual void SAL_CALL parseStream( const InputSource& structSource) throw ( SAXException, IOException, RuntimeException, exception) override; @@ -86,9 +151,9 @@ class CallbackDocumentHandler : public WeakImplHelper< XFastDocumentHandler > { private: Reference< XDocumentHandler > m_xDocumentHandler; + rtl::Reference< NamespaceHandler > m_aNamespaceHandler; public: - CallbackDocumentHandler( Reference< XDocumentHandler > const & xDocumentHandler ) - { m_xDocumentHandler.set( xDocumentHandler ); } + CallbackDocumentHandler( Reference< XDocumentHandler > const & xDocumentHandler, rtl::Reference< NamespaceHandler > const & rNamespaceHandler ); // XFastDocumentHandler virtual void SAL_CALL startDocument() throw (SAXException, RuntimeException, exception) override; @@ -106,6 +171,12 @@ public: }; +CallbackDocumentHandler::CallbackDocumentHandler( Reference< XDocumentHandler > const & xDocumentHandler, rtl::Reference< NamespaceHandler > const & rNamespaceHandler ) +{ + m_xDocumentHandler.set( xDocumentHandler ); + m_aNamespaceHandler.set( rNamespaceHandler.get() ); +} + void SAL_CALL CallbackDocumentHandler::startDocument() throw (SAXException, RuntimeException, exception) { @@ -139,6 +210,7 @@ void SAL_CALL CallbackDocumentHandler::startUnknownElement( const OUString& Name { OUString elementName; rtl::Reference < comphelper::AttributeList > rAttrList = new comphelper::AttributeList; + m_aNamespaceHandler->addNSDeclAttributes( rAttrList ); if ( !Namespace.isEmpty() ) elementName = Namespace + ":" + Name; else @@ -200,11 +272,17 @@ void SAL_CALL CallbackDocumentHandler::characters( const OUString& aChars ) m_xDocumentHandler->characters( aChars ); } -SaxLegacyFastParser::SaxLegacyFastParser( ) +SaxLegacyFastParser::SaxLegacyFastParser( ) : m_aNamespaceHandler( new NamespaceHandler ) { m_xParser = FastParser::create( ::comphelper::getProcessComponentContext() ); m_xParser->setTokenHandler( new CallbackTokenHandler() ); + m_xParser->setNamespaceHandler( m_aNamespaceHandler.get() ); +} + +void SAL_CALL SaxLegacyFastParser::initialize(Sequence< Any > const&/* rArguments */) + throw (RuntimeException, Exception, exception) +{ } void SaxLegacyFastParser::parseStream( const InputSource& structSource ) @@ -212,7 +290,7 @@ void SaxLegacyFastParser::parseStream( const InputSource& structSource ) IOException, RuntimeException, exception) { - m_xParser->setFastDocumentHandler( new CallbackDocumentHandler( m_xDocumentHandler.get() ) ); + m_xParser->setFastDocumentHandler( new CallbackDocumentHandler( m_xDocumentHandler.get(), m_aNamespaceHandler.get() ) ); m_xParser->parseStream( structSource ); } |