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: sax_expat.cxx,v $
10 * $Revision: 1.18.10.1 $
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 ************************************************************************/
32 #include <sal/alloca.h>
35 #include <osl/diagnose.h>
37 #include <com/sun/star/lang/XServiceInfo.hpp>
38 #include <com/sun/star/util/XCloneable.hpp>
39 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
40 #include <com/sun/star/xml/sax/XParser.hpp>
41 #include <com/sun/star/xml/sax/SAXParseException.hpp>
42 #include <com/sun/star/io/XSeekable.hpp>
44 #include <cppuhelper/factory.hxx>
45 #include <cppuhelper/weak.hxx>
46 #include <cppuhelper/implbase1.hxx>
47 #include <cppuhelper/implbase2.hxx>
52 #include "expat/xmlparse.h"
55 using namespace ::rtl
;
56 using namespace ::std
;
57 using namespace ::osl
;
58 using namespace ::cppu
;
59 using namespace ::com::sun::star::uno
;
60 using namespace ::com::sun::star::lang
;
61 using namespace ::com::sun::star::registry
;
62 using namespace ::com::sun::star::xml::sax
;
63 using namespace ::com::sun::star::util
;
64 using namespace ::com::sun::star::io
;
66 #include "factory.hxx"
67 #include "attrlistimpl.hxx"
68 #include "xml2utf.hxx"
70 namespace sax_expatwrap
{
72 // Useful macros for correct String conversion depending on the choosen expat-mode
74 OUString
XmlNChar2OUString( const XML_Char
*p
, int nLen
)
77 if( sizeof( sal_Unicode
) == sizeof( XML_Char
) )
79 return OUString( (sal_Unicode
*)p
,nLen
);
83 sal_Unicode
*pWchar
= (sal_Unicode
*)alloca( sizeof( sal_Unicode
) * nLen
);
84 for( int n
= 0 ; n
< nLen
; n
++ ) {
85 pWchar
[n
] = (sal_Unicode
) p
[n
];
87 return OUString( pWchar
, nLen
);
95 OUString
XmlChar2OUString( const XML_Char
*p
)
99 for( nLen
= 0 ; p
[nLen
] ; nLen
++ )
101 return XmlNChar2OUString( p
, nLen
);
103 else return OUString();
107 #define XML_CHAR_TO_OUSTRING(x) XmlChar2OUString(x)
108 #define XML_CHAR_N_TO_USTRING(x,n) XmlNChar2OUString(x,n)
110 #define XML_CHAR_TO_OUSTRING(x) OUString(x , strlen( x ), RTL_TEXTENCODING_UTF8)
111 #define XML_CHAR_N_TO_USTRING(x,n) OUString(x,n, RTL_TEXTENCODING_UTF8 )
116 * The following macro encapsulates any call to an event handler.
117 * It ensures, that exceptions thrown by the event handler are
120 #define CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pThis,call) \
121 if( ! pThis->bExceptionWasThrown ) { \
125 catch( SAXParseException &e ) {\
126 pThis->callErrorHandler( pThis , e );\
128 catch( SAXException &e ) {\
129 pThis->callErrorHandler( pThis , SAXParseException(\
133 pThis->rDocumentLocator->getPublicId(),\
134 pThis->rDocumentLocator->getSystemId(),\
135 pThis->rDocumentLocator->getLineNumber(),\
136 pThis->rDocumentLocator->getColumnNumber()\
139 catch( com::sun::star::uno::RuntimeException &e ) {\
140 pThis->bExceptionWasThrown = sal_True; \
141 pThis->bRTExceptionWasThrown = sal_True; \
142 pImpl->rtexception = e; \
147 #define IMPLEMENTATION_NAME "com.sun.star.comp.extensions.xml.sax.ParserExpat"
148 #define SERVICE_NAME "com.sun.star.xml.sax.Parser"
150 class SaxExpatParser_Impl
;
153 // This class implements the external Parser interface
154 class SaxExpatParser
:
155 public WeakImplHelper2
<
167 // The implementation details
168 static Sequence
< OUString
> getSupportedServiceNames_Static(void) throw ();
171 // The SAX-Parser-Interface
172 virtual void SAL_CALL
parseStream( const InputSource
& structSource
)
173 throw ( SAXException
,
176 virtual void SAL_CALL
setDocumentHandler(const Reference
< XDocumentHandler
> & xHandler
)
177 throw (RuntimeException
);
179 virtual void SAL_CALL
setErrorHandler(const Reference
< XErrorHandler
> & xHandler
)
180 throw (RuntimeException
);
181 virtual void SAL_CALL
setDTDHandler(const Reference
< XDTDHandler
> & xHandler
)
182 throw (RuntimeException
);
183 virtual void SAL_CALL
setEntityResolver(const Reference
< XEntityResolver
>& xResolver
)
184 throw (RuntimeException
);
186 virtual void SAL_CALL
setLocale( const Locale
&locale
) throw (RuntimeException
);
188 public: // XServiceInfo
189 OUString SAL_CALL
getImplementationName() throw ();
190 Sequence
< OUString
> SAL_CALL
getSupportedServiceNames(void) throw ();
191 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) throw ();
195 SaxExpatParser_Impl
*m_pImpl
;
199 //--------------------------------------
200 // the extern interface
201 //---------------------------------------
202 Reference
< XInterface
> SAL_CALL
SaxExpatParser_CreateInstance(
203 const Reference
< XMultiServiceFactory
> & ) throw(Exception
)
205 SaxExpatParser
*p
= new SaxExpatParser
;
207 return Reference
< XInterface
> ( (OWeakObject
* ) p
);
212 Sequence
< OUString
> SaxExpatParser::getSupportedServiceNames_Static(void) throw ()
214 Sequence
<OUString
> aRet(1);
215 aRet
.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICE_NAME
) );
220 //---------------------------------------------
221 // the implementation part
222 //---------------------------------------------
225 // Entity binds all information neede for a single file
228 InputSource structSource
;
230 XMLFile2UTFConverter converter
;
234 class SaxExpatParser_Impl
236 public: // module scope
239 Reference
< XDocumentHandler
> rDocumentHandler
;
240 Reference
< XExtendedDocumentHandler
> rExtendedDocumentHandler
;
242 Reference
< XErrorHandler
> rErrorHandler
;
243 Reference
< XDTDHandler
> rDTDHandler
;
244 Reference
< XEntityResolver
> rEntityResolver
;
245 Reference
< XLocator
> rDocumentLocator
;
248 Reference
< XAttributeList
> rAttrList
;
249 AttributeList
*pAttrList
;
251 // External entity stack
252 vector
<struct Entity
> vecEntity
;
253 void pushEntity( const struct Entity
&entity
)
254 { vecEntity
.push_back( entity
); }
256 { vecEntity
.pop_back( ); }
257 struct Entity
&getEntity()
258 { return vecEntity
.back(); }
261 // Exception cannot be thrown through the C-XmlParser (possible resource leaks),
262 // therefor the exception must be saved somewhere.
263 SAXParseException exception
;
264 RuntimeException rtexception
;
265 sal_Bool bExceptionWasThrown
;
266 sal_Bool bRTExceptionWasThrown
;
271 // the C-Callbacks for the expat parser
272 void static callbackStartElement(void *userData
, const XML_Char
*name
, const XML_Char
**atts
);
273 void static callbackEndElement(void *userData
, const XML_Char
*name
);
274 void static callbackCharacters( void *userData
, const XML_Char
*s
, int nLen
);
275 void static callbackProcessingInstruction( void *userData
,
276 const XML_Char
*sTarget
,
277 const XML_Char
*sData
);
279 void static callbackUnparsedEntityDecl( void *userData
,
280 const XML_Char
*entityName
,
281 const XML_Char
*base
,
282 const XML_Char
*systemId
,
283 const XML_Char
*publicId
,
284 const XML_Char
*notationName
);
286 void static callbackNotationDecl( void *userData
,
287 const XML_Char
*notationName
,
288 const XML_Char
*base
,
289 const XML_Char
*systemId
,
290 const XML_Char
*publicId
);
292 int static callbackExternalEntityRef( XML_Parser parser
,
293 const XML_Char
*openEntityNames
,
294 const XML_Char
*base
,
295 const XML_Char
*systemId
,
296 const XML_Char
*publicId
);
298 int static callbackUnknownEncoding(void *encodingHandlerData
,
299 const XML_Char
*name
,
302 void static callbackDefault( void *userData
, const XML_Char
*s
, int len
);
304 void static callbackStartCDATA( void *userData
);
305 void static callbackEndCDATA( void *userData
);
306 void static callbackComment( void *userData
, const XML_Char
*s
);
307 void static callErrorHandler( SaxExpatParser_Impl
*pImpl
, const SAXParseException
&e
);
315 static void call_callbackStartElement(void *userData
, const XML_Char
*name
, const XML_Char
**atts
)
317 SaxExpatParser_Impl::callbackStartElement(userData
,name
,atts
);
319 static void call_callbackEndElement(void *userData
, const XML_Char
*name
)
321 SaxExpatParser_Impl::callbackEndElement(userData
,name
);
323 static void call_callbackCharacters( void *userData
, const XML_Char
*s
, int nLen
)
325 SaxExpatParser_Impl::callbackCharacters(userData
,s
,nLen
);
327 static void call_callbackProcessingInstruction(void *userData
,const XML_Char
*sTarget
,const XML_Char
*sData
)
329 SaxExpatParser_Impl::callbackProcessingInstruction(userData
,sTarget
,sData
);
331 static void call_callbackUnparsedEntityDecl(void *userData
,
332 const XML_Char
*entityName
,
333 const XML_Char
*base
,
334 const XML_Char
*systemId
,
335 const XML_Char
*publicId
,
336 const XML_Char
*notationName
)
338 SaxExpatParser_Impl::callbackUnparsedEntityDecl(userData
,entityName
,base
,systemId
,publicId
,notationName
);
340 static void call_callbackNotationDecl(void *userData
,
341 const XML_Char
*notationName
,
342 const XML_Char
*base
,
343 const XML_Char
*systemId
,
344 const XML_Char
*publicId
)
346 SaxExpatParser_Impl::callbackNotationDecl(userData
,notationName
,base
,systemId
,publicId
);
348 static int call_callbackExternalEntityRef(XML_Parser parser
,
349 const XML_Char
*openEntityNames
,
350 const XML_Char
*base
,
351 const XML_Char
*systemId
,
352 const XML_Char
*publicId
)
354 return SaxExpatParser_Impl::callbackExternalEntityRef(parser
,openEntityNames
,base
,systemId
,publicId
);
356 static int call_callbackUnknownEncoding(void *encodingHandlerData
,
357 const XML_Char
*name
,
360 return SaxExpatParser_Impl::callbackUnknownEncoding(encodingHandlerData
,name
,info
);
362 static void call_callbackDefault( void *userData
, const XML_Char
*s
, int len
)
364 SaxExpatParser_Impl::callbackDefault(userData
,s
,len
);
366 static void call_callbackStartCDATA( void *userData
)
368 SaxExpatParser_Impl::callbackStartCDATA(userData
);
370 static void call_callbackEndCDATA( void *userData
)
372 SaxExpatParser_Impl::callbackEndCDATA(userData
);
374 static void call_callbackComment( void *userData
, const XML_Char
*s
)
376 SaxExpatParser_Impl::callbackComment(userData
,s
);
381 //---------------------------------------------
383 //---------------------------------------------
385 public WeakImplHelper2
< XLocator
, com::sun::star::io::XSeekable
>
386 // should use a different interface for stream positions!
389 LocatorImpl( SaxExpatParser_Impl
*p
)
395 virtual sal_Int32 SAL_CALL
getColumnNumber(void) throw ()
397 return XML_GetCurrentColumnNumber( m_pParser
->getEntity().pParser
);
399 virtual sal_Int32 SAL_CALL
getLineNumber(void) throw ()
401 return XML_GetCurrentLineNumber( m_pParser
->getEntity().pParser
);
403 virtual OUString SAL_CALL
getPublicId(void) throw ()
405 return m_pParser
->getEntity().structSource
.sPublicId
;
407 virtual OUString SAL_CALL
getSystemId(void) throw ()
409 return m_pParser
->getEntity().structSource
.sSystemId
;
412 // XSeekable (only for getPosition)
414 virtual void SAL_CALL
seek( sal_Int64
) throw()
417 virtual sal_Int64 SAL_CALL
getPosition() throw()
419 return XML_GetCurrentByteIndex( m_pParser
->getEntity().pParser
);
421 virtual ::sal_Int64 SAL_CALL
getLength() throw()
428 SaxExpatParser_Impl
*m_pParser
;
434 SaxExpatParser::SaxExpatParser( )
436 m_pImpl
= new SaxExpatParser_Impl
;
438 LocatorImpl
*pLoc
= new LocatorImpl( m_pImpl
);
439 m_pImpl
->rDocumentLocator
= Reference
< XLocator
> ( pLoc
);
441 // performance-Improvment. Reference is needed when calling the startTag callback.
442 // Handing out the same object with every call is allowed (see sax-specification)
443 m_pImpl
->pAttrList
= new AttributeList
;
444 m_pImpl
->rAttrList
= Reference
< XAttributeList
> ( m_pImpl
->pAttrList
);
446 m_pImpl
->bExceptionWasThrown
= sal_False
;
447 m_pImpl
->bRTExceptionWasThrown
= sal_False
;
450 SaxExpatParser::~SaxExpatParser()
458 * parseStream does Parser-startup initializations. The SaxExpatParser_Impl::parse() method does
459 * the file-specific initialization work. (During a parser run, external files may be opened)
462 void SaxExpatParser::parseStream( const InputSource
& structSource
)
467 // Only one text at one time
468 MutexGuard
guard( m_pImpl
->aMutex
);
471 struct Entity entity
;
472 entity
.structSource
= structSource
;
474 if( ! entity
.structSource
.aInputStream
.is() )
476 throw SAXException( OUString::createFromAscii( "No input source" ) ,
477 Reference
< XInterface
> () , Any() );
480 entity
.converter
.setInputStream( entity
.structSource
.aInputStream
);
481 if( entity
.structSource
.sEncoding
.getLength() )
483 entity
.converter
.setEncoding(
484 OUStringToOString( entity
.structSource
.sEncoding
, RTL_TEXTENCODING_ASCII_US
) );
487 // create parser with proper encoding
488 entity
.pParser
= XML_ParserCreate( 0 );
489 if( ! entity
.pParser
)
491 throw SAXException( OUString::createFromAscii( "Couldn't create parser" ) ,
492 Reference
< XInterface
> (), Any() );
495 // set all necessary C-Callbacks
496 XML_SetUserData( entity
.pParser
, m_pImpl
);
497 XML_SetElementHandler( entity
.pParser
,
498 call_callbackStartElement
,
499 call_callbackEndElement
);
500 XML_SetCharacterDataHandler( entity
.pParser
, call_callbackCharacters
);
501 XML_SetProcessingInstructionHandler(entity
.pParser
,
502 call_callbackProcessingInstruction
);
503 XML_SetUnparsedEntityDeclHandler( entity
.pParser
,
504 call_callbackUnparsedEntityDecl
);
505 XML_SetNotationDeclHandler( entity
.pParser
, call_callbackNotationDecl
);
506 XML_SetExternalEntityRefHandler( entity
.pParser
,
507 call_callbackExternalEntityRef
);
508 XML_SetUnknownEncodingHandler( entity
.pParser
, call_callbackUnknownEncoding
,0);
510 if( m_pImpl
->rExtendedDocumentHandler
.is() ) {
512 // These handlers just delegate calls to the ExtendedHandler. If no extended handler is
513 // given, these callbacks can be ignored
514 XML_SetDefaultHandlerExpand( entity
.pParser
, call_callbackDefault
);
515 XML_SetCommentHandler( entity
.pParser
, call_callbackComment
);
516 XML_SetCdataSectionHandler( entity
.pParser
,
517 call_callbackStartCDATA
,
518 call_callbackEndCDATA
);
522 m_pImpl
->exception
= SAXParseException();
523 m_pImpl
->pushEntity( entity
);
526 // start the document
527 if( m_pImpl
->rDocumentHandler
.is() ) {
528 m_pImpl
->rDocumentHandler
->setDocumentLocator( m_pImpl
->rDocumentLocator
);
529 m_pImpl
->rDocumentHandler
->startDocument();
535 if( m_pImpl
->rDocumentHandler
.is() ) {
536 m_pImpl
->rDocumentHandler
->endDocument();
539 // catch( SAXParseException &e )
541 // m_pImpl->popEntity();
542 // XML_ParserFree( entity.pParser );
545 // throw SAXException( e.Message, e.Context, aAny );
547 catch( SAXException
& )
549 m_pImpl
->popEntity();
550 XML_ParserFree( entity
.pParser
);
553 catch( IOException
& )
555 m_pImpl
->popEntity();
556 XML_ParserFree( entity
.pParser
);
559 catch( RuntimeException
& )
561 m_pImpl
->popEntity();
562 XML_ParserFree( entity
.pParser
);
566 m_pImpl
->popEntity();
567 XML_ParserFree( entity
.pParser
);
570 void SaxExpatParser::setDocumentHandler(const Reference
< XDocumentHandler
> & xHandler
)
571 throw (RuntimeException
)
573 m_pImpl
->rDocumentHandler
= xHandler
;
574 m_pImpl
->rExtendedDocumentHandler
=
575 Reference
< XExtendedDocumentHandler
>( xHandler
, UNO_QUERY
);
578 void SaxExpatParser::setErrorHandler(const Reference
< XErrorHandler
> & xHandler
)
579 throw (RuntimeException
)
581 m_pImpl
->rErrorHandler
= xHandler
;
584 void SaxExpatParser::setDTDHandler(const Reference
< XDTDHandler
> & xHandler
)
585 throw (RuntimeException
)
587 m_pImpl
->rDTDHandler
= xHandler
;
590 void SaxExpatParser::setEntityResolver(const Reference
< XEntityResolver
> & xResolver
)
591 throw (RuntimeException
)
593 m_pImpl
->rEntityResolver
= xResolver
;
597 void SaxExpatParser::setLocale( const Locale
& locale
) throw (RuntimeException
)
599 m_pImpl
->locale
= locale
;
603 OUString
SaxExpatParser::getImplementationName() throw ()
605 return OUString::createFromAscii( IMPLEMENTATION_NAME
);
609 sal_Bool
SaxExpatParser::supportsService(const OUString
& ServiceName
) throw ()
611 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
612 const OUString
* pArray
= aSNL
.getConstArray();
614 for( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
615 if( pArray
[i
] == ServiceName
)
622 Sequence
< OUString
> SaxExpatParser::getSupportedServiceNames(void) throw ()
625 Sequence
<OUString
> seq(1);
626 seq
.getArray()[0] = OUString::createFromAscii( SERVICE_NAME
);
631 /*---------------------------------------
633 * Helper functions and classes
636 *-------------------------------------------*/
637 OUString
getErrorMessage( XML_Error xmlE
, OUString sSystemId
, sal_Int32 nLine
)
640 if( XML_ERROR_NONE
== xmlE
) {
641 Message
= OUString::createFromAscii( "No" );
643 else if( XML_ERROR_NO_MEMORY
== xmlE
) {
644 Message
= OUString::createFromAscii( "no memory" );
646 else if( XML_ERROR_SYNTAX
== xmlE
) {
647 Message
= OUString::createFromAscii( "syntax" );
649 else if( XML_ERROR_NO_ELEMENTS
== xmlE
) {
650 Message
= OUString::createFromAscii( "no elements" );
652 else if( XML_ERROR_INVALID_TOKEN
== xmlE
) {
653 Message
= OUString::createFromAscii( "invalid token" );
655 else if( XML_ERROR_UNCLOSED_TOKEN
== xmlE
) {
656 Message
= OUString::createFromAscii( "unclosed token" );
658 else if( XML_ERROR_PARTIAL_CHAR
== xmlE
) {
659 Message
= OUString::createFromAscii( "partial char" );
661 else if( XML_ERROR_TAG_MISMATCH
== xmlE
) {
662 Message
= OUString::createFromAscii( "tag mismatch" );
664 else if( XML_ERROR_DUPLICATE_ATTRIBUTE
== xmlE
) {
665 Message
= OUString::createFromAscii( "duplicate attribute" );
667 else if( XML_ERROR_JUNK_AFTER_DOC_ELEMENT
== xmlE
) {
668 Message
= OUString::createFromAscii( "junk after doc element" );
670 else if( XML_ERROR_PARAM_ENTITY_REF
== xmlE
) {
671 Message
= OUString::createFromAscii( "parameter entity reference" );
673 else if( XML_ERROR_UNDEFINED_ENTITY
== xmlE
) {
674 Message
= OUString::createFromAscii( "undefined entity" );
676 else if( XML_ERROR_RECURSIVE_ENTITY_REF
== xmlE
) {
677 Message
= OUString::createFromAscii( "recursive entity reference" );
679 else if( XML_ERROR_ASYNC_ENTITY
== xmlE
) {
680 Message
= OUString::createFromAscii( "async entity" );
682 else if( XML_ERROR_BAD_CHAR_REF
== xmlE
) {
683 Message
= OUString::createFromAscii( "bad char reference" );
685 else if( XML_ERROR_BINARY_ENTITY_REF
== xmlE
) {
686 Message
= OUString::createFromAscii( "binary entity reference" );
688 else if( XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
== xmlE
) {
689 Message
= OUString::createFromAscii( "attribute external entity reference" );
691 else if( XML_ERROR_MISPLACED_XML_PI
== xmlE
) {
692 Message
= OUString::createFromAscii( "misplaced xml processing instruction" );
694 else if( XML_ERROR_UNKNOWN_ENCODING
== xmlE
) {
695 Message
= OUString::createFromAscii( "unknown encoding" );
697 else if( XML_ERROR_INCORRECT_ENCODING
== xmlE
) {
698 Message
= OUString::createFromAscii( "incorrect encoding" );
700 else if( XML_ERROR_UNCLOSED_CDATA_SECTION
== xmlE
) {
701 Message
= OUString::createFromAscii( "unclosed cdata section" );
703 else if( XML_ERROR_EXTERNAL_ENTITY_HANDLING
== xmlE
) {
704 Message
= OUString::createFromAscii( "external entity reference" );
706 else if( XML_ERROR_NOT_STANDALONE
== xmlE
) {
707 Message
= OUString::createFromAscii( "not standalone" );
710 OUString str
= OUString::createFromAscii( "[" );
712 str
+= OUString::createFromAscii( " line " );
713 str
+= OUString::valueOf( nLine
);
714 str
+= OUString::createFromAscii( "]: " );
716 str
+= OUString::createFromAscii( "error" );
722 // starts parsing with actual parser !
723 void SaxExpatParser_Impl::parse( )
725 const int nBufSize
= 16*1024;
727 int nRead
= nBufSize
;
728 Sequence
< sal_Int8
> seqOut(nBufSize
);
731 nRead
= getEntity().converter
.readAndConvert( seqOut
, nBufSize
);
734 XML_Parse( getEntity().pParser
,
735 ( const char * ) seqOut
.getArray() ,
741 sal_Bool bContinue
= ( XML_Parse( getEntity().pParser
,
742 (const char *) seqOut
.getArray(),
746 if( ! bContinue
|| this->bExceptionWasThrown
) {
748 if ( this->bRTExceptionWasThrown
)
751 // Error during parsing !
752 XML_Error xmlE
= XML_GetErrorCode( getEntity().pParser
);
753 OUString sSystemId
= rDocumentLocator
->getSystemId();
754 sal_Int32 nLine
= rDocumentLocator
->getLineNumber();
756 SAXParseException
aExcept(
757 getErrorMessage(xmlE
, sSystemId
, nLine
) ,
758 Reference
< XInterface
>(),
759 Any( &exception
, getCppuType( &exception
) ),
760 rDocumentLocator
->getPublicId(),
761 rDocumentLocator
->getSystemId(),
762 rDocumentLocator
->getLineNumber(),
763 rDocumentLocator
->getColumnNumber()
766 if( rErrorHandler
.is() ) {
768 // error handler is set, so the handler may throw the exception
771 rErrorHandler
->fatalError( a
);
774 // Error handler has not thrown an exception, but parsing cannot go on,
775 // so an exception MUST be thrown.
777 } // if( ! bContinue )
781 //------------------------------------------
785 //-----------------------------------------
786 void SaxExpatParser_Impl::callbackStartElement( void *pvThis
,
787 const XML_Char
*pwName
,
788 const XML_Char
**awAttributes
)
790 // in case of two concurrent threads, there is only the danger of an leak,
791 // which is neglectable for one string
792 static OUString
g_CDATA( RTL_CONSTASCII_USTRINGPARAM( "CDATA" ) );
794 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
796 if( pImpl
->rDocumentHandler
.is() ) {
799 pImpl
->pAttrList
->clear();
801 while( awAttributes
[i
] ) {
802 OSL_ASSERT( awAttributes
[i
+1] );
803 pImpl
->pAttrList
->addAttribute(
804 XML_CHAR_TO_OUSTRING( awAttributes
[i
] ) ,
805 g_CDATA
, // expat doesn't know types
806 XML_CHAR_TO_OUSTRING( awAttributes
[i
+1] ) );
810 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
812 rDocumentHandler
->startElement( XML_CHAR_TO_OUSTRING( pwName
) ,
813 pImpl
->rAttrList
) );
817 void SaxExpatParser_Impl::callbackEndElement( void *pvThis
, const XML_Char
*pwName
)
819 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
821 if( pImpl
->rDocumentHandler
.is() ) {
822 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
823 rDocumentHandler
->endElement( XML_CHAR_TO_OUSTRING( pwName
) ) );
828 void SaxExpatParser_Impl::callbackCharacters( void *pvThis
, const XML_Char
*s
, int nLen
)
830 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
832 if( pImpl
->rDocumentHandler
.is() ) {
833 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
834 rDocumentHandler
->characters( XML_CHAR_N_TO_USTRING(s
,nLen
) ) );
838 void SaxExpatParser_Impl::callbackProcessingInstruction( void *pvThis
,
839 const XML_Char
*sTarget
,
840 const XML_Char
*sData
)
842 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
843 if( pImpl
->rDocumentHandler
.is() ) {
844 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
846 rDocumentHandler
->processingInstruction( XML_CHAR_TO_OUSTRING( sTarget
),
847 XML_CHAR_TO_OUSTRING( sData
) ) );
852 void SaxExpatParser_Impl::callbackUnparsedEntityDecl(void *pvThis
,
853 const XML_Char
*entityName
,
854 const XML_Char
* /*base*/,
855 const XML_Char
*systemId
,
856 const XML_Char
*publicId
,
857 const XML_Char
*notationName
)
859 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
860 if( pImpl
->rDTDHandler
.is() ) {
861 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
863 rDTDHandler
->unparsedEntityDecl(
864 XML_CHAR_TO_OUSTRING( entityName
),
865 XML_CHAR_TO_OUSTRING( publicId
) ,
866 XML_CHAR_TO_OUSTRING( systemId
) ,
867 XML_CHAR_TO_OUSTRING( notationName
) ) );
871 void SaxExpatParser_Impl::callbackNotationDecl( void *pvThis
,
872 const XML_Char
*notationName
,
873 const XML_Char
* /*base*/,
874 const XML_Char
*systemId
,
875 const XML_Char
*publicId
)
877 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
878 if( pImpl
->rDTDHandler
.is() ) {
879 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
880 rDTDHandler
->notationDecl( XML_CHAR_TO_OUSTRING( notationName
) ,
881 XML_CHAR_TO_OUSTRING( publicId
) ,
882 XML_CHAR_TO_OUSTRING( systemId
) ) );
889 int SaxExpatParser_Impl::callbackExternalEntityRef( XML_Parser parser
,
890 const XML_Char
*context
,
891 const XML_Char
* /*base*/,
892 const XML_Char
*systemId
,
893 const XML_Char
*publicId
)
895 sal_Bool bOK
= sal_True
;
897 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)XML_GetUserData( parser
));
899 struct Entity entity
;
901 if( pImpl
->rEntityResolver
.is() ) {
904 entity
.structSource
= pImpl
->rEntityResolver
->resolveEntity(
905 XML_CHAR_TO_OUSTRING( publicId
) ,
906 XML_CHAR_TO_OUSTRING( systemId
) );
908 catch( SAXParseException
& e
)
910 pImpl
->exception
= e
;
913 catch( SAXException
& e
)
915 pImpl
->exception
= SAXParseException(
916 e
.Message
, e
.Context
, e
.WrappedException
,
917 pImpl
->rDocumentLocator
->getPublicId(),
918 pImpl
->rDocumentLocator
->getSystemId(),
919 pImpl
->rDocumentLocator
->getLineNumber(),
920 pImpl
->rDocumentLocator
->getColumnNumber() );
925 if( entity
.structSource
.aInputStream
.is() ) {
926 entity
.pParser
= XML_ExternalEntityParserCreate( parser
, context
, 0 );
927 if( ! entity
.pParser
)
932 entity
.converter
.setInputStream( entity
.structSource
.aInputStream
);
933 pImpl
->pushEntity( entity
);
938 catch( SAXParseException
& e
)
940 pImpl
->exception
= e
;
943 catch( IOException
&e
)
945 pImpl
->exception
.WrappedException
<<= e
;
948 catch( RuntimeException
&e
)
950 pImpl
->exception
.WrappedException
<<=e
;
956 XML_ParserFree( entity
.pParser
);
962 int SaxExpatParser_Impl::callbackUnknownEncoding(void * /*encodingHandlerData*/,
963 const XML_Char
* /*name*/,
964 XML_Encoding
* /*info*/)
969 void SaxExpatParser_Impl::callbackDefault( void *pvThis
, const XML_Char
*s
, int len
)
971 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
973 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
974 rExtendedDocumentHandler
->unknown( XML_CHAR_N_TO_USTRING( s
,len
) ) );
977 void SaxExpatParser_Impl::callbackComment( void *pvThis
, const XML_Char
*s
)
979 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
980 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
,
981 rExtendedDocumentHandler
->comment( XML_CHAR_TO_OUSTRING( s
) ) );
984 void SaxExpatParser_Impl::callbackStartCDATA( void *pvThis
)
986 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
988 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl
, rExtendedDocumentHandler
->startCDATA() );
992 void SaxExpatParser_Impl::callErrorHandler( SaxExpatParser_Impl
*pImpl
,
993 const SAXParseException
& e
)
997 if( pImpl
->rErrorHandler
.is() ) {
1000 pImpl
->rErrorHandler
->error( a
);
1003 pImpl
->exception
= e
;
1004 pImpl
->bExceptionWasThrown
= sal_True
;
1007 catch( SAXParseException
& ex
) {
1008 pImpl
->exception
= ex
;
1009 pImpl
->bExceptionWasThrown
= sal_True
;
1011 catch( SAXException
& ex
) {
1012 pImpl
->exception
= SAXParseException(
1015 ex
.WrappedException
,
1016 pImpl
->rDocumentLocator
->getPublicId(),
1017 pImpl
->rDocumentLocator
->getSystemId(),
1018 pImpl
->rDocumentLocator
->getLineNumber(),
1019 pImpl
->rDocumentLocator
->getColumnNumber()
1021 pImpl
->bExceptionWasThrown
= sal_True
;
1025 void SaxExpatParser_Impl::callbackEndCDATA( void *pvThis
)
1027 SaxExpatParser_Impl
*pImpl
= ((SaxExpatParser_Impl
*)pvThis
);
1029 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pImpl
,rExtendedDocumentHandler
->endCDATA() );
1033 using namespace sax_expatwrap
;
1038 void SAL_CALL
component_getImplementationEnvironment(
1039 const sal_Char
** ppEnvTypeName
, uno_Environment
** /*ppEnv*/ )
1041 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
1045 sal_Bool SAL_CALL
component_writeInfo(
1046 void * /*pServiceManager*/, void * pRegistryKey
)
1052 Reference
< XRegistryKey
> xKey(
1053 reinterpret_cast< XRegistryKey
* >( pRegistryKey
) );
1055 Reference
< XRegistryKey
> xNewKey
= xKey
->createKey(
1056 OUString::createFromAscii( "/" IMPLEMENTATION_NAME
"/UNO/SERVICES" ) );
1057 xNewKey
->createKey( OUString::createFromAscii( SERVICE_NAME
) );
1059 xNewKey
= xKey
->createKey( OUString::createFromAscii("/") +
1060 SaxWriter_getImplementationName()+
1061 OUString::createFromAscii( "/UNO/SERVICES" ) );
1062 xNewKey
->createKey( SaxWriter_getServiceName() );
1066 catch (InvalidRegistryException
&)
1068 OSL_ENSURE( sal_False
, "### InvalidRegistryException!" );
1075 void * SAL_CALL
component_getFactory(
1076 const sal_Char
* pImplName
, void * pServiceManager
, void * /*pRegistryKey*/ )
1080 if (pServiceManager
)
1082 Reference
< XSingleServiceFactory
> xRet
;
1083 Reference
< XMultiServiceFactory
> xSMgr
=
1084 reinterpret_cast< XMultiServiceFactory
* > ( pServiceManager
);
1086 OUString aImplementationName
= OUString::createFromAscii( pImplName
);
1088 if (aImplementationName
==
1089 OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME
) ) )
1091 xRet
= createSingleFactory( xSMgr
, aImplementationName
,
1092 SaxExpatParser_CreateInstance
,
1093 SaxExpatParser::getSupportedServiceNames_Static() );
1095 else if ( aImplementationName
== SaxWriter_getImplementationName() )
1097 xRet
= createSingleFactory( xSMgr
, aImplementationName
,
1098 SaxWriter_CreateInstance
,
1099 SaxWriter_getSupportedServiceNames() );