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 .
21 #include <rtl/ustring.hxx>
23 #include "saxhelper.hxx"
24 #include "libxml/parserInternals.h"
26 #ifndef XMLSEC_NO_XSLT
27 #include "libxslt/xslt.h"
30 namespace cssu
= com::sun::star::uno
;
31 namespace cssxs
= com::sun::star::xml::sax
;
32 namespace cssxcsax
= com::sun::star::xml::csax
;
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() ) ;
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
) ;
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();
70 attrs
= ( const xmlChar
** )xmlMalloc( ( nLength
* 2 + 2 ) * sizeof( xmlChar
* ) ) ;
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
;
93 if( attvalue
!= NULL
)
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
)
112 LIBXML_TEST_VERSION
;
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() ;
129 * mmi : re-initialize the SAX handler to version 1
132 xmlSAXVersion(m_pParserCtxt
->sax
, 1);
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() ;
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() ;
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() ;
166 m_pSaxHandler
= m_pParserCtxt
->sax
;
169 m_pParserCtxt
->recovery
= 1 ;
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
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
)
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
) ;
291 for( int i
= 0 ; attrs
[i
] != NULL
; ++i
)
293 xmlFree( ( xmlChar
* )attrs
[i
] ) ;
297 xmlFree( ( void* ) attrs
) ;
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
) ;
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
;
329 chars
= ous_to_nxmlstr( aChars
, length
) ;
330 m_pSaxHandler
->characters( m_pParserCtxt
, chars
, length
) ;
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
;
347 chars
= ous_to_nxmlstr( aWhitespaces
, length
) ;
348 m_pSaxHandler
->ignorableWhitespace( m_pParserCtxt
, chars
, length
) ;
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
) ;
374 xmlFree( ( xmlChar
* )target
) ;
380 xmlFree( ( xmlChar
* )data
) ;
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: */