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 /unoxml | |
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>
Diffstat (limited to 'unoxml')
-rw-r--r-- | unoxml/Library_unoxml.mk | 1 | ||||
-rw-r--r-- | unoxml/source/dom/saxbuilder.cxx | 231 | ||||
-rw-r--r-- | unoxml/source/dom/saxbuilder.hxx | 25 |
3 files changed, 137 insertions, 120 deletions
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; |