1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: saxhelper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmlsecurity.hxx"
34 #include <rtl/ustring.hxx>
36 #include "saxhelper.hxx"
37 #include "libxml/parserInternals.h"
39 #ifndef XMLSEC_NO_XSLT
40 #include "libxslt/xslt.h"
43 namespace cssu
= com::sun::star::uno
;
44 namespace cssxs
= com::sun::star::xml::sax
;
45 namespace cssxcsax
= com::sun::star::xml::csax
;
48 * The return value is NULL terminated. The application has the responsibilty to
49 * deallocte the return value.
51 xmlChar
* ous_to_xmlstr( const rtl::OUString
& oustr
)
53 rtl::OString ostr
= rtl::OUStringToOString( oustr
, RTL_TEXTENCODING_UTF8
) ;
54 return xmlStrndup( ( xmlChar
* )ostr
.getStr(), ( int )ostr
.getLength() ) ;
58 * The return value is NULL terminated. The application has the responsibilty to
59 * deallocte the return value.
61 xmlChar
* ous_to_nxmlstr( const rtl::OUString
& oustr
, int& length
)
63 rtl::OString ostr
= rtl::OUStringToOString( oustr
, RTL_TEXTENCODING_UTF8
) ;
64 length
= ostr
.getLength();
66 return xmlStrndup( ( xmlChar
* )ostr
.getStr(), length
) ;
70 * The input parameter isn't necessaryly NULL terminated.
72 rtl::OUString
xmlchar_to_ous( const xmlChar
* pChar
, int length
)
76 return rtl::OUString( ( sal_Char
* )pChar
, length
, RTL_TEXTENCODING_UTF8
) ;
80 return rtl::OUString() ;
85 * The input parameter is NULL terminated
87 rtl::OUString
xmlstr_to_ous( const xmlChar
* pStr
)
91 return xmlchar_to_ous( pStr
, xmlStrlen( pStr
) ) ;
95 return rtl::OUString() ;
100 * The return value and the referenced value must be NULL terminated.
101 * The application has the responsibilty to deallocte the return value.
103 const xmlChar
** attrlist_to_nxmlstr( const cssu::Sequence
< cssxcsax::XMLAttribute
>& aAttributes
)
105 xmlChar
* attname
= NULL
;
106 xmlChar
* attvalue
= NULL
;
107 const xmlChar
** attrs
= NULL
;
108 rtl::OUString oustr
;
110 sal_Int32 nLength
= aAttributes
.getLength();;
114 attrs
= ( const xmlChar
** )xmlMalloc( ( nLength
* 2 + 2 ) * sizeof( xmlChar
* ) ) ;
121 for( int i
= 0 , j
= 0 ; j
< nLength
; ++j
)
123 attname
= ous_to_xmlstr( aAttributes
[j
].sName
) ;
124 attvalue
= ous_to_xmlstr( aAttributes
[j
].sValue
) ;
126 if( attname
!= NULL
&& attvalue
!= NULL
)
128 attrs
[i
++] = attname
;
129 attrs
[i
++] = attvalue
;
135 if( attname
!= NULL
)
137 if( attvalue
!= NULL
)
138 xmlFree( attvalue
) ;
148 * In this constructor, a libxml sax parser context is initialized. a libxml
149 * default sax handler is initialized with the context.
151 SAXHelper::SAXHelper( )
152 : m_pParserCtxt( NULL
),
153 m_pSaxHandler( NULL
)
156 LIBXML_TEST_VERSION
;
160 * xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS ;
162 xmlSubstituteEntitiesDefault( 1 ) ;
164 #ifndef XMLSEC_NO_XSLT
165 xmlIndentTreeOutput
= 1 ;
166 #endif /* XMLSEC_NO_XSLT */
168 m_pParserCtxt
= xmlNewParserCtxt() ;
173 * mmi : re-initialize the SAX handler to version 1
176 xmlSAXVersion(m_pParserCtxt
->sax
, 1);
180 if( m_pParserCtxt
->inputTab
[0] != NULL
)
182 m_pParserCtxt
->inputTab
[0] = NULL
;
185 if( m_pParserCtxt
== NULL
)
187 #ifndef XMLSEC_NO_XSLT
188 xsltCleanupGlobals() ;
190 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
191 // in other parts of the office.
192 // xmlCleanupParser() ;
193 throw cssu::RuntimeException() ;
195 else if( m_pParserCtxt
->sax
== NULL
)
197 xmlFreeParserCtxt( m_pParserCtxt
) ;
199 #ifndef XMLSEC_NO_XSLT
200 xsltCleanupGlobals() ;
202 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
203 // in other parts of the office.
204 // xmlCleanupParser() ;
205 m_pParserCtxt
= NULL
;
206 throw cssu::RuntimeException() ;
210 m_pSaxHandler
= m_pParserCtxt
->sax
;
213 m_pParserCtxt
->recovery
= 1 ;
220 * In this destructor, a libxml sax parser context is desturcted. The XML tree
221 * in the context is not deallocated because the tree is bind with a document
222 * model by the setTargetDocument method, which delegate the target document to
223 * destruct the xml tree.
225 SAXHelper::~SAXHelper() {
226 if( m_pParserCtxt
!= NULL
)
229 * In the situation that no object refer the Document, this destructor
230 * must deallocate the Document memory
232 if( m_pSaxHandler
== m_pParserCtxt
->sax
)
234 m_pSaxHandler
= NULL
;
237 xmlFreeParserCtxt( m_pParserCtxt
) ;
238 m_pParserCtxt
= NULL
;
241 if( m_pSaxHandler
!= NULL
)
243 xmlFree( m_pSaxHandler
) ;
244 m_pSaxHandler
= NULL
;
246 // see issue i74334, we cannot call xmlCleanupParser when libxml is still used
247 // in other parts of the office.
248 // xmlCleanupParser() ;
251 xmlNodePtr
SAXHelper::getCurrentNode()
253 return m_pParserCtxt
->node
;
256 void SAXHelper::setCurrentNode(const xmlNodePtr pNode
)
259 * This is really a black trick.
260 * When the current node is replaced, the nodeTab
261 * stack's top has to been replaced with the same
262 * node, in order to make compatibility.
264 m_pParserCtxt
->nodeTab
[m_pParserCtxt
->nodeNr
- 1]
265 = m_pParserCtxt
->node
269 xmlDocPtr
SAXHelper::getDocument()
271 return m_pParserCtxt
->myDoc
;
275 * XDocumentHandler -- start an xml document
277 void SAXHelper::startDocument( void )
278 throw( cssxs::SAXException
, cssu::RuntimeException
)
283 xmlParserInputPtr pInput
= xmlNewInputStream( m_pParserCtxt
) ;
285 if( m_pParserCtxt
->inputTab
!= NULL
&& m_pParserCtxt
->inputMax
!= 0 )
287 m_pParserCtxt
->inputTab
[0] = pInput
;
288 m_pParserCtxt
->input
= pInput
;
291 m_pSaxHandler
->startDocument( m_pParserCtxt
) ;
293 if( m_pParserCtxt
== NULL
|| m_pParserCtxt
->myDoc
== NULL
)
295 throw cssu::RuntimeException() ;
300 * XDocumentHandler -- end an xml document
302 void SAXHelper::endDocument( void )
303 throw( cssxs::SAXException
, cssu::RuntimeException
)
305 m_pSaxHandler
->endDocument( m_pParserCtxt
) ;
309 * XDocumentHandler -- start an xml element
311 void SAXHelper::startElement(
312 const rtl::OUString
& aName
,
313 const cssu::Sequence
< cssxcsax::XMLAttribute
>& aAttributes
)
314 throw( cssxs::SAXException
, cssu::RuntimeException
)
316 const xmlChar
* fullName
= NULL
;
317 const xmlChar
** attrs
= NULL
;
319 fullName
= ous_to_xmlstr( aName
) ;
320 attrs
= attrlist_to_nxmlstr( aAttributes
) ;
322 if( fullName
!= NULL
|| attrs
!= NULL
)
324 m_pSaxHandler
->startElement( m_pParserCtxt
, fullName
, attrs
) ;
327 if( fullName
!= NULL
)
329 xmlFree( ( xmlChar
* )fullName
) ;
335 for( int i
= 0 ; attrs
[i
] != NULL
; ++i
)
337 xmlFree( ( xmlChar
* )attrs
[i
] ) ;
341 xmlFree( ( void* ) attrs
) ;
347 * XDocumentHandler -- end an xml element
349 void SAXHelper::endElement( const rtl::OUString
& aName
)
350 throw( cssxs::SAXException
, cssu::RuntimeException
)
352 xmlChar
* fullname
= NULL
;
354 fullname
= ous_to_xmlstr( aName
) ;
355 m_pSaxHandler
->endElement( m_pParserCtxt
, fullname
) ;
357 if( fullname
!= NULL
)
359 xmlFree( ( xmlChar
* )fullname
) ;
365 * XDocumentHandler -- an xml element or cdata characters
367 void SAXHelper::characters( const rtl::OUString
& aChars
)
368 throw( cssxs::SAXException
, cssu::RuntimeException
)
370 const xmlChar
* chars
= NULL
;
373 chars
= ous_to_nxmlstr( aChars
, length
) ;
374 m_pSaxHandler
->characters( m_pParserCtxt
, chars
, length
) ;
378 xmlFree( ( xmlChar
* )chars
) ;
383 * XDocumentHandler -- ignorable xml white space
385 void SAXHelper::ignorableWhitespace( const rtl::OUString
& aWhitespaces
)
386 throw( cssxs::SAXException
, cssu::RuntimeException
)
388 const xmlChar
* chars
= NULL
;
391 chars
= ous_to_nxmlstr( aWhitespaces
, length
) ;
392 m_pSaxHandler
->ignorableWhitespace( m_pParserCtxt
, chars
, length
) ;
396 xmlFree( ( xmlChar
* )chars
) ;
401 * XDocumentHandler -- preaorocessing instruction
403 void SAXHelper::processingInstruction(
404 const rtl::OUString
& aTarget
,
405 const rtl::OUString
& aData
)
406 throw( cssxs::SAXException
, cssu::RuntimeException
)
408 xmlChar
* target
= NULL
;
409 xmlChar
* data
= NULL
;
411 target
= ous_to_xmlstr( aTarget
) ;
412 data
= ous_to_xmlstr( aData
) ;
414 m_pSaxHandler
->processingInstruction( m_pParserCtxt
, target
, data
) ;
418 xmlFree( ( xmlChar
* )target
) ;
424 xmlFree( ( xmlChar
* )data
) ;
430 * XDocumentHandler -- set document locator
431 * In this case, locator is useless.
433 void SAXHelper::setDocumentLocator(
434 const cssu::Reference
< cssxs::XLocator
> &)
435 throw( cssxs::SAXException
, cssu::RuntimeException
)
437 //--Pseudo code if necessary
438 //--m_pSaxLocator is a member defined as xmlSAXHabdlerPtr
439 //--m_pSaxLocatorHdl is a member defined as Sax_Locator
441 //if( m_pSaxLocator != NULL ) {
442 // //Deallocate the memory
444 //if( m_pSaxLocatorHdl != NULL ) {
445 // //Deallocate the memory
448 //m_pSaxLocatorHdl = new Sax_Locator( xLocator ) ;
449 //m_pSaxLocator = { m_pSaxLocatorHdl->getPublicId , m_pSaxLocatorHdl->getSystemId , m_pSaxLocatorHdl->getLineNumber , m_pSaxLocatorHdl->getColumnNumber } ;
451 //m_pSaxHandler->setDocumentLocator( m_pParserCtxt , m_pSaxLocator ) ;