Branch data Line data Source code
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 : :
21 : : #include <rtl/ustring.hxx>
22 : :
23 : : #include "saxhelper.hxx"
24 : : #include "libxml/parserInternals.h"
25 : :
26 : : #ifndef XMLSEC_NO_XSLT
27 : : #include "libxslt/xslt.h"
28 : : #endif
29 : :
30 : : namespace cssu = com::sun::star::uno;
31 : : namespace cssxs = com::sun::star::xml::sax;
32 : : namespace cssxcsax = com::sun::star::xml::csax;
33 : :
34 : : /**
35 : : * The return value is NULL terminated. The application has the responsibilty to
36 : : * deallocte the return value.
37 : : */
38 : 0 : xmlChar* ous_to_xmlstr( const rtl::OUString& oustr )
39 : : {
40 [ # # ]: 0 : rtl::OString ostr = rtl::OUStringToOString( oustr , RTL_TEXTENCODING_UTF8 ) ;
41 [ # # ]: 0 : return xmlStrndup( ( xmlChar* )ostr.getStr(), ( int )ostr.getLength() ) ;
42 : : }
43 : :
44 : : /**
45 : : * The return value is NULL terminated. The application has the responsibilty to
46 : : * deallocte the return value.
47 : : */
48 : 0 : xmlChar* ous_to_nxmlstr( const rtl::OUString& oustr, int& length )
49 : : {
50 [ # # ]: 0 : rtl::OString ostr = rtl::OUStringToOString( oustr , RTL_TEXTENCODING_UTF8 ) ;
51 : 0 : length = ostr.getLength();
52 : :
53 [ # # ]: 0 : return xmlStrndup( ( xmlChar* )ostr.getStr(), length ) ;
54 : : }
55 : :
56 : : /**
57 : : * The return value and the referenced value must be NULL terminated.
58 : : * The application has the responsibilty to deallocte the return value.
59 : : */
60 : 0 : const xmlChar** attrlist_to_nxmlstr( const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
61 : : {
62 : 0 : xmlChar* attname = NULL ;
63 : 0 : xmlChar* attvalue = NULL ;
64 : 0 : const xmlChar** attrs = NULL ;
65 : 0 : rtl::OUString oustr ;
66 : :
67 : 0 : sal_Int32 nLength = aAttributes.getLength();
68 : :
69 [ # # ]: 0 : if( nLength != 0 )
70 : : {
71 [ # # ]: 0 : attrs = ( const xmlChar** )xmlMalloc( ( nLength * 2 + 2 ) * sizeof( xmlChar* ) ) ;
72 : : }
73 : : else
74 : : {
75 : 0 : return NULL ;
76 : : }
77 : :
78 [ # # ]: 0 : for( int i = 0 , j = 0 ; j < nLength ; ++j )
79 : : {
80 [ # # ]: 0 : attname = ous_to_xmlstr( aAttributes[j].sName ) ;
81 [ # # ]: 0 : attvalue = ous_to_xmlstr( aAttributes[j].sValue ) ;
82 : :
83 [ # # ][ # # ]: 0 : if( attname != NULL && attvalue != NULL )
84 : : {
85 : 0 : attrs[i++] = attname ;
86 : 0 : attrs[i++] = attvalue ;
87 : 0 : attrs[i] = NULL ;
88 : 0 : attrs[i+1] = NULL ;
89 : : }
90 : : else
91 : : {
92 [ # # ]: 0 : if( attname != NULL )
93 [ # # ]: 0 : xmlFree( attname ) ;
94 [ # # ]: 0 : if( attvalue != NULL )
95 [ # # ]: 0 : xmlFree( attvalue ) ;
96 : : }
97 : : }
98 : :
99 : 0 : return attrs ;
100 : : }
101 : :
102 : : /**
103 : : * Constructor
104 : : *
105 : : * In this constructor, a libxml sax parser context is initialized. a libxml
106 : : * default sax handler is initialized with the context.
107 : : */
108 : 0 : SAXHelper::SAXHelper( )
109 : : : m_pParserCtxt( NULL ),
110 : 0 : m_pSaxHandler( NULL )
111 : : {
112 : 0 : xmlInitParser() ;
113 : 0 : LIBXML_TEST_VERSION ;
114 : :
115 : : /*
116 : : * compile error:
117 : : * xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS ;
118 : : */
119 : 0 : xmlSubstituteEntitiesDefault( 1 ) ;
120 : :
121 : : #ifndef XMLSEC_NO_XSLT
122 : : xmlIndentTreeOutput = 1 ;
123 : : #endif /* XMLSEC_NO_XSLT */
124 : :
125 : 0 : m_pParserCtxt = xmlNewParserCtxt() ;
126 : :
127 : : /*
128 : : * i41748
129 : : *
130 : : * mmi : re-initialize the SAX handler to version 1
131 : : */
132 : :
133 : 0 : xmlSAXVersion(m_pParserCtxt->sax, 1);
134 : :
135 : : /* end */
136 : :
137 [ # # ]: 0 : if( m_pParserCtxt->inputTab[0] != NULL )
138 : : {
139 : 0 : m_pParserCtxt->inputTab[0] = NULL ;
140 : : }
141 : :
142 [ # # ]: 0 : if( m_pParserCtxt == NULL )
143 : : {
144 : : #ifndef XMLSEC_NO_XSLT
145 : : xsltCleanupGlobals() ;
146 : : #endif
147 : : // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
148 : : // in other parts of the office.
149 : : // xmlCleanupParser() ;
150 [ # # ]: 0 : throw cssu::RuntimeException() ;
151 : : }
152 [ # # ]: 0 : else if( m_pParserCtxt->sax == NULL )
153 : : {
154 : 0 : xmlFreeParserCtxt( m_pParserCtxt ) ;
155 : :
156 : : #ifndef XMLSEC_NO_XSLT
157 : : xsltCleanupGlobals() ;
158 : : #endif
159 : : // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
160 : : // in other parts of the office.
161 : : // xmlCleanupParser() ;
162 : 0 : m_pParserCtxt = NULL ;
163 [ # # ]: 0 : throw cssu::RuntimeException() ;
164 : : }
165 : : else
166 : : {
167 : 0 : m_pSaxHandler = m_pParserCtxt->sax ;
168 : :
169 : : //Adjust the context
170 : 0 : m_pParserCtxt->recovery = 1 ;
171 : : }
172 : 0 : }
173 : :
174 : : /**
175 : : * Destructor
176 : : *
177 : : * In this destructor, a libxml sax parser context is desturcted. The XML tree
178 : : * in the context is not deallocated because the tree is bind with a document
179 : : * model by the setTargetDocument method, which delegate the target document to
180 : : * destruct the xml tree.
181 : : */
182 : 0 : SAXHelper::~SAXHelper() {
183 [ # # ]: 0 : if( m_pParserCtxt != NULL )
184 : : {
185 : : /*
186 : : * In the situation that no object refer the Document, this destructor
187 : : * must deallocate the Document memory
188 : : */
189 [ # # ]: 0 : if( m_pSaxHandler == m_pParserCtxt->sax )
190 : : {
191 : 0 : m_pSaxHandler = NULL ;
192 : : }
193 : :
194 : 0 : xmlFreeParserCtxt( m_pParserCtxt ) ;
195 : 0 : m_pParserCtxt = NULL ;
196 : : }
197 : :
198 [ # # ]: 0 : if( m_pSaxHandler != NULL )
199 : : {
200 : 0 : xmlFree( m_pSaxHandler ) ;
201 : 0 : m_pSaxHandler = NULL ;
202 : : }
203 : : // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
204 : : // in other parts of the office.
205 : : // xmlCleanupParser() ;
206 [ # # ]: 0 : }
207 : :
208 : 0 : xmlNodePtr SAXHelper::getCurrentNode()
209 : : {
210 : 0 : return m_pParserCtxt->node;
211 : : }
212 : :
213 : 0 : void SAXHelper::setCurrentNode(const xmlNodePtr pNode)
214 : : {
215 : : /*
216 : : * This is really a black trick.
217 : : * When the current node is replaced, the nodeTab
218 : : * stack's top has to been replaced with the same
219 : : * node, in order to make compatibility.
220 : : */
221 : 0 : m_pParserCtxt->nodeTab[m_pParserCtxt->nodeNr - 1]
222 : : = m_pParserCtxt->node
223 : 0 : = pNode;
224 : 0 : }
225 : :
226 : 0 : xmlDocPtr SAXHelper::getDocument()
227 : : {
228 : 0 : return m_pParserCtxt->myDoc;
229 : : }
230 : :
231 : : /**
232 : : * XDocumentHandler -- start an xml document
233 : : */
234 : 0 : void SAXHelper::startDocument( void )
235 : : throw( cssxs::SAXException , cssu::RuntimeException )
236 : : {
237 : : /*
238 : : * Adjust inputTab
239 : : */
240 : 0 : xmlParserInputPtr pInput = xmlNewInputStream( m_pParserCtxt ) ;
241 : :
242 [ # # ][ # # ]: 0 : if( m_pParserCtxt->inputTab != NULL && m_pParserCtxt->inputMax != 0 )
243 : : {
244 : 0 : m_pParserCtxt->inputTab[0] = pInput ;
245 : 0 : m_pParserCtxt->input = pInput ;
246 : : }
247 : :
248 : 0 : m_pSaxHandler->startDocument( m_pParserCtxt ) ;
249 : :
250 [ # # ][ # # ]: 0 : if( m_pParserCtxt == NULL || m_pParserCtxt->myDoc == NULL )
251 : : {
252 [ # # ]: 0 : throw cssu::RuntimeException() ;
253 : : }
254 : 0 : }
255 : :
256 : : /**
257 : : * XDocumentHandler -- end an xml document
258 : : */
259 : 0 : void SAXHelper::endDocument( void )
260 : : throw( cssxs::SAXException , cssu::RuntimeException )
261 : : {
262 : 0 : m_pSaxHandler->endDocument( m_pParserCtxt ) ;
263 : 0 : }
264 : :
265 : : /**
266 : : * XDocumentHandler -- start an xml element
267 : : */
268 : 0 : void SAXHelper::startElement(
269 : : const rtl::OUString& aName,
270 : : const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
271 : : throw( cssxs::SAXException , cssu::RuntimeException )
272 : : {
273 : 0 : const xmlChar* fullName = NULL ;
274 : 0 : const xmlChar** attrs = NULL ;
275 : :
276 : 0 : fullName = ous_to_xmlstr( aName ) ;
277 : 0 : attrs = attrlist_to_nxmlstr( aAttributes ) ;
278 : :
279 [ # # ][ # # ]: 0 : if( fullName != NULL || attrs != NULL )
280 : : {
281 : 0 : m_pSaxHandler->startElement( m_pParserCtxt , fullName , attrs ) ;
282 : : }
283 : :
284 [ # # ]: 0 : if( fullName != NULL )
285 : : {
286 : 0 : xmlFree( ( xmlChar* )fullName ) ;
287 : 0 : fullName = NULL ;
288 : : }
289 : :
290 [ # # ]: 0 : if( attrs != NULL )
291 : : {
292 [ # # ]: 0 : for( int i = 0 ; attrs[i] != NULL ; ++i )
293 : : {
294 : 0 : xmlFree( ( xmlChar* )attrs[i] ) ;
295 : 0 : attrs[i] = NULL ;
296 : : }
297 : :
298 : 0 : xmlFree( ( void* ) attrs ) ;
299 : 0 : attrs = NULL ;
300 : : }
301 : 0 : }
302 : :
303 : : /**
304 : : * XDocumentHandler -- end an xml element
305 : : */
306 : 0 : void SAXHelper::endElement( const rtl::OUString& aName )
307 : : throw( cssxs::SAXException , cssu::RuntimeException )
308 : : {
309 : 0 : xmlChar* fullname = NULL ;
310 : :
311 : 0 : fullname = ous_to_xmlstr( aName ) ;
312 : 0 : m_pSaxHandler->endElement( m_pParserCtxt , fullname ) ;
313 : :
314 [ # # ]: 0 : if( fullname != NULL )
315 : : {
316 : 0 : xmlFree( ( xmlChar* )fullname ) ;
317 : 0 : fullname = NULL ;
318 : : }
319 : 0 : }
320 : :
321 : : /**
322 : : * XDocumentHandler -- an xml element or cdata characters
323 : : */
324 : 0 : void SAXHelper::characters( const rtl::OUString& aChars )
325 : : throw( cssxs::SAXException , cssu::RuntimeException )
326 : : {
327 : 0 : const xmlChar* chars = NULL ;
328 : 0 : int length = 0 ;
329 : :
330 [ # # ]: 0 : chars = ous_to_nxmlstr( aChars, length ) ;
331 [ # # ]: 0 : m_pSaxHandler->characters( m_pParserCtxt , chars , length ) ;
332 : :
333 [ # # ]: 0 : if( chars != NULL )
334 : : {
335 [ # # ]: 0 : xmlFree( ( xmlChar* )chars ) ;
336 : : }
337 : 0 : }
338 : :
339 : : /**
340 : : * XDocumentHandler -- ignorable xml white space
341 : : */
342 : 0 : void SAXHelper::ignorableWhitespace( const rtl::OUString& aWhitespaces )
343 : : throw( cssxs::SAXException , cssu::RuntimeException )
344 : : {
345 : 0 : const xmlChar* chars = NULL ;
346 : 0 : int length = 0 ;
347 : :
348 [ # # ]: 0 : chars = ous_to_nxmlstr( aWhitespaces, length ) ;
349 [ # # ]: 0 : m_pSaxHandler->ignorableWhitespace( m_pParserCtxt , chars , length ) ;
350 : :
351 [ # # ]: 0 : if( chars != NULL )
352 : : {
353 [ # # ]: 0 : xmlFree( ( xmlChar* )chars ) ;
354 : : }
355 : 0 : }
356 : :
357 : : /**
358 : : * XDocumentHandler -- preaorocessing instruction
359 : : */
360 : 0 : void SAXHelper::processingInstruction(
361 : : const rtl::OUString& aTarget,
362 : : const rtl::OUString& aData )
363 : : throw( cssxs::SAXException , cssu::RuntimeException )
364 : : {
365 : 0 : xmlChar* target = NULL ;
366 : 0 : xmlChar* data = NULL ;
367 : :
368 : 0 : target = ous_to_xmlstr( aTarget ) ;
369 : 0 : data = ous_to_xmlstr( aData ) ;
370 : :
371 : 0 : m_pSaxHandler->processingInstruction( m_pParserCtxt , target , data ) ;
372 : :
373 [ # # ]: 0 : if( target != NULL )
374 : : {
375 : 0 : xmlFree( ( xmlChar* )target ) ;
376 : 0 : target = NULL ;
377 : : }
378 : :
379 [ # # ]: 0 : if( data != NULL )
380 : : {
381 : 0 : xmlFree( ( xmlChar* )data ) ;
382 : 0 : data = NULL ;
383 : : }
384 : 0 : }
385 : :
386 : : /**
387 : : * XDocumentHandler -- set document locator
388 : : * In this case, locator is useless.
389 : : */
390 : 0 : void SAXHelper::setDocumentLocator(
391 : : const cssu::Reference< cssxs::XLocator > &)
392 : : throw( cssxs::SAXException , cssu::RuntimeException )
393 : : {
394 : 0 : }
395 : :
396 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|