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