diff options
author | Mohammed Abdul Azeem <azeemmysore@gmail.com> | 2017-10-01 14:11:11 +0530 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2018-03-14 14:12:08 +0100 |
commit | bf46b46a1d734348096936284fb8a76e977936d0 (patch) | |
tree | a76c30897cf1e49491bf26580c823701b6d74778 | |
parent | 1b61d0417bf46896ef1f1bd1e1a8209588fc157a (diff) |
Moving XSAXDocumentBuilder2 to use XFastDocumentHandler:
This is used in parsing of meta Contexts across different
modules. This also involved moving to XFastParser for
parsing xml filters in sw, sd, starmath.
Change-Id: Ic663aaac6cb20ee8ce5b97cae87c93220f5a2929
Reviewed-on: https://gerrit.libreoffice.org/42989
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Jenkins <ci@libreoffice.org>
33 files changed, 637 insertions, 474 deletions
diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx index 364411681aa8..77b620a3f1df 100644 --- a/include/xmloff/xmlimp.hxx +++ b/include/xmloff/xmlimp.hxx @@ -55,6 +55,8 @@ #include <xmloff/formlayerimport.hxx> #include <comphelper/attributelist.hxx> #include <sax/fastattribs.hxx> +#include <rtl/ustring.hxx> +#include <unordered_map> #include <com/sun/star/beans/NamedValue.hpp> @@ -225,6 +227,7 @@ class XMLOFF_DLLPUBLIC SvXMLImport : public cppu::WeakImplHelper< css::uno::Reference< css::xml::sax::XFastDocumentHandler > mxFastDocumentHandler; static css::uno::Reference< css::xml::sax::XFastTokenHandler > xTokenHandler; static std::unordered_map< sal_Int32, std::pair< OUString, OUString > > aNamespaceMap; + static std::unordered_map< OUString, OUString, OUStringHash > aNamespaceURIPrefixMap; static bool bIsNSMapsInitialized; static void initializeNamespaceMaps(); @@ -378,6 +381,8 @@ public: static const OUString getNameFromToken( sal_Int32 nToken ); static const OUString getNamespacePrefixFromToken( sal_Int32 nToken ); + static const OUString getNamespaceURIFromToken( sal_Int32 nToken ); + static const OUString getNamespacePrefixFromURI( const OUString& rURI ); SvXMLNamespaceMap& GetNamespaceMap() { return *mpNamespaceMap; } const SvXMLNamespaceMap& GetNamespaceMap() const { return *mpNamespaceMap; } diff --git a/include/xmloff/xmlmetai.hxx b/include/xmloff/xmlmetai.hxx index 2b9160251bc0..9b9f59da7f10 100644 --- a/include/xmloff/xmlmetai.hxx +++ b/include/xmloff/xmlmetai.hxx @@ -40,22 +40,20 @@ private: css::uno::Reference< css::xml::dom::XSAXDocumentBuilder2> mxDocBuilder; public: - SvXMLMetaDocumentContext(SvXMLImport& rImport, sal_uInt16 nPrfx, - const OUString& rLName, - const css::uno::Reference< css::document::XDocumentProperties>& xDocProps); - SvXMLMetaDocumentContext(SvXMLImport& rImport, const css::uno::Reference< css::document::XDocumentProperties>& xDocProps); virtual ~SvXMLMetaDocumentContext() override; - virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix, - const OUString& rLocalName, - const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList ) override; + virtual void SAL_CALL characters( const OUString& aChars ) override; + + virtual void SAL_CALL startFastElement( sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; - virtual void StartElement( const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override; + virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override; - virtual void EndElement() override; + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; public: static void setBuildId(const OUString & rGenerator, diff --git a/offapi/com/sun/star/xml/dom/XSAXDocumentBuilder2.idl b/offapi/com/sun/star/xml/dom/XSAXDocumentBuilder2.idl index be151460b109..37560fd8dc6f 100644 --- a/offapi/com/sun/star/xml/dom/XSAXDocumentBuilder2.idl +++ b/offapi/com/sun/star/xml/dom/XSAXDocumentBuilder2.idl @@ -20,7 +20,7 @@ #ifndef __com_sun_star_xml_dom_XSAXDocumentBuilder2_idl #define __com_sun_star_xml_dom_XSAXDocumentBuilder2_idl -#include <com/sun/star/xml/sax/XDocumentHandler.idl> +#include <com/sun/star/xml/sax/XFastDocumentHandler.idl> #include <com/sun/star/xml/dom/XSAXDocumentBuilder.idl> module com { module sun { module star { module xml { module dom { @@ -33,7 +33,7 @@ module com { module sun { module star { module xml { module dom { interface XSAXDocumentBuilder2 { interface XSAXDocumentBuilder; - interface com::sun::star::xml::sax::XDocumentHandler; + interface com::sun::star::xml::sax::XFastDocumentHandler; }; };};};};}; diff --git a/reportdesign/source/filter/xml/xmlfilter.cxx b/reportdesign/source/filter/xml/xmlfilter.cxx index bf246129d9e3..054e9b2e39c9 100644 --- a/reportdesign/source/filter/xml/xmlfilter.cxx +++ b/reportdesign/source/filter/xml/xmlfilter.cxx @@ -745,10 +745,6 @@ SvXMLImportContext* ORptFilter::CreateDocumentContext( sal_uInt16 nPrefix, case XML_TOK_DOC_CONTENT: pContext = new RptXMLDocumentContentContext(*this, nPrefix, rLocalName); break; - case XML_TOK_DOC_META: - GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); - pContext = CreateMetaContext( rLocalName ); - break; default: break; } @@ -759,6 +755,23 @@ SvXMLImportContext* ORptFilter::CreateDocumentContext( sal_uInt16 nPrefix, return pContext; } +SvXMLImportContext *ORptFilter::CreateFastContext( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) +{ + SvXMLImportContext *pContext = nullptr; + + switch (nElement) + { + case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ): + GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + pContext = CreateMetaContext( nElement ); + break; + default: + pContext = new SvXMLImportContext(*this); + } + return pContext; +} + const SvXMLTokenMap& ORptFilter::GetDocElemTokenMap() const { if ( !m_pDocElemTokenMap.get() ) @@ -1102,14 +1115,14 @@ void ORptFilter::insertFunction(const css::uno::Reference< css::report::XFunctio m_aFunctions.emplace(_xFunction->getName(),_xFunction); } -SvXMLImportContext* ORptFilter::CreateMetaContext(const OUString& rLocalName) +SvXMLImportContext* ORptFilter::CreateMetaContext(const sal_Int32 /*nElement*/) { SvXMLImportContext* pContext = nullptr; if ( getImportFlags() & SvXMLImportFlags::META ) { uno::Reference<document::XDocumentPropertiesSupplier> xDPS(GetModel(), uno::UNO_QUERY_THROW); - pContext = new SvXMLMetaDocumentContext(*this,XML_NAMESPACE_OFFICE, rLocalName,xDPS->getDocumentProperties()); + pContext = new SvXMLMetaDocumentContext(*this, xDPS->getDocumentProperties()); } return pContext; } diff --git a/reportdesign/source/filter/xml/xmlfilter.hxx b/reportdesign/source/filter/xml/xmlfilter.hxx index eacb74e83969..6ecf8f061130 100644 --- a/reportdesign/source/filter/xml/xmlfilter.hxx +++ b/reportdesign/source/filter/xml/xmlfilter.hxx @@ -99,7 +99,7 @@ public: using SvXMLImport::SetMasterStyles; SvXMLImportContext* CreateStylesContext(const OUString& rLocalName, const Reference< XAttributeList>& xAttrList, bool bIsAutoStyle ); - SvXMLImportContext* CreateMetaContext(const OUString& rLocalName); + SvXMLImportContext* CreateMetaContext(const sal_Int32 nElement); SvXMLImportContext* CreateFontDeclsContext(const OUString& rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList ); protected: @@ -108,6 +108,9 @@ protected: const OUString& rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override; + virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + virtual XMLShapeImportHelper* CreateShapeImport() override; virtual ~ORptFilter() throw() override; diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx index 4e2c3bb56531..c85589ac9a73 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -234,10 +234,6 @@ protected: ScXMLImport& GetScImport() { return static_cast<ScXMLImport&>(GetImport()); } public: - ScXMLDocContext_Impl( ScXMLImport& rImport, - sal_uInt16 nPrfx, - const OUString& rLName ); - ScXMLDocContext_Impl( ScXMLImport& rImport ); virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix, @@ -256,13 +252,6 @@ public: virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; }; -ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport, sal_uInt16 nPrfx, - const OUString& rLName ) : -SvXMLImportContext( rImport, nPrfx, rLName ) -{ - -} - ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport ) : SvXMLImportContext( rImport ) { @@ -273,38 +262,23 @@ class ScXMLFlatDocContext_Impl : public ScXMLDocContext_Impl, public SvXMLMetaDocumentContext { public: - ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport, - sal_uInt16 i_nPrefix, const OUString & i_rLName, - const uno::Reference<document::XDocumentProperties>& i_xDocProps); ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport, const uno::Reference<document::XDocumentProperties>& i_xDocProps); - virtual SvXMLImportContextRef CreateChildContext( - sal_uInt16 i_nPrefix, const OUString& i_rLocalName, - const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) override; - virtual void SAL_CALL startFastElement (sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList) override; virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + virtual void SAL_CALL characters( const OUString& aChars ) override; + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 nElement, const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override; }; ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport, - sal_uInt16 i_nPrefix, const OUString & i_rLName, - const uno::Reference<document::XDocumentProperties>& i_xDocProps) : -SvXMLImportContext(i_rImport, i_nPrefix, i_rLName), -ScXMLDocContext_Impl(i_rImport, i_nPrefix, i_rLName), -SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName, - i_xDocProps) -{ -} - -ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport, const uno::Reference<document::XDocumentProperties>& i_xDocProps) : SvXMLImportContext(i_rImport), ScXMLDocContext_Impl(i_rImport), @@ -312,29 +286,14 @@ SvXMLMetaDocumentContext(i_rImport, i_xDocProps) { } -SvXMLImportContextRef ScXMLFlatDocContext_Impl::CreateChildContext( - sal_uInt16 i_nPrefix, const OUString& i_rLocalName, - const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) -{ - // behave like meta base class iff we encounter office:meta - const SvXMLTokenMap& rTokenMap = GetScImport().GetDocElemTokenMap(); - if ( XML_TOK_DOC_META == rTokenMap.Get( i_nPrefix, i_rLocalName ) ) { - return SvXMLMetaDocumentContext::CreateChildContext( - i_nPrefix, i_rLocalName, i_xAttrList ); - } else { - return ScXMLDocContext_Impl::CreateChildContext( - i_nPrefix, i_rLocalName, i_xAttrList ); - } -} - uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLFlatDocContext_Impl::createFastChildContext( sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList > & xAttrList ) { - if ( nElement != XML_ELEMENT( OFFICE, XML_META ) ) - return ScXMLDocContext_Impl::createFastChildContext( nElement, xAttrList ); + if ( nElement == XML_ELEMENT( OFFICE, XML_META ) ) + return SvXMLMetaDocumentContext::createFastChildContext( nElement, xAttrList ); else - return new SvXMLImportContext( GetImport() ); + return ScXMLDocContext_Impl::createFastChildContext( nElement, xAttrList ); } void SAL_CALL ScXMLFlatDocContext_Impl::startFastElement(sal_Int32 nElement, @@ -348,6 +307,11 @@ void SAL_CALL ScXMLFlatDocContext_Impl::endFastElement(sal_Int32 nElement) SvXMLMetaDocumentContext::endFastElement( nElement ); } +void SAL_CALL ScXMLFlatDocContext_Impl::characters(const OUString& rChars) +{ + SvXMLMetaDocumentContext::characters(rChars); +} + class ScXMLBodyContext_Impl : public ScXMLImportContext { public: @@ -659,29 +623,6 @@ sc::PivotTableSources& ScXMLImport::GetPivotTableSources() return *mpPivotSources; } -SvXMLImportContext *ScXMLImport::CreateDocumentContext( sal_uInt16 nPrefix, - const OUString& rLocalName, - const uno::Reference<xml::sax::XAttributeList>& xAttrList ) -{ - SvXMLImportContext *pContext = nullptr; - - if ( (XML_NAMESPACE_OFFICE == nPrefix) && - ( IsXMLToken(rLocalName, XML_DOCUMENT_META)) ) { - pContext = CreateMetaContext(rLocalName); - } else if ( (XML_NAMESPACE_OFFICE == nPrefix) && - ( IsXMLToken(rLocalName, XML_DOCUMENT)) ) { - uno::Reference<document::XDocumentPropertiesSupplier> xDPS( - GetModel(), uno::UNO_QUERY_THROW); - // flat OpenDocument file format - pContext = new ScXMLFlatDocContext_Impl( *this, nPrefix, rLocalName, - xDPS->getDocumentProperties()); - } - else - pContext = SvXMLImport::CreateDocumentContext( nPrefix, rLocalName, xAttrList ); - - return pContext; -} - SvXMLImportContext *ScXMLImport::CreateFastContext( sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) { @@ -695,6 +636,10 @@ SvXMLImportContext *ScXMLImport::CreateFastContext( sal_Int32 nElement, pContext = new ScXMLDocContext_Impl( *this ); break; + case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ): + pContext = CreateMetaContext(nElement); + break; + case XML_ELEMENT( OFFICE, XML_DOCUMENT ): { uno::Reference<document::XDocumentPropertiesSupplier> xDPS( @@ -847,7 +792,7 @@ SvXMLImportContext *ScXMLImport::CreateBodyContext(const rtl::Reference<sax_fast } SvXMLImportContext *ScXMLImport::CreateMetaContext( - const OUString& rLocalName ) + const sal_Int32 /*nElement*/ ) { SvXMLImportContext* pContext = nullptr; @@ -857,14 +802,11 @@ SvXMLImportContext *ScXMLImport::CreateMetaContext( GetModel(), uno::UNO_QUERY_THROW); uno::Reference<document::XDocumentProperties> const xDocProps( (IsStylesOnlyMode()) ? nullptr : xDPS->getDocumentProperties()); - pContext = new SvXMLMetaDocumentContext(*this, - XML_NAMESPACE_OFFICE, rLocalName, - xDocProps); + pContext = new SvXMLMetaDocumentContext(*this, xDocProps); } if( !pContext ) - pContext = new SvXMLImportContext( *this, - XML_NAMESPACE_OFFICE, rLocalName ); + pContext = new SvXMLImportContext( *this ); return pContext; } diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx index 1639c3285b0b..ed7df03a0f79 100644 --- a/sc/source/filter/xml/xmlimprt.hxx +++ b/sc/source/filter/xml/xmlimprt.hxx @@ -299,10 +299,8 @@ class ScXMLImport: public SvXMLImport protected: - virtual SvXMLImportContext *CreateDocumentContext(sal_uInt16 nPrefix, - const OUString& rLocalName, - const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList ) override; - + // This method is called after the namespace map has been updated, but + // before a context for the current element has been pushed. virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement, const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override; @@ -322,7 +320,7 @@ public: // NB: in contrast to other CreateFooContexts, this particular one handles // the root element (i.e. office:document-meta) SvXMLImportContext *CreateMetaContext( - const OUString& rLocalName ); + const sal_Int32 nElement ); SvXMLImportContext *CreateFontDeclsContext(const sal_uInt16 nPrefix, const OUString& rLocalName, const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList); SvXMLImportContext *CreateScriptContext( diff --git a/sd/source/filter/xml/sdxmlwrp.cxx b/sd/source/filter/xml/sdxmlwrp.cxx index da0c95bc12f3..3f8ad2f5f623 100644 --- a/sd/source/filter/xml/sdxmlwrp.cxx +++ b/sd/source/filter/xml/sdxmlwrp.cxx @@ -41,6 +41,7 @@ #include <strmname.h> #include <svx/xmleohlp.hxx> #include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/document/XFilter.hpp> #include <com/sun/star/document/XImporter.hpp> #include <com/sun/star/document/XExporter.hpp> @@ -216,11 +217,18 @@ ErrCode ReadThroughComponent( // connect model and filter Reference < XImporter > xImporter( xFilter, UNO_QUERY ); xImporter->setTargetDocument( xModelComponent ); + + uno::Reference< xml::sax::XFastParser > xFastParser = dynamic_cast< + xml::sax::XFastParser* >( xFilter.get() ); + // finally, parser the stream SAL_INFO( "sd.filter", "parsing stream" ); try { - xParser->parseStream( aParserInput ); + if( xFastParser.is() ) + xFastParser->parseStream( aParserInput ); + else + xParser->parseStream( aParserInput ); } catch (const xml::sax::SAXParseException& r) { diff --git a/sdext/CppunitTest_sdext_pdfimport.mk b/sdext/CppunitTest_sdext_pdfimport.mk index 83f3131fe40e..f5fc54696329 100644 --- a/sdext/CppunitTest_sdext_pdfimport.mk +++ b/sdext/CppunitTest_sdext_pdfimport.mk @@ -30,6 +30,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sdext_pdfimport,\ sal \ test \ unotest \ + xo \ )) $(eval $(call gb_CppunitTest_use_library_objects,sdext_pdfimport,pdfimport)) diff --git a/sdext/Executable_pdf2xml.mk b/sdext/Executable_pdf2xml.mk index 373f40da36fd..c0f7fe6f5727 100644 --- a/sdext/Executable_pdf2xml.mk +++ b/sdext/Executable_pdf2xml.mk @@ -30,6 +30,7 @@ $(eval $(call gb_Executable_use_libraries,pdf2xml,\ unotest \ cppuhelper \ sal \ + xo \ )) $(eval $(call gb_Executable_use_library_objects,pdf2xml,pdfimport)) diff --git a/sdext/Executable_pdfunzip.mk b/sdext/Executable_pdfunzip.mk index 74b1a964b0f1..006f8e5c9430 100644 --- a/sdext/Executable_pdfunzip.mk +++ b/sdext/Executable_pdfunzip.mk @@ -28,6 +28,7 @@ $(eval $(call gb_Executable_use_libraries,pdfunzip,\ cppuhelper \ sal \ vcl \ + xo \ )) $(eval $(call gb_Executable_use_library_objects,pdfunzip,pdfimport)) diff --git a/sdext/Library_pdfimport.mk b/sdext/Library_pdfimport.mk index 7c11d36e42ba..465a406b66b8 100644 --- a/sdext/Library_pdfimport.mk +++ b/sdext/Library_pdfimport.mk @@ -27,6 +27,7 @@ $(eval $(call gb_Library_use_libraries,pdfimport,\ cppu \ cppuhelper \ sal \ + xo \ )) $(eval $(call gb_Library_use_externals,pdfimport,\ diff --git a/sdext/source/pdfimport/sax/emitcontext.cxx b/sdext/source/pdfimport/sax/emitcontext.cxx index 7559d1e0ce2a..f21b17e60c88 100644 --- a/sdext/source/pdfimport/sax/emitcontext.cxx +++ b/sdext/source/pdfimport/sax/emitcontext.cxx @@ -27,6 +27,7 @@ #include <cppuhelper/exc_hlp.hxx> #include <com/sun/star/xml/sax/SAXException.hpp> #include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <xmloff/xmlimp.hxx> #if OSL_DEBUG_LEVEL > 0 #include <osl/file.hxx> @@ -43,6 +44,8 @@ SaxEmitter::SaxEmitter( const uno::Reference< xml::sax::XDocumentHandler >& xDoc m_xDocHdl( xDocHdl ) { OSL_PRECOND(m_xDocHdl.is(), "SaxEmitter(): invalid doc handler"); + if (SvXMLImport *pFastHandler = dynamic_cast<SvXMLImport*>(m_xDocHdl.get())) + m_xDocHdl.set( new SvXMLLegacyToFastDocHandler( pFastHandler ) ); try { m_xDocHdl->startDocument(); diff --git a/sfx2/source/doc/SfxDocumentMetaData.cxx b/sfx2/source/doc/SfxDocumentMetaData.cxx index a15ea43e0ed6..7e696129ad78 100644 --- a/sfx2/source/doc/SfxDocumentMetaData.cxx +++ b/sfx2/source/doc/SfxDocumentMetaData.cxx @@ -48,6 +48,7 @@ #include <com/sun/star/document/XFilter.hpp> #include <com/sun/star/xml/sax/Parser.hpp> #include <com/sun/star/xml/sax/Writer.hpp> +#include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/xml/dom/DOMException.hpp> #include <com/sun/star/xml/dom/XDocument.hpp> #include <com/sun/star/xml/dom/XElement.hpp> @@ -1770,8 +1771,13 @@ SfxDocumentMetaData::loadFromStorage( css::uno::UNO_QUERY_THROW); xImp->setTargetDocument(css::uno::Reference<css::lang::XComponent>(this)); xParser->setDocumentHandler(xDocHandler); + css::uno::Reference< css::xml::sax::XFastParser > xFastParser = dynamic_cast< + css::xml::sax::XFastParser* >( xDocHandler.get() ); try { - xParser->parseStream(input); + if( xFastParser.is() ) + xFastParser->parseStream(input); + else + xParser->parseStream(input); } catch (const css::xml::sax::SAXException &) { throw css::io::WrongFormatException( "SfxDocumentMetaData::loadFromStorage:" diff --git a/starmath/source/mathmlimport.cxx b/starmath/source/mathmlimport.cxx index 59b42570a2d0..a531412cf573 100644 --- a/starmath/source/mathmlimport.cxx +++ b/starmath/source/mathmlimport.cxx @@ -24,6 +24,7 @@ one go*/ #include <com/sun/star/xml/sax/InputSource.hpp> #include <com/sun/star/xml/sax/Parser.hpp> +#include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> #include <com/sun/star/packages/WrongPasswordException.hpp> @@ -286,10 +287,16 @@ ErrCode SmXMLImportWrapper::ReadThroughComponent( Reference < XImporter > xImporter( xFilter, UNO_QUERY ); xImporter->setTargetDocument( xModelComponent ); + uno::Reference< xml::sax::XFastParser > xFastParser = dynamic_cast< + xml::sax::XFastParser* >( xFilter.get() ); + // finally, parser the stream try { - xParser->parseStream( aParserInput ); + if( xFastParser.is() ) + xFastParser->parseStream( aParserInput ); + else + xParser->parseStream( aParserInput ); uno::Reference<lang::XUnoTunnel> xFilterTunnel( xFilter, uno::UNO_QUERY ); SmXMLImport *pFilter = reinterpret_cast< SmXMLImport * >( @@ -1935,11 +1942,20 @@ public: class SmXMLOfficeContext_Impl : public virtual SvXMLImportContext { public: - SmXMLOfficeContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx, - const OUString& rLName) - : SvXMLImportContext(rImport,nPrfx,rLName) {} + SmXMLOfficeContext_Impl( SmXMLImport &rImport ) + : SvXMLImportContext(rImport) {} + + virtual void SAL_CALL characters( const OUString& /*aChars*/ ) override {} + + virtual void SAL_CALL startFastElement( sal_Int32 /*nElement*/, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ ) override {} + + virtual void SAL_CALL endFastElement( sal_Int32 /*nElement*/ ) override {} virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList) override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; }; SvXMLImportContextRef SmXMLOfficeContext_Impl::CreateChildContext(sal_uInt16 nPrefix, @@ -1965,6 +1981,12 @@ SvXMLImportContextRef SmXMLOfficeContext_Impl::CreateChildContext(sal_uInt16 nPr return pContext; } +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SmXMLOfficeContext_Impl::createFastChildContext( + sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) +{ + return new SvXMLImportContext( GetImport() ); +} + // context for flat file xml format class SmXMLFlatDocContext_Impl @@ -1972,41 +1994,59 @@ class SmXMLFlatDocContext_Impl { public: SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport, - sal_uInt16 i_nPrefix, const OUString & i_rLName, const uno::Reference<document::XDocumentProperties>& i_xDocProps); - virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 i_nPrefix, const OUString& i_rLocalName, const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) override; + virtual void SAL_CALL characters( const OUString& aChars ) override; + + virtual void SAL_CALL startFastElement( sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; }; SmXMLFlatDocContext_Impl::SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport, - sal_uInt16 i_nPrefix, const OUString & i_rLName, const uno::Reference<document::XDocumentProperties>& i_xDocProps) : - SvXMLImportContext(i_rImport, i_nPrefix, i_rLName), - SmXMLOfficeContext_Impl(i_rImport, i_nPrefix, i_rLName), - SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName, - i_xDocProps) + SvXMLImportContext(i_rImport), + SmXMLOfficeContext_Impl(i_rImport), + SvXMLMetaDocumentContext(i_rImport, i_xDocProps) +{ +} + +void SAL_CALL SmXMLFlatDocContext_Impl::startFastElement( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) +{ + SvXMLMetaDocumentContext::startFastElement(nElement, xAttrList); +} + +void SAL_CALL SmXMLFlatDocContext_Impl::endFastElement( sal_Int32 nElement ) { + SvXMLMetaDocumentContext::endFastElement(nElement); } -SvXMLImportContextRef SmXMLFlatDocContext_Impl::CreateChildContext( - sal_uInt16 i_nPrefix, const OUString& i_rLocalName, - const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) +void SAL_CALL SmXMLFlatDocContext_Impl::characters( const OUString& rChars ) +{ + SvXMLMetaDocumentContext::characters(rChars); +} + +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SmXMLFlatDocContext_Impl::createFastChildContext( + sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) { // behave like meta base class iff we encounter office:meta - if ( XML_NAMESPACE_OFFICE == i_nPrefix && - i_rLocalName == GetXMLToken(XML_META) ) + if ( nElement == XML_ELEMENT(OFFICE, XML_META) ) { - return SvXMLMetaDocumentContext::CreateChildContext( - i_nPrefix, i_rLocalName, i_xAttrList ); + return SvXMLMetaDocumentContext::createFastChildContext( + nElement, xAttrList ); } else { - return SmXMLOfficeContext_Impl::CreateChildContext( - i_nPrefix, i_rLocalName, i_xAttrList ); + return SmXMLOfficeContext_Impl::createFastChildContext( + nElement, xAttrList ); } } - static const SvXMLTokenMapEntry aPresLayoutElemTokenMap[] = { { XML_NAMESPACE_MATH, XML_SEMANTICS, XML_TOK_SEMANTICS }, @@ -2823,28 +2863,40 @@ SvXMLImportContext *SmXMLImport::CreateDocumentContext(sal_uInt16 nPrefix, const OUString &rLocalName, const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/) { - if ( XML_NAMESPACE_OFFICE == nPrefix ) + SvXMLImportContext *pContext = nullptr; + if ( XML_NAMESPACE_OFFICE != nPrefix ) + pContext = new SmXMLDocContext_Impl(*this,nPrefix,rLocalName); + + return pContext; +} + +SvXMLImportContext *SmXMLImport::CreateFastContext(sal_Int32 nElement, + const uno::Reference <xml::sax::XFastAttributeList> & /*xAttrList*/) +{ + SvXMLImportContext *pContext = nullptr; + + switch (nElement) { - if ( IsXMLToken(rLocalName, XML_DOCUMENT) || - IsXMLToken(rLocalName, XML_DOCUMENT_META) ) + case XML_ELEMENT( OFFICE, XML_DOCUMENT ): + case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ): { uno::Reference<document::XDocumentPropertiesSupplier> xDPS( GetModel(), uno::UNO_QUERY_THROW); - return IsXMLToken(rLocalName, XML_DOCUMENT_META) - ? new SvXMLMetaDocumentContext(*this, - XML_NAMESPACE_OFFICE, rLocalName, - xDPS->getDocumentProperties()) + pContext = ( (nElement & TOKEN_MASK) == XML_DOCUMENT_META ) + ? new SvXMLMetaDocumentContext( *this, + xDPS->getDocumentProperties() ) // flat OpenDocument file format -- this has not been tested... - : new SmXMLFlatDocContext_Impl( *this, nPrefix, rLocalName, - xDPS->getDocumentProperties()); - } - else - { - return new SmXMLOfficeContext_Impl( *this,nPrefix,rLocalName); + : new SmXMLFlatDocContext_Impl( *this, + xDPS->getDocumentProperties() ); } + break; + default: + if ((nElement & NMSP_MASK) == NAMESPACE_TOKEN(XML_NAMESPACE_OFFICE)) + pContext = new SmXMLOfficeContext_Impl(*this); + else + pContext = new SvXMLImportContext(*this); } - else - return new SmXMLDocContext_Impl(*this,nPrefix,rLocalName); + return pContext; } SvXMLImportContext *SmXMLImport::CreateRowContext(sal_uInt16 nPrefix, diff --git a/starmath/source/mathmlimport.hxx b/starmath/source/mathmlimport.hxx index a0d2c6254f0c..b91a51bea2bd 100644 --- a/starmath/source/mathmlimport.hxx +++ b/starmath/source/mathmlimport.hxx @@ -99,6 +99,9 @@ public: const OUString &rLocalName, const css::uno::Reference < css::xml::sax::XAttributeList> &xAttrList) override; + SvXMLImportContext *CreateFastContext( sal_Int32 nElement, + const css::uno::Reference< + css::xml::sax::XFastAttributeList >& xAttrList ) override; SvXMLImportContext *CreateRowContext(sal_uInt16 nPrefix, const OUString &rLocalName); SvXMLImportContext *CreateEncloseContext(sal_uInt16 nPrefix, diff --git a/sw/source/filter/xml/swxml.cxx b/sw/source/filter/xml/swxml.cxx index a96433fa042e..cb5b122f5373 100644 --- a/sw/source/filter/xml/swxml.cxx +++ b/sw/source/filter/xml/swxml.cxx @@ -34,6 +34,7 @@ #include <com/sun/star/packages/zip/ZipIOException.hpp> #include <com/sun/star/packages/WrongPasswordException.hpp> #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> +#include <com/sun/star/xml/sax/XFastParser.hpp> #include <o3tl/any.hxx> #include <vcl/errinf.hxx> #include <sfx2/docfile.hxx> @@ -168,11 +169,16 @@ ErrCode ReadThroughComponent( // connect model and filter uno::Reference < XImporter > xImporter( xFilter, UNO_QUERY ); xImporter->setTargetDocument( xModelComponent ); + uno::Reference< xml::sax::XFastParser > xFastParser = dynamic_cast< + xml::sax::XFastParser* >( xFilter.get() ); // finally, parser the stream try { - xParser->parseStream( aParserInput ); + if( xFastParser.is() ) + xFastParser->parseStream( aParserInput ); + else + xParser->parseStream( aParserInput ); } catch( xml::sax::SAXParseException& r ) { diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx index 01460f6fe4c5..1a4988339d5a 100644 --- a/sw/source/filter/xml/xmlimp.cxx +++ b/sw/source/filter/xml/xmlimp.cxx @@ -196,9 +196,14 @@ public: SwXMLDocContext_Impl( SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName ); + SwXMLDocContext_Impl( SwXMLImport& rImport ); + virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< xml::sax::XAttributeList > & xAttrList ) override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; }; SwXMLDocContext_Impl::SwXMLDocContext_Impl( SwXMLImport& rImport, @@ -207,6 +212,17 @@ SwXMLDocContext_Impl::SwXMLDocContext_Impl( SwXMLImport& rImport, { } +SwXMLDocContext_Impl::SwXMLDocContext_Impl( SwXMLImport& rImport ) : + SvXMLImportContext( rImport ) +{ +} + +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SwXMLDocContext_Impl::createFastChildContext( + sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) +{ + return new SvXMLImportContext( GetImport() ); +} + SvXMLImportContextRef SwXMLDocContext_Impl::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, @@ -271,51 +287,41 @@ class SwXMLOfficeDocContext_Impl : public: SwXMLOfficeDocContext_Impl( SwXMLImport& rImport, - sal_uInt16 nPrfx, - const OUString& rLName, const Reference< document::XDocumentProperties >& xDocProps); - virtual SvXMLImportContextRef CreateChildContext( - sal_uInt16 nPrefix, - const OUString& rLocalName, - const Reference< xml::sax::XAttributeList > & xAttrList ) override; + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override; }; SwXMLOfficeDocContext_Impl::SwXMLOfficeDocContext_Impl( SwXMLImport& rImport, - sal_uInt16 nPrfx, - const OUString& rLName, const Reference< document::XDocumentProperties >& xDocProps) : - SvXMLImportContext( rImport, nPrfx, rLName ), - SwXMLDocContext_Impl( rImport, nPrfx, rLName ), - SvXMLMetaDocumentContext( rImport, nPrfx, rLName, xDocProps) + SvXMLImportContext( rImport ), + SwXMLDocContext_Impl( rImport ), + SvXMLMetaDocumentContext( rImport, xDocProps ) { } -SvXMLImportContextRef SwXMLOfficeDocContext_Impl::CreateChildContext( - sal_uInt16 nPrefix, - const OUString& rLocalName, - const Reference< xml::sax::XAttributeList > & xAttrList ) +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SwXMLOfficeDocContext_Impl::createFastChildContext( + sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) { - const SvXMLTokenMap& rTokenMap = GetSwImport().GetDocElemTokenMap(); - // assign paragraph styles to list levels of outline style after all styles // are imported and finished. This is the case, when <office:body> starts // in flat OpenDocument file format. { - if ( rTokenMap.Get( nPrefix, rLocalName ) == XML_TOK_DOC_BODY ) + if( nElement == XML_ELEMENT( OFFICE, XML_BODY ) ) { GetImport().GetTextImport()->SetOutlineStyles( true ); } } // behave like meta base class iff we encounter office:meta - if ( XML_TOK_DOC_META == rTokenMap.Get( nPrefix, rLocalName ) ) { - return SvXMLMetaDocumentContext::CreateChildContext( - nPrefix, rLocalName, xAttrList ); + if ( nElement == XML_ELEMENT( OFFICE, XML_META ) ) { + return SvXMLMetaDocumentContext::createFastChildContext( + nElement, xAttrList ); } else { - return SwXMLDocContext_Impl::CreateChildContext( - nPrefix, rLocalName, xAttrList ); + return SwXMLDocContext_Impl::createFastChildContext( + nElement, xAttrList ); } } @@ -370,30 +376,40 @@ SvXMLImportContext *SwXMLImport::CreateDocumentContext( IsXMLToken( rLocalName, XML_DOCUMENT_CONTENT ) )) pContext = new SwXMLDocContext_Impl( *this, nPrefix, rLocalName ); else if ( XML_NAMESPACE_OFFICE==nPrefix && - IsXMLToken( rLocalName, XML_DOCUMENT_META ) ) - { - pContext = CreateMetaContext(rLocalName); - } - else if ( XML_NAMESPACE_OFFICE==nPrefix && IsXMLToken( rLocalName, XML_DOCUMENT_STYLES ) ) { pContext = new SwXMLDocStylesContext_Impl( *this, nPrefix, rLocalName ); } - else if ( XML_NAMESPACE_OFFICE==nPrefix && - IsXMLToken( rLocalName, XML_DOCUMENT ) ) - { - uno::Reference<document::XDocumentProperties> const xDocProps( - GetDocumentProperties()); - // flat OpenDocument file format - pContext = new SwXMLOfficeDocContext_Impl( *this, nPrefix, rLocalName, - xDocProps); - } else pContext = SvXMLImport::CreateDocumentContext(nPrefix, rLocalName, xAttrList); return pContext; } +SvXMLImportContext *SwXMLImport::CreateFastContext( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) +{ + SvXMLImportContext *pContext = nullptr; + + switch (nElement) + { + case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ): + pContext = CreateMetaContext(nElement); + break; + case XML_ELEMENT( OFFICE, XML_DOCUMENT ): + { + uno::Reference<document::XDocumentProperties> const xDocProps( + GetDocumentProperties()); + // flat OpenDocument file format + pContext = new SwXMLOfficeDocContext_Impl( *this, xDocProps ); + } + break; + default: + pContext = new SvXMLImportContext( *this ); + } + return pContext; +} + SwXMLImport::SwXMLImport( const uno::Reference< uno::XComponentContext >& rContext, OUString const & implementationName, SvXMLImportFlags nImportFlags) diff --git a/sw/source/filter/xml/xmlimp.hxx b/sw/source/filter/xml/xmlimp.hxx index 8907970b62e9..cd399ea4821f 100644 --- a/sw/source/filter/xml/xmlimp.hxx +++ b/sw/source/filter/xml/xmlimp.hxx @@ -107,6 +107,9 @@ protected: const OUString& rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList ) override; + virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement, + const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override; + virtual XMLTextImportHelper* CreateTextImport() override; virtual XMLShapeImportHelper* CreateShapeImport() override; @@ -136,7 +139,7 @@ public: // NB: in contrast to other CreateFooContexts, this particular one handles // the root element (i.e. office:document-meta) - SvXMLImportContext *CreateMetaContext( const OUString& rLocalName ); + SvXMLImportContext *CreateMetaContext( const sal_Int32 nElement ); SvXMLImportContext *CreateScriptContext( const OUString& rLocalName ); SvXMLImportContext *CreateStylesContext( const OUString& rLocalName, diff --git a/sw/source/filter/xml/xmlmeta.cxx b/sw/source/filter/xml/xmlmeta.cxx index ddc37f10c8b9..3dcf81038287 100644 --- a/sw/source/filter/xml/xmlmeta.cxx +++ b/sw/source/filter/xml/xmlmeta.cxx @@ -53,7 +53,7 @@ SwXMLImport::GetDocumentProperties() const } SvXMLImportContext *SwXMLImport::CreateMetaContext( - const OUString& rLocalName ) + const sal_Int32 /*nElement*/ ) { SvXMLImportContext *pContext = nullptr; @@ -61,13 +61,11 @@ SvXMLImportContext *SwXMLImport::CreateMetaContext( { uno::Reference<document::XDocumentProperties> const xDocProps( GetDocumentProperties()); - pContext = new SvXMLMetaDocumentContext(*this, - XML_NAMESPACE_OFFICE, rLocalName, xDocProps); + pContext = new SvXMLMetaDocumentContext(*this, xDocProps); } if( !pContext ) - pContext = new SvXMLImportContext( *this, - XML_NAMESPACE_OFFICE, rLocalName ); + pContext = new SvXMLImportContext( *this ); return pContext; } diff --git a/unoxml/Library_unoxml.mk b/unoxml/Library_unoxml.mk index c55e4d6cf725..335bf10e9b38 100644 --- a/unoxml/Library_unoxml.mk +++ b/unoxml/Library_unoxml.mk @@ -32,6 +32,7 @@ $(eval $(call gb_Library_use_libraries,unoxml,\ cppuhelper \ cppu \ sal \ + xo \ )) $(eval $(call gb_Library_use_externals,unoxml,\ diff --git a/unoxml/source/dom/saxbuilder.cxx b/unoxml/source/dom/saxbuilder.cxx index 626293a4d4a7..698d923a3ba9 100644 --- a/unoxml/source/dom/saxbuilder.cxx +++ b/unoxml/source/dom/saxbuilder.cxx @@ -23,6 +23,8 @@ #include <com/sun/star/xml/sax/SAXException.hpp> #include <comphelper/processfactory.hxx> #include <cppuhelper/supportsservice.hxx> +#include <sax/fastattribs.hxx> +#include <xmloff/xmlimp.hxx> using namespace css::lang; using namespace css::uno; @@ -90,7 +92,6 @@ namespace DOM m_aDocument.clear(); m_aFragment.clear(); while (!m_aNodeStack.empty()) m_aNodeStack.pop(); - while (!m_aNSStack.empty()) m_aNSStack.pop(); m_aState = SAXDocumentBuilderState_READY; } @@ -144,9 +145,8 @@ namespace DOM m_aState = SAXDocumentBuilderState_FRAGMENT_FINISHED; } - // document handler - - void SAL_CALL CSAXDocumentBuilder::startDocument() + //XFastDocumentHandler + void SAL_CALL CSAXDocumentBuilder::startDocument() { ::osl::MutexGuard g(m_Mutex); @@ -177,107 +177,123 @@ namespace DOM m_aState = SAXDocumentBuilderState_DOCUMENT_FINISHED; } - void SAL_CALL CSAXDocumentBuilder::startElement(const OUString& aName, const Reference< XAttributeList>& attribs) + void SAL_CALL CSAXDocumentBuilder::processingInstruction( const OUString& rTarget, const OUString& rData ) { ::osl::MutexGuard g(m_Mutex); + // append PI node to the current top if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT && m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT) - { throw SAXException(); - } - // start with mappings in effect for last level - NSMap aNSMap; - if (!m_aNSStack.empty()) - aNSMap = NSMap(m_aNSStack.top()); - - // handle xmlns: attributes and add to mappings - OUString attr_qname; - OUString attr_value; - OUString newprefix; - AttrMap aAttrMap; - sal_Int32 idx=-1; - sal_Int16 nAttributes = attribs->getLength(); - for (sal_Int16 i=0; i<nAttributes; i++) + Reference< XProcessingInstruction > aInstruction = m_aDocument->createProcessingInstruction( + rTarget, rData); + m_aNodeStack.top()->appendChild(aInstruction); + } + + void SAL_CALL CSAXDocumentBuilder::setDocumentLocator( const Reference< XLocator >& xLocator ) + { + ::osl::MutexGuard g(m_Mutex); + + // set the document locator... + m_aLocator = xLocator; + } + + void SAL_CALL CSAXDocumentBuilder::startFastElement( sal_Int32 nElement , const Reference< XFastAttributeList >& xAttribs ) + { + ::osl::MutexGuard g(m_Mutex); + + if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT && + m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT) { - attr_qname = attribs->getNameByIndex(i); - attr_value = attribs->getValueByIndex(i); - // new prefix mapping - if (attr_qname.startsWith("xmlns:")) - { - newprefix = attr_qname.copy(attr_qname.indexOf(':')+1); - aNSMap.emplace(newprefix, attr_value); - } - else if ( attr_qname == "xmlns" ) - { - // new default prefix - aNSMap.emplace(OUString(), attr_value); - } - else - { - aAttrMap.emplace(attr_qname, attr_value); - } + throw SAXException(); } - // does the element have a prefix? - OUString aPrefix; - OUString aURI; Reference< XElement > aElement; - idx = aName.indexOf(':'); - if (idx != -1) - { - aPrefix = aName.copy(0, idx); - } - else - aPrefix.clear(); + const OUString& aPrefix( SvXMLImport::getNamespacePrefixFromToken( nElement ) ); + const OUString& aURI( SvXMLImport::getNamespaceURIFromToken( nElement ) ); + OUString aQualifiedName( SvXMLImport::getNameFromToken( nElement ) ); + if( !aPrefix.isEmpty() ) + aQualifiedName = aPrefix + SvXMLImport::aNamespaceSeparator + aQualifiedName; - NSMap::const_iterator result = aNSMap.find(aPrefix); - if ( result != aNSMap.end()) + if ( !aURI.isEmpty() ) { // found a URI for prefix // qualified name - aElement = m_aDocument->createElementNS( result->second, aName); + aElement = m_aDocument->createElementNS( aURI, aQualifiedName ); } else { // no URI for prefix - aElement = m_aDocument->createElement(aName); + aElement = m_aDocument->createElement( aQualifiedName ); } aElement.set( m_aNodeStack.top()->appendChild(aElement), UNO_QUERY); m_aNodeStack.push(aElement); - // set non xmlns attributes - aPrefix.clear(); - aURI.clear(); - AttrMap::const_iterator a = aAttrMap.begin(); - while (a != aAttrMap.end()) + if (xAttribs.is()) + setElementFastAttributes(aElement, xAttribs); + } + + // For arbitrary meta elements + void SAL_CALL CSAXDocumentBuilder::startUnknownElement( const OUString& rNamespace, const OUString& rName, const Reference< XFastAttributeList >& xAttribs ) + { + ::osl::MutexGuard g(m_Mutex); + + if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT && + m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT) { - attr_qname = a->first; - attr_value = a->second; - idx = attr_qname.indexOf(':'); - if (idx != -1) - aPrefix = attr_qname.copy(0, idx); - else - aPrefix.clear(); + throw SAXException(); + } + + Reference< XElement > aElement; + if ( !rNamespace.isEmpty() ) + aElement = m_aDocument->createElementNS( rNamespace, rName ); + else + aElement = m_aDocument->createElement( rName ); - result = aNSMap.find(aPrefix); - if (result != aNSMap.end()) + aElement.set( m_aNodeStack.top()->appendChild(aElement), UNO_QUERY); + m_aNodeStack.push(aElement); + + if (xAttribs.is()) + { + setElementFastAttributes(aElement, xAttribs); + Sequence< css::xml::Attribute > unknownAttribs = xAttribs->getUnknownAttributes(); + sal_Int32 len = unknownAttribs.getLength(); + for ( sal_Int32 i = 0; i < len; i++ ) { - // set attribute with namespace - aElement->setAttributeNS(result->second, attr_qname, attr_value); + const OUString& rAttrValue = unknownAttribs[i].Value; + const OUString& rAttrName = unknownAttribs[i].Name; + const OUString& rAttrNamespace = unknownAttribs[i].NamespaceURL; + if ( !rAttrNamespace.isEmpty() ) + aElement->setAttributeNS( rAttrNamespace, rAttrName, rAttrValue ); + else + aElement->setAttribute( rAttrName, rAttrValue ); } + } + } + + void CSAXDocumentBuilder::setElementFastAttributes(const Reference< XElement >& aElement, const Reference< XFastAttributeList >& xAttribs) + { + sax_fastparser::FastAttributeList *pAttribList = + sax_fastparser::FastAttributeList::castToFastAttributeList( xAttribs ); + + for (auto &it : *pAttribList) + { + sal_Int32 nAttrToken = it.getToken(); + const OUString& aAttrPrefix( SvXMLImport::getNamespacePrefixFromToken( nAttrToken ) ); + const OUString& aAttrURI( SvXMLImport::getNamespaceURIFromToken( nAttrToken ) ); + OUString aAttrQualifiedName( SvXMLImport::getNameFromToken( nAttrToken ) ); + if( !aAttrPrefix.isEmpty() ) + aAttrQualifiedName = aAttrPrefix + SvXMLImport::aNamespaceSeparator + aAttrQualifiedName; + + if ( !aAttrURI.isEmpty() ) + aElement->setAttributeNS( aAttrURI, aAttrQualifiedName, it.toString() ); else - { - // set attribute without namespace - aElement->setAttribute(attr_qname, attr_value); - } - ++a; + aElement->setAttribute( aAttrQualifiedName, it.toString() ); } - m_aNSStack.push(aNSMap); } - void SAL_CALL CSAXDocumentBuilder::endElement(const OUString& aName) + void SAL_CALL CSAXDocumentBuilder::endFastElement( sal_Int32 nElement ) { ::osl::MutexGuard g(m_Mutex); @@ -291,63 +307,64 @@ namespace DOM throw SAXException(); Reference< XElement > aElement(aNode, UNO_QUERY); - OUString aRefName; - OUString aPrefix = aElement->getPrefix(); - if (!aPrefix.isEmpty()) - aRefName = aPrefix + ":" + aElement->getTagName(); - else - aRefName = aElement->getTagName(); - if (aRefName != aName) // consistency check + if( aElement->getPrefix() != SvXMLImport::getNamespacePrefixFromToken( nElement ) || + aElement->getTagName() != SvXMLImport::getNameFromToken( nElement ) ) // consistency check throw SAXException(); // pop it m_aNodeStack.pop(); - m_aNSStack.pop(); } - void SAL_CALL CSAXDocumentBuilder::characters(const OUString& aChars) + + void SAL_CALL CSAXDocumentBuilder::endUnknownElement( const OUString& /*rNamespace*/, const OUString& rName ) { ::osl::MutexGuard g(m_Mutex); - // append text node to the current top element - if (m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT && + // pop the current element from the stack + if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT && m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT) throw SAXException(); - Reference< XText > aText = m_aDocument->createTextNode(aChars); - m_aNodeStack.top()->appendChild(aText); - } - - void SAL_CALL CSAXDocumentBuilder::ignorableWhitespace(const OUString& ) - { - ::osl::MutexGuard g(m_Mutex); + Reference< XNode > aNode(m_aNodeStack.top()); + if (aNode->getNodeType() != NodeType_ELEMENT_NODE) + throw SAXException(); - // ignore ignorable whitespace - if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT && - m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT) + Reference< XElement > aElement(aNode, UNO_QUERY); + OUString aRefName; + const OUString& aPrefix = aElement->getPrefix(); + if (!aPrefix.isEmpty()) + aRefName = aPrefix + SvXMLImport::aNamespaceSeparator + aElement->getTagName(); + else + aRefName = aElement->getTagName(); + if (aRefName != rName) // consistency check throw SAXException(); + + // pop it + m_aNodeStack.pop(); } - void SAL_CALL CSAXDocumentBuilder::processingInstruction(const OUString& aTarget, const OUString& aData) + Reference< XFastContextHandler > SAL_CALL CSAXDocumentBuilder::createFastChildContext( sal_Int32/* nElement */, const Reference< XFastAttributeList >&/* xAttribs */ ) { - ::osl::MutexGuard g(m_Mutex); + return nullptr; + } - // append PI node to the current top - if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT && - m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT) - throw SAXException(); - Reference< XProcessingInstruction > aInstruction = m_aDocument->createProcessingInstruction( - aTarget, aData); - m_aNodeStack.top()->appendChild(aInstruction); + Reference< XFastContextHandler > SAL_CALL CSAXDocumentBuilder::createUnknownChildContext( const OUString&/* rNamespace */, const OUString&/* rName */, const Reference< XFastAttributeList >&/* xAttribs */ ) + { + return nullptr; } - void SAL_CALL CSAXDocumentBuilder::setDocumentLocator(const Reference< XLocator >& aLocator) + void SAL_CALL CSAXDocumentBuilder::characters( const OUString& rChars ) { ::osl::MutexGuard g(m_Mutex); - // set the document locator... - m_aLocator = aLocator; + // append text node to the current top element + if (m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT && + m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT) + throw SAXException(); + + Reference< XText > aText = m_aDocument->createTextNode(rChars); + m_aNodeStack.top()->appendChild(aText); } } diff --git a/unoxml/source/dom/saxbuilder.hxx b/unoxml/source/dom/saxbuilder.hxx index dd2331426c63..6f2ab24fcbbd 100644 --- a/unoxml/source/dom/saxbuilder.hxx +++ b/unoxml/source/dom/saxbuilder.hxx @@ -43,10 +43,6 @@ namespace DOM { - - typedef std::map< OUString, OUString > NSMap; - typedef std::map< OUString, OUString > AttrMap; - class CSAXDocumentBuilder : public ::cppu::WeakImplHelper< css::xml::dom::XSAXDocumentBuilder2, css::lang::XServiceInfo > { @@ -57,7 +53,6 @@ namespace DOM css::xml::dom::SAXDocumentBuilderState m_aState; std::stack< css::uno::Reference< css::xml::dom::XNode > > m_aNodeStack; - std::stack< NSMap > m_aNSStack; css::uno::Reference< css::xml::dom::XDocument > m_aDocument; css::uno::Reference< css::xml::dom::XDocumentFragment > m_aFragment; @@ -73,24 +68,28 @@ namespace DOM static css::uno::Reference< XInterface > _getInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& rSMgr); explicit CSAXDocumentBuilder(const css::uno::Reference< css::lang::XMultiServiceFactory >& mgr); + void setElementFastAttributes(const css::uno::Reference< css::xml::dom::XElement >& aElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttribs); + // XServiceInfo virtual OUString SAL_CALL getImplementationName() override; virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override; virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames () override; - // XDocumentHandler + // XFastDocumentHandler virtual void SAL_CALL startDocument() override; virtual void SAL_CALL endDocument() override; - virtual void SAL_CALL startElement( const OUString& aName, - const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs ) override; - virtual void SAL_CALL endElement( const OUString& aName ) override; - virtual void SAL_CALL characters( const OUString& aChars ) override; - virtual void SAL_CALL ignorableWhitespace( const OUString& aWhitespaces ) override; - virtual void SAL_CALL processingInstruction( const OUString& aTarget, - const OUString& aData ) override; + virtual void SAL_CALL processingInstruction( const OUString& rTarget, const OUString& rData ) override; virtual void SAL_CALL setDocumentLocator( const css::uno::Reference< css::xml::sax::XLocator >& xLocator ) override; + // XFastContextHandler + virtual void SAL_CALL startFastElement( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override; + virtual void SAL_CALL startUnknownElement( const OUString& Namespace, const OUString& Name, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override; + virtual void SAL_CALL endFastElement( sal_Int32 Element ) override; + virtual void SAL_CALL endUnknownElement( const OUString& Namespace, const OUString& Name ) override; + virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override; + virtual css::uno::Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const OUString& Namespace, const OUString& Name, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override; + virtual void SAL_CALL characters( const OUString& aChars ) override; // XSAXDocumentBuilder virtual css::xml::dom::SAXDocumentBuilderState SAL_CALL getState() override; diff --git a/xmloff/inc/SchXMLImport.hxx b/xmloff/inc/SchXMLImport.hxx index 3248d4ceadbd..5b9db7bdac34 100644 --- a/xmloff/inc/SchXMLImport.hxx +++ b/xmloff/inc/SchXMLImport.hxx @@ -159,6 +159,9 @@ protected: const OUString& rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override; + virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement, + const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override; + public: SchXMLImport( const css::uno::Reference< css::uno::XComponentContext >& xContext, diff --git a/xmloff/source/chart/SchXMLImport.cxx b/xmloff/source/chart/SchXMLImport.cxx index eab97676edff..c1cdfc91d813 100644 --- a/xmloff/source/chart/SchXMLImport.cxx +++ b/xmloff/source/chart/SchXMLImport.cxx @@ -528,16 +528,7 @@ SvXMLImportContext *SchXMLImport::CreateDocumentContext(sal_uInt16 const nPrefix uno::Reference<document::XDocumentPropertiesSupplier> xDPS( GetModel(), uno::UNO_QUERY); // mst@: right now, this seems to be not supported, so it is untested - if (xDPS.is()) { - pContext = (IsXMLToken(rLocalName, XML_DOCUMENT_META)) - ? new SvXMLMetaDocumentContext(*this, - XML_NAMESPACE_OFFICE, rLocalName, - xDPS->getDocumentProperties()) - // flat OpenDocument file format - : new SchXMLFlatDocContext_Impl( - *maImportHelper.get(), *this, nPrefix, rLocalName, - xDPS->getDocumentProperties()); - } else { + if (!xDPS.is()) { pContext = (IsXMLToken(rLocalName, XML_DOCUMENT_META)) ? SvXMLImport::CreateDocumentContext(nPrefix, rLocalName, xAttrList) : new SchXMLDocContext( *maImportHelper.get(), *this, @@ -550,6 +541,36 @@ SvXMLImportContext *SchXMLImport::CreateDocumentContext(sal_uInt16 const nPrefix return pContext; } +SvXMLImportContext *SchXMLImport::CreateFastContext( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) +{ + SvXMLImportContext* pContext = nullptr; + + switch (nElement) + { + case XML_ELEMENT( OFFICE, XML_DOCUMENT ): + case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ): + { + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + GetModel(), uno::UNO_QUERY); + // mst@: right now, this seems to be not supported, so it is untested + if (xDPS.is()) { + pContext = (nElement == XML_ELEMENT( OFFICE, XML_DOCUMENT_META )) + ? new SvXMLMetaDocumentContext(*this, + xDPS->getDocumentProperties()) + // flat OpenDocument file format + : new SchXMLFlatDocContext_Impl( + *maImportHelper.get(), *this, nElement, + xDPS->getDocumentProperties()); + } + } + break; + default: + pContext = new SvXMLImportContext( *this ); + } + return pContext; +} + SvXMLImportContext* SchXMLImport::CreateStylesContext( const OUString& rLocalName, const Reference<xml::sax::XAttributeList>& xAttrList ) diff --git a/xmloff/source/chart/contexts.cxx b/xmloff/source/chart/contexts.cxx index 2ddb5030cb6c..ebba9adaed70 100644 --- a/xmloff/source/chart/contexts.cxx +++ b/xmloff/source/chart/contexts.cxx @@ -77,6 +77,18 @@ SchXMLDocContext::SchXMLDocContext( SchXMLImportHelper& rImpHelper, !IsXMLToken( rLName, XML_DOCUMENT_CONTENT) ), "xmloff.chart", "SchXMLDocContext instantiated with no <office:document> element" ); } +SchXMLDocContext::SchXMLDocContext( SchXMLImportHelper& rImpHelper, + SvXMLImport& rImport, + sal_Int32 nElement ) : + SvXMLImportContext( rImport ), + mrImportHelper( rImpHelper ) +{ + SAL_WARN_IF(( nElement != XML_ELEMENT( OFFICE, XML_DOCUMENT ) && + nElement != XML_ELEMENT( OFFICE, XML_DOCUMENT_META ) && + nElement != XML_ELEMENT( OFFICE, XML_DOCUMENT_STYLES ) && + nElement != XML_ELEMENT( OFFICE, XML_DOCUMENT_CONTENT ) ), "xmloff.chart", "SchXMLDocContext instantiated with no <office:document> element" ); +} + SchXMLDocContext::~SchXMLDocContext() {} @@ -122,31 +134,33 @@ SvXMLImportContextRef SchXMLDocContext::CreateChildContext( return xContext; } +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SchXMLDocContext::createFastChildContext( + sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) +{ + return new SvXMLImportContext( GetImport() ); +} + SchXMLFlatDocContext_Impl::SchXMLFlatDocContext_Impl( SchXMLImportHelper& i_rImpHelper, SchXMLImport& i_rImport, - sal_uInt16 i_nPrefix, const OUString & i_rLName, + sal_Int32 i_nElement, const uno::Reference<document::XDocumentProperties>& i_xDocProps) : - SvXMLImportContext(i_rImport, i_nPrefix, i_rLName), - SchXMLDocContext(i_rImpHelper, i_rImport, i_nPrefix, i_rLName), - SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName, - i_xDocProps) + SvXMLImportContext(i_rImport), + SchXMLDocContext(i_rImpHelper, i_rImport, i_nElement), + SvXMLMetaDocumentContext(i_rImport, i_xDocProps) { } -SvXMLImportContextRef SchXMLFlatDocContext_Impl::CreateChildContext( - sal_uInt16 i_nPrefix, const OUString& i_rLocalName, - const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SchXMLFlatDocContext_Impl::createFastChildContext( + sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) { // behave like meta base class iff we encounter office:meta - const SvXMLTokenMap& rTokenMap = - mrImportHelper.GetDocElemTokenMap(); - if ( XML_TOK_DOC_META == rTokenMap.Get( i_nPrefix, i_rLocalName ) ) { - return SvXMLMetaDocumentContext::CreateChildContext( - i_nPrefix, i_rLocalName, i_xAttrList ); + if ( nElement == XML_ELEMENT( OFFICE, XML_META ) ) { + return SvXMLMetaDocumentContext::createFastChildContext( + nElement, xAttrList ); } else { - return SchXMLDocContext::CreateChildContext( - i_nPrefix, i_rLocalName, i_xAttrList ); + return SchXMLDocContext::createFastChildContext( + nElement, xAttrList ); } } diff --git a/xmloff/source/chart/contexts.hxx b/xmloff/source/chart/contexts.hxx index 9820cd3b76e4..c2980d800682 100644 --- a/xmloff/source/chart/contexts.hxx +++ b/xmloff/source/chart/contexts.hxx @@ -47,13 +47,21 @@ public: SvXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName ); - virtual ~SchXMLDocContext() override; + SchXMLDocContext( + SchXMLImportHelper& rImpHelper, + SvXMLImport& rImport, + sal_Int32 nElement ); + + virtual ~SchXMLDocContext() override; virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; }; // context for flat file xml format @@ -64,12 +72,11 @@ public: SchXMLFlatDocContext_Impl( SchXMLImportHelper& i_rImpHelper, SchXMLImport& i_rImport, - sal_uInt16 i_nPrefix, const OUString & i_rLName, + sal_Int32 i_nElement, const css::uno::Reference<css::document::XDocumentProperties>& i_xDocProps); - virtual SvXMLImportContextRef CreateChildContext( - sal_uInt16 i_nPrefix, const OUString& i_rLocalName, - const css::uno::Reference<css::xml::sax::XAttributeList>& i_xAttrList) override; + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; }; class SchXMLBodyContext : public SvXMLImportContext diff --git a/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx b/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx index a90ec6b643bc..bfa90235b40b 100644 --- a/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx +++ b/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx @@ -116,6 +116,9 @@ void XMLEmbeddedObjectImportContext::SetComponent( Reference< XComponent > const if( !xHandler.is() ) return; + if (SvXMLImport *pFastHandler = dynamic_cast<SvXMLImport*>(xHandler.get())) + xHandler.set( new SvXMLLegacyToFastDocHandler( pFastHandler ) ); + try { Reference < XModifiable2 > xModifiable2( rComp, UNO_QUERY_THROW ); diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx index b92d5edc64c1..ba656fe41131 100644 --- a/xmloff/source/core/xmlimp.cxx +++ b/xmloff/source/core/xmlimp.cxx @@ -80,6 +80,7 @@ using namespace ::xmloff::token; css::uno::Reference< css::xml::sax::XFastTokenHandler > SvXMLImport::xTokenHandler( new FastTokenHandler() ); std::unordered_map< sal_Int32, std::pair< OUString, OUString > > SvXMLImport::aNamespaceMap; +std::unordered_map< OUString, OUString, OUStringHash > SvXMLImport::aNamespaceURIPrefixMap; const OUString SvXMLImport::aDefaultNamespace = OUString(""); const OUString SvXMLImport::aNamespaceSeparator = OUString(":"); bool SvXMLImport::bIsNSMapsInitialized = false; @@ -1125,6 +1126,11 @@ void SAL_CALL SvXMLImport::initialize( const uno::Sequence< uno::Any >& aArgumen } } } + + uno::Reference<lang::XInitialization> const xInit(mxParser, uno::UNO_QUERY_THROW); + uno::Sequence<uno::Any> args(1); + args[0] <<= OUString("IgnoreMissingNSDecl"); + xInit->initialize( args ); } // XServiceInfo @@ -2062,14 +2068,35 @@ const OUString SvXMLImport::getNamespacePrefixFromToken( sal_Int32 nToken ) return OUString(); } +const OUString SvXMLImport::getNamespaceURIFromToken( sal_Int32 nToken ) +{ + sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT; + auto aIter( aNamespaceMap.find( nNamespaceToken ) ); + if( aIter != aNamespaceMap.end() ) + return (*aIter).second.second; + else + return OUString(); +} + +const OUString SvXMLImport::getNamespacePrefixFromURI( const OUString& rURI ) +{ + auto aIter( aNamespaceURIPrefixMap.find(rURI) ); + if( aIter != aNamespaceURIPrefixMap.end() ) + return (*aIter).second; + else + return OUString(); +} + void SvXMLImport::initializeNamespaceMaps() { auto mapTokenToNamespace = [&]( sal_Int32 nToken, sal_Int32 nPrefix, sal_Int32 nNamespace ) { if ( nToken >= 0 ) { - aNamespaceMap[ nToken + 1 ] = std::make_pair( GetXMLToken( static_cast<XMLTokenEnum>( nPrefix ) ), - GetXMLToken( static_cast<XMLTokenEnum>( nNamespace ) ) ); + const OUString& sNamespace = GetXMLToken( static_cast<XMLTokenEnum>( nNamespace ) ); + const OUString& sPrefix = GetXMLToken( static_cast<XMLTokenEnum>( nPrefix ) ); + aNamespaceMap[ nToken + 1 ] = std::make_pair( sPrefix, sNamespace ); + aNamespaceURIPrefixMap.emplace( sNamespace, sPrefix ); } }; @@ -2180,6 +2207,12 @@ void SvXMLImportFastNamespaceHandler::addNSDeclAttributes( rtl::Reference < comp void SvXMLImportFastNamespaceHandler::registerNamespace( const OUString& rNamespacePrefix, const OUString& rNamespaceURI ) { + // Elements with default namespace parsed by FastParser have namepsace prefix. + // A default namespace needs to be registered with the prefix, to maintan the compatibility. + if ( rNamespacePrefix.isEmpty() ) + m_aNamespaceDefines.push_back( o3tl::make_unique<NamespaceDefine>( + SvXMLImport::getNamespacePrefixFromURI( rNamespaceURI ), rNamespaceURI) ); + m_aNamespaceDefines.push_back( o3tl::make_unique<NamespaceDefine>( rNamespacePrefix, rNamespaceURI) ); } diff --git a/xmloff/source/draw/sdxmlimp.cxx b/xmloff/source/draw/sdxmlimp.cxx index 3d5e91ea814e..2430ff381a13 100644 --- a/xmloff/source/draw/sdxmlimp.cxx +++ b/xmloff/source/draw/sdxmlimp.cxx @@ -90,23 +90,26 @@ protected: SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); } public: - SdXMLDocContext_Impl( - SdXMLImport& rImport, - sal_uInt16 nPrfx, - const OUString& rLName, - const uno::Reference<xml::sax::XAttributeList>& xAttrList); + SdXMLDocContext_Impl( SdXMLImport& rImport ); virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference<xml::sax::XAttributeList>& xAttrList) override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual void SAL_CALL characters( const OUString& /*aChars*/ ) override {} + + virtual void SAL_CALL startFastElement( sal_Int32 /*nElement*/, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ ) override {} + + virtual void SAL_CALL endFastElement( sal_Int32 /*nElement*/ ) override {} }; SdXMLDocContext_Impl::SdXMLDocContext_Impl( - SdXMLImport& rImport, - sal_uInt16 nPrfx, - const OUString& rLName, - const uno::Reference<xml::sax::XAttributeList>&) -: SvXMLImportContext(rImport, nPrfx, rLName) + SdXMLImport& rImport ) +: SvXMLImportContext(rImport) { } @@ -193,44 +196,65 @@ SvXMLImportContextRef SdXMLDocContext_Impl::CreateChildContext( return xContext; } +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SdXMLDocContext_Impl::createFastChildContext( + sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) +{ + return new SvXMLImportContext( GetImport() ); +} + // context for flat file xml format class SdXMLFlatDocContext_Impl : public SdXMLDocContext_Impl, public SvXMLMetaDocumentContext { public: SdXMLFlatDocContext_Impl( SdXMLImport& i_rImport, - sal_uInt16 i_nPrefix, const OUString & i_rLName, - const uno::Reference<xml::sax::XAttributeList>& i_xAttrList, - const uno::Reference<document::XDocumentProperties>& i_xDocProps); + const uno::Reference<document::XDocumentProperties>& i_xDocProps ); - virtual SvXMLImportContextRef CreateChildContext( - sal_uInt16 i_nPrefix, const OUString& i_rLocalName, - const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) override; + virtual void SAL_CALL startFastElement( sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override; + + virtual void SAL_CALL characters( const OUString& aChars ) override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; }; SdXMLFlatDocContext_Impl::SdXMLFlatDocContext_Impl( SdXMLImport& i_rImport, - sal_uInt16 i_nPrefix, const OUString & i_rLName, - const uno::Reference<xml::sax::XAttributeList>& i_xAttrList, const uno::Reference<document::XDocumentProperties>& i_xDocProps) : - SvXMLImportContext(i_rImport, i_nPrefix, i_rLName), - SdXMLDocContext_Impl(i_rImport, i_nPrefix, i_rLName, i_xAttrList), - SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName, - i_xDocProps) + SvXMLImportContext(i_rImport), + SdXMLDocContext_Impl(i_rImport), + SvXMLMetaDocumentContext(i_rImport, i_xDocProps) +{ +} + +void SAL_CALL SdXMLFlatDocContext_Impl::startFastElement( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) +{ + SvXMLMetaDocumentContext::startFastElement(nElement, xAttrList); +} + +void SAL_CALL SdXMLFlatDocContext_Impl::endFastElement( sal_Int32 nElement ) +{ + SvXMLMetaDocumentContext::endFastElement(nElement); +} + +void SAL_CALL SdXMLFlatDocContext_Impl::characters( const OUString& rChars ) { + SvXMLMetaDocumentContext::characters(rChars); } -SvXMLImportContextRef SdXMLFlatDocContext_Impl::CreateChildContext( - sal_uInt16 i_nPrefix, const OUString& i_rLocalName, - const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SdXMLFlatDocContext_Impl::createFastChildContext( + sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) { // behave like meta base class iff we encounter office:meta - const SvXMLTokenMap& rTokenMap = GetSdImport().GetDocElemTokenMap(); - if ( XML_TOK_DOC_META == rTokenMap.Get( i_nPrefix, i_rLocalName ) ) { - return SvXMLMetaDocumentContext::CreateChildContext( - i_nPrefix, i_rLocalName, i_xAttrList ); + if ( nElement == XML_ELEMENT( OFFICE, XML_META ) ) { + return SvXMLMetaDocumentContext::createFastChildContext( + nElement, xAttrList ); } else { - return SdXMLDocContext_Impl::CreateChildContext( - i_nPrefix, i_rLocalName, i_xAttrList ); + return SdXMLDocContext_Impl::createFastChildContext( + nElement, xAttrList ); } } @@ -584,37 +608,37 @@ const SvXMLTokenMap& SdXMLImport::GetPresentationPlaceholderAttrTokenMap() return *mpPresentationPlaceholderAttrTokenMap; } -SvXMLImportContext *SdXMLImport::CreateDocumentContext(sal_uInt16 nPrefix, - const OUString& rLocalName, - const uno::Reference<xml::sax::XAttributeList>& xAttrList) +SvXMLImportContext *SdXMLImport::CreateFastContext( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) { SvXMLImportContext* pContext = nullptr; - if(XML_NAMESPACE_OFFICE == nPrefix && - ( IsXMLToken( rLocalName, XML_DOCUMENT_STYLES ) || - IsXMLToken( rLocalName, XML_DOCUMENT_CONTENT ) || - IsXMLToken( rLocalName, XML_DOCUMENT_SETTINGS ) )) + switch (nElement) { - pContext = new SdXMLDocContext_Impl(*this, nPrefix, rLocalName, xAttrList); - } else if ( (XML_NAMESPACE_OFFICE == nPrefix) && - ( IsXMLToken(rLocalName, XML_DOCUMENT_META)) ) { - pContext = CreateMetaContext(rLocalName, xAttrList); - } else if ( (XML_NAMESPACE_OFFICE == nPrefix) && - ( IsXMLToken(rLocalName, XML_DOCUMENT)) ) { - uno::Reference<document::XDocumentPropertiesSupplier> xDPS( - GetModel(), uno::UNO_QUERY_THROW); - // flat OpenDocument file format - pContext = new SdXMLFlatDocContext_Impl( *this, nPrefix, rLocalName, - xAttrList, xDPS->getDocumentProperties()); - } else { - pContext = SvXMLImport::CreateDocumentContext(nPrefix, rLocalName, xAttrList); + case XML_ELEMENT( OFFICE, XML_DOCUMENT_STYLES ): + case XML_ELEMENT( OFFICE, XML_DOCUMENT_CONTENT ): + case XML_ELEMENT( OFFICE, XML_DOCUMENT_SETTINGS ): + pContext = new SdXMLDocContext_Impl(*this); + break; + case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ): + pContext = CreateMetaContext(nElement, xAttrList); + break; + case XML_ELEMENT( OFFICE, XML_DOCUMENT ): + { + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + GetModel(), uno::UNO_QUERY_THROW); + // flat OpenDocument file format + pContext = new SdXMLFlatDocContext_Impl( *this, xDPS->getDocumentProperties()); + } + break; + default: + pContext = SvXMLImport::CreateFastContext(nElement, xAttrList); } - return pContext; } -SvXMLImportContext *SdXMLImport::CreateMetaContext(const OUString& rLocalName, - const uno::Reference<xml::sax::XAttributeList>&) +SvXMLImportContext *SdXMLImport::CreateMetaContext(const sal_Int32 /*nElement*/, + const uno::Reference<xml::sax::XFastAttributeList>&) { SvXMLImportContext* pContext = nullptr; @@ -624,14 +648,12 @@ SvXMLImportContext *SdXMLImport::CreateMetaContext(const OUString& rLocalName, GetModel(), uno::UNO_QUERY_THROW); uno::Reference<document::XDocumentProperties> const xDocProps( !mbLoadDoc ? nullptr : xDPS->getDocumentProperties()); - pContext = new SvXMLMetaDocumentContext(*this, - XML_NAMESPACE_OFFICE, rLocalName, - xDocProps); + pContext = new SvXMLMetaDocumentContext(*this, xDocProps); } if(!pContext) { - pContext = new SvXMLImportContext(*this, XML_NAMESPACE_OFFICE, rLocalName); + pContext = new SvXMLImportContext(*this); } return pContext; diff --git a/xmloff/source/draw/sdxmlimp_impl.hxx b/xmloff/source/draw/sdxmlimp_impl.hxx index 3900aa02aaf4..7b029895c766 100644 --- a/xmloff/source/draw/sdxmlimp_impl.hxx +++ b/xmloff/source/draw/sdxmlimp_impl.hxx @@ -176,9 +176,10 @@ class SdXMLImport: public SvXMLImport protected: - virtual SvXMLImportContext *CreateDocumentContext(sal_uInt16 nPrefix, - const OUString& rLocalName, - const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList) override; + // This method is called after the namespace map has been updated, but + // before a context for the current element has been pushed. + virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement, + const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override; public: SdXMLImport( @@ -198,8 +199,8 @@ public: // namespace office // NB: in contrast to other CreateFooContexts, this particular one handles // the root element (i.e. office:document-meta) - SvXMLImportContext* CreateMetaContext(const OUString& rLocalName, - const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList); + SvXMLImportContext* CreateMetaContext(const sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList); SvXMLImportContext* CreateScriptContext( const OUString& rLocalName ); SvXMLImportContext* CreateBodyContext(const OUString& rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList); diff --git a/xmloff/source/meta/MetaImportComponent.cxx b/xmloff/source/meta/MetaImportComponent.cxx index d10d9c8f9bd0..6f5d7c0d1a5f 100644 --- a/xmloff/source/meta/MetaImportComponent.cxx +++ b/xmloff/source/meta/MetaImportComponent.cxx @@ -43,10 +43,8 @@ public: protected: - virtual SvXMLImportContext* CreateDocumentContext( - sal_uInt16 nPrefix, - const OUString& rLocalName, - const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList ) override; + virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement, + const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override; // XImporter virtual void SAL_CALL setTargetDocument( const css::uno::Reference< css::lang::XComponent >& xDoc ) override; @@ -68,25 +66,22 @@ XMLMetaImportComponent::XMLMetaImportComponent( { } -SvXMLImportContext* XMLMetaImportComponent::CreateDocumentContext( - sal_uInt16 nPrefix, - const OUString& rLocalName, - const uno::Reference<xml::sax::XAttributeList > & xAttrList ) +SvXMLImportContext *XMLMetaImportComponent::CreateFastContext( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) { - if ( (XML_NAMESPACE_OFFICE == nPrefix) && - IsXMLToken(rLocalName, XML_DOCUMENT_META) ) + if (nElement == XML_ELEMENT( OFFICE, XML_DOCUMENT_META )) { if (!mxDocProps.is()) { throw uno::RuntimeException( - "XMLMetaImportComponent::CreateContext: setTargetDocument " + "XMLMetaImportComponent::CreateFastContext: setTargetDocument " "has not been called", *this); } return new SvXMLMetaDocumentContext( - *this, nPrefix, rLocalName, mxDocProps); + *this, mxDocProps); } else { - return SvXMLImport::CreateDocumentContext(nPrefix, rLocalName, xAttrList); + return SvXMLImport::CreateFastContext(nElement, xAttrList); } } diff --git a/xmloff/source/meta/xmlmetai.cxx b/xmloff/source/meta/xmlmetai.cxx index 1f9a1b9604e2..10f60b7717dd 100644 --- a/xmloff/source/meta/xmlmetai.cxx +++ b/xmloff/source/meta/xmlmetai.cxx @@ -41,57 +41,66 @@ private: css::uno::Reference< css::xml::dom::XSAXDocumentBuilder2> mxDocBuilder; public: - XMLDocumentBuilderContext(SvXMLImport& rImport, sal_uInt16 nPrfx, - const OUString& rLName, - const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList, + XMLDocumentBuilderContext(SvXMLImport& rImport, sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList, const css::uno::Reference< css::xml::dom::XSAXDocumentBuilder2>& rDocBuilder); - virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix, - const OUString& rLocalName, - const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList ) override; + virtual void SAL_CALL characters( const OUString& aChars ) override; - virtual void StartElement( const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override; + virtual void SAL_CALL startFastElement( sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; - virtual void Characters( const OUString& rChars ) override; + virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override; + + virtual void SAL_CALL startUnknownElement( const OUString& Namespace, const OUString& Name, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override; + + virtual void SAL_CALL endUnknownElement( const OUString& Namespace, const OUString& Name ) override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; - virtual void EndElement() override; }; XMLDocumentBuilderContext::XMLDocumentBuilderContext(SvXMLImport& rImport, - sal_uInt16 nPrfx, const OUString& rLName, - const uno::Reference<xml::sax::XAttributeList>&, + sal_Int32 /*nElement*/, const uno::Reference<xml::sax::XFastAttributeList>&, const uno::Reference<xml::dom::XSAXDocumentBuilder2>& rDocBuilder) : - SvXMLImportContext( rImport, nPrfx, rLName ), + SvXMLImportContext( rImport ), mxDocBuilder(rDocBuilder) { } -SvXMLImportContextRef -XMLDocumentBuilderContext::CreateChildContext( sal_uInt16 nPrefix, - const OUString& rLocalName, - const uno::Reference< xml::sax::XAttributeList>& rAttrs) +void SAL_CALL XMLDocumentBuilderContext::startFastElement( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& xAttribs ) +{ + mxDocBuilder->startFastElement(nElement, xAttribs); +} + +void SAL_CALL XMLDocumentBuilderContext::endFastElement( sal_Int32 nElement ) +{ + mxDocBuilder->endFastElement(nElement); +} + +void SAL_CALL XMLDocumentBuilderContext::startUnknownElement( const OUString& rNamespace, + const OUString& rName, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) { - return new XMLDocumentBuilderContext( - GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder); + mxDocBuilder->startUnknownElement(rNamespace, rName, xAttrList); } -void XMLDocumentBuilderContext::StartElement( - const uno::Reference< xml::sax::XAttributeList >& xAttrList ) +void SAL_CALL XMLDocumentBuilderContext::endUnknownElement( const OUString& rNamespace, const OUString& rName ) { - mxDocBuilder->startElement( - GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()), - xAttrList); + mxDocBuilder->endUnknownElement(rNamespace, rName); } -void XMLDocumentBuilderContext::Characters( const OUString& rChars ) +void SAL_CALL XMLDocumentBuilderContext::characters( const OUString& rChars ) { mxDocBuilder->characters(rChars); } -void XMLDocumentBuilderContext::EndElement() +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL XMLDocumentBuilderContext::createFastChildContext( + sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) { - mxDocBuilder->endElement( - GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName())); + return new XMLDocumentBuilderContext( GetImport(), nElement, xAttrList, mxDocBuilder ); } static void @@ -150,19 +159,6 @@ lcl_initGenerator(SvXMLImport & rImport, } SvXMLMetaDocumentContext::SvXMLMetaDocumentContext(SvXMLImport& rImport, - sal_uInt16 nPrfx, const OUString& rLName, - const uno::Reference<document::XDocumentProperties>& xDocProps) : - SvXMLImportContext( rImport, nPrfx, rLName ), - mxDocProps(xDocProps), - mxDocBuilder( - xml::dom::SAXDocumentBuilder::create( - comphelper::getProcessComponentContext())) -{ -// #i103539#: must always read meta.xml for generator, xDocProps unwanted then -// OSL_ENSURE(xDocProps.is(), "SvXMLMetaDocumentContext: no document props"); -} - -SvXMLMetaDocumentContext::SvXMLMetaDocumentContext(SvXMLImport& rImport, const uno::Reference<document::XDocumentProperties>& xDocProps) : SvXMLImportContext( rImport ), mxDocProps(xDocProps), @@ -178,39 +174,18 @@ SvXMLMetaDocumentContext::~SvXMLMetaDocumentContext() { } -SvXMLImportContextRef SvXMLMetaDocumentContext::CreateChildContext( - sal_uInt16 nPrefix, const OUString& rLocalName, - const uno::Reference<xml::sax::XAttributeList>& rAttrs) -{ - if ( (XML_NAMESPACE_OFFICE == nPrefix) && - IsXMLToken(rLocalName, XML_META) ) - { - return new XMLDocumentBuilderContext( - GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder); - } - else - { - return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); - } -} - -void SvXMLMetaDocumentContext::StartElement( - const uno::Reference< xml::sax::XAttributeList >& xAttrList ) +void SAL_CALL SvXMLMetaDocumentContext::startFastElement( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) { mxDocBuilder->startDocument(); // hardcode office:document-meta (necessary in case of flat file ODF) - mxDocBuilder->startElement( - GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), - GetXMLToken(XML_DOCUMENT_META)), xAttrList); - + mxDocBuilder->startFastElement( ( nElement & NMSP_MASK ) | XML_DOCUMENT_META, xAttrList ); } -void SvXMLMetaDocumentContext::EndElement() +void SAL_CALL SvXMLMetaDocumentContext::endFastElement( sal_Int32 nElement ) { // hardcode office:document-meta (necessary in case of flat file ODF) - mxDocBuilder->endElement( - GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), - GetXMLToken(XML_DOCUMENT_META))); + mxDocBuilder->endFastElement( ( nElement & NMSP_MASK ) | XML_DOCUMENT_META ); mxDocBuilder->endDocument(); if (mxDocProps.is()) { @@ -222,6 +197,20 @@ void SvXMLMetaDocumentContext::EndElement() } } +void SAL_CALL SvXMLMetaDocumentContext::characters( const OUString& /*rChars*/ ) +{ +} + +uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SvXMLMetaDocumentContext::createFastChildContext( + sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) +{ + if ( nElement == ( NAMESPACE_TOKEN( XML_NAMESPACE_OFFICE ) | XML_META ) ) + return new XMLDocumentBuilderContext( + GetImport(), nElement, xAttrList, mxDocBuilder); + else + return new SvXMLImportContext( GetImport() ); +} + void SvXMLMetaDocumentContext::setBuildId(OUString const& i_rBuildId, const uno::Reference<beans::XPropertySet>& xImportInfo ) { OUString sBuildId; |