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 <sal/alloca.h>
25 #include <osl/diagnose.h>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <com/sun/star/lang/XInitialization.hpp>
29 #include <com/sun/star/uno/XComponentContext.hpp>
30 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
31 #include <com/sun/star/xml/sax/XParser.hpp>
32 #include <com/sun/star/xml/sax/SAXParseException.hpp>
33 #include <com/sun/star/io/XSeekable.hpp>
34 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
36 #include <cppuhelper/weak.hxx>
37 #include <cppuhelper/implbase3.hxx>
38 #include <cppuhelper/supportsservice.hxx>
39 #include <rtl/ref.hxx>
40 #include <sal/log.hxx>
44 using namespace ::std
;
45 using namespace ::osl
;
46 using namespace ::cppu
;
47 using namespace ::com::sun::star::lang
;
48 using namespace ::com::sun::star::xml::sax
;
49 using namespace ::com::sun::star::io
;
51 #include "attrlistimpl.hxx"
52 #include "xml2utf.hxx"
56 // Useful macros for correct String conversion depending on the chosen expat-mode
58 OUString
XmlNChar2OUString( const XML_Char
*p
, int nLen
)
61 if( sizeof( sal_Unicode
) == sizeof( XML_Char
) )
63 return OUString( (sal_Unicode
*)p
,nLen
);
67 sal_Unicode
*pWchar
= (sal_Unicode
*)alloca( sizeof( sal_Unicode
) * nLen
);
68 for( int n
= 0 ; n
< nLen
; n
++ ) {
69 pWchar
[n
] = (sal_Unicode
) p
[n
];
71 return OUString( pWchar
, nLen
);
79 OUString
XmlChar2OUString( const XML_Char
*p
)
83 for( nLen
= 0 ; p
[nLen
] ; nLen
++ )
85 return XmlNChar2OUString( p
, nLen
);
87 else return OUString();
91 #define XML_CHAR_TO_OUSTRING(x) XmlChar2OUString(x)
92 #define XML_CHAR_N_TO_USTRING(x,n) XmlNChar2OUString(x,n)
94 #define XML_CHAR_TO_OUSTRING(x) OUString(x , strlen( x ), RTL_TEXTENCODING_UTF8)
95 #define XML_CHAR_N_TO_USTRING(x,n) OUString(x,n, RTL_TEXTENCODING_UTF8 )
100 * The following macro encapsulates any call to an event handler.
101 * It ensures, that exceptions thrown by the event handler are
104 #define CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pThis,call) \
105 if( ! pThis->bExceptionWasThrown ) { \
109 catch( const SAXParseException &e ) {\
110 callErrorHandler( pThis , e );\
112 catch( const SAXException &e ) {\
113 callErrorHandler( pThis , SAXParseException(\
117 pThis->rDocumentLocator->getPublicId(),\
118 pThis->rDocumentLocator->getSystemId(),\
119 pThis->rDocumentLocator->getLineNumber(),\
120 pThis->rDocumentLocator->getColumnNumber()\
123 catch( const com::sun::star::uno::RuntimeException &e ) {\
124 pThis->bExceptionWasThrown = true; \
125 pThis->bRTExceptionWasThrown = true; \
126 pImpl->rtexception = e; \
128 catch( const com::sun::star::uno::Exception &e ) {\
129 pThis->bExceptionWasThrown = true; \
130 pThis->bRTExceptionWasThrown = true; \
131 pImpl->rtexception = WrappedTargetRuntimeException("Non-runtime UNO exception caught during parse", e.Context, makeAny(e)); \
137 class SaxExpatParser_Impl
;
139 // This class implements the external Parser interface
141 : public WeakImplHelper3
< XInitialization
148 virtual ~SaxExpatParser();
150 // ::com::sun::star::lang::XInitialization:
151 virtual void SAL_CALL
initialize(css::uno::Sequence
<css::uno::Any
> const& rArguments
)
152 throw (css::uno::RuntimeException
, css::uno::Exception
, std::exception
) SAL_OVERRIDE
;
154 // The SAX-Parser-Interface
155 virtual void SAL_CALL
parseStream( const InputSource
& structSource
)
156 throw ( SAXException
,
158 css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
159 virtual void SAL_CALL
setDocumentHandler(const css::uno::Reference
< XDocumentHandler
> & xHandler
)
160 throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
162 virtual void SAL_CALL
setErrorHandler(const css::uno::Reference
< XErrorHandler
> & xHandler
)
163 throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
164 virtual void SAL_CALL
setDTDHandler(const css::uno::Reference
< XDTDHandler
> & xHandler
)
165 throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
166 virtual void SAL_CALL
setEntityResolver(const css::uno::Reference
< XEntityResolver
>& xResolver
)
167 throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
169 virtual void SAL_CALL
setLocale( const Locale
&locale
) throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
171 public: // XServiceInfo
172 OUString SAL_CALL
getImplementationName() throw (std::exception
) SAL_OVERRIDE
;
173 css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() throw (std::exception
) SAL_OVERRIDE
;
174 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) throw (std::exception
) SAL_OVERRIDE
;
178 SaxExpatParser_Impl
*m_pImpl
;
183 // Entity binds all information neede for a single file
186 InputSource structSource
;
188 sax_expatwrap::XMLFile2UTFConverter converter
;
192 class SaxExpatParser_Impl
194 public: // module scope
197 bool m_bEnableDoS
; // fdo#60471 thank you Adobe Illustrator
199 css::uno::Reference
< XDocumentHandler
> rDocumentHandler
;
200 css::uno::Reference
< XExtendedDocumentHandler
> rExtendedDocumentHandler
;
202 css::uno::Reference
< XErrorHandler
> rErrorHandler
;
203 css::uno::Reference
< XDTDHandler
> rDTDHandler
;
204 css::uno::Reference
< XEntityResolver
> rEntityResolver
;
205 css::uno::Reference
< XLocator
> rDocumentLocator
;
208 rtl::Reference
< sax_expatwrap::AttributeList
> rAttrList
;
210 // External entity stack
211 vector
<struct Entity
> vecEntity
;
212 void pushEntity( const struct Entity
&entity
)
213 { vecEntity
.push_back( entity
); }
215 { vecEntity
.pop_back( ); }
216 struct Entity
&getEntity()
217 { return vecEntity
.back(); }
220 // Exception cannot be thrown through the C-XmlParser (possible resource leaks),
221 // therefore the exception must be saved somewhere.
222 SAXParseException exception
;
223 css::uno::RuntimeException rtexception
;
224 bool bExceptionWasThrown
;
225 bool bRTExceptionWasThrown
;
230 SaxExpatParser_Impl()
232 , m_bEnableDoS(false)
233 , bExceptionWasThrown(false)
234 , bRTExceptionWasThrown(false)
238 // the C-Callbacks for the expat parser
239 void static callbackStartElement(void *userData
, const XML_Char
*name
, const XML_Char
**atts
);
240 void static callbackEndElement(void *userData
, const XML_Char
*name
);
241 void static callbackCharacters( void *userData
, const XML_Char
*s
, int nLen
);
242 void static callbackProcessingInstruction( void *userData
,
243 const XML_Char
*sTarget
,
244 const XML_Char
*sData
);
246 void static callbackEntityDecl( void *userData
,
247 const XML_Char
*entityName
,
248 int is_parameter_entity
,
249 const XML_Char
*value
,
251 const XML_Char
*base
,
252 const XML_Char
*systemId
,
253 const XML_Char
*publicId
,
254 const XML_Char
*notationName
);
256 void static callbackNotationDecl( void *userData
,
257 const XML_Char
*notationName
,
258 const XML_Char
*base
,
259 const XML_Char
*systemId
,
260 const XML_Char
*publicId
);
262 bool static callbackExternalEntityRef( XML_Parser parser
,
263 const XML_Char
*openEntityNames
,
264 const XML_Char
*base
,
265 const XML_Char
*systemId
,
266 const XML_Char
*publicId
);
268 int static callbackUnknownEncoding(void *encodingHandlerData
,
269 const XML_Char
*name
,
272 void static callbackDefault( void *userData
, const XML_Char
*s
, int len
);
274 void static callbackStartCDATA( void *userData
);
275 void static callbackEndCDATA( void *userData
);
276 void static callbackComment( void *userData
, const XML_Char
*s
);
277 void static callErrorHandler( SaxExpatParser_Impl
*pImpl
, const SAXParseException
&e
);
285 static void call_callbackStartElement(void *userData
, const XML_Char
*name
, const XML_Char
**atts
)
287 SaxExpatParser_Impl::callbackStartElement(userData
,name
,atts
);
289 static void call_callbackEndElement(void *userData
, const XML_Char
*name
)
291 SaxExpatParser_Impl::callbackEndElement(userData
,name
);
293 static void call_callbackCharacters( void *userData
, const XML_Char
*s
, int nLen
)
295 SaxExpatParser_Impl::callbackCharacters(userData
,s
,nLen
);
297 static void call_callbackProcessingInstruction(void *userData
,const XML_Char
*sTarget
,const XML_Char
*sData
)
299 SaxExpatParser_Impl::callbackProcessingInstruction(userData
,sTarget
,sData
);
301 static void call_callbackEntityDecl(void *userData
,
302 const XML_Char
*entityName
,
303 int is_parameter_entity
,
304 const XML_Char
*value
,
306 const XML_Char
*base
,
307 const XML_Char
*systemId
,
308 const XML_Char
*publicId
,
309 const XML_Char
*notationName
)
311 SaxExpatParser_Impl::callbackEntityDecl(userData
, entityName
,
312 is_parameter_entity
, value
, value_length
,
313 base
, systemId
, publicId
, notationName
);
315 static void call_callbackNotationDecl(void *userData
,
316 const XML_Char
*notationName
,
317 const XML_Char
*base
,
318 const XML_Char
*systemId
,
319 const XML_Char
*publicId
)
321 SaxExpatParser_Impl::callbackNotationDecl(userData
,notationName
,base
,systemId
,publicId
);
323 static int call_callbackExternalEntityRef(XML_Parser parser
,
324 const XML_Char
*openEntityNames
,
325 const XML_Char
*base
,
326 const XML_Char
*systemId
,
327 const XML_Char
*publicId
)
329 return SaxExpatParser_Impl::callbackExternalEntityRef(parser
,openEntityNames
,base
,systemId
,publicId
);
331 static int call_callbackUnknownEncoding(void *encodingHandlerData
,
332 const XML_Char
*name
,
335 return SaxExpatParser_Impl::callbackUnknownEncoding(encodingHandlerData
,name
,info
);
337 static void call_callbackDefault( void *userData
, const XML_Char
*s
, int len
)
339 SaxExpatParser_Impl::callbackDefault(userData
,s
,len
);
341 static void call_callbackStartCDATA( void *userData
)
343 SaxExpatParser_Impl::callbackStartCDATA(userData
);
345 static void call_callbackEndCDATA( void *userData
)
347 SaxExpatParser_Impl::callbackEndCDATA(userData
);
349 static void call_callbackComment( void *userData
, const XML_Char
*s
)
351 SaxExpatParser_Impl::callbackComment(userData
,s
);
360 public WeakImplHelper2
< XLocator
, com::sun::star::io::XSeekable
>
361 // should use a different interface for stream positions!
364 explicit LocatorImpl(SaxExpatParser_Impl
*p
)
370 virtual sal_Int32 SAL_CALL
getColumnNumber() throw (std::exception
) SAL_OVERRIDE
372 return XML_GetCurrentColumnNumber( m_pParser
->getEntity().pParser
);
374 virtual sal_Int32 SAL_CALL
getLineNumber() throw (std::exception
) SAL_OVERRIDE
376 return XML_GetCurrentLineNumber( m_pParser
->getEntity().pParser
);
378 virtual OUString SAL_CALL
getPublicId() throw (std::exception
) SAL_OVERRIDE
380 return m_pParser
->getEntity().structSource
.sPublicId
;
382 virtual OUString SAL_CALL
getSystemId() throw (std::exception
) SAL_OVERRIDE
384 return m_pParser
->getEntity().structSource
.sSystemId
;
387 // XSeekable (only for getPosition)
389 virtual void SAL_CALL
seek( sal_Int64
) throw(std::exception
) SAL_OVERRIDE
392 virtual sal_Int64 SAL_CALL
getPosition() throw(std::exception
) SAL_OVERRIDE
394 return XML_GetCurrentByteIndex( m_pParser
->getEntity().pParser
);
396 virtual ::sal_Int64 SAL_CALL
getLength() throw(std::exception
) SAL_OVERRIDE
403 SaxExpatParser_Impl
*m_pParser
;
409 SaxExpatParser::SaxExpatParser( )
411 m_pImpl
= new SaxExpatParser_Impl
;
413 LocatorImpl
*pLoc
= new LocatorImpl( m_pImpl
);
414 m_pImpl
->rDocumentLocator
= css::uno::Reference
< XLocator
> ( pLoc
);
416 // Performance-improvement; handing out the same object with every call of
417 // the startElement callback is allowed (see sax-specification):
418 m_pImpl
->rAttrList
= new sax_expatwrap::AttributeList
;
420 m_pImpl
->bExceptionWasThrown
= false;
421 m_pImpl
->bRTExceptionWasThrown
= false;
424 SaxExpatParser::~SaxExpatParser()
429 // ::com::sun::star::lang::XInitialization:
431 SaxExpatParser::initialize(css::uno::Sequence
< css::uno::Any
> const& rArguments
)
432 throw (css::uno::RuntimeException
, css::uno::Exception
, std::exception
)
434 // possible arguments: a string "DoSmeplease"
435 if (rArguments
.getLength())
438 if ((rArguments
[0] >>= str
) && "DoSmeplease" == str
)
440 MutexGuard
guard( m_pImpl
->aMutex
);
441 m_pImpl
->m_bEnableDoS
= true;
448 * parseStream does Parser-startup initializations. The SaxExpatParser_Impl::parse() method does
449 * the file-specific initialization work. (During a parser run, external files may be opened)
452 void SaxExpatParser::parseStream( const InputSource
& structSource
)
455 css::uno::RuntimeException
, std::exception
)
457 // Only one text at one time
458 MutexGuard
guard( m_pImpl
->aMutex
);
461 struct Entity entity
;
462 entity
.structSource
= structSource
;
464 if( ! entity
.structSource
.aInputStream
.is() )
466 throw SAXException("No input source",
467 css::uno::Reference
< css::uno::XInterface
> () , css::uno::Any() );
470 entity
.converter
.setInputStream( entity
.structSource
.aInputStream
);
471 if( !entity
.structSource
.sEncoding
.isEmpty() )
473 entity
.converter
.setEncoding(
474 OUStringToOString( entity
.structSource
.sEncoding
, RTL_TEXTENCODING_ASCII_US
) );
477 // create parser with proper encoding
478 entity
.pParser
= XML_ParserCreate( 0 );
479 if( ! entity
.pParser
)
481 throw SAXException("Couldn't create parser",
482 css::uno::Reference
< css::uno::XInterface
> (), css::uno::Any() );
485 // set all necessary C-Callbacks
486 XML_SetUserData( entity
.pParser
, m_pImpl
);
487 XML_SetElementHandler( entity
.pParser
,
488 call_callbackStartElement
,
489 call_callbackEndElement
);
490 XML_SetCharacterDataHandler( entity
.pParser
, call_callbackCharacters
);
491 XML_SetProcessingInstructionHandler(entity
.pParser
,
492 call_callbackProcessingInstruction
);
493 if (!m_pImpl
->m_bEnableDoS
)
495 XML_SetEntityDeclHandler(entity
.pParser
, call_callbackEntityDecl
);
497 XML_SetNotationDeclHandler( entity
.pParser
, call_callbackNotationDecl
);
498 XML_SetExternalEntityRefHandler( entity
.pParser
,
499 call_callbackExternalEntityRef
);
500 XML_SetUnknownEncodingHandler( entity
.pParser
, call_callbackUnknownEncoding
,0);
502 if( m_pImpl
->rExtendedDocumentHandler
.is() ) {
504 // These handlers just delegate calls to the ExtendedHandler. If no extended handler is
505 // given, these callbacks can be ignored
506 XML_SetDefaultHandlerExpand( entity
.pParser
, call_callbackDefault
);
507 XML_SetCommentHandler( entity
.pParser
, call_callbackComment
);
508 XML_SetCdataSectionHandler( entity
.pParser
,
509 call_callbackStartCDATA
,
510 call_callbackEndCDATA
);
514 m_pImpl
->exception
= SAXParseException();
515 m_pImpl
->pushEntity( entity
);
518 // start the document
519 if( m_pImpl
->rDocumentHandler
.is() ) {
520 m_pImpl
->rDocumentHandler
->setDocumentLocator( m_pImpl
->rDocumentLocator
);
521 m_pImpl
->rDocumentHandler
->startDocument();
527 if( m_pImpl
->rDocumentHandler
.is() ) {
528 m_pImpl
->rDocumentHandler
->endDocument();
531 // catch( SAXParseException &e )
533 // m_pImpl->popEntity();
534 // XML_ParserFree( entity.pParser );
535 // css::uno::Any aAny;
537 // throw SAXException( e.Message, e.Context, aAny );
539 catch( SAXException
& )
541 m_pImpl
->popEntity();
542 XML_ParserFree( entity
.pParser
);
545 catch( IOException
& )
547 m_pImpl
->popEntity();
548 XML_ParserFree( entity
.pParser
);
551 catch( css::uno::RuntimeException
& )
553 m_pImpl
->popEntity();
554 XML_ParserFree( entity
.pParser
);
558 m_pImpl
->popEntity();
559 XML_ParserFree( entity
.pParser
);
562 void SaxExpatParser::setDocumentHandler(const css::uno::Reference
< XDocumentHandler
> & xHandler
)
563 throw (css::uno::RuntimeException
, std::exception
)
565 m_pImpl
->rDocumentHandler
= xHandler
;
566 m_pImpl
->rExtendedDocumentHandler
=
567 css::uno::Reference
< XExtendedDocumentHandler
>( xHandler
, css::uno::UNO_QUERY
);
570 void SaxExpatParser::setErrorHandler(const css::uno::Reference
< XErrorHandler
> & xHandler
)
571 throw (css::uno::RuntimeException
, std::exception
)
573 m_pImpl
->rErrorHandler
= xHandler
;
576 void SaxExpatParser::setDTDHandler(const css::uno::Reference
< XDTDHandler
> & xHandler
)
577 throw (css::uno::RuntimeException
, std::exception
)
579 m_pImpl
->rDTDHandler
= xHandler
;
582 void SaxExpatParser::setEntityResolver(const css::uno::Reference
< XEntityResolver
> & xResolver
)
583 throw (css::uno::RuntimeException
, std::exception
)
585 m_pImpl
->rEntityResolver
= xResolver
;
589 void SaxExpatParser::setLocale( const Locale
& locale
) throw (css::uno::RuntimeException
, std::exception
)
591 m_pImpl
->locale
= locale
;
595 OUString
SaxExpatParser::getImplementationName() throw (std::exception
)
597 return OUString("com.sun.star.comp.extensions.xml.sax.ParserExpat");
601 sal_Bool
SaxExpatParser::supportsService(const OUString
& ServiceName
) throw (std::exception
)
603 return cppu::supportsService(this, ServiceName
);
607 css::uno::Sequence
< OUString
> SaxExpatParser::getSupportedServiceNames() throw (std::exception
)
609 css::uno::Sequence
<OUString
> seq(1);
610 seq
[0] = "com.sun.star.xml.sax.Parser";
615 /*---------------------------------------
617 * Helper functions and classes
620 *-------------------------------------------*/
621 OUString
getErrorMessage( XML_Error xmlE
, const OUString
& sSystemId
, sal_Int32 nLine
)
624 if( XML_ERROR_NONE
== xmlE
) {
627 else if( XML_ERROR_NO_MEMORY
== xmlE
) {
628 Message
= "no memory";
630 else if( XML_ERROR_SYNTAX
== xmlE
) {
633 else if( XML_ERROR_NO_ELEMENTS
== xmlE
) {
634 Message
= "no elements";
636 else if( XML_ERROR_INVALID_TOKEN
== xmlE
) {
637 Message
= "invalid token";
639 else if( XML_ERROR_UNCLOSED_TOKEN
== xmlE
) {
640 Message
= "unclosed token";
642 else if( XML_ERROR_PARTIAL_CHAR
== xmlE
) {
643 Message
= "partial char";
645 else if( XML_ERROR_TAG_MISMATCH
== xmlE
) {
646 Message
= "tag mismatch";
648 else if( XML_ERROR_DUPLICATE_ATTRIBUTE
== xmlE
) {
649 Message
= "duplicate attribute";
651 else if( XML_ERROR_JUNK_AFTER_DOC_ELEMENT
== xmlE
) {
652 Message
= "junk after doc element";
654 else if( XML_ERROR_PARAM_ENTITY_REF
== xmlE
) {
655 Message
= "parameter entity reference";
657 else if( XML_ERROR_UNDEFINED_ENTITY
== xmlE
) {
658 Message
= "undefined entity";
660 else if( XML_ERROR_RECURSIVE_ENTITY_REF
== xmlE
) {
661 Message
= "recursive entity reference";
663 else if( XML_ERROR_ASYNC_ENTITY
== xmlE
) {
664 Message
= "async entity";
666 else if( XML_ERROR_BAD_CHAR_REF
== xmlE
) {
667 Message
= "bad char reference";
669 else if( XML_ERROR_BINARY_ENTITY_REF
== xmlE
) {
670 Message
= "binary entity reference";
672 else if( XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
== xmlE
) {
673 Message
= "attribute external entity reference";
675 else if( XML_ERROR_MISPLACED_XML_PI
== xmlE
) {
676 Message
= "misplaced xml processing instruction";
678 else if( XML_ERROR_UNKNOWN_ENCODING
== xmlE
) {
679 Message
= "unknown encoding";
681 else if( XML_ERROR_INCORRECT_ENCODING
== xmlE
) {
682 Message
= "incorrect encoding";
684 else if( XML_ERROR_UNCLOSED_CDATA_SECTION
== xmlE
) {
685 Message
= "unclosed cdata section";
687 else if( XML_ERROR_EXTERNAL_ENTITY_HANDLING
== xmlE
) {
688 Message
= "external entity reference";
690 else if( XML_ERROR_NOT_STANDALONE
== xmlE
) {
691 Message
= "not standalone";
697 str
+= OUString::number( nLine
);
706 // starts parsing with actual parser !
707 void SaxExpatParser_Impl::parse( )
709 const int nBufSize
= 16*1024;
711 int nRead
= nBufSize
;
712 css::uno::Sequence
< sal_Int8
> seqOut(nBufSize
);
715 nRead
= getEntity().converter
.readAndConvert( seqOut
, nBufSize
);
718 XML_Parse( getEntity().pParser
,
719 reinterpret_cast<const char *>(seqOut
.getConstArray()),
725 bool bContinue
= ( XML_Parse( getEntity().pParser
,
726 reinterpret_cast<const char *>(seqOut
.getConstArray()),
728 0 ) != XML_STATUS_ERROR
);
730 if( ! bContinue
|| this->bExceptionWasThrown
) {
732 if ( this->bRTExceptionWasThrown
)
735 // Error during parsing !
736 XML_Error xmlE
= XML_GetErrorCode( getEntity().pParser
);
737 OUString sSystemId
= rDocumentLocator
->getSystemId();
738 sal_Int32 nLine
= rDocumentLocator
->getLineNumber();
740 SAXParseException
aExcept(
741 getErrorMessage(xmlE
, sSystemId
, nLine
) ,
742 css::uno::Reference
< css::uno::XInterface
>(),
743 css::uno::Any( &exception
, cppu::UnoType
<decltype(exception
)>::get() ),
744 rDocumentLocator
->getPublicId(),
745 rDocumentLocator
->getSystemId(),
746 rDocumentLocator
->getLineNumber(),
747 rDocumentLocator
->getColumnNumber()
750 if( rErrorHandler
.is() ) {
752 // error handler is set, so the handler may throw the exception
755 rErrorHandler
->fatalError( a
);
758 // Error handler has not thrown an exception, but parsing cannot go on,
759 // so an exception MUST be thrown.
761 } // if( ! bContinue )
770 void SaxExpatParser_Impl::callbackStartElement( void *pvThis
,
771 const XML_Char
*pwName
,
772 const XML_Char
**awAttributes
)
774 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
776 if( pImpl
->rDocumentHandler
.is() ) {
779 pImpl
->rAttrList
->clear();
781 while( awAttributes
[i
] ) {
782 assert(awAttributes
[i
+1]);
783 pImpl
->rAttrList
->addAttribute(
784 XML_CHAR_TO_OUSTRING( awAttributes
[i
] ) ,
785 pImpl
->sCDATA
, // expat doesn't know types
786 XML_CHAR_TO_OUSTRING( awAttributes
[i
+1] ) );
790 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
792 rDocumentHandler
->startElement( XML_CHAR_TO_OUSTRING( pwName
) ,
793 pImpl
->rAttrList
.get() ) );
797 void SaxExpatParser_Impl::callbackEndElement( void *pvThis
, const XML_Char
*pwName
)
799 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
801 if( pImpl
->rDocumentHandler
.is() ) {
802 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
803 rDocumentHandler
->endElement( XML_CHAR_TO_OUSTRING( pwName
) ) );
808 void SaxExpatParser_Impl::callbackCharacters( void *pvThis
, const XML_Char
*s
, int nLen
)
810 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
812 if( pImpl
->rDocumentHandler
.is() ) {
813 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
814 rDocumentHandler
->characters( XML_CHAR_N_TO_USTRING(s
,nLen
) ) );
818 void SaxExpatParser_Impl::callbackProcessingInstruction( void *pvThis
,
819 const XML_Char
*sTarget
,
820 const XML_Char
*sData
)
822 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
823 if( pImpl
->rDocumentHandler
.is() ) {
824 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
826 rDocumentHandler
->processingInstruction( XML_CHAR_TO_OUSTRING( sTarget
),
827 XML_CHAR_TO_OUSTRING( sData
) ) );
832 void SaxExpatParser_Impl::callbackEntityDecl(
833 void *pvThis
, const XML_Char
*entityName
,
834 SAL_UNUSED_PARAMETER
int /*is_parameter_entity*/,
835 const XML_Char
*value
, SAL_UNUSED_PARAMETER
int /*value_length*/,
836 SAL_UNUSED_PARAMETER
const XML_Char
* /*base*/, const XML_Char
*systemId
,
837 const XML_Char
*publicId
, const XML_Char
*notationName
)
839 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
840 if (value
) { // value != 0 means internal entity
841 SAL_INFO("sax","SaxExpatParser: internal entity declaration, stopping");
842 XML_StopParser(pImpl
->getEntity().pParser
, XML_FALSE
);
843 pImpl
->exception
= SAXParseException(
844 "SaxExpatParser: internal entity declaration, stopping",
846 pImpl
->rDocumentLocator
->getPublicId(),
847 pImpl
->rDocumentLocator
->getSystemId(),
848 pImpl
->rDocumentLocator
->getLineNumber(),
849 pImpl
->rDocumentLocator
->getColumnNumber() );
850 pImpl
->bExceptionWasThrown
= true;
852 if( pImpl
->rDTDHandler
.is() ) {
853 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
855 rDTDHandler
->unparsedEntityDecl(
856 XML_CHAR_TO_OUSTRING( entityName
),
857 XML_CHAR_TO_OUSTRING( publicId
) ,
858 XML_CHAR_TO_OUSTRING( systemId
) ,
859 XML_CHAR_TO_OUSTRING( notationName
) ) );
864 void SaxExpatParser_Impl::callbackNotationDecl(
865 void *pvThis
, const XML_Char
*notationName
,
866 SAL_UNUSED_PARAMETER
const XML_Char
* /*base*/, const XML_Char
*systemId
,
867 const XML_Char
*publicId
)
869 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
870 if( pImpl
->rDTDHandler
.is() ) {
871 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
872 rDTDHandler
->notationDecl( XML_CHAR_TO_OUSTRING( notationName
) ,
873 XML_CHAR_TO_OUSTRING( publicId
) ,
874 XML_CHAR_TO_OUSTRING( systemId
) ) );
881 bool SaxExpatParser_Impl::callbackExternalEntityRef(
882 XML_Parser parser
, const XML_Char
*context
,
883 SAL_UNUSED_PARAMETER
const XML_Char
* /*base*/, const XML_Char
*systemId
,
884 const XML_Char
*publicId
)
888 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(XML_GetUserData( parser
));
890 struct Entity entity
;
892 if( pImpl
->rEntityResolver
.is() ) {
895 entity
.structSource
= pImpl
->rEntityResolver
->resolveEntity(
896 XML_CHAR_TO_OUSTRING( publicId
) ,
897 XML_CHAR_TO_OUSTRING( systemId
) );
899 catch( const SAXParseException
& e
)
901 pImpl
->exception
= e
;
904 catch( const SAXException
& e
)
906 pImpl
->exception
= SAXParseException(
907 e
.Message
, e
.Context
, e
.WrappedException
,
908 pImpl
->rDocumentLocator
->getPublicId(),
909 pImpl
->rDocumentLocator
->getSystemId(),
910 pImpl
->rDocumentLocator
->getLineNumber(),
911 pImpl
->rDocumentLocator
->getColumnNumber() );
916 if( entity
.structSource
.aInputStream
.is() ) {
917 entity
.pParser
= XML_ExternalEntityParserCreate( parser
, context
, 0 );
918 if( ! entity
.pParser
)
923 entity
.converter
.setInputStream( entity
.structSource
.aInputStream
);
924 pImpl
->pushEntity( entity
);
929 catch( const SAXParseException
& e
)
931 pImpl
->exception
= e
;
934 catch( const IOException
&e
)
936 pImpl
->exception
.WrappedException
<<= e
;
939 catch( const css::uno::RuntimeException
&e
)
941 pImpl
->exception
.WrappedException
<<=e
;
947 XML_ParserFree( entity
.pParser
);
953 int SaxExpatParser_Impl::callbackUnknownEncoding(
954 SAL_UNUSED_PARAMETER
void * /*encodingHandlerData*/,
955 SAL_UNUSED_PARAMETER
const XML_Char
* /*name*/,
956 SAL_UNUSED_PARAMETER XML_Encoding
* /*info*/)
961 void SaxExpatParser_Impl::callbackDefault( void *pvThis
, const XML_Char
*s
, int len
)
963 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
965 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
966 rExtendedDocumentHandler
->unknown( XML_CHAR_N_TO_USTRING( s
,len
) ) );
969 void SaxExpatParser_Impl::callbackComment( void *pvThis
, const XML_Char
*s
)
971 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
972 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
973 rExtendedDocumentHandler
->comment( XML_CHAR_TO_OUSTRING( s
) ) );
976 void SaxExpatParser_Impl::callbackStartCDATA( void *pvThis
)
978 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
980 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
, rExtendedDocumentHandler
->startCDATA() );
984 void SaxExpatParser_Impl::callErrorHandler( SaxExpatParser_Impl
*pImpl
,
985 const SAXParseException
& e
)
989 if( pImpl
->rErrorHandler
.is() ) {
992 pImpl
->rErrorHandler
->error( a
);
995 pImpl
->exception
= e
;
996 pImpl
->bExceptionWasThrown
= true;
999 catch( const SAXParseException
& ex
) {
1000 pImpl
->exception
= ex
;
1001 pImpl
->bExceptionWasThrown
= true;
1003 catch( const SAXException
& ex
) {
1004 pImpl
->exception
= SAXParseException(
1007 ex
.WrappedException
,
1008 pImpl
->rDocumentLocator
->getPublicId(),
1009 pImpl
->rDocumentLocator
->getSystemId(),
1010 pImpl
->rDocumentLocator
->getLineNumber(),
1011 pImpl
->rDocumentLocator
->getColumnNumber()
1013 pImpl
->bExceptionWasThrown
= true;
1017 void SaxExpatParser_Impl::callbackEndCDATA( void *pvThis
)
1019 SaxExpatParser_Impl
*pImpl
= static_cast<SaxExpatParser_Impl
*>(pvThis
);
1021 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pImpl
,rExtendedDocumentHandler
->endCDATA() );
1026 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
* SAL_CALL
1027 com_sun_star_comp_extensions_xml_sax_ParserExpat_get_implementation(
1028 css::uno::XComponentContext
*,
1029 css::uno::Sequence
<css::uno::Any
> const &)
1031 return cppu::acquire(new SaxExpatParser
);
1034 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */