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