xref: /aoo41x/main/sax/source/expatwrap/sax_expat.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sal/alloca.h>
30 #include <vector>
31 
32 #include <osl/diagnose.h>
33 
34 #include <com/sun/star/lang/XServiceInfo.hpp>
35 #include <com/sun/star/util/XCloneable.hpp>
36 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
37 #include <com/sun/star/xml/sax/XParser.hpp>
38 #include <com/sun/star/xml/sax/SAXParseException.hpp>
39 #include <com/sun/star/io/XSeekable.hpp>
40 
41 #include <cppuhelper/factory.hxx>
42 #include <cppuhelper/weak.hxx>
43 #include <cppuhelper/implbase1.hxx>
44 #include <cppuhelper/implbase2.hxx>
45 
46 #include <expat.h>
47 
48 using namespace ::rtl;
49 using namespace ::std;
50 using namespace ::osl;
51 using namespace ::cppu;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::registry;
55 using namespace ::com::sun::star::xml::sax;
56 using namespace ::com::sun::star::util;
57 using namespace ::com::sun::star::io;
58 
59 #include "factory.hxx"
60 #include "attrlistimpl.hxx"
61 #include "xml2utf.hxx"
62 
63 namespace sax_expatwrap {
64 
65 // Useful macros for correct String conversion depending on the choosen expat-mode
66 #ifdef XML_UNICODE
67 OUString XmlNChar2OUString( const XML_Char *p , int nLen )
68 {
69 	if( p ) {
70 		if( sizeof( sal_Unicode ) == sizeof( XML_Char ) )
71 		{
72 			return OUString( (sal_Unicode*)p,nLen);
73 		}
74 		else
75 		{
76 			sal_Unicode *pWchar = (sal_Unicode *)alloca( sizeof( sal_Unicode ) * nLen );
77 			for( int n = 0 ; n < nLen ; n++ ) {
78 				pWchar[n] = (sal_Unicode) p[n];
79 			}
80 			return OUString( pWchar , nLen );
81 		}
82 	}
83 	else {
84 		return OUString();
85 	}
86 }
87 
88 OUString XmlChar2OUString( const XML_Char *p )
89 {
90 	if( p ) {
91 	    int nLen;
92 	    for( nLen = 0 ; p[nLen] ; nLen ++ )
93 			;
94 	 	return XmlNChar2OUString( p , nLen );
95 	 }
96 	 else return OUString();
97 }
98 
99 
100 #define XML_CHAR_TO_OUSTRING(x) XmlChar2OUString(x)
101 #define XML_CHAR_N_TO_USTRING(x,n) XmlNChar2OUString(x,n)
102 #else
103 #define XML_CHAR_TO_OUSTRING(x) OUString(x , strlen( x ), RTL_TEXTENCODING_UTF8)
104 #define XML_CHAR_N_TO_USTRING(x,n) OUString(x,n, RTL_TEXTENCODING_UTF8 )
105 #endif
106 
107 
108 /*
109 * The following macro encapsulates any call to an event handler.
110 * It ensures, that exceptions thrown by the event handler are
111 * treated properly.
112 */
113 #define CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pThis,call) \
114 	if( ! pThis->bExceptionWasThrown ) { \
115 		try {\
116 			pThis->call;\
117 		}\
118 		catch( SAXParseException &e ) {\
119 			pThis->callErrorHandler( pThis ,  e );\
120 	 	}\
121 		catch( SAXException &e ) {\
122 			pThis->callErrorHandler( pThis , SAXParseException(\
123 											e.Message, \
124 											e.Context, \
125 											e.WrappedException,\
126 											pThis->rDocumentLocator->getPublicId(),\
127 											pThis->rDocumentLocator->getSystemId(),\
128 											pThis->rDocumentLocator->getLineNumber(),\
129 											pThis->rDocumentLocator->getColumnNumber()\
130 									 ) );\
131         }\
132         catch( com::sun::star::uno::RuntimeException &e ) {\
133             pThis->bExceptionWasThrown = sal_True; \
134             pThis->bRTExceptionWasThrown = sal_True; \
135 			pImpl->rtexception = e; \
136 		}\
137 	}\
138 	((void)0)
139 
140 #define IMPLEMENTATION_NAME	"com.sun.star.comp.extensions.xml.sax.ParserExpat"
141 #define SERVICE_NAME		"com.sun.star.xml.sax.Parser"
142 
143 class SaxExpatParser_Impl;
144 
145 
146 // This class implements the external Parser interface
147 class SaxExpatParser :
148 	public WeakImplHelper2<
149 				XParser,
150 				XServiceInfo
151                           >
152 {
153 
154 public:
155 	SaxExpatParser();
156 	~SaxExpatParser();
157 
158 public:
159 
160 	// The implementation details
161     static Sequence< OUString > 	getSupportedServiceNames_Static(void) throw ();
162 
163 public:
164 	// The SAX-Parser-Interface
165     virtual void SAL_CALL parseStream(	const InputSource& structSource)
166 		throw (	SAXException,
167 				IOException,
168 				RuntimeException);
169     virtual void SAL_CALL setDocumentHandler(const Reference< XDocumentHandler > & xHandler)
170 		throw (RuntimeException);
171 
172     virtual void SAL_CALL setErrorHandler(const Reference< XErrorHandler > & xHandler)
173 		throw (RuntimeException);
174     virtual void SAL_CALL setDTDHandler(const Reference < XDTDHandler > & xHandler)
175 		throw (RuntimeException);
176     virtual void SAL_CALL setEntityResolver(const Reference<  XEntityResolver >& xResolver)
177 		throw (RuntimeException);
178 
179 	virtual void SAL_CALL setLocale( const Locale &locale ) 					throw (RuntimeException);
180 
181 public: // XServiceInfo
182     OUString                     SAL_CALL getImplementationName() throw ();
183     Sequence< OUString >         SAL_CALL getSupportedServiceNames(void) throw ();
184     sal_Bool                     SAL_CALL supportsService(const OUString& ServiceName) throw ();
185 
186 private:
187 
188 	SaxExpatParser_Impl 		*m_pImpl;
189 
190 };
191 
192 //--------------------------------------
193 // the extern interface
194 //---------------------------------------
195 Reference< XInterface > SAL_CALL SaxExpatParser_CreateInstance(
196 	const Reference< XMultiServiceFactory  >  & ) throw(Exception)
197 {
198 	SaxExpatParser *p = new SaxExpatParser;
199 
200 	return Reference< XInterface > ( (OWeakObject * ) p );
201 }
202 
203 
204 
205 Sequence< OUString > 	SaxExpatParser::getSupportedServiceNames_Static(void) throw ()
206 {
207 	Sequence<OUString> aRet(1);
208 	aRet.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICE_NAME) );
209 	return aRet;
210 }
211 
212 
213 //---------------------------------------------
214 // the implementation part
215 //---------------------------------------------
216 
217 
218 // Entity binds all information neede for a single file
219 struct Entity
220 {
221 	InputSource			structSource;
222 	XML_Parser			pParser;
223 	XMLFile2UTFConverter converter;
224 };
225 
226 
227 class SaxExpatParser_Impl
228 {
229 public: // module scope
230 	Mutex				aMutex;
231 
232 	Reference< XDocumentHandler >	rDocumentHandler;
233 	Reference< XExtendedDocumentHandler > rExtendedDocumentHandler;
234 
235 	Reference< XErrorHandler > 	rErrorHandler;
236 	Reference< XDTDHandler > 	rDTDHandler;
237 	Reference< XEntityResolver > rEntityResolver;
238 	Reference < XLocator >		rDocumentLocator;
239 
240 
241 	Reference < XAttributeList >	rAttrList;
242 	AttributeList	*pAttrList;
243 
244 	// External entity stack
245 	vector<struct Entity> 	vecEntity;
246 	void pushEntity( const struct Entity &entity )
247 		{ vecEntity.push_back( entity ); }
248 	void popEntity()
249 		{ vecEntity.pop_back( ); }
250 	struct Entity &getEntity()
251 		{ return vecEntity.back(); }
252 
253 
254 	// Exception cannot be thrown through the C-XmlParser (possible resource leaks),
255 	// therefor the exception must be saved somewhere.
256 	SAXParseException 	exception;
257     RuntimeException    rtexception;
258 	sal_Bool 			bExceptionWasThrown;
259     sal_Bool            bRTExceptionWasThrown;
260 
261 	Locale				locale;
262 
263 public:
264 	// the C-Callbacks for the expat parser
265 	void static callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts);
266 	void static callbackEndElement(void *userData, const XML_Char *name);
267 	void static callbackCharacters( void *userData , const XML_Char *s , int nLen );
268 	void static callbackProcessingInstruction( 	void *userData ,
269 												const XML_Char *sTarget ,
270 												const XML_Char *sData );
271 
272 	void static callbackUnparsedEntityDecl(	void *userData ,
273 						  					const XML_Char *entityName,
274 					      					const XML_Char *base,
275 					      					const XML_Char *systemId,
276 					      					const XML_Char *publicId,
277 					      					const XML_Char *notationName);
278 
279 	void static callbackNotationDecl(	void *userData,
280 										const XML_Char *notationName,
281 										const XML_Char *base,
282 										const XML_Char *systemId,
283 										const XML_Char *publicId);
284 
285 	int static callbackExternalEntityRef(	XML_Parser parser,
286 					    					const XML_Char *openEntityNames,
287 					    					const XML_Char *base,
288 					    					const XML_Char *systemId,
289 					    					const XML_Char *publicId);
290 
291 	int static callbackUnknownEncoding(void *encodingHandlerData,
292 					  							const XML_Char *name,
293 					  							XML_Encoding *info);
294 
295 	void static callbackDefault( void *userData,  const XML_Char *s,  int len);
296 
297 	void static callbackStartCDATA( void *userData );
298 	void static callbackEndCDATA( void *userData );
299 	void static callbackComment( void *userData , const XML_Char *s );
300 	void static callErrorHandler( SaxExpatParser_Impl *pImpl , const SAXParseException &e );
301 
302 public:
303 	void parse();
304 };
305 
306 extern "C"
307 {
308     static void call_callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts)
309     {
310         SaxExpatParser_Impl::callbackStartElement(userData,name,atts);
311     }
312 	static void call_callbackEndElement(void *userData, const XML_Char *name)
313     {
314         SaxExpatParser_Impl::callbackEndElement(userData,name);
315     }
316 	static void call_callbackCharacters( void *userData , const XML_Char *s , int nLen )
317     {
318         SaxExpatParser_Impl::callbackCharacters(userData,s,nLen);
319     }
320 	static void call_callbackProcessingInstruction(void *userData,const XML_Char *sTarget,const XML_Char *sData )
321     {
322         SaxExpatParser_Impl::callbackProcessingInstruction(userData,sTarget,sData );
323     }
324 	static void call_callbackUnparsedEntityDecl(void *userData ,
325 						  					    const XML_Char *entityName,
326                                                 const XML_Char *base,
327                                                 const XML_Char *systemId,
328                                                 const XML_Char *publicId,
329                                                 const XML_Char *notationName)
330     {
331         SaxExpatParser_Impl::callbackUnparsedEntityDecl(userData,entityName,base,systemId,publicId,notationName);
332     }
333 	static void call_callbackNotationDecl(void *userData,
334                                           const XML_Char *notationName,
335                                           const XML_Char *base,
336                                           const XML_Char *systemId,
337                                           const XML_Char *publicId)
338     {
339         SaxExpatParser_Impl::callbackNotationDecl(userData,notationName,base,systemId,publicId);
340     }
341 	static int call_callbackExternalEntityRef(XML_Parser parser,
342 					    					  const XML_Char *openEntityNames,
343                                               const XML_Char *base,
344                                               const XML_Char *systemId,
345                                               const XML_Char *publicId)
346     {
347         return SaxExpatParser_Impl::callbackExternalEntityRef(parser,openEntityNames,base,systemId,publicId);
348     }
349 	static int call_callbackUnknownEncoding(void *encodingHandlerData,
350 					  						const XML_Char *name,
351                                             XML_Encoding *info)
352     {
353         return SaxExpatParser_Impl::callbackUnknownEncoding(encodingHandlerData,name,info);
354     }
355 	static void call_callbackDefault( void *userData,  const XML_Char *s,  int len)
356     {
357         SaxExpatParser_Impl::callbackDefault(userData,s,len);
358     }
359 	static void call_callbackStartCDATA( void *userData )
360     {
361         SaxExpatParser_Impl::callbackStartCDATA(userData);
362     }
363 	static void call_callbackEndCDATA( void *userData )
364     {
365         SaxExpatParser_Impl::callbackEndCDATA(userData);
366     }
367 	static void call_callbackComment( void *userData , const XML_Char *s )
368     {
369         SaxExpatParser_Impl::callbackComment(userData,s);
370     }
371 }
372 
373 
374 //---------------------------------------------
375 // LocatorImpl
376 //---------------------------------------------
377 class LocatorImpl :
378     public WeakImplHelper2< XLocator, com::sun::star::io::XSeekable >
379     // should use a different interface for stream positions!
380 {
381 public:
382 	LocatorImpl( SaxExpatParser_Impl *p )
383 	{
384 		m_pParser 	 = p;
385 	}
386 
387 public: //XLocator
388     virtual sal_Int32 SAL_CALL getColumnNumber(void) throw ()
389     {
390     	return XML_GetCurrentColumnNumber( m_pParser->getEntity().pParser );
391     }
392     virtual sal_Int32 SAL_CALL getLineNumber(void) throw ()
393     {
394     	return XML_GetCurrentLineNumber( m_pParser->getEntity().pParser );
395     }
396     virtual OUString SAL_CALL getPublicId(void) throw ()
397     {
398     	return m_pParser->getEntity().structSource.sPublicId;
399     }
400     virtual OUString SAL_CALL getSystemId(void) throw ()
401     {
402     	return m_pParser->getEntity().structSource.sSystemId;
403     }
404 
405     // XSeekable (only for getPosition)
406 
407     virtual void SAL_CALL seek( sal_Int64 ) throw()
408     {
409     }
410     virtual sal_Int64 SAL_CALL getPosition() throw()
411     {
412         return XML_GetCurrentByteIndex( m_pParser->getEntity().pParser );
413     }
414     virtual ::sal_Int64 SAL_CALL getLength() throw()
415     {
416         return 0;
417     }
418 
419 private:
420 
421 	SaxExpatParser_Impl *m_pParser;
422 };
423 
424 
425 
426 
427 SaxExpatParser::SaxExpatParser(  )
428 {
429 	m_pImpl = new SaxExpatParser_Impl;
430 
431 	LocatorImpl *pLoc = new LocatorImpl( m_pImpl );
432 	m_pImpl->rDocumentLocator = Reference< XLocator > ( pLoc );
433 
434 	// performance-Improvment. Reference is needed when calling the startTag callback.
435 	// Handing out the same object with every call is allowed (see sax-specification)
436 	m_pImpl->pAttrList = new AttributeList;
437 	m_pImpl->rAttrList = Reference< XAttributeList > ( m_pImpl->pAttrList );
438 
439 	m_pImpl->bExceptionWasThrown = sal_False;
440 	m_pImpl->bRTExceptionWasThrown = sal_False;
441 }
442 
443 SaxExpatParser::~SaxExpatParser()
444 {
445 	delete m_pImpl;
446 }
447 
448 
449 /***************
450 *
451 * parseStream does Parser-startup initializations. The SaxExpatParser_Impl::parse() method does
452 * the file-specific initialization work. (During a parser run, external files may be opened)
453 *
454 ****************/
455 void SaxExpatParser::parseStream(	const InputSource& structSource)
456 	throw (SAXException,
457 		   IOException,
458 		   RuntimeException)
459 {
460 	// Only one text at one time
461 	MutexGuard guard( m_pImpl->aMutex );
462 
463 
464 	struct Entity entity;
465 	entity.structSource = structSource;
466 
467 	if( ! entity.structSource.aInputStream.is() )
468 	{
469 		throw SAXException( OUString::createFromAscii( "No input source" ) ,
470 							Reference< XInterface > () , Any() );
471 	}
472 
473 	entity.converter.setInputStream( entity.structSource.aInputStream );
474 	if( entity.structSource.sEncoding.getLength() )
475 	{
476 		entity.converter.setEncoding(
477 			OUStringToOString( entity.structSource.sEncoding , RTL_TEXTENCODING_ASCII_US ) );
478 	}
479 
480 	// create parser with proper encoding
481 	entity.pParser = XML_ParserCreate( 0 );
482 	if( ! entity.pParser )
483 	{
484 		throw SAXException( OUString::createFromAscii( "Couldn't create parser" ) ,
485 							Reference< XInterface > (), Any() );
486 	}
487 
488 	// set all necessary C-Callbacks
489 	XML_SetUserData( entity.pParser , m_pImpl );
490 	XML_SetElementHandler( 	entity.pParser ,
491 							call_callbackStartElement ,
492 							call_callbackEndElement );
493 	XML_SetCharacterDataHandler( entity.pParser , call_callbackCharacters );
494 	XML_SetProcessingInstructionHandler(entity.pParser ,
495 										call_callbackProcessingInstruction );
496 	XML_SetUnparsedEntityDeclHandler( 	entity.pParser,
497 										call_callbackUnparsedEntityDecl );
498 	XML_SetNotationDeclHandler( entity.pParser, call_callbackNotationDecl );
499 	XML_SetExternalEntityRefHandler( 	entity.pParser,
500 										call_callbackExternalEntityRef);
501 	XML_SetUnknownEncodingHandler( entity.pParser, 	call_callbackUnknownEncoding ,0);
502 
503 	if( m_pImpl->rExtendedDocumentHandler.is() ) {
504 
505 		// These handlers just delegate calls to the ExtendedHandler. If no extended handler is
506 		// given, these callbacks can be ignored
507 		XML_SetDefaultHandlerExpand( entity.pParser, call_callbackDefault );
508 		XML_SetCommentHandler( entity.pParser, call_callbackComment );
509 		XML_SetCdataSectionHandler( 	entity.pParser ,
510 										call_callbackStartCDATA ,
511 									 	call_callbackEndCDATA );
512 	}
513 
514 
515 	m_pImpl->exception = SAXParseException();
516 	m_pImpl->pushEntity( entity );
517 	try
518 	{
519 		// start the document
520 		if( m_pImpl->rDocumentHandler.is() ) {
521 			m_pImpl->rDocumentHandler->setDocumentLocator( m_pImpl->rDocumentLocator );
522 			m_pImpl->rDocumentHandler->startDocument();
523 		}
524 
525 		m_pImpl->parse();
526 
527 		// finish document
528 		if( m_pImpl->rDocumentHandler.is() ) {
529 			m_pImpl->rDocumentHandler->endDocument();
530 		}
531 	}
532 //  	catch( SAXParseException &e )
533 // 	{
534 // 		m_pImpl->popEntity();
535 //  		XML_ParserFree( entity.pParser );
536 //        Any aAny;
537 //        aAny <<= e;
538 //  		throw SAXException( e.Message, e.Context, aAny );
539 //  	}
540 	catch( SAXException & )
541 	{
542 		m_pImpl->popEntity();
543 		XML_ParserFree( entity.pParser );
544   		throw;
545 	}
546 	catch( IOException & )
547 	{
548 		m_pImpl->popEntity();
549 		XML_ParserFree( entity.pParser );
550 		throw;
551 	}
552 	catch( RuntimeException & )
553 	{
554 		m_pImpl->popEntity();
555 		XML_ParserFree( entity.pParser );
556 		throw;
557 	}
558 
559 	m_pImpl->popEntity();
560 	XML_ParserFree( entity.pParser );
561 }
562 
563 void SaxExpatParser::setDocumentHandler(const Reference< XDocumentHandler > & xHandler)
564 	throw (RuntimeException)
565 {
566 	m_pImpl->rDocumentHandler = xHandler;
567 	m_pImpl->rExtendedDocumentHandler =
568 		Reference< XExtendedDocumentHandler >( xHandler , UNO_QUERY );
569 }
570 
571 void SaxExpatParser::setErrorHandler(const Reference< XErrorHandler > & xHandler)
572 	throw (RuntimeException)
573 {
574 	m_pImpl->rErrorHandler = xHandler;
575 }
576 
577 void SaxExpatParser::setDTDHandler(const Reference< XDTDHandler > & xHandler)
578 	throw (RuntimeException)
579 {
580 	m_pImpl->rDTDHandler = xHandler;
581 }
582 
583 void SaxExpatParser::setEntityResolver(const Reference < XEntityResolver > & xResolver)
584 	throw (RuntimeException)
585 {
586 	m_pImpl->rEntityResolver = xResolver;
587 }
588 
589 
590 void SaxExpatParser::setLocale( const Locale & locale )	throw (RuntimeException)
591 {
592 	m_pImpl->locale = locale;
593 }
594 
595 // XServiceInfo
596 OUString SaxExpatParser::getImplementationName() throw ()
597 {
598     return OUString::createFromAscii( IMPLEMENTATION_NAME );
599 }
600 
601 // XServiceInfo
602 sal_Bool SaxExpatParser::supportsService(const OUString& ServiceName) throw ()
603 {
604     Sequence< OUString > aSNL = getSupportedServiceNames();
605     const OUString * pArray = aSNL.getConstArray();
606 
607     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
608         if( pArray[i] == ServiceName )
609             return sal_True;
610 
611     return sal_False;
612 }
613 
614 // XServiceInfo
615 Sequence< OUString > SaxExpatParser::getSupportedServiceNames(void) throw ()
616 {
617 
618     Sequence<OUString> seq(1);
619     seq.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
620     return seq;
621 }
622 
623 
624 /*---------------------------------------
625 *
626 * Helper functions and classes
627 *
628 *
629 *-------------------------------------------*/
630 OUString getErrorMessage( XML_Error xmlE, OUString sSystemId , sal_Int32 nLine )
631 {
632 	OUString Message;
633 	if( XML_ERROR_NONE == xmlE ) {
634 		Message = OUString::createFromAscii( "No" );
635 	}
636 	else if( XML_ERROR_NO_MEMORY == xmlE ) {
637 		Message = OUString::createFromAscii( "no memory" );
638 	}
639 	else if( XML_ERROR_SYNTAX == xmlE ) {
640 		Message = OUString::createFromAscii( "syntax" );
641 	}
642 	else if( XML_ERROR_NO_ELEMENTS == xmlE ) {
643 		Message = OUString::createFromAscii( "no elements" );
644 	}
645 	else if( XML_ERROR_INVALID_TOKEN == xmlE ) {
646 		Message = OUString::createFromAscii( "invalid token" );
647 	}
648 	else if( XML_ERROR_UNCLOSED_TOKEN == xmlE ) {
649 		Message = OUString::createFromAscii( "unclosed token" );
650 	}
651 	else if( XML_ERROR_PARTIAL_CHAR == xmlE ) {
652 		Message = OUString::createFromAscii( "partial char" );
653 	}
654 	else if( XML_ERROR_TAG_MISMATCH == xmlE ) {
655 		Message = OUString::createFromAscii( "tag mismatch" );
656 	}
657 	else if( XML_ERROR_DUPLICATE_ATTRIBUTE == xmlE ) {
658 		Message = OUString::createFromAscii( "duplicate attribute" );
659 	}
660 	else if( XML_ERROR_JUNK_AFTER_DOC_ELEMENT == xmlE ) {
661 		Message = OUString::createFromAscii( "junk after doc element" );
662 	}
663 	else if( XML_ERROR_PARAM_ENTITY_REF == xmlE ) {
664 		Message = OUString::createFromAscii( "parameter entity reference" );
665 	}
666 	else if( XML_ERROR_UNDEFINED_ENTITY == xmlE ) {
667 		Message = OUString::createFromAscii( "undefined entity" );
668 	}
669 	else if( XML_ERROR_RECURSIVE_ENTITY_REF == xmlE ) {
670 		Message = OUString::createFromAscii( "recursive entity reference" );
671 	}
672 	else if( XML_ERROR_ASYNC_ENTITY == xmlE ) {
673 		Message = OUString::createFromAscii( "async entity" );
674 	}
675 	else if( XML_ERROR_BAD_CHAR_REF == xmlE ) {
676 		Message = OUString::createFromAscii( "bad char reference" );
677 	}
678 	else if( XML_ERROR_BINARY_ENTITY_REF == xmlE ) {
679 		Message = OUString::createFromAscii( "binary entity reference" );
680 	}
681 	else if( XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF == xmlE ) {
682 		Message = OUString::createFromAscii( "attribute external entity reference" );
683 	}
684 	else if( XML_ERROR_MISPLACED_XML_PI == xmlE ) {
685 		Message = OUString::createFromAscii( "misplaced xml processing instruction" );
686 	}
687 	else if( XML_ERROR_UNKNOWN_ENCODING == xmlE ) {
688 		Message = OUString::createFromAscii( "unknown encoding" );
689 	}
690 	else if( XML_ERROR_INCORRECT_ENCODING == xmlE ) {
691 		Message = OUString::createFromAscii( "incorrect encoding" );
692 	}
693 	else if( XML_ERROR_UNCLOSED_CDATA_SECTION == xmlE ) {
694 		Message = OUString::createFromAscii( "unclosed cdata section" );
695 	}
696 	else if( XML_ERROR_EXTERNAL_ENTITY_HANDLING == xmlE ) {
697 		Message = OUString::createFromAscii( "external entity reference" );
698 	}
699 	else if( XML_ERROR_NOT_STANDALONE == xmlE ) {
700 		Message = OUString::createFromAscii( "not standalone" );
701 	}
702 
703 	OUString str = OUString::createFromAscii( "[" );
704 	str += sSystemId;
705 	str += OUString::createFromAscii( " line " );
706 	str += OUString::valueOf( nLine );
707 	str += OUString::createFromAscii( "]: " );
708 	str += Message;
709 	str += OUString::createFromAscii( "error" );
710 
711 	return str;
712 }
713 
714 
715 // starts parsing with actual parser !
716 void SaxExpatParser_Impl::parse( )
717 {
718 	const int nBufSize = 16*1024;
719 
720 	int nRead   = nBufSize;
721 	Sequence< sal_Int8 > seqOut(nBufSize);
722 
723 	while( nRead ) {
724 		nRead = getEntity().converter.readAndConvert( seqOut , nBufSize );
725 
726 		if( ! nRead ) {
727 			XML_Parse( getEntity().pParser ,
728                                    ( const char * ) seqOut.getArray() ,
729                                    0 ,
730                                    1 );
731 			break;
732 		}
733 
734 		sal_Bool bContinue = ( XML_Parse( getEntity().pParser ,
735                                                 (const char *) seqOut.getArray(),
736                                                 nRead,
737                                                 0 ) != 0 );
738 
739 		if( ! bContinue || this->bExceptionWasThrown ) {
740 
741             if ( this->bRTExceptionWasThrown )
742                 throw rtexception;
743 
744 			// Error during parsing !
745 			XML_Error xmlE = XML_GetErrorCode( getEntity().pParser );
746 			OUString sSystemId = rDocumentLocator->getSystemId();
747 			sal_Int32 nLine = rDocumentLocator->getLineNumber();
748 
749 			SAXParseException aExcept(
750 				getErrorMessage(xmlE , sSystemId, nLine) ,
751 				Reference< XInterface >(),
752 				Any( &exception , getCppuType( &exception) ),
753 				rDocumentLocator->getPublicId(),
754 				rDocumentLocator->getSystemId(),
755 				rDocumentLocator->getLineNumber(),
756 				rDocumentLocator->getColumnNumber()
757 				);
758 
759 			if( rErrorHandler.is() ) {
760 
761 				// error handler is set, so the handler may throw the exception
762 				Any a;
763 				a <<= aExcept;
764 				rErrorHandler->fatalError( a );
765 			}
766 
767 			// Error handler has not thrown an exception, but parsing cannot go on,
768 			// so an exception MUST be thrown.
769 			throw aExcept;
770 		} // if( ! bContinue )
771 	} // while
772 }
773 
774 //------------------------------------------
775 //
776 // The C-Callbacks
777 //
778 //-----------------------------------------
779 void SaxExpatParser_Impl::callbackStartElement( void *pvThis ,
780 												const XML_Char *pwName ,
781 												const XML_Char **awAttributes )
782 {
783     // in case of two concurrent threads, there is only the danger of an leak,
784     // which is neglectable for one string
785     static OUString g_CDATA( RTL_CONSTASCII_USTRINGPARAM( "CDATA" ) );
786 
787 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
788 
789 	if( pImpl->rDocumentHandler.is() ) {
790 
791 		int i = 0;
792 		pImpl->pAttrList->clear();
793 
794 		while( awAttributes[i] ) {
795 			OSL_ASSERT( awAttributes[i+1] );
796 			pImpl->pAttrList->addAttribute(
797 				XML_CHAR_TO_OUSTRING( awAttributes[i] ) ,
798 				g_CDATA ,  // expat doesn't know types
799 				XML_CHAR_TO_OUSTRING( awAttributes[i+1] ) );
800 			i +=2;
801 		}
802 
803 		CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
804 			pImpl ,
805 			rDocumentHandler->startElement( XML_CHAR_TO_OUSTRING( pwName ) ,
806 											pImpl->rAttrList ) );
807 	}
808 }
809 
810 void SaxExpatParser_Impl::callbackEndElement( void *pvThis , const XML_Char *pwName  )
811 {
812 	SaxExpatParser_Impl  *pImpl = ((SaxExpatParser_Impl*)pvThis);
813 
814 	if( pImpl->rDocumentHandler.is() ) {
815 		CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl,
816 				rDocumentHandler->endElement( XML_CHAR_TO_OUSTRING( pwName ) ) );
817 	}
818 }
819 
820 
821 void SaxExpatParser_Impl::callbackCharacters( void *pvThis , const XML_Char *s , int nLen )
822 {
823 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
824 
825 	if( pImpl->rDocumentHandler.is() ) {
826 		CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl ,
827 				rDocumentHandler->characters( XML_CHAR_N_TO_USTRING(s,nLen) ) );
828 	}
829 }
830 
831 void SaxExpatParser_Impl::callbackProcessingInstruction(	void *pvThis,
832 													const XML_Char *sTarget ,
833 													const XML_Char *sData )
834 {
835 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
836 	if( pImpl->rDocumentHandler.is() ) {
837 		CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
838                     pImpl ,
839                     rDocumentHandler->processingInstruction( XML_CHAR_TO_OUSTRING( sTarget ),
840                     XML_CHAR_TO_OUSTRING( sData ) ) );
841 	}
842 }
843 
844 
845 void SaxExpatParser_Impl::callbackUnparsedEntityDecl(void *pvThis ,
846                                                      const XML_Char *entityName,
847                                                      const XML_Char * /*base*/,
848                                                      const XML_Char *systemId,
849                                                      const XML_Char *publicId,
850                                                      const XML_Char *notationName)
851 {
852 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
853 	if( pImpl->rDTDHandler.is() ) {
854 		CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(
855 			pImpl ,
856 			rDTDHandler->unparsedEntityDecl(
857 				XML_CHAR_TO_OUSTRING( entityName ),
858 				XML_CHAR_TO_OUSTRING( publicId ) ,
859 				XML_CHAR_TO_OUSTRING( systemId ) ,
860 				XML_CHAR_TO_OUSTRING( notationName ) ) );
861 	}
862 }
863 
864 void SaxExpatParser_Impl::callbackNotationDecl(	void *pvThis,
865                                                 const XML_Char *notationName,
866                                                 const XML_Char * /*base*/,
867                                                 const XML_Char *systemId,
868                                                 const XML_Char *publicId)
869 {
870 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
871 	if( pImpl->rDTDHandler.is() ) {
872 		CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl,
873 			    rDTDHandler->notationDecl( 	XML_CHAR_TO_OUSTRING( notationName ) ,
874 											XML_CHAR_TO_OUSTRING( publicId ) ,
875 											XML_CHAR_TO_OUSTRING( systemId ) ) );
876 	}
877 
878 }
879 
880 
881 
882 int SaxExpatParser_Impl::callbackExternalEntityRef( XML_Parser parser,
883                                                     const XML_Char *context,
884                                                     const XML_Char * /*base*/,
885                                                     const XML_Char *systemId,
886                                                     const XML_Char *publicId)
887 {
888 	sal_Bool bOK = sal_True;
889 	InputSource source;
890 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)XML_GetUserData( parser ));
891 
892 	struct Entity entity;
893 
894 	if( pImpl->rEntityResolver.is() ) {
895 		try
896 		{
897 	    	entity.structSource = pImpl->rEntityResolver->resolveEntity(
898 				XML_CHAR_TO_OUSTRING( publicId ) ,
899 				XML_CHAR_TO_OUSTRING( systemId ) );
900 	    }
901 	    catch( SAXParseException & e )
902 		{
903 	    	pImpl->exception = e;
904 	    	bOK = sal_False;
905 	    }
906 	    catch( SAXException & e )
907 		{
908 	    	pImpl->exception = SAXParseException(
909 				e.Message , e.Context , e.WrappedException ,
910 				pImpl->rDocumentLocator->getPublicId(),
911 				pImpl->rDocumentLocator->getSystemId(),
912 				pImpl->rDocumentLocator->getLineNumber(),
913 				pImpl->rDocumentLocator->getColumnNumber() );
914 			bOK = sal_False;
915 	    }
916 	}
917 
918 	if( entity.structSource.aInputStream.is() ) {
919 		entity.pParser = XML_ExternalEntityParserCreate( parser , context, 0 );
920 		if( ! entity.pParser )
921 		{
922 			return sal_False;
923 		}
924 
925 		entity.converter.setInputStream( entity.structSource.aInputStream );
926 		pImpl->pushEntity( entity );
927 		try
928 		{
929 			pImpl->parse();
930 		}
931 		catch( SAXParseException & e )
932 		{
933 			pImpl->exception = e;
934 			bOK = sal_False;
935 		}
936 		catch( IOException &e )
937 		{
938 			pImpl->exception.WrappedException <<= e;
939 			bOK = sal_False;
940 		}
941 		catch( RuntimeException &e )
942 		{
943 			pImpl->exception.WrappedException <<=e;
944 			bOK = sal_False;
945 		}
946 
947 		pImpl->popEntity();
948 
949 		XML_ParserFree( entity.pParser );
950 	}
951 
952 	return bOK;
953 }
954 
955 int SaxExpatParser_Impl::callbackUnknownEncoding(void * /*encodingHandlerData*/,
956                                                  const XML_Char * /*name*/,
957                                                  XML_Encoding * /*info*/)
958 {
959 	return 0;
960 }
961 
962 void SaxExpatParser_Impl::callbackDefault( void *pvThis,  const XML_Char *s,  int len)
963 {
964 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
965 
966 	CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(  pImpl,
967 				rExtendedDocumentHandler->unknown( XML_CHAR_N_TO_USTRING( s ,len) ) );
968 }
969 
970 void SaxExpatParser_Impl::callbackComment( void *pvThis , const XML_Char *s )
971 {
972 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
973 	CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl,
974 				rExtendedDocumentHandler->comment( XML_CHAR_TO_OUSTRING( s ) ) );
975 }
976 
977 void SaxExpatParser_Impl::callbackStartCDATA( void *pvThis )
978 {
979 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
980 
981 	CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS( pImpl, rExtendedDocumentHandler->startCDATA() );
982 }
983 
984 
985 void SaxExpatParser_Impl::callErrorHandler( SaxExpatParser_Impl *pImpl ,
986 											const SAXParseException & e )
987 {
988 	try
989 	{
990 		if( pImpl->rErrorHandler.is() ) {
991 			Any a;
992 			a <<= e;
993 			pImpl->rErrorHandler->error( a );
994 		}
995 		else {
996 			pImpl->exception = e;
997 			pImpl->bExceptionWasThrown = sal_True;
998 		}
999 	}
1000 	catch( SAXParseException & ex ) {
1001 		pImpl->exception = ex;
1002 		pImpl->bExceptionWasThrown = sal_True;
1003 	}
1004 	catch( SAXException & ex ) {
1005 		pImpl->exception = SAXParseException(
1006 									ex.Message,
1007 									ex.Context,
1008 									ex.WrappedException,
1009 									pImpl->rDocumentLocator->getPublicId(),
1010 									pImpl->rDocumentLocator->getSystemId(),
1011 									pImpl->rDocumentLocator->getLineNumber(),
1012 									pImpl->rDocumentLocator->getColumnNumber()
1013 							 );
1014 		pImpl->bExceptionWasThrown = sal_True;
1015 	}
1016 }
1017 
1018 void SaxExpatParser_Impl::callbackEndCDATA( void *pvThis )
1019 {
1020 	SaxExpatParser_Impl *pImpl = ((SaxExpatParser_Impl*)pvThis);
1021 
1022 	CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pImpl,rExtendedDocumentHandler->endCDATA() );
1023 }
1024 
1025 }
1026 using namespace sax_expatwrap;
1027 
1028 extern "C"
1029 {
1030 
1031 void SAL_CALL component_getImplementationEnvironment(
1032 	const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
1033 {
1034 	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
1035 }
1036 
1037 void * SAL_CALL component_getFactory(
1038 	const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
1039 {
1040 	void * pRet = 0;
1041 
1042 	if (pServiceManager )
1043 	{
1044 		Reference< XSingleServiceFactory > xRet;
1045 		Reference< XMultiServiceFactory > xSMgr =
1046 			reinterpret_cast< XMultiServiceFactory * > ( pServiceManager );
1047 
1048 		OUString aImplementationName = OUString::createFromAscii( pImplName );
1049 
1050 		if (aImplementationName ==
1051 			OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME  ) ) )
1052 		{
1053 			xRet = createSingleFactory( xSMgr, aImplementationName,
1054 										SaxExpatParser_CreateInstance,
1055 										SaxExpatParser::getSupportedServiceNames_Static() );
1056 		}
1057 		else if ( aImplementationName == SaxWriter_getImplementationName() )
1058 		{
1059 			xRet = createSingleFactory( xSMgr, aImplementationName,
1060 										SaxWriter_CreateInstance,
1061 										SaxWriter_getSupportedServiceNames() );
1062 		}
1063 
1064 		if (xRet.is())
1065 		{
1066 			xRet->acquire();
1067 			pRet = xRet.get();
1068 		}
1069 	}
1070 
1071 	return pRet;
1072 }
1073 
1074 
1075 }
1076 
1077