/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include "xmlelementwrapper_xmlsecimpl.hxx" #include #include #ifdef UNX #define stricmp strcasecmp #endif using namespace com::sun::star; #define STRXMLNS "xmlns" /* used by the recursiveDelete method */ #define NODE_REMOVED 0 #define NODE_NOTREMOVED 1 #define NODE_STOPPED 2 XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl() : m_nCurrentPosition(0) , m_pStopAtNode(nullptr) , m_pCurrentReservedNode(nullptr) , m_nReservedNodeIndex(0) { saxHelper.startDocument(); m_pDocument = saxHelper.getDocument(); /* * creates the virtual root element */ saxHelper.startElement(u"root", uno::Sequence()); m_pRootElement = saxHelper.getCurrentNode(); m_pCurrentElement = m_pRootElement; } XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl() { saxHelper.endDocument(); xmlFreeDoc(m_pDocument); } void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent() /****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent ************************* * * NAME * getNextSAXEvent -- Prepares the next SAX event to be manipulate * * FUNCTION * When converting the document into SAX events, this method is used to * decide the next SAX event to be generated. * Two member variables are checked to make the decision, the * m_pCurrentElement and the m_nCurrentPosition. * The m_pCurrentElement represents the node which have been covered, and * the m_nCurrentPosition represents the event which have been sent. * For example, suppose that the m_pCurrentElement * points to element A, and the m_nCurrentPosition equals to * NODEPOSITION_STARTELEMENT, then the next SAX event should be the * endElement for element A if A has no child, or startElement for the * first child element of element A otherwise. * The m_nCurrentPosition can be one of following values: * NODEPOSITION_STARTELEMENT for startElement; * NODEPOSITION_ENDELEMENT for endElement; * NODEPOSITION_NORMAL for other SAX events; ******************************************************************************/ { assert(m_pCurrentElement != nullptr); /* * Get the next event through tree order. * * if the current event is a startElement, then the next * event depends on whether or not the current node has * children. */ if (m_nCurrentPosition == NODEPOSITION_STARTELEMENT) { /* * If the current node has children, then its first child * should be next current node, and the next event will be * startElement or characters(PI) based on that child's node * type. Otherwise, the endElement of current node is the * next event. */ if (m_pCurrentElement->children != nullptr) { m_pCurrentElement = m_pCurrentElement->children; m_nCurrentPosition = (m_pCurrentElement->type == XML_ELEMENT_NODE)? NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL; } else { m_nCurrentPosition = NODEPOSITION_ENDELEMENT; } } /* * if the current event is a not startElement, then the next * event depends on whether or not the current node has * following sibling. */ else if (m_nCurrentPosition == NODEPOSITION_ENDELEMENT || m_nCurrentPosition == NODEPOSITION_NORMAL) { xmlNodePtr pNextSibling = m_pCurrentElement->next; /* * If the current node has following sibling, that sibling * should be next current node, and the next event will be * startElement or characters(PI) based on that sibling's node * type. Otherwise, the endElement of current node's parent * becomes the next event. */ if (pNextSibling != nullptr) { m_pCurrentElement = pNextSibling; m_nCurrentPosition = (m_pCurrentElement->type == XML_ELEMENT_NODE)? NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL; } else { m_pCurrentElement = m_pCurrentElement->parent; m_nCurrentPosition = NODEPOSITION_ENDELEMENT; } } } void XMLDocumentWrapper_XmlSecImpl::sendStartElement( const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler, const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler2, const xmlNodePtr pNode) /****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************ * * NAME * sendStartElement -- Constructs a startElement SAX event * * FUNCTION * Used when converting the document into SAX event stream. * This method constructs a startElement SAX event for a particular * element, then calls the startElement methods of the XDocumentHandlers. * * INPUTS * xHandler - the first XDocumentHandler interface to receive the * startElement SAX event. It can be NULL. * xHandler2 - the second XDocumentHandler interface to receive the * startElement SAX event. It can't be NULL. * pNode - the node on which the startElement should be generated. * This node must be an element type. ******************************************************************************/ { rtl::Reference pAttributeList = new comphelper::AttributeList(); xmlNsPtr pNsDef = pNode->nsDef; while (pNsDef != nullptr) { const xmlChar* pNsPrefix = pNsDef->prefix; const xmlChar* pNsHref = pNsDef->href; if (pNsDef->prefix == nullptr) { pAttributeList->AddAttribute( u"" STRXMLNS ""_ustr, OUString::fromUtf8(reinterpret_cast(pNsHref))); } else { pAttributeList->AddAttribute( STRXMLNS ":" +OUString::fromUtf8(reinterpret_cast(pNsPrefix)), OUString::fromUtf8(reinterpret_cast(pNsHref))); } pNsDef = pNsDef->next; } xmlAttrPtr pAttr = pNode->properties; while (pAttr != nullptr) { const xmlChar* pAttrName = pAttr->name; xmlNsPtr pAttrNs = pAttr->ns; OUString ouAttrName; if (pAttrNs == nullptr) { ouAttrName = OUString::fromUtf8(reinterpret_cast(pAttrName)); } else { ouAttrName = OUString::fromUtf8(reinterpret_cast(pAttrNs->prefix)) + ":" + OUString::fromUtf8(reinterpret_cast(pAttrName)); } pAttributeList->AddAttribute( ouAttrName, OUString::fromUtf8(reinterpret_cast(pAttr->children->content))); pAttr = pAttr->next; } OString sNodeName = getNodeQName(pNode); if (xHandler.is()) { xHandler->startElement( OUString::fromUtf8(sNodeName), pAttributeList); } xHandler2->startElement( OUString::fromUtf8(sNodeName), pAttributeList); } void XMLDocumentWrapper_XmlSecImpl::sendEndElement( const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler, const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler2, const xmlNodePtr pNode) /****** XMLDocumentWrapper_XmlSecImpl/sendEndElement ************************** * * NAME * sendEndElement -- Constructs an endElement SAX event * * FUNCTION * Used when converting the document into SAX event stream. * This method constructs an endElement SAX event for a particular * element, then calls the endElement methods of the XDocumentHandlers. * * INPUTS * xHandler - the first XDocumentHandler interface to receive the * endElement SAX event. It can be NULL. * xHandler2 - the second XDocumentHandler interface to receive the * endElement SAX event. It can't be NULL. * pNode - the node on which the endElement should be generated. * This node must be an element type. ******************************************************************************/ { OString sNodeName = getNodeQName(pNode); if (xHandler.is()) { xHandler->endElement(OUString::fromUtf8(sNodeName)); } xHandler2->endElement(OUString::fromUtf8(sNodeName)); } void XMLDocumentWrapper_XmlSecImpl::sendNode( const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler, const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler2, const xmlNodePtr pNode) /****** XMLDocumentWrapper_XmlSecImpl/sendNode ******************************** * * NAME * sendNode -- Constructs a characters SAX event or a * processingInstruction SAX event * * FUNCTION * Used when converting the document into SAX event stream. * This method constructs a characters SAX event or a * processingInstructionfor SAX event based on the type of a particular * element, then calls the corresponding methods of the XDocumentHandlers. * * INPUTS * xHandler - the first XDocumentHandler interface to receive the * SAX event. It can be NULL. * xHandler2 - the second XDocumentHandler interface to receive the * SAX event. It can't be NULL. * pNode - the node on which the endElement should be generated. * If it is a text node, then a characters SAX event is * generated; if it is a PI node, then a * processingInstructionfor SAX event is generated. ******************************************************************************/ { xmlElementType type = pNode->type; if (type == XML_TEXT_NODE) { if (xHandler.is()) { xHandler->characters(OUString::fromUtf8(reinterpret_cast(pNode->content))); } xHandler2->characters(OUString::fromUtf8(reinterpret_cast(pNode->content))); } else if (type == XML_PI_NODE) { if (xHandler.is()) { xHandler->processingInstruction( OUString::fromUtf8(reinterpret_cast(pNode->name)), OUString::fromUtf8(reinterpret_cast(pNode->content))); } xHandler2->processingInstruction( OUString::fromUtf8(reinterpret_cast(pNode->name)), OUString::fromUtf8(reinterpret_cast(pNode->content))); } } OString XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode) /****** XMLDocumentWrapper_XmlSecImpl/getNodeQName **************************** * * NAME * getNodeQName -- Retrieves the qualified name of a node * * INPUTS * pNode - the node whose name will be retrieved * * RESULT * name - the node's qualified name ******************************************************************************/ { OString sNodeName(reinterpret_cast(pNode->name)); if (pNode->ns != nullptr) { xmlNsPtr pNs = pNode->ns; if (pNs->prefix != nullptr) { OString sPrefix(reinterpret_cast(pNs->prefix)); sNodeName = sPrefix + ":" + sNodeName; } } return sNodeName; } xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& xXMLElement) /****** XMLDocumentWrapper_XmlSecImpl/checkElement **************************** * * NAME * checkElement -- Retrieves the node wrapped by an XXMLElementWrapper * interface * * INPUTS * xXMLElement - the XXMLElementWrapper interface wrapping a node * * RESULT * node - the node wrapped in the XXMLElementWrapper interface ******************************************************************************/ { xmlNodePtr rc = nullptr; if (xXMLElement.is()) { XMLElementWrapper_XmlSecImpl* pElement = dynamic_cast(xXMLElement.get()); if( pElement == nullptr ) { throw uno::RuntimeException() ; } rc = pElement->getNativeElement(); } return rc; } sal_Int32 XMLDocumentWrapper_XmlSecImpl::recursiveDelete( const xmlNodePtr pNode) /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete ************************* * * NAME * recursiveDelete -- Deletes a particular node with its branch. * * FUNCTION * Deletes a particular node with its branch, while reserving the nodes * (and their branches) listed in the m_aReservedNodes. * The deletion process is performed in the tree order, that is, a node * is deleted after its previous sibling node is deleted, a parent node * is deleted after its branch is deleted. * During the deletion process when the m_pStopAtNode is reached, the * progress is interrupted at once. * * INPUTS * pNode - the node to be deleted * * RESULT * result - the result of the deletion process, can be one of following * values: * NODE_STOPPED - the process is interrupted by meeting the * m_pStopAtNode * NODE_NOTREMOVED - the pNode is not completely removed * because there is its descendant in the * m_aReservedNodes list * NODE_REMOVED - the pNode and its branch are completely * removed * * NOTES * The node in the m_aReservedNodes list must be in the tree order, otherwise * the result is unpredictable. ******************************************************************************/ { if (pNode == m_pStopAtNode) { return NODE_STOPPED; } if (pNode != m_pCurrentReservedNode) { xmlNodePtr pChild = pNode->children; xmlNodePtr pNextSibling; bool bIsRemoved = true; sal_Int32 nResult; while( pChild != nullptr ) { pNextSibling = pChild->next; nResult = recursiveDelete(pChild); switch (nResult) { case NODE_STOPPED: return NODE_STOPPED; case NODE_NOTREMOVED: bIsRemoved = false; break; case NODE_REMOVED: removeNode(pChild); break; default: throw uno::RuntimeException(); } pChild = pNextSibling; } if (pNode == m_pCurrentElement) { bIsRemoved = false; } return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED; } else { getNextReservedNode(); return NODE_NOTREMOVED; } } void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode() /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode ********************* * * NAME * getNextReservedNode -- Highlights the next reserved node in the * reserved node list * * FUNCTION * The m_aReservedNodes array holds a node list, while the * m_pCurrentReservedNode points to the one currently highlighted. * This method is used to highlight the next node in the node list. * This method is called at the time when the current highlighted node * has been already processed, and the next node should be ready. ******************************************************************************/ { if (m_nReservedNodeIndex < m_aReservedNodes.getLength()) { m_pCurrentReservedNode = checkElement( m_aReservedNodes[m_nReservedNodeIndex] ); m_nReservedNodeIndex ++; } else { m_pCurrentReservedNode = nullptr; } } void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const /****** XMLDocumentWrapper_XmlSecImpl/removeNode ****************************** * * NAME * removeNode -- Deletes a node with its branch unconditionally * * FUNCTION * Delete the node along with its branch from the document. * * INPUTS * pNode - the node to be deleted ******************************************************************************/ { /* you can't remove the current node */ OSL_ASSERT( m_pCurrentElement != pNode ); xmlAttrPtr pAttr = pNode->properties; while (pAttr != nullptr) { if (!stricmp(reinterpret_cast(pAttr->name), "id")) { xmlRemoveID(m_pDocument, pAttr); } pAttr = pAttr->next; } xmlUnlinkNode(pNode); xmlFreeNode(pNode); } void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode) const /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr ***************************** * * NAME * buildIDAttr -- build the ID attribute of a node * * INPUTS * pNode - the node whose id attribute will be built ******************************************************************************/ { xmlAttrPtr idAttr = xmlHasProp( pNode, reinterpret_cast("id") ); if (idAttr == nullptr) { idAttr = xmlHasProp( pNode, reinterpret_cast("Id") ); } if (idAttr != nullptr) { xmlChar* idValue = xmlNodeListGetString( m_pDocument, idAttr->children, 1 ) ; xmlAddID( nullptr, m_pDocument, idValue, idAttr ); } } void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode) const /****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink *************************** * * NAME * rebuildIDLink -- rebuild the ID link for the branch * * INPUTS * pNode - the node, from which the branch will be rebuilt ******************************************************************************/ { if (pNode != nullptr && pNode->type == XML_ELEMENT_NODE) { buildIDAttr( pNode ); xmlNodePtr child = pNode->children; while (child != nullptr) { rebuildIDLink(child); child = child->next; } } } /* XXMLDocumentWrapper */ uno::Reference< css::xml::wrapper::XXMLElementWrapper > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getCurrentElement( ) { return new XMLElementWrapper_XmlSecImpl(m_pCurrentElement); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& element ) { m_pCurrentElement = checkElement( element ); saxHelper.setCurrentNode( m_pCurrentElement ); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::removeCurrentElement( ) { OSL_ASSERT( m_pCurrentElement != nullptr ); xmlNodePtr pOldCurrentElement = m_pCurrentElement; /* * pop the top node in the parser context's * nodeTab stack, then the parent of that node will * automatically become the new stack top, and * the current node as well. */ saxHelper.endElement(OUString::fromUtf8(reinterpret_cast(pOldCurrentElement->name))); m_pCurrentElement = saxHelper.getCurrentNode(); /* * remove the node */ removeNode(pOldCurrentElement); } sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrent( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node ) { xmlNodePtr pNode = checkElement(node); return (pNode == m_pCurrentElement); } sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty( ) { bool rc = false; if (m_pCurrentElement->children == nullptr) { rc = true; } return rc; } OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getNodeName( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node ) { xmlNodePtr pNode = checkElement(node); return OUString::fromUtf8(reinterpret_cast(pNode->name)); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::clearUselessData( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node, const uno::Sequence< uno::Reference< css::xml::wrapper::XXMLElementWrapper > >& reservedDescendants, const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& stopAtNode ) { xmlNodePtr pTargetNode = checkElement(node); m_pStopAtNode = checkElement(stopAtNode); m_aReservedNodes = reservedDescendants; m_nReservedNodeIndex = 0; getNextReservedNode(); recursiveDelete(pTargetNode); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::collapse( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node ) { xmlNodePtr pTargetNode = checkElement(node); xmlNodePtr pParent; while (pTargetNode != nullptr) { if (pTargetNode->children != nullptr || pTargetNode == m_pCurrentElement) { break; } pParent = pTargetNode->parent; removeNode(pTargetNode); pTargetNode = pParent; } } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::getTree( const uno::Reference< css::xml::sax::XDocumentHandler >& handler ) { if (m_pRootElement == nullptr) return; xmlNodePtr pTempCurrentElement = m_pCurrentElement; sal_Int32 nTempCurrentPosition = m_nCurrentPosition; m_pCurrentElement = m_pRootElement; m_nCurrentPosition = NODEPOSITION_STARTELEMENT; while(true) { switch (m_nCurrentPosition) { case NODEPOSITION_STARTELEMENT: sendStartElement(nullptr, handler, m_pCurrentElement); break; case NODEPOSITION_ENDELEMENT: sendEndElement(nullptr, handler, m_pCurrentElement); break; case NODEPOSITION_NORMAL: sendNode(nullptr, handler, m_pCurrentElement); break; } if ( (m_pCurrentElement == m_pRootElement) && (m_nCurrentPosition == NODEPOSITION_ENDELEMENT )) { break; } getNextSAXEvent(); } m_pCurrentElement = pTempCurrentElement; m_nCurrentPosition = nTempCurrentPosition; } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::generateSAXEvents( const uno::Reference< css::xml::sax::XDocumentHandler >& handler, const uno::Reference< css::xml::sax::XDocumentHandler >& xEventKeeperHandler, const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& startNode, const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& endNode ) { /* * The first SAX event is the startElement of the startNode * element. */ bool bHasCurrentElementChild = (m_pCurrentElement->children != nullptr); xmlNodePtr pTempCurrentElement = m_pCurrentElement; m_pCurrentElement = checkElement(startNode); if (m_pCurrentElement->type == XML_ELEMENT_NODE) { m_nCurrentPosition = NODEPOSITION_STARTELEMENT; } else { m_nCurrentPosition = NODEPOSITION_NORMAL; } xmlNodePtr pEndNode = checkElement(endNode); uno::Reference < css::xml::crypto::sax::XSAXEventKeeper > xSAXEventKeeper( xEventKeeperHandler, uno::UNO_QUERY ); uno::Reference< css::xml::sax::XDocumentHandler > xHandler = handler; while(true) { switch (m_nCurrentPosition) { case NODEPOSITION_STARTELEMENT: sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement); break; case NODEPOSITION_ENDELEMENT: sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement); break; case NODEPOSITION_NORMAL: sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement); break; default: throw uno::RuntimeException(); } if (xSAXEventKeeper->isBlocking()) { xHandler = nullptr; } if (pEndNode == nullptr && ((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) || (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT))) { break; } getNextSAXEvent(); /* * If there is an end point specified, then check whether * the current node equals to the end point. If so, stop * generating. */ if (pEndNode != nullptr && m_pCurrentElement == pEndNode) { break; } } m_pCurrentElement = pTempCurrentElement; } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::rebuildIDLink( const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node ) { xmlNodePtr pNode = checkElement( node ); rebuildIDLink(pNode); } /* css::xml::sax::XDocumentHandler */ void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startDocument( ) { } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endDocument( ) { } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startElement( const OUString& aName, const uno::Reference< css::xml::sax::XAttributeList >& xAttribs ) { sal_Int32 nLength = xAttribs->getLength(); uno::Sequence< css::xml::csax::XMLAttribute > aAttributes (nLength); auto aAttributesRange = asNonConstRange(aAttributes); for (int i = 0; i < nLength; ++i) { aAttributesRange[i].sName = xAttribs->getNameByIndex(static_cast(i)); aAttributesRange[i].sValue =xAttribs->getValueByIndex(static_cast(i)); } compressedStartElement(aName, aAttributes); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endElement( const OUString& aName ) { saxHelper.endElement(aName); m_pCurrentElement = saxHelper.getCurrentNode(); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::characters( const OUString& aChars ) { saxHelper.characters(aChars); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const OUString& aWhitespaces ) { saxHelper.ignorableWhitespace(aWhitespaces); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::processingInstruction( const OUString& aTarget, const OUString& aData ) { saxHelper.processingInstruction(aTarget, aData); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const uno::Reference< css::xml::sax::XLocator >& ) { } /* XCompressedDocumentHandler */ void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedStartDocument( ) { } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedEndDocument( ) { } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedStartElement( const OUString& aName, const uno::Sequence< css::xml::csax::XMLAttribute >& aAttributes ) { saxHelper.startElement(aName, aAttributes); m_pCurrentElement = saxHelper.getCurrentNode(); buildIDAttr( m_pCurrentElement ); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedEndElement( const OUString& aName ) { endElement( aName ); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedCharacters( const OUString& aChars ) { characters( aChars ); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedIgnorableWhitespace( const OUString& aWhitespaces ) { ignorableWhitespace( aWhitespaces ); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedProcessingInstruction( const OUString& aTarget, const OUString& aData ) { processingInstruction( aTarget, aData ); } void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedSetDocumentLocator( sal_Int32 /*columnNumber*/, sal_Int32 /*lineNumber*/, const OUString& /*publicId*/, const OUString& /*systemId*/ ) { } /* XServiceInfo */ OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getImplementationName( ) { return u"com.sun.star.xml.wrapper.XMLDocumentWrapper"_ustr; } sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::supportsService( const OUString& rServiceName ) { return cppu::supportsService( this, rServiceName ); } uno::Sequence< OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames( ) { return { u"com.sun.star.xml.wrapper.XMLDocumentWrapper"_ustr }; } extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* com_sun_star_xml_wrapper_XMLDocumentWrapper_get_implementation( uno::XComponentContext* /*pCtx*/, uno::Sequence const& /*rSeq*/) { return cppu::acquire(new XMLDocumentWrapper_XmlSecImpl()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */