LCOV - code coverage report
Current view: top level - sax/source/expatwrap - sax_expat.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 366 0.0 %
Date: 2014-04-14 Functions: 0 59 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10