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 42 #include <expat.h> 43 44 using namespace ::rtl; 45 using namespace ::std; 46 using namespace ::osl; 47 using namespace ::cppu; 48 using namespace ::com::sun::star::uno; 49 using namespace ::com::sun::star::lang; 50 using namespace ::com::sun::star::registry; 51 using namespace ::com::sun::star::xml::sax; 52 using namespace ::com::sun::star::util; 53 using namespace ::com::sun::star::io; 54 55 #include "factory.hxx" 56 #include "attrlistimpl.hxx" 57 #include "xml2utf.hxx" 58 59 namespace sax_expatwrap { 60 61 // Useful macros for correct String conversion depending on the chosen expat-mode 62 #ifdef XML_UNICODE 63 OUString XmlNChar2OUString( const XML_Char *p , int nLen ) 64 { 65 if( p ) { 66 if( sizeof( sal_Unicode ) == sizeof( XML_Char ) ) 67 { 68 return OUString( (sal_Unicode*)p,nLen); 69 } 70 else 71 { 72 sal_Unicode *pWchar = (sal_Unicode *)alloca( sizeof( sal_Unicode ) * nLen ); 73 for( int n = 0 ; n < nLen ; n++ ) { 74 pWchar[n] = (sal_Unicode) p[n]; 75 } 76 return OUString( pWchar , nLen ); 77 } 78 } 79 else { 80 return OUString(); 81 } 82 } 83 84 OUString XmlChar2OUString( const XML_Char *p ) 85 { 86 if( p ) { 87 int nLen; 88 for( nLen = 0 ; p[nLen] ; nLen ++ ) 89 ; 90 return XmlNChar2OUString( p , nLen ); 91 } 92 else return OUString(); 93 } 94 95 96 #define XML_CHAR_TO_OUSTRING(x) XmlChar2OUString(x) 97 #define XML_CHAR_N_TO_USTRING(x,n) XmlNChar2OUString(x,n) 98 #else 99 #define XML_CHAR_TO_OUSTRING(x) OUString(x , strlen( x ), RTL_TEXTENCODING_UTF8) 100 #define XML_CHAR_N_TO_USTRING(x,n) OUString(x,n, RTL_TEXTENCODING_UTF8 ) 101 #endif 102 103 104 /* 105 * The following macro encapsulates any call to an event handler. 106 * It ensures, that exceptions thrown by the event handler are 107 * treated properly. 108 */ 109 #define CALL_ELEMENT_HANDLER_AND_CARE_FOR_EXCEPTIONS(pThis,call) \ 110 if( ! pThis->bExceptionWasThrown ) { \ 111 try {\ 112 pThis->call;\ 113 }\ 114 catch( SAXParseException &e ) {\ 115 pThis->callErrorHandler( pThis , e );\ 116 }\ 117 catch( SAXException &e ) {\ 118 pThis->callErrorHandler( pThis , SAXParseException(\ 119 e.Message, \ 120 e.Context, \ 121 e.WrappedException,\ 122 pThis->rDocumentLocator->getPublicId(),\ 123 pThis->rDocumentLocator->getSystemId(),\ 124 pThis->rDocumentLocator->getLineNumber(),\ 125 pThis->rDocumentLocator->getColumnNumber()\ 126 ) );\ 127 }\ 128 catch( com::sun::star::uno::RuntimeException &e ) {\ 129 pThis->bExceptionWasThrown = sal_True; \ 130 pThis->bRTExceptionWasThrown = sal_True; \ 131 pImpl->rtexception = e; \ 132 }\ 133 }\ 134 ((void)0) 135 136 #define IMPLEMENTATION_NAME "com.sun.star.comp.extensions.xml.sax.ParserExpat" 137 #define SERVICE_NAME "com.sun.star.xml.sax.Parser" 138 139 class SaxExpatParser_Impl; 140 141 142 // This class implements the external Parser interface 143 class SaxExpatParser : 144 public WeakImplHelper2< 145 XParser, 146 XServiceInfo 147 > 148 { 149 150 public: 151 SaxExpatParser(); 152 ~SaxExpatParser(); 153 154 public: 155 156 // The implementation details 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 const Reference< XMultiServiceFactory > & ) throw(Exception) 193 { 194 SaxExpatParser *p = new SaxExpatParser; 195 196 return Reference< XInterface > ( (OWeakObject * ) p ); 197 } 198 199 200 201 Sequence< OUString > SaxExpatParser::getSupportedServiceNames_Static(void) throw () 202 { 203 Sequence<OUString> aRet(1); 204 aRet.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICE_NAME) ); 205 return aRet; 206 } 207 208 209 //--------------------------------------------- 210 // the implementation part 211 //--------------------------------------------- 212 213 214 // Entity binds all information neede for a single file 215 struct Entity 216 { 217 InputSource structSource; 218 XML_Parser pParser; 219 XMLFile2UTFConverter converter; 220 }; 221 222 223 class SaxExpatParser_Impl 224 { 225 public: // module scope 226 Mutex aMutex; 227 228 Reference< XDocumentHandler > rDocumentHandler; 229 Reference< XExtendedDocumentHandler > rExtendedDocumentHandler; 230 231 Reference< XErrorHandler > rErrorHandler; 232 Reference< XDTDHandler > rDTDHandler; 233 Reference< XEntityResolver > rEntityResolver; 234 Reference < XLocator > rDocumentLocator; 235 236 237 Reference < XAttributeList > rAttrList; 238 AttributeList *pAttrList; 239 240 // External entity stack 241 vector<struct Entity> vecEntity; 242 void pushEntity( const struct Entity &entity ) 243 { vecEntity.push_back( entity ); } 244 void popEntity() 245 { vecEntity.pop_back( ); } 246 struct Entity &getEntity() 247 { return vecEntity.back(); } 248 249 250 // Exception cannot be thrown through the C-XmlParser (possible resource leaks), 251 // therefor the exception must be saved somewhere. 252 SAXParseException exception; 253 RuntimeException rtexception; 254 sal_Bool bExceptionWasThrown; 255 sal_Bool bRTExceptionWasThrown; 256 257 Locale locale; 258 259 public: 260 // the C-Callbacks for the expat parser 261 void static callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts); 262 void static callbackEndElement(void *userData, const XML_Char *name); 263 void static callbackCharacters( void *userData , const XML_Char *s , int nLen ); 264 void static callbackProcessingInstruction( void *userData , 265 const XML_Char *sTarget , 266 const XML_Char *sData ); 267 268 void static callbackUnparsedEntityDecl( void *userData , 269 const XML_Char *entityName, 270 const XML_Char *base, 271 const XML_Char *systemId, 272 const XML_Char *publicId, 273 const XML_Char *notationName); 274 275 void static callbackNotationDecl( void *userData, 276 const XML_Char *notationName, 277 const XML_Char *base, 278 const XML_Char *systemId, 279 const XML_Char *publicId); 280 281 int static callbackExternalEntityRef( XML_Parser parser, 282 const XML_Char *openEntityNames, 283 const XML_Char *base, 284 const XML_Char *systemId, 285 const XML_Char *publicId); 286 287 int static callbackUnknownEncoding(void *encodingHandlerData, 288 const XML_Char *name, 289 XML_Encoding *info); 290 291 void static callbackDefault( void *userData, const XML_Char *s, int len); 292 293 void static callbackStartCDATA( void *userData ); 294 void static callbackEndCDATA( void *userData ); 295 void static callbackComment( void *userData , const XML_Char *s ); 296 void static callErrorHandler( SaxExpatParser_Impl *pImpl , const SAXParseException &e ); 297 298 public: 299 void parse(); 300 }; 301 302 extern "C" 303 { 304 static void call_callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts) 305 { 306 SaxExpatParser_Impl::callbackStartElement(userData,name,atts); 307 } 308 static void call_callbackEndElement(void *userData, const XML_Char *name) 309 { 310 SaxExpatParser_Impl::callbackEndElement(userData,name); 311 } 312 static void call_callbackCharacters( void *userData , const XML_Char *s , int nLen ) 313 { 314 SaxExpatParser_Impl::callbackCharacters(userData,s,nLen); 315 } 316 static void call_callbackProcessingInstruction(void *userData,const XML_Char *sTarget,const XML_Char *sData ) 317 { 318 SaxExpatParser_Impl::callbackProcessingInstruction(userData,sTarget,sData ); 319 } 320 static void call_callbackUnparsedEntityDecl(void *userData , 321 const XML_Char *entityName, 322 const XML_Char *base, 323 const XML_Char *systemId, 324 const XML_Char *publicId, 325 const XML_Char *notationName) 326 { 327 SaxExpatParser_Impl::callbackUnparsedEntityDecl(userData,entityName,base,systemId,publicId,notationName); 328 } 329 static void call_callbackNotationDecl(void *userData, 330 const XML_Char *notationName, 331 const XML_Char *base, 332 const XML_Char *systemId, 333 const XML_Char *publicId) 334 { 335 SaxExpatParser_Impl::callbackNotationDecl(userData,notationName,base,systemId,publicId); 336 } 337 static int call_callbackExternalEntityRef(XML_Parser parser, 338 const XML_Char *openEntityNames, 339 const XML_Char *base, 340 const XML_Char *systemId, 341 const XML_Char *publicId) 342 { 343 return SaxExpatParser_Impl::callbackExternalEntityRef(parser,openEntityNames,base,systemId,publicId); 344 } 345 static int call_callbackUnknownEncoding(void *encodingHandlerData, 346 const XML_Char *name, 347 XML_Encoding *info) 348 { 349 return SaxExpatParser_Impl::callbackUnknownEncoding(encodingHandlerData,name,info); 350 } 351 static void call_callbackDefault( void *userData, const XML_Char *s, int len) 352 { 353 SaxExpatParser_Impl::callbackDefault(userData,s,len); 354 } 355 static void call_callbackStartCDATA( void *userData ) 356 { 357 SaxExpatParser_Impl::callbackStartCDATA(userData); 358 } 359 static void call_callbackEndCDATA( void *userData ) 360 { 361 SaxExpatParser_Impl::callbackEndCDATA(userData); 362 } 363 static void call_callbackComment( void *userData , const XML_Char *s ) 364 { 365 SaxExpatParser_Impl::callbackComment(userData,s); 366 } 367 } 368 369 370 //--------------------------------------------- 371 // LocatorImpl 372 //--------------------------------------------- 373 class LocatorImpl : 374 public WeakImplHelper2< XLocator, com::sun::star::io::XSeekable > 375 // should use a different interface for stream positions! 376 { 377 public: 378 LocatorImpl( SaxExpatParser_Impl *p ) 379 { 380 m_pParser = p; 381 } 382 383 public: //XLocator 384 virtual sal_Int32 SAL_CALL getColumnNumber(void) throw () 385 { 386 return XML_GetCurrentColumnNumber( m_pParser->getEntity().pParser ); 387 } 388 virtual sal_Int32 SAL_CALL getLineNumber(void) throw () 389 { 390 return XML_GetCurrentLineNumber( m_pParser->getEntity().pParser ); 391 } 392 virtual OUString SAL_CALL getPublicId(void) throw () 393 { 394 return m_pParser->getEntity().structSource.sPublicId; 395 } 396 virtual OUString SAL_CALL getSystemId(void) throw () 397 { 398 return m_pParser->getEntity().structSource.sSystemId; 399 } 400 401 // XSeekable (only for getPosition) 402 403 virtual void SAL_CALL seek( sal_Int64 ) throw() 404 { 405 } 406 virtual sal_Int64 SAL_CALL getPosition() throw() 407 { 408 return XML_GetCurrentByteIndex( m_pParser->getEntity().pParser ); 409 } 410 virtual ::sal_Int64 SAL_CALL getLength() throw() 411 { 412 return 0; 413 } 414 415 private: 416 417 SaxExpatParser_Impl *m_pParser; 418 }; 419 420 421 422 423 SaxExpatParser::SaxExpatParser( ) 424 { 425 m_pImpl = new SaxExpatParser_Impl; 426 427 LocatorImpl *pLoc = new LocatorImpl( m_pImpl ); 428 m_pImpl->rDocumentLocator = Reference< XLocator > ( pLoc ); 429 430 // performance-Improvment. Reference is needed when calling the startTag callback. 431 // Handing out the same object with every call is allowed (see sax-specification) 432 m_pImpl->pAttrList = new AttributeList; 433 m_pImpl->rAttrList = Reference< XAttributeList > ( m_pImpl->pAttrList ); 434 435 m_pImpl->bExceptionWasThrown = sal_False; 436 m_pImpl->bRTExceptionWasThrown = sal_False; 437 } 438 439 SaxExpatParser::~SaxExpatParser() 440 { 441 delete m_pImpl; 442 } 443 444 445 /*************** 446 * 447 * parseStream does Parser-startup initializations. The SaxExpatParser_Impl::parse() method does 448 * the file-specific initialization work. (During a parser run, external files may be opened) 449 * 450 ****************/ 451 void SaxExpatParser::parseStream( const InputSource& structSource) 452 throw (SAXException, 453 IOException, 454 RuntimeException) 455 { 456 // Only one text at one time 457 MutexGuard guard( m_pImpl->aMutex ); 458 459 460 struct Entity entity; 461 entity.structSource = structSource; 462 463 if( ! entity.structSource.aInputStream.is() ) 464 { 465 throw SAXException( OUString::createFromAscii( "No input source" ) , 466 Reference< XInterface > () , Any() ); 467 } 468 469 entity.converter.setInputStream( entity.structSource.aInputStream ); 470 if( entity.structSource.sEncoding.getLength() ) 471 { 472 entity.converter.setEncoding( 473 OUStringToOString( entity.structSource.sEncoding , RTL_TEXTENCODING_ASCII_US ) ); 474 } 475 476 // create parser with proper encoding 477 entity.pParser = XML_ParserCreate( 0 ); 478 if( ! entity.pParser ) 479 { 480 throw SAXException( OUString::createFromAscii( "Couldn't create parser" ) , 481 Reference< XInterface > (), Any() ); 482 } 483 484 // set all necessary C-Callbacks 485 XML_SetUserData( entity.pParser , m_pImpl ); 486 XML_SetElementHandler( entity.pParser , 487 call_callbackStartElement , 488 call_callbackEndElement ); 489 XML_SetCharacterDataHandler( entity.pParser , call_callbackCharacters ); 490 XML_SetProcessingInstructionHandler(entity.pParser , 491 call_callbackProcessingInstruction ); 492 XML_SetUnparsedEntityDeclHandler( entity.pParser, 493 call_callbackUnparsedEntityDecl ); 494 XML_SetNotationDeclHandler( entity.pParser, call_callbackNotationDecl ); 495 XML_SetExternalEntityRefHandler( entity.pParser, 496 call_callbackExternalEntityRef); 497 XML_SetUnknownEncodingHandler( entity.pParser, call_callbackUnknownEncoding ,0); 498 499 if( m_pImpl->rExtendedDocumentHandler.is() ) { 500 501 // These handlers just delegate calls to the ExtendedHandler. If no extended handler is 502 // given, these callbacks can be ignored 503 XML_SetDefaultHandlerExpand( entity.pParser, call_callbackDefault ); 504 XML_SetCommentHandler( entity.pParser, call_callbackComment ); 505 XML_SetCdataSectionHandler( entity.pParser , 506 call_callbackStartCDATA , 507 call_callbackEndCDATA ); 508 } 509 510 511 m_pImpl->exception = SAXParseException(); 512 m_pImpl->pushEntity( entity ); 513 try 514 { 515 // start the document 516 if( m_pImpl->rDocumentHandler.is() ) { 517 m_pImpl->rDocumentHandler->setDocumentLocator( m_pImpl->rDocumentLocator ); 518 m_pImpl->rDocumentHandler->startDocument(); 519 } 520 521 m_pImpl->parse(); 522 523 // finish document 524 if( m_pImpl->rDocumentHandler.is() ) { 525 m_pImpl->rDocumentHandler->endDocument(); 526 } 527 } 528 // catch( SAXParseException &e ) 529 // { 530 // m_pImpl->popEntity(); 531 // XML_ParserFree( entity.pParser ); 532 // Any aAny; 533 // aAny <<= e; 534 // throw SAXException( e.Message, e.Context, aAny ); 535 // } 536 catch( SAXException & ) 537 { 538 m_pImpl->popEntity(); 539 XML_ParserFree( entity.pParser ); 540 throw; 541 } 542 catch( IOException & ) 543 { 544 m_pImpl->popEntity(); 545 XML_ParserFree( entity.pParser ); 546 throw; 547 } 548 catch( RuntimeException & ) 549 { 550 m_pImpl->popEntity(); 551 XML_ParserFree( entity.pParser ); 552 throw; 553 } 554 555 m_pImpl->popEntity(); 556 XML_ParserFree( entity.pParser ); 557 } 558 559 void SaxExpatParser::setDocumentHandler(const Reference< XDocumentHandler > & xHandler) 560 throw (RuntimeException) 561 { 562 m_pImpl->rDocumentHandler = xHandler; 563 m_pImpl->rExtendedDocumentHandler = 564 Reference< XExtendedDocumentHandler >( xHandler , UNO_QUERY ); 565 } 566 567 void SaxExpatParser::setErrorHandler(const Reference< XErrorHandler > & xHandler) 568 throw (RuntimeException) 569 { 570 m_pImpl->rErrorHandler = xHandler; 571 } 572 573 void SaxExpatParser::setDTDHandler(const Reference< XDTDHandler > & xHandler) 574 throw (RuntimeException) 575 { 576 m_pImpl->rDTDHandler = xHandler; 577 } 578 579 void SaxExpatParser::setEntityResolver(const Reference < XEntityResolver > & xResolver) 580 throw (RuntimeException) 581 { 582 m_pImpl->rEntityResolver = xResolver; 583 } 584 585 586 void SaxExpatParser::setLocale( const Locale & locale ) throw (RuntimeException) 587 { 588 m_pImpl->locale = locale; 589 } 590 591 // XServiceInfo 592 OUString SaxExpatParser::getImplementationName() throw () 593 { 594 return OUString::createFromAscii( IMPLEMENTATION_NAME ); 595 } 596 597 // XServiceInfo 598 sal_Bool SaxExpatParser::supportsService(const OUString& ServiceName) throw () 599 { 600 Sequence< OUString > aSNL = getSupportedServiceNames(); 601 const OUString * pArray = aSNL.getConstArray(); 602 603 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 604 if( pArray[i] == ServiceName ) 605 return sal_True; 606 607 return sal_False; 608 } 609 610 // XServiceInfo 611 Sequence< OUString > SaxExpatParser::getSupportedServiceNames(void) throw () 612 { 613 614 Sequence<OUString> seq(1); 615 seq.getArray()[0] = OUString::createFromAscii( SERVICE_NAME ); 616 return seq; 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 extern "C" 1025 { 1026 1027 void SAL_CALL component_getImplementationEnvironment( 1028 const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) 1029 { 1030 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 1031 } 1032 1033 void * SAL_CALL component_getFactory( 1034 const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ ) 1035 { 1036 void * pRet = 0; 1037 1038 if (pServiceManager ) 1039 { 1040 Reference< XSingleServiceFactory > xRet; 1041 Reference< XMultiServiceFactory > xSMgr = 1042 reinterpret_cast< XMultiServiceFactory * > ( pServiceManager ); 1043 1044 OUString aImplementationName = OUString::createFromAscii( pImplName ); 1045 1046 if (aImplementationName == 1047 OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) ) ) 1048 { 1049 xRet = createSingleFactory( xSMgr, aImplementationName, 1050 SaxExpatParser_CreateInstance, 1051 SaxExpatParser::getSupportedServiceNames_Static() ); 1052 } 1053 else if ( aImplementationName == SaxWriter_getImplementationName() ) 1054 { 1055 xRet = createSingleFactory( xSMgr, aImplementationName, 1056 SaxWriter_CreateInstance, 1057 SaxWriter_getSupportedServiceNames() ); 1058 } 1059 1060 if (xRet.is()) 1061 { 1062 xRet->acquire(); 1063 pRet = xRet.get(); 1064 } 1065 } 1066 1067 return pRet; 1068 } 1069 1070 1071 } 1072 1073