Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / xmlsecurity / source / xmlsec / saxhelper.cxx
blobdbf1b370470290863828a63e732b7a0c518222a8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include <rtl/ustring.hxx>
23 #include "saxhelper.hxx"
24 #include "libxml/parserInternals.h"
26 #ifndef XMLSEC_NO_XSLT
27 #include "libxslt/xslt.h"
28 #endif
30 namespace cssu = com::sun::star::uno;
31 namespace cssxs = com::sun::star::xml::sax;
32 namespace cssxcsax = com::sun::star::xml::csax;
34 /**
35 * The return value is NULL terminated. The application has the responsibilty to
36 * deallocte the return value.
38 xmlChar* ous_to_xmlstr( const rtl::OUString& oustr )
40 rtl::OString ostr = rtl::OUStringToOString( oustr , RTL_TEXTENCODING_UTF8 ) ;
41 return xmlStrndup( ( xmlChar* )ostr.getStr(), ( int )ostr.getLength() ) ;
44 /**
45 * The return value is NULL terminated. The application has the responsibilty to
46 * deallocte the return value.
48 xmlChar* ous_to_nxmlstr( const rtl::OUString& oustr, int& length )
50 rtl::OString ostr = rtl::OUStringToOString( oustr , RTL_TEXTENCODING_UTF8 ) ;
51 length = ostr.getLength();
53 return xmlStrndup( ( xmlChar* )ostr.getStr(), length ) ;
56 /**
57 * The return value and the referenced value must be NULL terminated.
58 * The application has the responsibilty to deallocte the return value.
60 const xmlChar** attrlist_to_nxmlstr( const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
62 xmlChar* attname = NULL ;
63 xmlChar* attvalue = NULL ;
64 const xmlChar** attrs = NULL ;
66 sal_Int32 nLength = aAttributes.getLength();
68 if( nLength != 0 )
70 attrs = ( const xmlChar** )xmlMalloc( ( nLength * 2 + 2 ) * sizeof( xmlChar* ) ) ;
72 else
74 return NULL ;
77 for( int i = 0 , j = 0 ; j < nLength ; ++j )
79 attname = ous_to_xmlstr( aAttributes[j].sName ) ;
80 attvalue = ous_to_xmlstr( aAttributes[j].sValue ) ;
82 if( attname != NULL && attvalue != NULL )
84 attrs[i++] = attname ;
85 attrs[i++] = attvalue ;
86 attrs[i] = NULL ;
87 attrs[i+1] = NULL ;
89 else
91 if( attname != NULL )
92 xmlFree( attname ) ;
93 if( attvalue != NULL )
94 xmlFree( attvalue ) ;
98 return attrs ;
102 * Constructor
104 * In this constructor, a libxml sax parser context is initialized. a libxml
105 * default sax handler is initialized with the context.
107 SAXHelper::SAXHelper( )
108 : m_pParserCtxt( NULL ),
109 m_pSaxHandler( NULL )
111 xmlInitParser() ;
112 LIBXML_TEST_VERSION ;
115 * compile error:
116 * xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS ;
118 xmlSubstituteEntitiesDefault( 1 ) ;
120 #ifndef XMLSEC_NO_XSLT
121 xmlIndentTreeOutput = 1 ;
122 #endif /* XMLSEC_NO_XSLT */
124 m_pParserCtxt = xmlNewParserCtxt() ;
127 * i41748
129 * mmi : re-initialize the SAX handler to version 1
132 xmlSAXVersion(m_pParserCtxt->sax, 1);
134 /* end */
136 if( m_pParserCtxt->inputTab[0] != NULL )
138 m_pParserCtxt->inputTab[0] = NULL ;
141 if( m_pParserCtxt == NULL )
143 #ifndef XMLSEC_NO_XSLT
144 xsltCleanupGlobals() ;
145 #endif
146 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
147 // in other parts of the office.
148 // xmlCleanupParser() ;
149 throw cssu::RuntimeException() ;
151 else if( m_pParserCtxt->sax == NULL )
153 xmlFreeParserCtxt( m_pParserCtxt ) ;
155 #ifndef XMLSEC_NO_XSLT
156 xsltCleanupGlobals() ;
157 #endif
158 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
159 // in other parts of the office.
160 // xmlCleanupParser() ;
161 m_pParserCtxt = NULL ;
162 throw cssu::RuntimeException() ;
164 else
166 m_pSaxHandler = m_pParserCtxt->sax ;
168 //Adjust the context
169 m_pParserCtxt->recovery = 1 ;
174 * Destructor
176 * In this destructor, a libxml sax parser context is desturcted. The XML tree
177 * in the context is not deallocated because the tree is bind with a document
178 * model by the setTargetDocument method, which delegate the target document to
179 * destruct the xml tree.
181 SAXHelper::~SAXHelper() {
182 if( m_pParserCtxt != NULL )
185 * In the situation that no object refer the Document, this destructor
186 * must deallocate the Document memory
188 if( m_pSaxHandler == m_pParserCtxt->sax )
190 m_pSaxHandler = NULL ;
193 xmlFreeParserCtxt( m_pParserCtxt ) ;
194 m_pParserCtxt = NULL ;
197 if( m_pSaxHandler != NULL )
199 xmlFree( m_pSaxHandler ) ;
200 m_pSaxHandler = NULL ;
202 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
203 // in other parts of the office.
204 // xmlCleanupParser() ;
207 xmlNodePtr SAXHelper::getCurrentNode()
209 return m_pParserCtxt->node;
212 void SAXHelper::setCurrentNode(const xmlNodePtr pNode)
215 * This is really a black trick.
216 * When the current node is replaced, the nodeTab
217 * stack's top has to been replaced with the same
218 * node, in order to make compatibility.
220 m_pParserCtxt->nodeTab[m_pParserCtxt->nodeNr - 1]
221 = m_pParserCtxt->node
222 = pNode;
225 xmlDocPtr SAXHelper::getDocument()
227 return m_pParserCtxt->myDoc;
231 * XDocumentHandler -- start an xml document
233 void SAXHelper::startDocument( void )
234 throw( cssxs::SAXException , cssu::RuntimeException )
237 * Adjust inputTab
239 xmlParserInputPtr pInput = xmlNewInputStream( m_pParserCtxt ) ;
241 if( m_pParserCtxt->inputTab != NULL && m_pParserCtxt->inputMax != 0 )
243 m_pParserCtxt->inputTab[0] = pInput ;
244 m_pParserCtxt->input = pInput ;
247 m_pSaxHandler->startDocument( m_pParserCtxt ) ;
249 if( m_pParserCtxt == NULL || m_pParserCtxt->myDoc == NULL )
251 throw cssu::RuntimeException() ;
256 * XDocumentHandler -- end an xml document
258 void SAXHelper::endDocument( void )
259 throw( cssxs::SAXException , cssu::RuntimeException )
261 m_pSaxHandler->endDocument( m_pParserCtxt ) ;
265 * XDocumentHandler -- start an xml element
267 void SAXHelper::startElement(
268 const rtl::OUString& aName,
269 const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
270 throw( cssxs::SAXException , cssu::RuntimeException )
272 const xmlChar* fullName = NULL ;
273 const xmlChar** attrs = NULL ;
275 fullName = ous_to_xmlstr( aName ) ;
276 attrs = attrlist_to_nxmlstr( aAttributes ) ;
278 if( fullName != NULL || attrs != NULL )
280 m_pSaxHandler->startElement( m_pParserCtxt , fullName , attrs ) ;
283 if( fullName != NULL )
285 xmlFree( ( xmlChar* )fullName ) ;
286 fullName = NULL ;
289 if( attrs != NULL )
291 for( int i = 0 ; attrs[i] != NULL ; ++i )
293 xmlFree( ( xmlChar* )attrs[i] ) ;
294 attrs[i] = NULL ;
297 xmlFree( ( void* ) attrs ) ;
298 attrs = NULL ;
303 * XDocumentHandler -- end an xml element
305 void SAXHelper::endElement( const rtl::OUString& aName )
306 throw( cssxs::SAXException , cssu::RuntimeException )
308 xmlChar* fullname = NULL ;
310 fullname = ous_to_xmlstr( aName ) ;
311 m_pSaxHandler->endElement( m_pParserCtxt , fullname ) ;
313 if( fullname != NULL )
315 xmlFree( ( xmlChar* )fullname ) ;
316 fullname = NULL ;
321 * XDocumentHandler -- an xml element or cdata characters
323 void SAXHelper::characters( const rtl::OUString& aChars )
324 throw( cssxs::SAXException , cssu::RuntimeException )
326 const xmlChar* chars = NULL ;
327 int length = 0 ;
329 chars = ous_to_nxmlstr( aChars, length ) ;
330 m_pSaxHandler->characters( m_pParserCtxt , chars , length ) ;
332 if( chars != NULL )
334 xmlFree( ( xmlChar* )chars ) ;
339 * XDocumentHandler -- ignorable xml white space
341 void SAXHelper::ignorableWhitespace( const rtl::OUString& aWhitespaces )
342 throw( cssxs::SAXException , cssu::RuntimeException )
344 const xmlChar* chars = NULL ;
345 int length = 0 ;
347 chars = ous_to_nxmlstr( aWhitespaces, length ) ;
348 m_pSaxHandler->ignorableWhitespace( m_pParserCtxt , chars , length ) ;
350 if( chars != NULL )
352 xmlFree( ( xmlChar* )chars ) ;
357 * XDocumentHandler -- preaorocessing instruction
359 void SAXHelper::processingInstruction(
360 const rtl::OUString& aTarget,
361 const rtl::OUString& aData )
362 throw( cssxs::SAXException , cssu::RuntimeException )
364 xmlChar* target = NULL ;
365 xmlChar* data = NULL ;
367 target = ous_to_xmlstr( aTarget ) ;
368 data = ous_to_xmlstr( aData ) ;
370 m_pSaxHandler->processingInstruction( m_pParserCtxt , target , data ) ;
372 if( target != NULL )
374 xmlFree( ( xmlChar* )target ) ;
375 target = NULL ;
378 if( data != NULL )
380 xmlFree( ( xmlChar* )data ) ;
381 data = NULL ;
386 * XDocumentHandler -- set document locator
387 * In this case, locator is useless.
389 void SAXHelper::setDocumentLocator(
390 const cssu::Reference< cssxs::XLocator > &)
391 throw( cssxs::SAXException , cssu::RuntimeException )
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */