LibreOffice Module xmlsecurity (master) 1
xmldocumentwrapper_xmlsecimpl.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <osl/diagnose.h>
23#include <com/sun/star/uno/XComponentContext.hpp>
24#include <com/sun/star/xml/crypto/sax/XSAXEventKeeper.hpp>
29#include <rtl/ref.hxx>
30
31#ifdef UNX
32#define stricmp strcasecmp
33#endif
34
35using namespace com::sun::star;
36
37#define STRXMLNS "xmlns"
38
39/* used by the recursiveDelete method */
40#define NODE_REMOVED 0
41#define NODE_NOTREMOVED 1
42#define NODE_STOPPED 2
43
45 : m_nCurrentPosition(0)
46 , m_pStopAtNode(nullptr)
47 , m_pCurrentReservedNode(nullptr)
48 , m_nReservedNodeIndex(0)
49{
52
53 /*
54 * creates the virtual root element
55 */
56 saxHelper.startElement(u"root", uno::Sequence<css::xml::csax::XMLAttribute>());
57
60}
61
63{
65 xmlFreeDoc(m_pDocument);
66}
67
69/****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent *************************
70 *
71 * NAME
72 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
73 *
74 * FUNCTION
75 * When converting the document into SAX events, this method is used to
76 * decide the next SAX event to be generated.
77 * Two member variables are checked to make the decision, the
78 * m_pCurrentElement and the m_nCurrentPosition.
79 * The m_pCurrentElement represents the node which have been covered, and
80 * the m_nCurrentPosition represents the event which have been sent.
81 * For example, suppose that the m_pCurrentElement
82 * points to element A, and the m_nCurrentPosition equals to
83 * NODEPOSITION_STARTELEMENT, then the next SAX event should be the
84 * endElement for element A if A has no child, or startElement for the
85 * first child element of element A otherwise.
86 * The m_nCurrentPosition can be one of following values:
87 * NODEPOSITION_STARTELEMENT for startElement;
88 * NODEPOSITION_ENDELEMENT for endElement;
89 * NODEPOSITION_NORMAL for other SAX events;
90 ******************************************************************************/
91{
92 OSL_ASSERT( m_pCurrentElement != nullptr );
93
94 /*
95 * Get the next event through tree order.
96 *
97 * if the current event is a startElement, then the next
98 * event depends on whether or not the current node has
99 * children.
100 */
102 {
103 /*
104 * If the current node has children, then its first child
105 * should be next current node, and the next event will be
106 * startElement or characters(PI) based on that child's node
107 * type. Otherwise, the endElement of current node is the
108 * next event.
109 */
110 if (m_pCurrentElement->children != nullptr)
111 {
114 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
116 }
117 else
118 {
120 }
121 }
122 /*
123 * if the current event is a not startElement, then the next
124 * event depends on whether or not the current node has
125 * following sibling.
126 */
128 {
129 xmlNodePtr pNextSibling = m_pCurrentElement->next;
130
131 /*
132 * If the current node has following sibling, that sibling
133 * should be next current node, and the next event will be
134 * startElement or characters(PI) based on that sibling's node
135 * type. Otherwise, the endElement of current node's parent
136 * becomes the next event.
137 */
138 if (pNextSibling != nullptr)
139 {
140 m_pCurrentElement = pNextSibling;
142 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
144 }
145 else
146 {
149 }
150 }
151}
152
154 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler,
155 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler2,
156 const xmlNodePtr pNode)
157/****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************
158 *
159 * NAME
160 * sendStartElement -- Constructs a startElement SAX event
161 *
162 * FUNCTION
163 * Used when converting the document into SAX event stream.
164 * This method constructs a startElement SAX event for a particular
165 * element, then calls the startElement methods of the XDocumentHandlers.
166 *
167 * INPUTS
168 * xHandler - the first XDocumentHandler interface to receive the
169 * startElement SAX event. It can be NULL.
170 * xHandler2 - the second XDocumentHandler interface to receive the
171 * startElement SAX event. It can't be NULL.
172 * pNode - the node on which the startElement should be generated.
173 * This node must be an element type.
174 ******************************************************************************/
175{
177
178 xmlNsPtr pNsDef = pNode->nsDef;
179
180 while (pNsDef != nullptr)
181 {
182 const xmlChar* pNsPrefix = pNsDef->prefix;
183 const xmlChar* pNsHref = pNsDef->href;
184
185 if (pNsDef->prefix == nullptr)
186 {
187 pAttributeList->AddAttribute(
188 STRXMLNS,
189 OUString::fromUtf8(reinterpret_cast<char const *>(pNsHref)));
190 }
191 else
192 {
193 pAttributeList->AddAttribute(
194 STRXMLNS ":"
195 +OUString::fromUtf8(reinterpret_cast<char const *>(pNsPrefix)),
196 OUString::fromUtf8(reinterpret_cast<char const *>(pNsHref)));
197 }
198
199 pNsDef = pNsDef->next;
200 }
201
202 xmlAttrPtr pAttr = pNode->properties;
203
204 while (pAttr != nullptr)
205 {
206 const xmlChar* pAttrName = pAttr->name;
207 xmlNsPtr pAttrNs = pAttr->ns;
208
209 OUString ouAttrName;
210 if (pAttrNs == nullptr)
211 {
212 ouAttrName = OUString::fromUtf8(reinterpret_cast<char const *>(pAttrName));
213 }
214 else
215 {
216 ouAttrName = OUString::fromUtf8(reinterpret_cast<char const *>(pAttrNs->prefix))
217 + ":" + OUString::fromUtf8(reinterpret_cast<char const *>(pAttrName));
218 }
219
220 pAttributeList->AddAttribute(
221 ouAttrName,
222 OUString::fromUtf8(reinterpret_cast<char*>(pAttr->children->content)));
223 pAttr = pAttr->next;
224 }
225
226 OString sNodeName = getNodeQName(pNode);
227
228 if (xHandler.is())
229 {
230 xHandler->startElement(
231 OUString::fromUtf8(sNodeName),
232 pAttributeList);
233 }
234
235 xHandler2->startElement(
236 OUString::fromUtf8(sNodeName),
237 pAttributeList);
238}
239
241 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler,
242 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler2,
243 const xmlNodePtr pNode)
244/****** XMLDocumentWrapper_XmlSecImpl/sendEndElement **************************
245 *
246 * NAME
247 * sendEndElement -- Constructs an endElement SAX event
248 *
249 * FUNCTION
250 * Used when converting the document into SAX event stream.
251 * This method constructs an endElement SAX event for a particular
252 * element, then calls the endElement methods of the XDocumentHandlers.
253 *
254 * INPUTS
255 * xHandler - the first XDocumentHandler interface to receive the
256 * endElement SAX event. It can be NULL.
257 * xHandler2 - the second XDocumentHandler interface to receive the
258 * endElement SAX event. It can't be NULL.
259 * pNode - the node on which the endElement should be generated.
260 * This node must be an element type.
261 ******************************************************************************/
262{
263 OString sNodeName = getNodeQName(pNode);
264
265 if (xHandler.is())
266 {
267 xHandler->endElement(OUString::fromUtf8(sNodeName));
268 }
269
270 xHandler2->endElement(OUString::fromUtf8(sNodeName));
271}
272
274 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler,
275 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler2,
276 const xmlNodePtr pNode)
277/****** XMLDocumentWrapper_XmlSecImpl/sendNode ********************************
278 *
279 * NAME
280 * sendNode -- Constructs a characters SAX event or a
281 * processingInstruction SAX event
282 *
283 * FUNCTION
284 * Used when converting the document into SAX event stream.
285 * This method constructs a characters SAX event or a
286 * processingInstructionfor SAX event based on the type of a particular
287 * element, then calls the corresponding methods of the XDocumentHandlers.
288 *
289 * INPUTS
290 * xHandler - the first XDocumentHandler interface to receive the
291 * SAX event. It can be NULL.
292 * xHandler2 - the second XDocumentHandler interface to receive the
293 * SAX event. It can't be NULL.
294 * pNode - the node on which the endElement should be generated.
295 * If it is a text node, then a characters SAX event is
296 * generated; if it is a PI node, then a
297 * processingInstructionfor SAX event is generated.
298 ******************************************************************************/
299{
300 xmlElementType type = pNode->type;
301
302 if (type == XML_TEXT_NODE)
303 {
304 if (xHandler.is())
305 {
306 xHandler->characters(OUString::fromUtf8(reinterpret_cast<char*>(pNode->content)));
307 }
308
309 xHandler2->characters(OUString::fromUtf8(reinterpret_cast<char*>(pNode->content)));
310 }
311 else if (type == XML_PI_NODE)
312 {
313 if (xHandler.is())
314 {
315 xHandler->processingInstruction(
316 OUString::fromUtf8(reinterpret_cast<char const *>(pNode->name)),
317 OUString::fromUtf8(reinterpret_cast<char const *>(pNode->content)));
318 }
319
320 xHandler2->processingInstruction(
321 OUString::fromUtf8(reinterpret_cast<char const *>(pNode->name)),
322 OUString::fromUtf8(reinterpret_cast<char*>(pNode->content)));
323 }
324}
325
326OString XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode)
327/****** XMLDocumentWrapper_XmlSecImpl/getNodeQName ****************************
328 *
329 * NAME
330 * getNodeQName -- Retrieves the qualified name of a node
331 *
332 * INPUTS
333 * pNode - the node whose name will be retrieved
334 *
335 * RESULT
336 * name - the node's qualified name
337 ******************************************************************************/
338{
339 OString sNodeName(reinterpret_cast<const char*>(pNode->name));
340 if (pNode->ns != nullptr)
341 {
342 xmlNsPtr pNs = pNode->ns;
343
344 if (pNs->prefix != nullptr)
345 {
346 OString sPrefix(reinterpret_cast<const char*>(pNs->prefix));
347 sNodeName = sPrefix + ":" + sNodeName;
348 }
349 }
350
351 return sNodeName;
352}
353
354xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& xXMLElement)
355/****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
356 *
357 * NAME
358 * checkElement -- Retrieves the node wrapped by an XXMLElementWrapper
359 * interface
360 *
361 * INPUTS
362 * xXMLElement - the XXMLElementWrapper interface wrapping a node
363 *
364 * RESULT
365 * node - the node wrapped in the XXMLElementWrapper interface
366 ******************************************************************************/
367{
368 xmlNodePtr rc = nullptr;
369
370 if (xXMLElement.is())
371 {
373 = dynamic_cast<XMLElementWrapper_XmlSecImpl*>(xXMLElement.get());
374
375 if( pElement == nullptr ) {
376 throw uno::RuntimeException() ;
377 }
378
379 rc = pElement->getNativeElement();
380 }
381
382 return rc;
383}
384
386 const xmlNodePtr pNode)
387/****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
388 *
389 * NAME
390 * recursiveDelete -- Deletes a particular node with its branch.
391 *
392 * FUNCTION
393 * Deletes a particular node with its branch, while reserving the nodes
394 * (and their branches) listed in the m_aReservedNodes.
395 * The deletion process is performed in the tree order, that is, a node
396 * is deleted after its previous sibling node is deleted, a parent node
397 * is deleted after its branch is deleted.
398 * During the deletion process when the m_pStopAtNode is reached, the
399 * progress is interrupted at once.
400 *
401 * INPUTS
402 * pNode - the node to be deleted
403 *
404 * RESULT
405 * result - the result of the deletion process, can be one of following
406 * values:
407 * NODE_STOPPED - the process is interrupted by meeting the
408 * m_pStopAtNode
409 * NODE_NOTREMOVED - the pNode is not completely removed
410 * because there is its descendant in the
411 * m_aReservedNodes list
412 * NODE_REMOVED - the pNode and its branch are completely
413 * removed
414 *
415 * NOTES
416 * The node in the m_aReservedNodes list must be in the tree order, otherwise
417 * the result is unpredictable.
418 ******************************************************************************/
419{
420 if (pNode == m_pStopAtNode)
421 {
422 return NODE_STOPPED;
423 }
424
425 if (pNode != m_pCurrentReservedNode)
426 {
427 xmlNodePtr pChild = pNode->children;
428
429 xmlNodePtr pNextSibling;
430 bool bIsRemoved = true;
431 sal_Int32 nResult;
432
433 while( pChild != nullptr )
434 {
435 pNextSibling = pChild->next;
436 nResult = recursiveDelete(pChild);
437
438 switch (nResult)
439 {
440 case NODE_STOPPED:
441 return NODE_STOPPED;
442 case NODE_NOTREMOVED:
443 bIsRemoved = false;
444 break;
445 case NODE_REMOVED:
446 removeNode(pChild);
447 break;
448 default:
449 throw uno::RuntimeException();
450 }
451
452 pChild = pNextSibling;
453 }
454
455 if (pNode == m_pCurrentElement)
456 {
457 bIsRemoved = false;
458 }
459
460 return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED;
461 }
462 else
463 {
465 return NODE_NOTREMOVED;
466 }
467}
468
470/****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
471 *
472 * NAME
473 * getNextReservedNode -- Highlights the next reserved node in the
474 * reserved node list
475 *
476 * FUNCTION
477 * The m_aReservedNodes array holds a node list, while the
478 * m_pCurrentReservedNode points to the one currently highlighted.
479 * This method is used to highlight the next node in the node list.
480 * This method is called at the time when the current highlighted node
481 * has been already processed, and the next node should be ready.
482 ******************************************************************************/
483{
484 if (m_nReservedNodeIndex < m_aReservedNodes.getLength())
485 {
488 }
489 else
490 {
491 m_pCurrentReservedNode = nullptr;
492 }
493}
494
495void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const
496/****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
497 *
498 * NAME
499 * removeNode -- Deletes a node with its branch unconditionally
500 *
501 * FUNCTION
502 * Delete the node along with its branch from the document.
503 *
504 * INPUTS
505 * pNode - the node to be deleted
506 ******************************************************************************/
507{
508 /* you can't remove the current node */
509 OSL_ASSERT( m_pCurrentElement != pNode );
510
511 xmlAttrPtr pAttr = pNode->properties;
512
513 while (pAttr != nullptr)
514 {
515 if (!stricmp(reinterpret_cast<char const *>(pAttr->name), "id"))
516 {
517 xmlRemoveID(m_pDocument, pAttr);
518 }
519
520 pAttr = pAttr->next;
521 }
522
523 xmlUnlinkNode(pNode);
524 xmlFreeNode(pNode);
525}
526
528/****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
529 *
530 * NAME
531 * buildIDAttr -- build the ID attribute of a node
532 *
533 * INPUTS
534 * pNode - the node whose id attribute will be built
535 ******************************************************************************/
536{
537 xmlAttrPtr idAttr = xmlHasProp( pNode, reinterpret_cast<const unsigned char *>("id") );
538 if (idAttr == nullptr)
539 {
540 idAttr = xmlHasProp( pNode, reinterpret_cast<const unsigned char *>("Id") );
541 }
542
543 if (idAttr != nullptr)
544 {
545 xmlChar* idValue = xmlNodeListGetString( m_pDocument, idAttr->children, 1 ) ;
546 xmlAddID( nullptr, m_pDocument, idValue, idAttr );
547 }
548}
549
551/****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink ***************************
552 *
553 * NAME
554 * rebuildIDLink -- rebuild the ID link for the branch
555 *
556 * INPUTS
557 * pNode - the node, from which the branch will be rebuilt
558 ******************************************************************************/
559{
560 if (pNode != nullptr && pNode->type == XML_ELEMENT_NODE)
561 {
562 buildIDAttr( pNode );
563
564 xmlNodePtr child = pNode->children;
565 while (child != nullptr)
566 {
567 rebuildIDLink(child);
568 child = child->next;
569 }
570 }
571}
572
573/* XXMLDocumentWrapper */
574uno::Reference< css::xml::wrapper::XXMLElementWrapper > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getCurrentElement( )
575{
577}
578
579void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& element )
580{
581 m_pCurrentElement = checkElement( element );
583}
584
586{
587 OSL_ASSERT( m_pCurrentElement != nullptr );
588
589 xmlNodePtr pOldCurrentElement = m_pCurrentElement;
590
591 /*
592 * pop the top node in the parser context's
593 * nodeTab stack, then the parent of that node will
594 * automatically become the new stack top, and
595 * the current node as well.
596 */
597 saxHelper.endElement(OUString::fromUtf8(reinterpret_cast<char const *>(pOldCurrentElement->name)));
599
600 /*
601 * remove the node
602 */
603 removeNode(pOldCurrentElement);
604}
605
606sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrent( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node )
607{
608 xmlNodePtr pNode = checkElement(node);
609 return (pNode == m_pCurrentElement);
610}
611
613{
614 bool rc = false;
615
616 if (m_pCurrentElement->children == nullptr)
617 {
618 rc = true;
619 }
620
621 return rc;
622}
623
624OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getNodeName( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node )
625{
626 xmlNodePtr pNode = checkElement(node);
627 return OUString::fromUtf8(reinterpret_cast<char const *>(pNode->name));
628}
629
631 const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node,
632 const uno::Sequence< uno::Reference< css::xml::wrapper::XXMLElementWrapper > >& reservedDescendants,
633 const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& stopAtNode )
634{
635 xmlNodePtr pTargetNode = checkElement(node);
636
637 m_pStopAtNode = checkElement(stopAtNode);
638 m_aReservedNodes = reservedDescendants;
640
642
643 recursiveDelete(pTargetNode);
644}
645
646void SAL_CALL XMLDocumentWrapper_XmlSecImpl::collapse( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node )
647{
648 xmlNodePtr pTargetNode = checkElement(node);
649 xmlNodePtr pParent;
650
651 while (pTargetNode != nullptr)
652 {
653 if (pTargetNode->children != nullptr || pTargetNode == m_pCurrentElement)
654 {
655 break;
656 }
657
658 pParent = pTargetNode->parent;
659 removeNode(pTargetNode);
660 pTargetNode = pParent;
661 }
662}
663
664void SAL_CALL XMLDocumentWrapper_XmlSecImpl::getTree( const uno::Reference< css::xml::sax::XDocumentHandler >& handler )
665{
666 if (m_pRootElement == nullptr)
667 return;
668
669 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
670 sal_Int32 nTempCurrentPosition = m_nCurrentPosition;
671
673
675
676 while(true)
677 {
678 switch (m_nCurrentPosition)
679 {
681 sendStartElement(nullptr, handler, m_pCurrentElement);
682 break;
684 sendEndElement(nullptr, handler, m_pCurrentElement);
685 break;
687 sendNode(nullptr, handler, m_pCurrentElement);
688 break;
689 }
690
692 {
693 break;
694 }
695
697 }
698
699 m_pCurrentElement = pTempCurrentElement;
700 m_nCurrentPosition = nTempCurrentPosition;
701}
702
704 const uno::Reference< css::xml::sax::XDocumentHandler >& handler,
705 const uno::Reference< css::xml::sax::XDocumentHandler >& xEventKeeperHandler,
706 const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& startNode,
707 const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& endNode )
708{
709 /*
710 * The first SAX event is the startElement of the startNode
711 * element.
712 */
713 bool bHasCurrentElementChild = (m_pCurrentElement->children != nullptr);
714
715 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
716
717 m_pCurrentElement = checkElement(startNode);
718
719 if (m_pCurrentElement->type == XML_ELEMENT_NODE)
720 {
722 }
723 else
724 {
726 }
727
728 xmlNodePtr pEndNode = checkElement(endNode);
729
730 uno::Reference < css::xml::crypto::sax::XSAXEventKeeper > xSAXEventKeeper( xEventKeeperHandler, uno::UNO_QUERY );
731
732 uno::Reference< css::xml::sax::XDocumentHandler > xHandler = handler;
733
734 while(true)
735 {
736 switch (m_nCurrentPosition)
737 {
739 sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
740 break;
742 sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
743 break;
745 sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement);
746 break;
747 default:
748 throw uno::RuntimeException();
749 }
750
751 if (xSAXEventKeeper->isBlocking())
752 {
753 xHandler = nullptr;
754 }
755
756 if (pEndNode == nullptr &&
757 ((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) ||
758 (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT)))
759 {
760 break;
761 }
762
764
765 /*
766 * If there is an end point specified, then check whether
767 * the current node equals to the end point. If so, stop
768 * generating.
769 */
770 if (pEndNode != nullptr && m_pCurrentElement == pEndNode)
771 {
772 break;
773 }
774 }
775
776 m_pCurrentElement = pTempCurrentElement;
777}
778
780 const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node )
781{
782 xmlNodePtr pNode = checkElement( node );
783 rebuildIDLink(pNode);
784}
785
786
787/* css::xml::sax::XDocumentHandler */
789{
790}
791
793{
794}
795
796void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startElement( const OUString& aName, const uno::Reference< css::xml::sax::XAttributeList >& xAttribs )
797{
798 sal_Int32 nLength = xAttribs->getLength();
799 uno::Sequence< css::xml::csax::XMLAttribute > aAttributes (nLength);
800 auto aAttributesRange = asNonConstRange(aAttributes);
801
802 for (int i = 0; i < nLength; ++i)
803 {
804 aAttributesRange[i].sName = xAttribs->getNameByIndex(static_cast<short>(i));
805 aAttributesRange[i].sValue =xAttribs->getValueByIndex(static_cast<short>(i));
806 }
807
808 compressedStartElement(aName, aAttributes);
809}
810
811void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endElement( const OUString& aName )
812{
815}
816
817void SAL_CALL XMLDocumentWrapper_XmlSecImpl::characters( const OUString& aChars )
818{
819 saxHelper.characters(aChars);
820}
821
822void SAL_CALL XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const OUString& aWhitespaces )
823{
824 saxHelper.ignorableWhitespace(aWhitespaces);
825}
826
827void SAL_CALL XMLDocumentWrapper_XmlSecImpl::processingInstruction( const OUString& aTarget, const OUString& aData )
828{
830}
831
832void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const uno::Reference< css::xml::sax::XLocator >& )
833{
834}
835
836/* XCompressedDocumentHandler */
838{
839}
840
842{
843}
844
845void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedStartElement( const OUString& aName, const uno::Sequence< css::xml::csax::XMLAttribute >& aAttributes )
846{
847 saxHelper.startElement(aName, aAttributes);
849
851}
852
853void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedEndElement( const OUString& aName )
854{
855 endElement( aName );
856}
857
858void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedCharacters( const OUString& aChars )
859{
860 characters( aChars );
861}
862
863void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedIgnorableWhitespace( const OUString& aWhitespaces )
864{
865 ignorableWhitespace( aWhitespaces );
866}
867
868void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedProcessingInstruction( const OUString& aTarget, const OUString& aData )
869{
870 processingInstruction( aTarget, aData );
871}
872
873void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedSetDocumentLocator( sal_Int32 /*columnNumber*/, sal_Int32 /*lineNumber*/, const OUString& /*publicId*/, const OUString& /*systemId*/ )
874{
875}
876
877/* XServiceInfo */
879{
880 return "com.sun.star.xml.wrapper.XMLDocumentWrapper";
881}
882
883sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::supportsService( const OUString& rServiceName )
884{
885 return cppu::supportsService( this, rServiceName );
886}
887
889{
890 return { "com.sun.star.xml.wrapper.XMLDocumentWrapper" };
891}
892
893extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
895 uno::XComponentContext* /*pCtx*/, uno::Sequence<uno::Any> const& /*rSeq*/)
896{
897 return cppu::acquire(new XMLDocumentWrapper_XmlSecImpl());
898}
899
900/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
xmlDocPtr getDocument()
Definition: saxhelper.hxx:48
void characters(std::u16string_view aChars)
XDocumentHandler – an xml element or cdata characters.
Definition: saxhelper.cxx:305
void endElement(std::u16string_view aName)
XDocumentHandler – end an xml element.
Definition: saxhelper.cxx:290
void setCurrentNode(const xmlNodePtr pNode)
Definition: saxhelper.cxx:200
void startElement(std::u16string_view aName, const css::uno::Sequence< css::xml::csax::XMLAttribute > &aAttributes)
XDocumentHandler – start an xml element.
Definition: saxhelper.cxx:253
void ignorableWhitespace(std::u16string_view aWhitespaces)
XDocumentHandler – ignorable xml white space.
Definition: saxhelper.cxx:322
void startDocument()
XDocumentHandler – start an xml document.
Definition: saxhelper.cxx:217
void endDocument()
XDocumentHandler – end an xml document.
Definition: saxhelper.cxx:245
xmlNodePtr getCurrentNode()
Definition: saxhelper.hxx:46
void processingInstruction(std::u16string_view aTarget, std::u16string_view aData)
XDocumentHandler – preprocessing instruction.
Definition: saxhelper.cxx:339
NAME XMLDocumentWrapper_XmlSecImpl – Class to manipulate a libxml2 document.
virtual sal_Bool SAL_CALL isCurrentElementEmpty() override
virtual void SAL_CALL compressedCharacters(const OUString &aChars) override
virtual css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > SAL_CALL getCurrentElement() override
virtual void SAL_CALL collapse(const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > &node) override
virtual OUString SAL_CALL getImplementationName() override
virtual void SAL_CALL processingInstruction(const OUString &aTarget, const OUString &aData) override
virtual void SAL_CALL compressedEndElement(const OUString &aName) override
virtual void SAL_CALL endElement(const OUString &aName) override
virtual void SAL_CALL generateSAXEvents(const css::uno::Reference< css::xml::sax::XDocumentHandler > &handler, const css::uno::Reference< css::xml::sax::XDocumentHandler > &xEventKeeperHandler, const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > &startNode, const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > &endNode) override
css::uno::Sequence< css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > > m_aReservedNodes
sal_Int32 recursiveDelete(const xmlNodePtr pNode)
virtual void SAL_CALL startDocument() override
virtual void SAL_CALL startElement(const OUString &aName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttribs) override
virtual OUString SAL_CALL getNodeName(const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > &node) override
virtual void SAL_CALL getTree(const css::uno::Reference< css::xml::sax::XDocumentHandler > &handler) override
virtual void SAL_CALL clearUselessData(const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > &node, const css::uno::Sequence< css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > > &reservedDescendants, const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > &stopAtNode) override
virtual void SAL_CALL compressedEndDocument() override
void removeNode(const xmlNodePtr pNode) const
virtual void SAL_CALL compressedStartDocument() override
virtual void SAL_CALL compressedIgnorableWhitespace(const OUString &aWhitespaces) override
virtual void SAL_CALL compressedProcessingInstruction(const OUString &aTarget, const OUString &aData) override
static void sendEndElement(const css::uno::Reference< css::xml::sax::XDocumentHandler > &xHandler, const css::uno::Reference< css::xml::sax::XDocumentHandler > &xHandler2, const xmlNodePtr pNode)
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual void SAL_CALL endDocument() override
virtual void SAL_CALL compressedStartElement(const OUString &aName, const css::uno::Sequence< css::xml::csax::XMLAttribute > &aAttributes) override
virtual void SAL_CALL removeCurrentElement() override
virtual void SAL_CALL characters(const OUString &aChars) override
virtual sal_Bool SAL_CALL isCurrent(const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > &node) override
static OString getNodeQName(const xmlNodePtr pNode)
static xmlNodePtr checkElement(const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > &xXMLElement)
virtual void SAL_CALL ignorableWhitespace(const OUString &aWhitespaces) override
static void sendNode(const css::uno::Reference< css::xml::sax::XDocumentHandler > &xHandler, const css::uno::Reference< css::xml::sax::XDocumentHandler > &xHandler2, const xmlNodePtr pNode)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
void rebuildIDLink(xmlNodePtr pNode) const
virtual void SAL_CALL setDocumentLocator(const css::uno::Reference< css::xml::sax::XLocator > &xLocator) override
static void sendStartElement(const css::uno::Reference< css::xml::sax::XDocumentHandler > &xHandler, const css::uno::Reference< css::xml::sax::XDocumentHandler > &xHandler2, const xmlNodePtr pNode)
virtual void SAL_CALL compressedSetDocumentLocator(sal_Int32 columnNumber, sal_Int32 lineNumber, const OUString &publicId, const OUString &systemId) override
virtual void SAL_CALL setCurrentElement(const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper > &element) override
float u
OUString sPrefix
OUString aName
constexpr OUStringLiteral aData
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
unsigned char sal_Bool
ResultType type
#define NODE_REMOVED
#define NODE_NOTREMOVED
#define NODE_STOPPED
SAL_DLLPUBLIC_EXPORT uno::XInterface * com_sun_star_xml_wrapper_XMLDocumentWrapper_get_implementation(uno::XComponentContext *, uno::Sequence< uno::Any > const &)
#define NODEPOSITION_NORMAL
#define NODEPOSITION_ENDELEMENT
#define NODEPOSITION_STARTELEMENT
sal_Int32 nLength