Update ooo320-m1
[ooovba.git] / sax / source / expatwrap / sax_expat.cxx
blob61620e8f112245b57e773686d7637f961adec999
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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 ************************************************************************/
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sal/alloca.h>
33 #include <vector>
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>
49 #ifdef SYSTEM_EXPAT
50 #include <expat.h>
51 #else
52 #include "expat/xmlparse.h"
53 #endif
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
73 #ifdef XML_UNICODE
74 OUString XmlNChar2OUString( const XML_Char *p , int nLen )
76 if( p ) {
77 if( sizeof( sal_Unicode ) == sizeof( XML_Char ) )
79 return OUString( (sal_Unicode*)p,nLen);
81 else
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 );
90 else {
91 return OUString();
95 OUString XmlChar2OUString( const XML_Char *p )
97 if( p ) {
98 int nLen;
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)
109 #else
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 )
112 #endif
116 * The following macro encapsulates any call to an event handler.
117 * It ensures, that exceptions thrown by the event handler are
118 * treated properly.
120 #define CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pThis,call) \
121 if( ! pThis->bExceptionWasThrown ) { \
122 try {\
123 pThis->call;\
125 catch( SAXParseException &e ) {\
126 pThis->callErrorHandler( pThis , e );\
128 catch( SAXException &e ) {\
129 pThis->callErrorHandler( pThis , SAXParseException(\
130 e.Message, \
131 e.Context, \
132 e.WrappedException,\
133 pThis->rDocumentLocator->getPublicId(),\
134 pThis->rDocumentLocator->getSystemId(),\
135 pThis->rDocumentLocator->getLineNumber(),\
136 pThis->rDocumentLocator->getColumnNumber()\
137 ) );\
139 catch( com::sun::star::uno::RuntimeException &e ) {\
140 pThis->bExceptionWasThrown = sal_True; \
141 pThis->bRTExceptionWasThrown = sal_True; \
142 pImpl->rtexception = e; \
145 ((void)0)
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<
156 XParser,
157 XServiceInfo
161 public:
162 SaxExpatParser();
163 ~SaxExpatParser();
165 public:
167 // The implementation details
168 static Sequence< OUString > getSupportedServiceNames_Static(void) throw ();
170 public:
171 // The SAX-Parser-Interface
172 virtual void SAL_CALL parseStream( const InputSource& structSource)
173 throw ( SAXException,
174 IOException,
175 RuntimeException);
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 ();
193 private:
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) );
216 return aRet;
220 //---------------------------------------------
221 // the implementation part
222 //---------------------------------------------
225 // Entity binds all information neede for a single file
226 struct Entity
228 InputSource structSource;
229 XML_Parser pParser;
230 XMLFile2UTFConverter converter;
234 class SaxExpatParser_Impl
236 public: // module scope
237 Mutex aMutex;
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 ); }
255 void popEntity()
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;
268 Locale locale;
270 public:
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,
300 XML_Encoding *info);
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 );
309 public:
310 void parse();
313 extern "C"
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,
358 XML_Encoding *info)
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 //---------------------------------------------
382 // LocatorImpl
383 //---------------------------------------------
384 class LocatorImpl :
385 public WeakImplHelper2< XLocator, com::sun::star::io::XSeekable >
386 // should use a different interface for stream positions!
388 public:
389 LocatorImpl( SaxExpatParser_Impl *p )
391 m_pParser = p;
394 public: //XLocator
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()
423 return 0;
426 private:
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()
452 delete m_pImpl;
456 /***************
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)
461 ****************/
462 void SaxExpatParser::parseStream( const InputSource& structSource)
463 throw (SAXException,
464 IOException,
465 RuntimeException)
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();
532 m_pImpl->parse();
534 // finish document
535 if( m_pImpl->rDocumentHandler.is() ) {
536 m_pImpl->rDocumentHandler->endDocument();
539 // catch( SAXParseException &e )
540 // {
541 // m_pImpl->popEntity();
542 // XML_ParserFree( entity.pParser );
543 // Any aAny;
544 // aAny <<= e;
545 // throw SAXException( e.Message, e.Context, aAny );
546 // }
547 catch( SAXException & )
549 m_pImpl->popEntity();
550 XML_ParserFree( entity.pParser );
551 throw;
553 catch( IOException & )
555 m_pImpl->popEntity();
556 XML_ParserFree( entity.pParser );
557 throw;
559 catch( RuntimeException & )
561 m_pImpl->popEntity();
562 XML_ParserFree( entity.pParser );
563 throw;
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;
602 // XServiceInfo
603 OUString SaxExpatParser::getImplementationName() throw ()
605 return OUString::createFromAscii( IMPLEMENTATION_NAME );
608 // XServiceInfo
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 )
616 return sal_True;
618 return sal_False;
621 // XServiceInfo
622 Sequence< OUString > SaxExpatParser::getSupportedServiceNames(void) throw ()
625 Sequence<OUString> seq(1);
626 seq.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
627 return seq;
631 /*---------------------------------------
633 * Helper functions and classes
636 *-------------------------------------------*/
637 OUString getErrorMessage( XML_Error xmlE, OUString sSystemId , sal_Int32 nLine )
639 OUString Message;
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( "[" );
711 str += sSystemId;
712 str += OUString::createFromAscii( " line " );
713 str += OUString::valueOf( nLine );
714 str += OUString::createFromAscii( "]: " );
715 str += Message;
716 str += OUString::createFromAscii( "error" );
718 return str;
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);
730 while( nRead ) {
731 nRead = getEntity().converter.readAndConvert( seqOut , nBufSize );
733 if( ! nRead ) {
734 XML_Parse( getEntity().pParser ,
735 ( const char * ) seqOut.getArray() ,
736 0 ,
737 1 );
738 break;
741 sal_Bool bContinue = ( XML_Parse( getEntity().pParser ,
742 (const char *) seqOut.getArray(),
743 nRead,
744 0 ) != 0 );
746 if( ! bContinue || this->bExceptionWasThrown ) {
748 if ( this->bRTExceptionWasThrown )
749 throw rtexception;
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
769 Any a;
770 a <<= aExcept;
771 rErrorHandler->fatalError( a );
774 // Error handler has not thrown an exception, but parsing cannot go on,
775 // so an exception MUST be thrown.
776 throw aExcept;
777 } // if( ! bContinue )
778 } // while
781 //------------------------------------------
783 // The C-Callbacks
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() ) {
798 int i = 0;
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] ) );
807 i +=2;
810 CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
811 pImpl ,
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(
845 pImpl ,
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(
862 pImpl ,
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;
896 InputSource source;
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;
911 bOK = sal_False;
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() );
921 bOK = sal_False;
925 if( entity.structSource.aInputStream.is() ) {
926 entity.pParser = XML_ExternalEntityParserCreate( parser , context, 0 );
927 if( ! entity.pParser )
929 return sal_False;
932 entity.converter.setInputStream( entity.structSource.aInputStream );
933 pImpl->pushEntity( entity );
936 pImpl->parse();
938 catch( SAXParseException & e )
940 pImpl->exception = e;
941 bOK = sal_False;
943 catch( IOException &e )
945 pImpl->exception.WrappedException <<= e;
946 bOK = sal_False;
948 catch( RuntimeException &e )
950 pImpl->exception.WrappedException <<=e;
951 bOK = sal_False;
954 pImpl->popEntity();
956 XML_ParserFree( entity.pParser );
959 return bOK;
962 int SaxExpatParser_Impl::callbackUnknownEncoding(void * /*encodingHandlerData*/,
963 const XML_Char * /*name*/,
964 XML_Encoding * /*info*/)
966 return 0;
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() ) {
998 Any a;
999 a <<= e;
1000 pImpl->rErrorHandler->error( a );
1002 else {
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(
1013 ex.Message,
1014 ex.Context,
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;
1035 extern "C"
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 )
1048 if (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() );
1064 return sal_True;
1066 catch (InvalidRegistryException &)
1068 OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
1071 return sal_False;
1075 void * SAL_CALL component_getFactory(
1076 const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
1078 void * pRet = 0;
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() );
1102 if (xRet.is())
1104 xRet->acquire();
1105 pRet = xRet.get();
1109 return pRet;