1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <osl/diagnose.h>
23 #include <com/sun/star/uno/XComponentContext.hpp>
24 #include <com/sun/star/xml/crypto/sax/XSAXEventKeeper.hpp>
25 #include <cppuhelper/supportsservice.hxx>
26 #include <xmlsec/xmldocumentwrapper_xmlsecimpl.hxx>
27 #include "xmlelementwrapper_xmlsecimpl.hxx"
29 #include <xmloff/attrlist.hxx>
32 #define stricmp strcasecmp
35 using namespace com::sun::star
;
36 namespace cssl
= com::sun::star::lang
;
37 namespace cssxc
= com::sun::star::xml::crypto
;
38 namespace cssxcsax
= com::sun::star::xml::csax
;
39 namespace cssxs
= com::sun::star::xml::sax
;
40 namespace cssxw
= com::sun::star::xml::wrapper
;
42 #define STRXMLNS "xmlns"
44 /* used by the recursiveDelete method */
45 #define NODE_REMOVED 0
46 #define NODE_NOTREMOVED 1
47 #define NODE_STOPPED 2
49 XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl()
50 : m_nCurrentPosition(0)
51 , m_pStopAtNode(nullptr)
52 , m_pCurrentReservedNode(nullptr)
53 , m_nReservedNodeIndex(0)
55 saxHelper
.startDocument();
56 m_pDocument
= saxHelper
.getDocument();
59 * creates the virtual root element
61 saxHelper
.startElement("root", uno::Sequence
<cssxcsax::XMLAttribute
>());
63 m_pRootElement
= saxHelper
.getCurrentNode();
64 m_pCurrentElement
= m_pRootElement
;
67 XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl()
69 saxHelper
.endDocument();
70 xmlFreeDoc(m_pDocument
);
73 void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent()
74 /****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent *************************
77 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
80 * When converting the document into SAX events, this method is used to
81 * decide the next SAX event to be generated.
82 * Two member variables are checked to make the decision, the
83 * m_pCurrentElement and the m_nCurrentPosition.
84 * The m_pCurrentElement represents the node which have been covered, and
85 * the m_nCurrentPosition represents the event which have been sent.
86 * For example, suppose that the m_pCurrentElement
87 * points to element A, and the m_nCurrentPosition equals to
88 * NODEPOSITION_STARTELEMENT, then the next SAX event should be the
89 * endElement for element A if A has no child, or startElement for the
90 * first child element of element A otherwise.
91 * The m_nCurrentPosition can be one of following values:
92 * NODEPOSITION_STARTELEMENT for startElement;
93 * NODEPOSITION_ENDELEMENT for endElement;
94 * NODEPOSITION_NORMAL for other SAX events;
95 ******************************************************************************/
97 OSL_ASSERT( m_pCurrentElement
!= nullptr );
100 * Get the next event through tree order.
102 * if the current event is a startElement, then the next
103 * event depends on whether or not the current node has
106 if (m_nCurrentPosition
== NODEPOSITION_STARTELEMENT
)
109 * If the current node has children, then its first child
110 * should be next current node, and the next event will be
111 * startElement or characters(PI) based on that child's node
112 * type. Otherwise, the endElement of current node is the
115 if (m_pCurrentElement
->children
!= nullptr)
117 m_pCurrentElement
= m_pCurrentElement
->children
;
119 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
120 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
124 m_nCurrentPosition
= NODEPOSITION_ENDELEMENT
;
128 * if the current event is a not startElement, then the next
129 * event depends on whether or not the current node has
132 else if (m_nCurrentPosition
== NODEPOSITION_ENDELEMENT
|| m_nCurrentPosition
== NODEPOSITION_NORMAL
)
134 xmlNodePtr pNextSibling
= m_pCurrentElement
->next
;
137 * If the current node has following sibling, that sibling
138 * should be next current node, and the next event will be
139 * startElement or characters(PI) based on that sibling's node
140 * type. Otherwise, the endElement of current node's parent
141 * becomes the next event.
143 if (pNextSibling
!= nullptr)
145 m_pCurrentElement
= pNextSibling
;
147 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
148 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
152 m_pCurrentElement
= m_pCurrentElement
->parent
;
153 m_nCurrentPosition
= NODEPOSITION_ENDELEMENT
;
158 void XMLDocumentWrapper_XmlSecImpl::sendStartElement(
159 const uno::Reference
< cssxs::XDocumentHandler
>& xHandler
,
160 const uno::Reference
< cssxs::XDocumentHandler
>& xHandler2
,
161 const xmlNodePtr pNode
)
162 /****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************
165 * sendStartElement -- Constructs a startElement SAX event
168 * Used when converting the document into SAX event stream.
169 * This method constructs a startElement SAX event for a particular
170 * element, then calls the startElement methods of the XDocumentHandlers.
173 * xHandler - the first XDocumentHandler interface to receive the
174 * startElement SAX event. It can be NULL.
175 * xHandler2 - the second XDocumentHandler interface to receive the
176 * startElement SAX event. It can't be NULL.
177 * pNode - the node on which the startElement should be generated.
178 * This node must be an element type.
179 ******************************************************************************/
181 SvXMLAttributeList
* pAttributeList
= new SvXMLAttributeList();
182 uno::Reference
< cssxs::XAttributeList
> xAttrList(pAttributeList
);
184 xmlNsPtr pNsDef
= pNode
->nsDef
;
186 while (pNsDef
!= nullptr)
188 const xmlChar
* pNsPrefix
= pNsDef
->prefix
;
189 const xmlChar
* pNsHref
= pNsDef
->href
;
191 if (pNsDef
->prefix
== nullptr)
193 pAttributeList
->AddAttribute(
195 OUString::fromUtf8(reinterpret_cast<char const *>(pNsHref
)));
199 pAttributeList
->AddAttribute(
201 +OUString::fromUtf8(reinterpret_cast<char const *>(pNsPrefix
)),
202 OUString::fromUtf8(reinterpret_cast<char const *>(pNsHref
)));
205 pNsDef
= pNsDef
->next
;
208 xmlAttrPtr pAttr
= pNode
->properties
;
210 while (pAttr
!= nullptr)
212 const xmlChar
* pAttrName
= pAttr
->name
;
213 xmlNsPtr pAttrNs
= pAttr
->ns
;
216 if (pAttrNs
== nullptr)
218 ouAttrName
= OUString::fromUtf8(reinterpret_cast<char const *>(pAttrName
));
222 ouAttrName
= OUString::fromUtf8(reinterpret_cast<char const *>(pAttrNs
->prefix
))
223 + ":" + OUString::fromUtf8(reinterpret_cast<char const *>(pAttrName
));
226 pAttributeList
->AddAttribute(
228 OUString::fromUtf8(reinterpret_cast<char*>(pAttr
->children
->content
)));
232 OString sNodeName
= getNodeQName(pNode
);
236 xHandler
->startElement(
237 OUString::fromUtf8(sNodeName
),
241 xHandler2
->startElement(
242 OUString::fromUtf8(sNodeName
),
246 void XMLDocumentWrapper_XmlSecImpl::sendEndElement(
247 const uno::Reference
< cssxs::XDocumentHandler
>& xHandler
,
248 const uno::Reference
< cssxs::XDocumentHandler
>& xHandler2
,
249 const xmlNodePtr pNode
)
250 /****** XMLDocumentWrapper_XmlSecImpl/sendEndElement **************************
253 * sendEndElement -- Constructs an endElement SAX event
256 * Used when converting the document into SAX event stream.
257 * This method constructs an endElement SAX event for a particular
258 * element, then calls the endElement methods of the XDocumentHandlers.
261 * xHandler - the first XDocumentHandler interface to receive the
262 * endElement SAX event. It can be NULL.
263 * xHandler2 - the second XDocumentHandler interface to receive the
264 * endElement SAX event. It can't be NULL.
265 * pNode - the node on which the endElement should be generated.
266 * This node must be an element type.
267 ******************************************************************************/
269 OString sNodeName
= getNodeQName(pNode
);
273 xHandler
->endElement(OUString::fromUtf8(sNodeName
));
276 xHandler2
->endElement(OUString::fromUtf8(sNodeName
));
279 void XMLDocumentWrapper_XmlSecImpl::sendNode(
280 const uno::Reference
< cssxs::XDocumentHandler
>& xHandler
,
281 const uno::Reference
< cssxs::XDocumentHandler
>& xHandler2
,
282 const xmlNodePtr pNode
)
283 /****** XMLDocumentWrapper_XmlSecImpl/sendNode ********************************
286 * sendNode -- Constructs a characters SAX event or a
287 * processingInstruction SAX event
290 * Used when converting the document into SAX event stream.
291 * This method constructs a characters SAX event or a
292 * processingInstructionfor SAX event based on the type of a particular
293 * element, then calls the corresponding methods of the XDocumentHandlers.
296 * xHandler - the first XDocumentHandler interface to receive the
297 * SAX event. It can be NULL.
298 * xHandler2 - the second XDocumentHandler interface to receive the
299 * SAX event. It can't be NULL.
300 * pNode - the node on which the endElement should be generated.
301 * If it is a text node, then a characters SAX event is
302 * generated; if it is a PI node, then a
303 * processingInstructionfor SAX event is generated.
304 ******************************************************************************/
306 xmlElementType type
= pNode
->type
;
308 if (type
== XML_TEXT_NODE
)
312 xHandler
->characters(OUString::fromUtf8(reinterpret_cast<char*>(pNode
->content
)));
315 xHandler2
->characters(OUString::fromUtf8(reinterpret_cast<char*>(pNode
->content
)));
317 else if (type
== XML_PI_NODE
)
321 xHandler
->processingInstruction(
322 OUString::fromUtf8(reinterpret_cast<char const *>(pNode
->name
)),
323 OUString::fromUtf8(reinterpret_cast<char const *>(pNode
->content
)));
326 xHandler2
->processingInstruction(
327 OUString::fromUtf8(reinterpret_cast<char const *>(pNode
->name
)),
328 OUString::fromUtf8(reinterpret_cast<char*>(pNode
->content
)));
332 OString
XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode
)
333 /****** XMLDocumentWrapper_XmlSecImpl/getNodeQName ****************************
336 * getNodeQName -- Retrieves the qualified name of a node
339 * pNode - the node whose name will be retrieved
342 * name - the node's qualified name
343 ******************************************************************************/
345 OString
sNodeName(reinterpret_cast<const char*>(pNode
->name
));
346 if (pNode
->ns
!= nullptr)
348 xmlNsPtr pNs
= pNode
->ns
;
350 if (pNs
->prefix
!= nullptr)
352 OString
sPrefix(reinterpret_cast<const char*>(pNs
->prefix
));
353 sNodeName
= sPrefix
+ ":" + sNodeName
;
360 xmlNodePtr
XMLDocumentWrapper_XmlSecImpl::checkElement( const uno::Reference
< cssxw::XXMLElementWrapper
>& xXMLElement
)
361 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
364 * checkElement -- Retrieves the node wrapped by an XXMLElementWrapper
368 * xXMLElement - the XXMLElementWrapper interface wrapping a node
371 * node - the node wrapped in the XXMLElementWrapper interface
372 ******************************************************************************/
374 xmlNodePtr rc
= nullptr;
376 if (xXMLElement
.is())
378 uno::Reference
< cssl::XUnoTunnel
> xNodTunnel( xXMLElement
, uno::UNO_QUERY_THROW
) ;
379 XMLElementWrapper_XmlSecImpl
* pElement
380 = reinterpret_cast<XMLElementWrapper_XmlSecImpl
*>(
381 sal::static_int_cast
<sal_uIntPtr
>(
382 xNodTunnel
->getSomething(
383 XMLElementWrapper_XmlSecImpl::getUnoTunnelId() ))) ;
385 if( pElement
== nullptr ) {
386 throw uno::RuntimeException() ;
389 rc
= pElement
->getNativeElement();
395 sal_Int32
XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
396 const xmlNodePtr pNode
)
397 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
400 * recursiveDelete -- Deletes a particular node with its branch.
403 * Deletes a particular node with its branch, while reserving the nodes
404 * (and their branches) listed in the m_aReservedNodes.
405 * The deletion process is performed in the tree order, that is, a node
406 * is deleted after its previous sibling node is deleted, a parent node
407 * is deleted after its branch is deleted.
408 * During the deletion process when the m_pStopAtNode is reached, the
409 * progress is interrupted at once.
412 * pNode - the node to be deleted
415 * result - the result of the deletion process, can be one of following
417 * NODE_STOPPED - the process is interrupted by meeting the
419 * NODE_NOTREMOVED - the pNode is not completely removed
420 * because there is its descendant in the
421 * m_aReservedNodes list
422 * NODE_REMOVED - the pNode and its branch are completely
426 * The node in the m_aReservedNodes list must be in the tree order, otherwise
427 * the result is unpredictable.
428 ******************************************************************************/
430 if (pNode
== m_pStopAtNode
)
435 if (pNode
!= m_pCurrentReservedNode
)
437 xmlNodePtr pChild
= pNode
->children
;
439 xmlNodePtr pNextSibling
;
440 bool bIsRemoved
= true;
443 while( pChild
!= nullptr )
445 pNextSibling
= pChild
->next
;
446 nResult
= recursiveDelete(pChild
);
452 case NODE_NOTREMOVED
:
459 throw uno::RuntimeException();
462 pChild
= pNextSibling
;
465 if (pNode
== m_pCurrentElement
)
470 return bIsRemoved
?NODE_REMOVED
:NODE_NOTREMOVED
;
474 getNextReservedNode();
475 return NODE_NOTREMOVED
;
479 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
480 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
483 * getNextReservedNode -- Highlights the next reserved node in the
487 * The m_aReservedNodes array holds a node list, while the
488 * m_pCurrentReservedNode points to the one currently highlighted.
489 * This method is used to highlight the next node in the node list.
490 * This method is called at the time when the current highlighted node
491 * has been already processed, and the next node should be ready.
492 ******************************************************************************/
494 if (m_nReservedNodeIndex
< m_aReservedNodes
.getLength())
496 m_pCurrentReservedNode
= checkElement( m_aReservedNodes
[m_nReservedNodeIndex
] );
497 m_nReservedNodeIndex
++;
501 m_pCurrentReservedNode
= nullptr;
505 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode
) const
506 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
509 * removeNode -- Deletes a node with its branch unconditionally
512 * Delete the node along with its branch from the document.
515 * pNode - the node to be deleted
516 ******************************************************************************/
518 /* you can't remove the current node */
519 OSL_ASSERT( m_pCurrentElement
!= pNode
);
521 xmlAttrPtr pAttr
= pNode
->properties
;
523 while (pAttr
!= nullptr)
525 if (!stricmp(reinterpret_cast<char const *>(pAttr
->name
), "id"))
527 xmlRemoveID(m_pDocument
, pAttr
);
533 xmlUnlinkNode(pNode
);
537 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode
) const
538 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
541 * buildIDAttr -- build the ID attribute of a node
544 * pNode - the node whose id attribute will be built
545 ******************************************************************************/
547 xmlAttrPtr idAttr
= xmlHasProp( pNode
, reinterpret_cast<const unsigned char *>("id") );
548 if (idAttr
== nullptr)
550 idAttr
= xmlHasProp( pNode
, reinterpret_cast<const unsigned char *>("Id") );
553 if (idAttr
!= nullptr)
555 xmlChar
* idValue
= xmlNodeListGetString( m_pDocument
, idAttr
->children
, 1 ) ;
556 xmlAddID( nullptr, m_pDocument
, idValue
, idAttr
);
560 void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode
) const
561 /****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink ***************************
564 * rebuildIDLink -- rebuild the ID link for the branch
567 * pNode - the node, from which the branch will be rebuilt
568 ******************************************************************************/
570 if (pNode
!= nullptr && pNode
->type
== XML_ELEMENT_NODE
)
572 buildIDAttr( pNode
);
574 xmlNodePtr child
= pNode
->children
;
575 while (child
!= nullptr)
577 rebuildIDLink(child
);
583 /* XXMLDocumentWrapper */
584 uno::Reference
< cssxw::XXMLElementWrapper
> SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getCurrentElement( )
586 XMLElementWrapper_XmlSecImpl
* pElement
= new XMLElementWrapper_XmlSecImpl(m_pCurrentElement
);
587 return uno::Reference
< cssxw::XXMLElementWrapper
>(pElement
);
590 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const uno::Reference
< cssxw::XXMLElementWrapper
>& element
)
592 m_pCurrentElement
= checkElement( element
);
593 saxHelper
.setCurrentNode( m_pCurrentElement
);
596 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::removeCurrentElement( )
598 OSL_ASSERT( m_pCurrentElement
!= nullptr );
600 xmlNodePtr pOldCurrentElement
= m_pCurrentElement
;
603 * pop the top node in the parser context's
604 * nodeTab stack, then the parent of that node will
605 * automatically become the new stack top, and
606 * the current node as well.
608 saxHelper
.endElement(OUString::fromUtf8(reinterpret_cast<char const *>(pOldCurrentElement
->name
)));
609 m_pCurrentElement
= saxHelper
.getCurrentNode();
614 removeNode(pOldCurrentElement
);
617 sal_Bool SAL_CALL
XMLDocumentWrapper_XmlSecImpl::isCurrent( const uno::Reference
< cssxw::XXMLElementWrapper
>& node
)
619 xmlNodePtr pNode
= checkElement(node
);
620 return (pNode
== m_pCurrentElement
);
623 sal_Bool SAL_CALL
XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty( )
627 if (m_pCurrentElement
->children
== nullptr)
635 OUString SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getNodeName( const uno::Reference
< cssxw::XXMLElementWrapper
>& node
)
637 xmlNodePtr pNode
= checkElement(node
);
638 return OUString::fromUtf8(reinterpret_cast<char const *>(pNode
->name
));
641 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::clearUselessData(
642 const uno::Reference
< cssxw::XXMLElementWrapper
>& node
,
643 const uno::Sequence
< uno::Reference
< cssxw::XXMLElementWrapper
> >& reservedDescendants
,
644 const uno::Reference
< cssxw::XXMLElementWrapper
>& stopAtNode
)
646 xmlNodePtr pTargetNode
= checkElement(node
);
648 m_pStopAtNode
= checkElement(stopAtNode
);
649 m_aReservedNodes
= reservedDescendants
;
650 m_nReservedNodeIndex
= 0;
652 getNextReservedNode();
654 recursiveDelete(pTargetNode
);
657 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::collapse( const uno::Reference
< cssxw::XXMLElementWrapper
>& node
)
659 xmlNodePtr pTargetNode
= checkElement(node
);
662 while (pTargetNode
!= nullptr)
664 if (pTargetNode
->children
!= nullptr || pTargetNode
== m_pCurrentElement
)
669 pParent
= pTargetNode
->parent
;
670 removeNode(pTargetNode
);
671 pTargetNode
= pParent
;
675 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getTree( const uno::Reference
< cssxs::XDocumentHandler
>& handler
)
677 if (m_pRootElement
!= nullptr)
679 xmlNodePtr pTempCurrentElement
= m_pCurrentElement
;
680 sal_Int32 nTempCurrentPosition
= m_nCurrentPosition
;
682 m_pCurrentElement
= m_pRootElement
;
684 m_nCurrentPosition
= NODEPOSITION_STARTELEMENT
;
688 switch (m_nCurrentPosition
)
690 case NODEPOSITION_STARTELEMENT
:
691 sendStartElement(nullptr, handler
, m_pCurrentElement
);
693 case NODEPOSITION_ENDELEMENT
:
694 sendEndElement(nullptr, handler
, m_pCurrentElement
);
696 case NODEPOSITION_NORMAL
:
697 sendNode(nullptr, handler
, m_pCurrentElement
);
701 if ( (m_pCurrentElement
== m_pRootElement
) && (m_nCurrentPosition
== NODEPOSITION_ENDELEMENT
))
709 m_pCurrentElement
= pTempCurrentElement
;
710 m_nCurrentPosition
= nTempCurrentPosition
;
714 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::generateSAXEvents(
715 const uno::Reference
< cssxs::XDocumentHandler
>& handler
,
716 const uno::Reference
< cssxs::XDocumentHandler
>& xEventKeeperHandler
,
717 const uno::Reference
< cssxw::XXMLElementWrapper
>& startNode
,
718 const uno::Reference
< cssxw::XXMLElementWrapper
>& endNode
)
721 * The first SAX event is the startElement of the startNode
724 bool bHasCurrentElementChild
= (m_pCurrentElement
->children
!= nullptr);
726 xmlNodePtr pTempCurrentElement
= m_pCurrentElement
;
728 m_pCurrentElement
= checkElement(startNode
);
730 if (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)
732 m_nCurrentPosition
= NODEPOSITION_STARTELEMENT
;
736 m_nCurrentPosition
= NODEPOSITION_NORMAL
;
739 xmlNodePtr pEndNode
= checkElement(endNode
);
741 uno::Reference
< cssxc::sax::XSAXEventKeeper
> xSAXEventKeeper( xEventKeeperHandler
, uno::UNO_QUERY
);
743 uno::Reference
< cssxs::XDocumentHandler
> xHandler
= handler
;
747 switch (m_nCurrentPosition
)
749 case NODEPOSITION_STARTELEMENT
:
750 sendStartElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
752 case NODEPOSITION_ENDELEMENT
:
753 sendEndElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
755 case NODEPOSITION_NORMAL
:
756 sendNode(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
759 throw uno::RuntimeException();
762 if (xSAXEventKeeper
->isBlocking())
767 if (pEndNode
== nullptr &&
768 ((bHasCurrentElementChild
&& m_pCurrentElement
== xmlGetLastChild(pTempCurrentElement
) && m_nCurrentPosition
!= NODEPOSITION_STARTELEMENT
) ||
769 (!bHasCurrentElementChild
&& m_pCurrentElement
== pTempCurrentElement
&& m_nCurrentPosition
== NODEPOSITION_STARTELEMENT
)))
777 * If there is an end point specified, then check whether
778 * the current node equals to the end point. If so, stop
781 if (pEndNode
!= nullptr && m_pCurrentElement
== pEndNode
)
787 m_pCurrentElement
= pTempCurrentElement
;
790 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(
791 const css::uno::Reference
< css::xml::wrapper::XXMLElementWrapper
>& node
)
793 xmlNodePtr pNode
= checkElement( node
);
794 rebuildIDLink(pNode
);
798 /* cssxs::XDocumentHandler */
799 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::startDocument( )
803 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::endDocument( )
807 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::startElement( const OUString
& aName
, const uno::Reference
< cssxs::XAttributeList
>& xAttribs
)
809 sal_Int32 nLength
= xAttribs
->getLength();
810 uno::Sequence
< cssxcsax::XMLAttribute
> aAttributes (nLength
);
812 for (int i
= 0; i
< nLength
; ++i
)
814 aAttributes
[i
].sName
= xAttribs
->getNameByIndex(static_cast<short>(i
));
815 aAttributes
[i
].sValue
=xAttribs
->getValueByIndex(static_cast<short>(i
));
818 compressedStartElement(aName
, aAttributes
);
821 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::endElement( const OUString
& aName
)
823 saxHelper
.endElement(aName
);
824 m_pCurrentElement
= saxHelper
.getCurrentNode();
827 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::characters( const OUString
& aChars
)
829 saxHelper
.characters(aChars
);
832 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const OUString
& aWhitespaces
)
834 saxHelper
.ignorableWhitespace(aWhitespaces
);
837 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::processingInstruction( const OUString
& aTarget
, const OUString
& aData
)
839 saxHelper
.processingInstruction(aTarget
, aData
);
842 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const uno::Reference
< cssxs::XLocator
>& )
846 /* XCompressedDocumentHandler */
847 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedStartDocument( )
851 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedEndDocument( )
855 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedStartElement( const OUString
& aName
, const uno::Sequence
< cssxcsax::XMLAttribute
>& aAttributes
)
857 saxHelper
.startElement(aName
, aAttributes
);
858 m_pCurrentElement
= saxHelper
.getCurrentNode();
860 buildIDAttr( m_pCurrentElement
);
863 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedEndElement( const OUString
& aName
)
868 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedCharacters( const OUString
& aChars
)
870 characters( aChars
);
873 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedIgnorableWhitespace( const OUString
& aWhitespaces
)
875 ignorableWhitespace( aWhitespaces
);
878 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedProcessingInstruction( const OUString
& aTarget
, const OUString
& aData
)
880 processingInstruction( aTarget
, aData
);
883 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedSetDocumentLocator( sal_Int32
/*columnNumber*/, sal_Int32
/*lineNumber*/, const OUString
& /*publicId*/, const OUString
& /*systemId*/ )
888 OUString SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getImplementationName( )
890 return "com.sun.star.xml.wrapper.XMLDocumentWrapper";
893 sal_Bool SAL_CALL
XMLDocumentWrapper_XmlSecImpl::supportsService( const OUString
& rServiceName
)
895 return cppu::supportsService( this, rServiceName
);
898 uno::Sequence
< OUString
> SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames( )
900 uno::Sequence
<OUString
> aRet
{ "com.sun.star.xml.wrapper.XMLDocumentWrapper" };
904 extern "C" SAL_DLLPUBLIC_EXPORT
uno::XInterface
*
905 com_sun_star_xml_wrapper_XMLDocumentWrapper_get_implementation(
906 uno::XComponentContext
* /*pCtx*/, uno::Sequence
<uno::Any
> const& /*rSeq*/)
908 return cppu::acquire(new XMLDocumentWrapper_XmlSecImpl());
911 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */